基于C++枚举的井字棋游戏开发技术求助
双人井字棋实现(优化版,基于枚举)
需求:编写双人人类对战的井字棋游戏,尽可能使用枚举表示棋盘状态;提问者仅掌握数组和枚举基础概念,尝试3天未解决,寻求帮助。
#include <iostream> #include <string> // 用枚举明确表示棋盘每个格子的三种状态,完全贴合需求 enum class BoardState { Empty, Player1, Player2 }; // 全局变量(适合新手理解,避免复杂类结构) std::string player1Name, player2Name; BoardState board[3][3] = { {BoardState::Empty, BoardState::Empty, BoardState::Empty}, {BoardState::Empty, BoardState::Empty, BoardState::Empty}, {BoardState::Empty, BoardState::Empty, BoardState::Empty} }; BoardState currentPlayer = BoardState::Player1; // 跟踪当前回合玩家 // 渲染棋盘:根据枚举状态输出对应符号 void drawBoard() { std::cout << "\n | | \n"; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { char symbol = ' '; if (board[i][j] == BoardState::Player1) symbol = 'X'; else if (board[i][j] == BoardState::Player2) symbol = 'O'; else symbol = '1' + (i*3 + j); // 空格子显示对应数字1-9 std::cout << " " << symbol << " "; if (j < 2) std::cout << "|"; } std::cout << "\n"; if (i < 2) std::cout << "_____|_____|_____\n | | \n"; } std::cout << " | | \n\n"; } // 处理玩家输入,转换为棋盘行列并检查合法性 bool handleInput() { int choice; const std::string& currentName = (currentPlayer == BoardState::Player1) ? player1Name : player2Name; std::cout << currentName << ",请输入要下的位置(1-9):"; std::cin >> choice; // 检查输入范围 if (choice < 1 || choice > 9) { std::cout << "输入无效,请输入1-9之间的数字!\n"; return false; } // 将1-9转换为棋盘的行和列索引 int row = (choice - 1) / 3; int col = (choice - 1) % 3; // 检查位置是否已被占用 if (board[row][col] != BoardState::Empty) { std::cout << "该位置已经被占用,请重新选择!\n"; return false; } // 落子并切换回合 board[row][col] = currentPlayer; currentPlayer = (currentPlayer == BoardState::Player1) ? BoardState::Player2 : BoardState::Player1; return true; } // 检查游戏是否结束(获胜或平局) bool checkGameOver(bool& isTie) { isTie = true; // 检查行获胜 for (int i = 0; i < 3; ++i) { if (board[i][0] != BoardState::Empty && board[i][0] == board[i][1] && board[i][1] == board[i][2]) { return true; } // 检查是否还有空位置 for (int j = 0; j < 3; ++j) { if (board[i][j] == BoardState::Empty) { isTie = false; } } } // 检查列获胜 for (int j = 0; j < 3; ++j) { if (board[0][j] != BoardState::Empty && board[0][j] == board[1][j] && board[1][j] == board[2][j]) { return true; } } // 检查对角线获胜 if (board[0][0] != BoardState::Empty && board[0][0] == board[1][1] && board[1][1] == board[2][2]) { return true; } if (board[0][2] != BoardState::Empty && board[0][2] == board[1][1] && board[1][1] == board[2][0]) { return true; } return isTie; } int main() { std::cout << "请输入玩家1的名字:"; std::cin >> player1Name; std::cout << player1Name << " 将使用 X 符号,先手\n"; std::cout << "请输入玩家2的名字:"; std::cin >> player2Name; std::cout << player2Name << " 将使用 O 符号,后手\n"; bool gameOver = false; bool isTie = false; while (!gameOver) { drawBoard(); // 直到输入有效才进入下一环节 while (!handleInput()) {} gameOver = checkGameOver(isTie); } drawBoard(); // 渲染最终棋盘状态 if (isTie) { std::cout << "平局!\n"; } else { // 最后切换了玩家,获胜者是上一回合的玩家 const std::string& winnerName = (currentPlayer == BoardState::Player1) ? player2Name : player1Name; std::cout << winnerName << " 获胜!恭喜!\n"; } return 0; }
关键改进说明
- 枚举的规范使用:用
enum class BoardState统一表示棋盘格子状态,彻底解决原代码中枚举与char数组混用的混乱问题,完全符合需求。 - 简洁的回合管理:通过全局变量
currentPlayer跟踪当前玩家,落子后直接切换,逻辑清晰易懂。 - 高效的输入转换:将玩家输入的1-9通过数学运算直接转换为棋盘行列索引,替代原代码中冗余的if-else判断。
- 准确的胜负判定:分别检查行、列、对角线的获胜条件,同时遍历棋盘判断是否还有空位置,精准识别平局。
- 友好的界面渲染:空格子显示对应数字1-9,玩家落子后显示X/O,操作引导更直观。
内容的提问来源于stack exchange,提问作者Japer
相关产品推荐
相关产品推荐

