Система сохранений и ходов компьютера в консольных крестиках-ноликах - C (СИ)
Формулировка задачи:
Вчера вечером решил продолжить изучать С++, что бы вспомнить основы начал с СИ и собрался написать игру крестики нолики. Игра практически готова и даже работает для режима "2 игрока", но я пока не знаю, как реализовать систему ходов компьютера и систему сохранений. Подкиньте идею, как можно реализовать такие системы.
P.S. Вот исходник:
///////////////////////////////// // Program : крестики - нолики // // Autor : Бесчастных Денис // ///////////////////////////////// #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> #include <locale.h> #include <time.h> #define MAX_SAVES 3 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); //Получаение дескриптора устройства стандартного вывода static int hightMenu = 1; /* 1 - Начать игру 2 - Загрузить игру 3 - Как играть? 4 - Выход */ static int lowMenu = 1; /* 1 - 2 игрока 2 - Против компьютера 3 - Назад */ static int inGameMenu = 1; /* 1 - Продолжить игру 2 - Сохранить игру 3 - Как играть? 4 - К главному меню 5 - Выход */ static int turn; /* чья очередь ходить 1 - 1-ый игрок 2 - 2-ой игрок */ static int loadMenu = 1; static int win = 0; static int numberMoves = 0; static int gamemode = -1; /* 0 - 2 игрока 1 - против компьютера */ static char gamer1 = (turn == 1) ? 'X' : 'O'; static char gamer2 = (turn == 2) ? 'X' : 'O'; static int coordX = 1; static int coordY = 1; static int gameMatrix[3][3]; static char form[14][15]; static int saveNumber = 0; static int EXIT = 0; static int saves[MAX_SAVES][11]; char bufRus[256]; FILE* FORM; FILE* SAVES; ///Список прототипов void paintComponent(); //делает отрисовку после загрузки void setGame(int); //устанавливает игру по сохранению void saveGame(); //сохраняет текущую игру void isWin(); //функция определения победы char *Rus(const char *text); //функция вывода русских букв void readForm(); //читает форму void generateForm(); //создает форму, если ее нет void printForm(); //выводит форму void setForm(int, int, int); //устанавливает в форму новое значение void readSaves(); //читает сохранения void fileSystem(); //открывает/создает системные файлы void printHelp(); //выводит справку void printHightMenu(); //выводит главное меню void printLowMenu(); //выводит меню новой игры void printGame(); //выводит игровое окно void printInGameMenu(); //выводит меню во время игры void printLoadMenu(); //выводит меню загрузки void printWin(); //вывод победы void hightMenuCycle(); //цикл главного меню void lowMenuCycle(); //цикл меню новой игры void gameCycle(); //цикл игры void inGameCycle(); //цикл меню во время игры void loadMenuCycle(); //цикл меню загрузки void paintComponent() { for(int x = 1; x < 4; x++) for(int y = 1; y < 4; y++) if (gameMatrix[x - 1][y - 1]) setForm(gameMatrix[x - 1][y - 1], x, y); } void setGame(int n) { numberMoves = 0; for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++) { gameMatrix[i][j] = saves[n][i * 3 + j]; if (gameMatrix[i][j]) numberMoves++; } turn = saves[n][9]; gamemode = saves[n][10]; win = 0; if (numberMoves % 2) { gamer1 = (turn == 2) ? 'O' : 'X'; gamer2 = (turn == 2) ? 'X' : 'O'; } else { gamer1 = (turn == 1) ? 'O' : 'X'; gamer2 = (turn == 1) ? 'X' : 'O'; } } void saveGame() { SAVES = fopen("saves.txt", "w"); if (saveNumber < MAX_SAVES) { saveNumber++; fprintf(SAVES, "%d ", saveNumber); for(int i = 0; i < saveNumber - 1; i++) for(int j = 0; j < 10; j++) fprintf(SAVES, "%d ", saves[i][j]); for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++) { fprintf(SAVES, "%d ", gameMatrix[i][j]); saves[saveNumber - 1][i * 3 + j] = gameMatrix[i][j]; } fprintf(SAVES, "%d %d", turn, gamemode); saves[saveNumber - 1][9] = turn; saves[saveNumber - 1][10] = gamemode; fclose(SAVES); system("cls"); printf(Rus("Игра сохранена!\n")); system("pause"); } else { system("cls"); printf(Rus("Нет места для сохранения!\n")); system("pause"); } } void isWin() { for(int j = 0; j < 3; j++) { if (gameMatrix[j][0] == gameMatrix[j][1] && gameMatrix[j][1] == gameMatrix[j][2]) win = gameMatrix[j][0]; if (win) break; if (gameMatrix[0][j] == gameMatrix[1][j] && gameMatrix[1][j] == gameMatrix[2][j]) win = gameMatrix[0][j]; if (win) break; } if (win) return; if ((gameMatrix[0][0] == gameMatrix[1][1] && gameMatrix[1][1] == gameMatrix[2][2]) || (gameMatrix[2][0] == gameMatrix[1][1] && gameMatrix[1][1] == gameMatrix[0][2])) win = gameMatrix[1][1]; } char *Rus(const char *text) { CharToOem(text,bufRus); return bufRus; } void readForm() { for(int i = 0; i < 14; i++) fgets(form[i], 15, FORM); } void generateForm() { char c01 = (char)201; //левый вырхний угол char c02 = (char)187; //правый верхний угол char c03 = (char)200; //нижний левый угол char c04 = (char)188; //нижний правый угол char c05 = (char)205; //равно горизонтальное char c06 = (char)186; //равно вертикальное char c07 = (char)203; //верхний тристоронник char c08 = (char)202; //нижний тристоронник char c09 = (char)204; //левый тристоронник char c10 = (char)185; //правый тристоронник char c11 = (char)206; //четверосторонник char s00[14] = {c01, c05, c05, c05, c07, c05, c05, c05, c07, c05, c05, c05, c02, '\0'}; char s01[14] = {c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, '\0'}; char s02[14] = {c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, '\0'}; char s03[14] = {c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, '\0'}; char s04[14] = {c09, c05, c05, c05, c11, c05, c05, c05, c11, c05, c05, c05, c10, '\0'}; char s05[14] = {c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, '\0'}; char s06[14] = {c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, '\0'}; char s07[14] = {c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, '\0'}; char s08[14] = {c09, c05, c05, c05, c11, c05, c05, c05, c11, c05, c05, c05, c10, '\0'}; char s09[14] = {c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, '\0'}; char s10[14] = {c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, '\0'}; char s11[14] = {c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, ' ', ' ', ' ', c06, '\0'}; char s12[14] = {c03, c05, c05, c05, c08, c05, c05, c05, c08, c05, c05, c05, c04, '\0'}; fprintf(FORM, "%s\n", s00); fprintf(FORM, "%s\n", s01); fprintf(FORM, "%s\n", s02); fprintf(FORM, "%s\n", s03); fprintf(FORM, "%s\n", s04); fprintf(FORM, "%s\n", s05); fprintf(FORM, "%s\n", s06); fprintf(FORM, "%s\n", s07); fprintf(FORM, "%s\n", s08); fprintf(FORM, "%s\n", s09); fprintf(FORM, "%s\n", s10); fprintf(FORM, "%s\n", s11); fprintf(FORM, "%s\n", s12); }
Решение задачи: «Система сохранений и ходов компьютера в консольных крестиках-ноликах»
textual
Листинг программы
void printLoadMenu() { system("cls"); SetConsoleTextAttribute(hConsole, (WORD) ((12) | 10)); printf(Rus("################################################################################")); printf(Rus("# #")); printf(Rus("# Крестики-Нолики #")); printf(Rus("# #")); printf(Rus("################################################################################")); printf(Rus("\n\nЗагрузка сохранения:\n\n")); char s1[] = "Сохранений нет\n"; char s2[] = "Назад\n"; if (!saveNumber) printf(Rus(s1)); for(int i = 0; i < saveNumber + 1; i++) if (loadMenu == i + 1) { SetConsoleTextAttribute(hConsole, (WORD) ((15 << 5) | 0)); if (i == saveNumber) printf("%s", Rus(s2)); else printf("%s%d%d\n", Rus("Сохранение"), i / 10, i % 10); SetConsoleTextAttribute(hConsole, (WORD) ((12) | 10)); } else if (i == saveNumber) printf("%s", Rus(s2)); else printf("%s%d%d\n", Rus("Сохранение"), i / 10, i % 10); } void printWin() { system("cls"); printf(Rus("################################################################################")); printf(Rus("# #")); printf(Rus("# Крестики-Нолики #")); printf(Rus("# #")); printf(Rus("################################################################################")); printf("\n\n"); printf(Rus("\t\t\t\tИГРА ОКОНЧЕНА\n")); if (!win) printf(Rus("Ничья!!!\n")); else if ((turn == 1 && gamer2 == 'X') || (turn == 2 && gamer2 == 'O')) if (gamemode) printf(Rus("Победил компьютер!!!\n")); else printf(Rus("Победил 2-ой игрок!!!\n")); else if (gamemode) printf(Rus("Вы победили!!!\n")); else printf(Rus("Победил 1-ый игрок!!!\n")); printf("\n\n\n"); system("pause"); } void hightMenuCycle() { for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++) gameMatrix[i][j] = 0; srand(time(NULL)); turn = rand() % 2 + 1; gamer1 = (turn == 1) ? 'X' : 'O'; gamer2 = (turn == 2) ? 'X' : 'O'; gamemode = -1; numberMoves = 0; turn = 1; coordX = 1; coordY = 1; fileSystem(); win = 0; for(int number = 0; gamemode == -1;) { printHightMenu(); number = getch(); if (number == 224) number = getch(); //служебная клавища состоит из 2 символов 224 + еще чет switch (number) { case 13: // если ENTER switch(hightMenu) { case 1: lowMenuCycle(); break; case 2: loadMenuCycle(); break; case 3: printHelp(); break; case 4: EXIT = 1; return; } break; case 80: // если ВНИЗ hightMenu = hightMenu % 4 + 1; break; case 72: // если ВВЕРХ hightMenu = hightMenu - 1 + (hightMenu - 1 == 0) * 4; break; } } if (gamemode > -1) gameCycle(); } void lowMenuCycle() { for(int number = 0;;) { printLowMenu(); number = getch(); if (number == 224) number = getch(); //служебная клавища состоит из 2 символов 224 + еще чет switch (number) { case 13: // если ENTER switch(lowMenu) { case 1: gamemode = 0; return; case 2: gamemode = 1; return; case 3: return; } case 80: // если ВНИЗ lowMenu = lowMenu % 3 + 1; break; case 72: // если ВВЕРХ lowMenu = lowMenu - 1 + (lowMenu - 1 == 0) * 3; break; } } } void gameCycle() { for(int number = 0; numberMoves < 10;) { printGame(); if (numberMoves == 9) { numberMoves++; continue; } if (win) break; number = getch(); if (number == 224) number = getch(); //служебная клавища состоит из 2 символов 224 + еще чет switch (number) { case 27: // если ESC inGameCycle(); break; case 13: // если ENTER if (!gameMatrix[coordX - 1][coordY - 1]) { gameMatrix[coordX - 1][coordY - 1] = turn; isWin(); numberMoves++; setForm(numberMoves, coordX, coordY); if (win) break; turn++; turn = turn % 3 + (turn % 3 == 0); } break; case 75: //если ВЛЕВО if (coordY != 1) coordY--; break; case 77: //если ВПРАВО if (coordY != 3) coordY++; break; case 80: // если ВНИЗ if (coordX != 3) coordX++; break; case 72: // если ВВЕРХ if (coordX != 1) coordX--; break; } } printWin(); } void inGameCycle() { for(int number = 0; numberMoves < 10;) { printInGameMenu(); number = getch(); if (number == 224) number = getch(); //служебная клавища состоит из 2 символов 224 + еще чет switch (number) { case 27: // если ESC return; case 13: // если ENTER switch(inGameMenu) { case 1: return; case 2: saveGame(); break; case 3: printHelp(); break; case 5: EXIT = 1; case 4: numberMoves = 10; } break; case 80: // если ВНИЗ inGameMenu = inGameMenu % 5 + 1; break; case 72: // если ВВЕРХ inGameMenu = inGameMenu - 1 + (inGameMenu - 1 == 0) * 5; break; } } } void loadMenuCycle() { for(int number = 0;;) { printLoadMenu(); number = getch(); if (number == 224) number = getch(); //служебная клавища состоит из 2 символов 224 + еще чет switch (number) { case 27: // если ESC return; case 13: // если ENTER if (loadMenu == saveNumber + 1) return; else setGame(loadMenu); paintComponent(); system("cls"); for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) printf("%d ", gameMatrix[i][j]); printf("\n"); } system("pause"); return; case 80: // если ВНИЗ loadMenu = loadMenu % (saveNumber + 1) + 1; break; case 72: // если ВВЕРХ loadMenu = loadMenu - 1 + (loadMenu - 1 == 0) * (saveNumber + 1); break; } } } int main() { system("chcp 866"); for(; !EXIT;) hightMenuCycle(); return 0; }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д