#include\ \ #include\ \ using\ namespace\ std;\ \ \ class\ TicTacToe\ {\ private:\ \ \ \ vector<vector>\ board;\ \ //\ 用二维向量来表示棋盘\ \ \ \ char\ player;\ \ //\ 玩家的符号\ \ \ \ char\ computer;\ \ //\ 电脑的符号\ \ public:\ \ \ \ TicTacToe()\ {\ \ board.resize(3,\ vector(3,\ ''));\ \ //\ 初始化棋盘为3x3的空棋盘\ \ player\ =\ ' ';\ \ //\ 初始化玩家符号为空\ \ computer\ =\ ' ';\ \ //\ 初始化电脑符号为空\ \ }\ \ \ \ void\ startGame()\ {\ \ cout\ <<\ "Welcome\ to\ Tic\ Tac\ Toe!"\ <<\ endl;\ \ cout\ <<\ "Please\ choose\ 'X'\ or\ 'O':\ ";\ \ cin\ >>\ player;\ \ //\ 玩家选择自己的符号\ \ \ \ if\ (player\ ==\ 'X'\ ||\ player\ ==\ 'x')\ {\ \ computer\ =\ 'O';\ \ //\ 如果玩家选择X,则电脑选择O\ \ }\ else\ if\ (player\ ==\ 'O'\ ||\ player\ ==\ 'o')\ {\ \ computer\ =\ 'X';\ \ //\ 如果玩家选择O,则电脑选择X\ \ }\ else\ {\ \ cout\ <<\ "Invalid\ input.\ Please\ choose\ 'X'\ or\ 'O'."\ <<\ endl;\ \ //\ 如果玩家输入无效符号,则提示重新选择\ \ return;\ \ }\ \ \ \ cout\ <<\ "Do\ you\ want\ to\ play\ first?\ (Y/N):\ ";\ \ char\ choice;\ \ cin\ >>\ choice;\ \ //\ 玩家选择是否先手\ \ \ \ if\ (choice\ ==\ 'N'\ ||\ choice\ ==\ 'n')\ {\ \ //\ 如果玩家选择不先手,则电脑先行\ \ computerMove();\ \ printBoard();\ \ }\ \ \ \ playGame();\ \ //\ 进行游戏\ \ }\ \ private:\ \ \ \ void\ playGame()\ {\ \ while\ (!isGameOver())\ {\ \ //\ 当游戏没有结束时,进行下一步操作\ \ playerMove();\ \ //\ 玩家行动\ \ \ \ if\ (isGameOver())\ {\ \ //\ 如果游戏结束,则跳出循环\ \ break;\ \ }\ \ \ \ computerMove();\ \ //\ 电脑行动\ \ printBoard();\ \ }\ \ \ \ char\ winner\ =\ getWinner();\ \ //\ 获取胜利者\ \ if\ (winner\ ==\ player)\ {\ \ cout\ <<\ "Congratulations!\ You\ win!"\ <<\ endl;\ \ }\ else\ if\ (winner\ ==\ computer)\ {\ \ cout\ <<\ "Sorry,\ you\ lose.\ Computer\ wins!"\ <<\ endl;\ \ }\ else\ {\ \ cout\ <<\ "It's\ a\ draw!"\ <<\ endl;\ \ }\ \ }\ \ \ \ void\ playerMove()\ {\ \ cout\ <<\ "Enter\ your\ move\ (1-9):\ ";\ \ int\ move;\ \ cin\ >>\ move;\ \ //\ 玩家选择落子的位置\ \ \ \ int\ row\ =\ (move\ -\ 1)\ /\ 3;\ \ //\ 计算落子位置的行号\ \ int\ col\ =\ (move\ -\ 1)\ %\ 3;\ \ //\ 计算落子位置的列号\ \ \ \ if\ (board[row][col]\ ==\ '')\ {\ \ //\ 如果落子位置为空,则进行落子\ \ board[row][col]\ =\ player;\ \ }\ else\ {\ \ cout\ <<\ "Invalid\ move.\ Please\ choose\ an\ empty\ cell."\ <<\ endl;\ \ //\ 如果落子位置非空,则提示重新选择\ \ playerMove();\ \ }\ \ \ \ printBoard();\ \ }\ \ \ \ void\ computerMove()\ {\ \ int\ bestScore\ =\ INT_MIN;\ \ //\ 初始化最佳得分为负无穷大\ \ int\ bestMoveRow,\ bestMoveCol;\ \ //\ 初始化最佳落子位置的行号和列号\ \ \ \ for\ (int\ i\ =\ 0;\ i\ <\ 3;\ i++)\ {\ \ //\ 遍历棋盘的所有位置\ \ for\ (int\ j\ =\ 0;\ j\ <\ 3;\ j++)\ {\ \ if\ (board[i][j]\ ==\ '')\ {\ \ //\ 如果当前位置为空,则进行落子,并计算得分\ \ board[i][j]\ =\ computer;\ \ int\ score\ =\ minimax(board,\ 0,\ false);\ \ board[i][j]\ =\ '';\ \ \ \ if\ (score\ >\ bestScore)\ {\ \ //\ 如果得分比当前最佳得分高,则更新最佳得分和最佳落子位置\ \ bestScore\ =\ score;\ \ bestMoveRow\ =\ i;\ \ bestMoveCol\ =\ j;\ \ }\ \ }\ \ }\ \ }\ \ \ \ board[bestMoveRow][bestMoveCol]\ =\ computer;\ \ //\ 电脑在最佳落子位置落子\ \ }\ \ \ \ int\ minimax(vector<vector>&\ board,\ int\ depth,\ bool\ isMaximizingPlayer)\ {\ \ if\ (isGameOver())\ {\ \ //\ 如果游戏结束,则返回对应的得分\ \ char\ winner\ =\ getWinner();\ \ if\ (winner\ ==\ computer)\ {\ \ return\ 1;\ \ }\ else\ if\ (winner\ ==\ player)\ {\ \ return\ -1;\ \ }\ else\ {\ \ return\ 0;\ \ }\ \ }\ \ \ \ if\ (isMaximizingPlayer)\ {\ \ //\ 如果当前是最大化玩家的回合\ \ int\ bestScore\ =\ INT_MIN;\ \ //\ 初始化最佳得分为负无穷大\ \ \ \ for\ (int\ i\ =\ 0;\ i\ <\ 3;\ i++)\ {\ \ for\ (int\ j\ =\ 0;\ j\ <\ 3;\ j++)\ {\ \ if\ (board[i][j]\ ==\ '')\ {\ \ //\ 如果当前位置为空,则进行落子,并计算得分\ \ board[i][j]\ =\ computer;\ \ int\ score\ =\ minimax(board,\ depth\ +\ 1,\ false);\ \ board[i][j]\ =\ '';\ \ \ \ bestScore\ =\ max(score,\ bestScore);\ \ //\ 取得分的最大值\ \ }\ \ }\ \ }\ \ \ \ return\ bestScore;\ \ //\ 返回最佳得分\ \ }\ else\ {\ \ //\ 如果当前是最小化玩家的回合\ \ int\ bestScore\ =\ INT_MAX;\ \ //\ 初始化最佳得分为正无穷大\ \ \ \ for\ (int\ i\ =\ 0;\ i\ <\ 3;\ i++)\ {\ \ for\ (int\ j\ =\ 0;\ j\ <\ 3;\ j++)\ {\ \ if\ (board[i][j]\ ==\ '')\ {\ \ //\ 如果当前位置为空,则进行落子,并计算得分\ \ board[i][j]\ =\ player;\ \ int\ score\ =\ minimax(board,\ depth\ +\ 1,\ true);\ \ board[i][j]\ =\ '';\ \ \ \ bestScore\ =\ min(score,\ bestScore);\ \ //\ 取得分的最小值\ \ }\ \ }\ \ }\ \ \ \ return\ bestScore;\ \ //\ 返回最佳得分\ \ }\ \ }\ \ \ \ bool\ isGameOver()\ {\ \ return\ isBoardFull()\ ||\ getWinner()\ !=\ ' ';\ \ //\ 判断游戏是否结束,如果棋盘已满或者有玩家胜利,则游戏结束\ \ }\ \ \ \ bool\ isBoardFull()\ {\ \ for\ (int\ i\ =\ 0;\ i\ <\ 3;\ i++)\ {\ \ //\ 遍历棋盘的所有位置,如果有空位置,则棋盘未满\ \ for\ (int\ j\ =\ 0;\ j\ <\ 3;\ j++)\ {\ \ if\ (board[i][j]\ ==\ '')\ {\ \ return\ false;\ \ }\ \ }\ \ }\ \ \ \ return\ true;\ \ //\ 如果所有位置都不为空,则棋盘已满\ \ }\ \ \ \ char\ getWinner()\ {\ \ for\ (int\ i\ =\ 0;\ i\ <\ 3;\ i++)\ {\ \ //\ 检查每一行是否有玩家胜利\ \ if\ (board[i][0]\ !=\ ''\ &&\ board[i][0]\ ==\ board[i][1]\ &&\ board[i][0]\ ==\ board[i][2])\ {\ \ return\ board[i][0];\ \ }\ \ }\ \ \ \ for\ (int\ j\ =\ 0;\ j\ <\ 3;\ j++)\ {\ \ //\ 检查每一列是否有玩家胜利\ \ if\ (board[0][j]\ !=\ ''\ &&\ board[0][j]\ ==\ board[1][j]\ &&\ board[0][j]\ ==\ board[2][j])\ {\ \ return\ board[0][j];\ \ }\ \ }\ \ \ \ if\ (board[0][0]\ !=\ ''\ &&\ board[0][0]\ ==\ board[1][1]\ &&\ board[0][0]\ ==\ board[2][2])\ {\ \ //\ 检查对角线是否有玩家胜利\ \ return\ board[0][0];\ \ }\ \ \ \ if\ (board[0][2]\ !=\ '*'\ &&\ board[0][2]\ ==\ board[1][1]\ &&\ board[0][2]\ ==\ board[2][0])\ {\ \ //\ 检查反对角线是否有玩家胜利\ \ return\ board[0][2];\ \ }\ \ \ \ return\ ' ';\ \ //\ 如果没有玩家胜利,则返回空字符\ \ }\ \ \ \ void\ printBoard()\ {\ \ cout\ <<\ "-------------"\ <<\ endl;\ \ for\ (int\ i\ =\ 0;\ i\ <\ 3;\ i++)\ {\ \ cout\ <<\ "|\ ";\ \ for\ (int\ j\ =\ 0;\ j\ <\ 3;\ j++)\ {\ \ cout\ <<\ board[i][j]\ <<\ "\ |\ ";\ \ }\ \ cout\ <<\ endl\ <<\ "-------------"\ <<\ endl;\ \ }\ \ }\ \ };\ \ \ int\ main()\ {\ \ TicTacToe\ game;\ \ game.startGame();\ \ return\ 0;\ \ }

Tic Tac Toe Game with AI using Minimax Algorithm - C++

原文地址: https://www.cveoy.top/t/topic/qzyj 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录