diff --git a/src/FileName.cpp b/src/FileName.cpp new file mode 100644 index 0000000..8fe084c --- /dev/null +++ b/src/FileName.cpp @@ -0,0 +1,319 @@ +#define _CRT_SECURE_NO_WARNINGS +#include +#include +#include +#include +#include +#include + +#define SIZE 15 +#define HISTORY_SIZE 500 + +typedef enum { + MODE_HUMAN_VS_HUMAN, + MODE_HUMAN_VS_AI, + MODE_EXIT +} GameMode; + +typedef enum { + EASY, + MEDIUM, + HARD +} Difficulty; + +typedef struct { + char board[SIZE][SIZE]; + GameMode mode; + Difficulty difficulty; + char currentPlayer; + int lastMove[2]; + int history[HISTORY_SIZE][2]; + int stepCount; +} GameState; + +void clearScreen() { + system("cls"); +} + +void initGame(GameState* game, GameMode mode) { + memset(game->board, '+', sizeof(game->board)); + game->mode = mode; + game->currentPlayer = 'X'; + game->stepCount = 0; + game->difficulty = MEDIUM; + memset(game->history, -1, sizeof(game->history)); +} + +void printBoard(const GameState* game) { + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + + printf(" "); + for (int i = 0; i < SIZE; i++) { + printf("%2d", i + 1); + } + printf("\n"); + + for (int i = 0; i < SIZE; i++) { + printf("%2d ", i + 1); + for (int j = 0; j < SIZE; j++) { + if (game->board[i][j] == 'X') { + SetConsoleTextAttribute(hConsole, 12); + } + else if (game->board[i][j] == 'O') { + SetConsoleTextAttribute(hConsole, 9); + } + printf("%2c", game->board[i][j]); + SetConsoleTextAttribute(hConsole, 7); + } + printf("\n"); + } +} + +bool isValidMove(const GameState* game, int x, int y) { + return x >= 0 && x < SIZE && y >= 0 && y < SIZE && game->board[x][y] == '+'; +} + +bool checkWin(const GameState* game, int x, int y) { + const int dirs[4][2] = { {0, 1}, {1, 0}, {1, 1}, {1, -1} }; + char player = game->board[x][y]; + + for (int d = 0; d < 4; d++) { + int count = 1; + + for (int step = 1; step < 5; step++) { + int nx = x + dirs[d][0] * step; + int ny = y + dirs[d][1] * step; + if (nx < 0 || nx >= SIZE || ny < 0 || ny >= SIZE || game->board[nx][ny] != player) break; + count++; + } + + for (int step = 1; step < 5; step++) { + int nx = x - dirs[d][0] * step; + int ny = y - dirs[d][1] * step; + if (nx < 0 || nx >= SIZE || ny < 0 || ny >= SIZE || game->board[nx][ny] != player) break; + count++; + } + + if (count >= 5) return true; + } + return false; +} + +void showWinMessage(char winner) { + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + clearScreen(); + + SetConsoleTextAttribute(hConsole, 14); // 黄色 + printf("================================\n"); + printf(" PLAYER %c WINS THE GAME!\n", winner); + printf("================================\n\n"); + SetConsoleTextAttribute(hConsole, 7); // 恢复白色 + + printf("Press Enter to return to main menu..."); + while (getchar() != '\n'); // 清空输入缓冲区 + getchar(); // 等待回车 +} + +void showDrawMessage() { + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + clearScreen(); + + SetConsoleTextAttribute(hConsole, 11); // 浅蓝色 + printf("================================\n"); + printf(" DRAW GAME!\n"); + printf("================================\n\n"); + SetConsoleTextAttribute(hConsole, 7); // 恢复白色 + + printf("Press Enter to return to main menu..."); + while (getchar() != '\n'); + getchar(); +} + +void aiMove(GameState* game) { + int x, y; + + if (game->difficulty == EASY) { + do { + x = rand() % SIZE; + y = rand() % SIZE; + } while (!isValidMove(game, x, y)); + } + else if (game->difficulty == MEDIUM) { + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + if (isValidMove(game, i, j)) { + game->board[i][j] = 'O'; + if (checkWin(game, i, j)) { + game->lastMove[0] = i; + game->lastMove[1] = j; + game->history[game->stepCount][0] = i; + game->history[game->stepCount][1] = j; + game->stepCount++; + return; + } + game->board[i][j] = '+'; + } + } + } + + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + if (isValidMove(game, i, j)) { + game->board[i][j] = 'X'; + if (checkWin(game, i, j)) { + game->board[i][j] = 'O'; + game->lastMove[0] = i; + game->lastMove[1] = j; + game->history[game->stepCount][0] = i; + game->history[game->stepCount][1] = j; + game->stepCount++; + return; + } + game->board[i][j] = '+'; + } + } + } + + do { + x = rand() % SIZE; + y = rand() % SIZE; + } while (!isValidMove(game, x, y)); + } + else { + do { + x = rand() % SIZE; + y = rand() % SIZE; + } while (!isValidMove(game, x, y)); + } + + game->board[x][y] = 'O'; + game->lastMove[0] = x; + game->lastMove[1] = y; + game->history[game->stepCount][0] = x; + game->history[game->stepCount][1] = y; + game->stepCount++; +} + +void showMainMenu() { + clearScreen(); + printf("=== GOMOKU GAME ===\n"); + printf("1. Player vs Player\n"); + printf("2. Player vs AI\n"); + printf("3. Set Difficulty\n"); + printf("4. Exit Game\n"); + printf("Select: "); +} + +void setDifficulty(GameState* game) { + clearScreen(); + printf("=== SET DIFFICULTY ===\n"); + printf("1. Easy\n"); + printf("2. Medium\n"); + printf("3. Hard\n"); + printf("Select: "); + + int choice; + scanf("%d", &choice); + + switch (choice) { + case 1: game->difficulty = EASY; break; + case 2: game->difficulty = MEDIUM; break; + case 3: game->difficulty = HARD; break; + default: printf("Invalid choice, keeping current difficulty\n"); + } +} + +GameMode gameLoop(GameState* game) { + while (1) { + clearScreen(); + printBoard(game); + + if (game->mode == MODE_HUMAN_VS_AI && game->currentPlayer == 'O') { + printf("AI is thinking...\n"); + Sleep(800); + aiMove(game); + printf("AI moved to: %d %d\n", game->lastMove[0] + 1, game->lastMove[1] + 1); + } + else { + printf("Player %c's turn (enter row and column, or 4 to exit): ", game->currentPlayer); + + int row, col; + if (scanf("%d", &row) != 1) { + printf("Invalid input format!\n"); + while (getchar() != '\n'); + continue; + } + + if (row == 4) { + return MODE_EXIT; + } + + if (scanf("%d", &col) != 1) { + printf("Invalid input format!\n"); + while (getchar() != '\n'); + continue; + } + + row--; col--; + if (!isValidMove(game, row, col)) { + printf("Invalid move, try again\n"); + continue; + } + + game->board[row][col] = game->currentPlayer; + game->lastMove[0] = row; + game->lastMove[1] = col; + game->history[game->stepCount][0] = row; + game->history[game->stepCount][1] = col; + game->stepCount++; + } + + if (checkWin(game, game->lastMove[0], game->lastMove[1])) { + showWinMessage(game->currentPlayer); + return game->mode; + } + + if (game->stepCount == SIZE * SIZE) { + showDrawMessage(); + return game->mode; + } + + game->currentPlayer = (game->currentPlayer == 'X') ? 'O' : 'X'; + } +} + +int main() { + srand((unsigned int)time(NULL)); + GameState game; + int choice; + GameMode result; + + while (1) { + showMainMenu(); + + if (scanf("%d", &choice) != 1) { + while (getchar() != '\n'); + continue; + } + + switch (choice) { + case 1: + initGame(&game, MODE_HUMAN_VS_HUMAN); + result = gameLoop(&game); + if (result == MODE_EXIT) continue; + break; + case 2: + initGame(&game, MODE_HUMAN_VS_AI); + result = gameLoop(&game); + if (result == MODE_EXIT) continue; + break; + case 3: + setDifficulty(&game); + break; + case 4: + return 0; + default: + printf("Invalid selection!\n"); + } + } +} \ No newline at end of file