专栏文章
Ultimate Tik Tak Toe
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mioo3hrs
- 此快照首次捕获于
- 2025/12/02 22:22 3 个月前
- 此快照最后确认于
- 2025/12/02 22:22 3 个月前
Ultimate Tik Tak Toe游戏。
支持局域网联机和单人与MINMAX对站(很难打)
坐标的表示非常简单:
TEXT | |
1 | 2 | 3
| |
---+---+---
| |
4 | 5 | 6
| |
---+---+---
| |
7 | 8 | 9
| |
表示为 (大格子编号,小格子编号)
不会规则的网上搜,你不一定是先手,你是蓝方。
注意,对于MINMAX,程序卡了5秒以内是正常现象,因为MINMAX的搜索层数达到了7层!如果想要减轻难度/提高运行速度,修改第二行的
DIFFICULTY!源码
大号UI版本
CPP#include<bits/stdc++.h>
#define DIFFICULTY 7
#include<windows.h>
using namespace std;
const char EMPTY='.';
const char PLAYER_X='X';
const char PLAYER_O='O';
const char TIE='T';
mt19937 rng(time(0));
void color(int r,int g,int b)
{wprintf(L"\x1b[38;2;%d;%d;%dm",r,g,b);}
void HideCursor(){
CONSOLE_CURSOR_INFO cursor_info={1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
using namespace std;
void gotoxy(int x, int y){
HANDLE hout;
COORD pos;
pos.X=x;
pos.Y=y;
hout=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hout, pos);
}
class SmallBoard{
public:
char board[3][3];
char winner;
SmallBoard(){
for(int i=0;i<3;i++)for(int j=0;j<3;j++)
board[i][j]=EMPTY;winner=EMPTY;
}
bool makeMove(int row,int col,char player){
if(row<0||row>=3||col<0||col>=3||board[row][col]
!=EMPTY||winner!=EMPTY)return false;
board[row][col]=player;checkWinner();
return true;
}
void checkWinner(){
for(int i=0;i<3;i++)
if(board[i][0]!=EMPTY&&board[i][0]==
board[i][1]&&board[i][0]==board[i][2]){
winner=board[i][0];return;}
for(int j=0;j<3;j++)
if(board[0][j]!=EMPTY&&board[0][j]==
board[1][j]&&board[0][j]==board[2][j]){
winner=board[0][j];return;}
if(board[0][0]!=EMPTY&&board[0][0]==
board[1][1]&&board[0][0]==board[2][2]){
winner=board[0][0];return;}
if(board[0][2]!=EMPTY&&board[0][2]==
board[1][1]&&board[0][2]==board[2][0]){
winner=board[0][2];return;}
bool isFull=true;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
if(board[i][j]==EMPTY){
isFull=false;break;}
if (!isFull)break;
}
if(isFull)winner=TIE;
}
};
class UltimateBoard{
public:
SmallBoard boards[3][3];
char currentPlayer;
int nextBoardRow;
int nextBoardCol;
bool gameOver;
char ultimateWinner;
UltimateBoard():currentPlayer(PLAYER_X),nextBoardRow(-1)
,nextBoardCol(-1),gameOver(false),ultimateWinner(EMPTY){}
bool makeMove(int bigRow,int bigCol,int smallRow,int smallCol){
if(gameOver)return false;
if(nextBoardRow!=-1&&nextBoardCol!=-1&&(bigRow!=
nextBoardRow||bigCol!=nextBoardCol))return false;
if(boards[bigRow][bigCol].winner!=EMPTY)return false;
if(!boards[bigRow][bigCol].makeMove
(smallRow,smallCol,currentPlayer))return false;
checkUltimateWinner();
nextBoardRow=smallRow;nextBoardCol=smallCol;
if(boards[nextBoardRow][nextBoardCol].winner!=EMPTY)
nextBoardRow=-1,nextBoardCol=-1;
currentPlayer=(currentPlayer==PLAYER_X)?PLAYER_O:PLAYER_X;
return true;
}
void checkUltimateWinner(){
for(int i=0;i<3;i++){
if(boards[i][0].winner==PLAYER_X&& boards[i][1].
winner==PLAYER_X&&boards[i][2].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[i][0].winner==PLAYER_O&& boards[i][1].
winner==PLAYER_O&&boards[i][2].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
}
for(int j=0;j<3;j++){
if(boards[0][j].winner==PLAYER_X&&boards[1][j].
winner==PLAYER_X&&boards[2][j].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[0][j].winner==PLAYER_O&&boards[1][j].
winner==PLAYER_O&&boards[2][j].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
}
if(boards[0][0].winner==PLAYER_X&&boards[1][1].
winner==PLAYER_X&&boards[2][2].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[0][2].winner==PLAYER_X&&boards[1][1].
winner==PLAYER_X&&boards[2][0].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[0][0].winner==PLAYER_O&&boards[1][1].
winner==PLAYER_O&&boards[2][2].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
if(boards[0][2].winner==PLAYER_O&&boards[1][1].
winner==PLAYER_O&&boards[2][0].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
bool isFull=true;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
if(boards[i][j].winner==EMPTY){
isFull=false;
break;
}
if(!isFull)break;
}
if(isFull){
gameOver=true;
ultimateWinner=TIE;
}
}
tuple<int,int,int> down(char w){
if(w==PLAYER_O)return make_tuple(200,10,10);
else if(w==PLAYER_X)return make_tuple(10,150,150);
else if(w==TIE)return make_tuple(120,120,120);
else return make_tuple(50,50,50);
}
void print_square(int x,int y){
int rol=(y-3)/8,col=(x-4)/16;
tuple<int,int,int>c;
gotoxy(x,y);
c=down(boards[rol][col].board[0][0]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
color(120,120,120);cout<<"■";
c=down(boards[rol][col].board[0][1]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
color(120,120,120);cout<<"■";
c=down(boards[rol][col].board[0][2]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
gotoxy(x,y+1);
color(120,120,120);cout<<"■■■■■";
gotoxy(x,y+2);
c=down(boards[rol][col].board[1][0]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
color(120,120,120);cout<<"■";
c=down(boards[rol][col].board[1][1]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
color(120,120,120);cout<<"■";
c=down(boards[rol][col].board[1][2]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
gotoxy(x,y+3);
color(120,120,120);cout<<"■■■■■";
gotoxy(x,y+4);
c=down(boards[rol][col].board[2][0]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
color(120,120,120);cout<<"■";
c=down(boards[rol][col].board[2][1]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
color(120,120,120);cout<<"■";
c=down(boards[rol][col].board[2][2]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
}
void print(){
color(200,200,200);
puts("\
\n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■■■■■■■■■■■■■■■■■■■■■■■\n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■■■■■■■■■■■■■■■■■■■■■■■\n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \
");
color(120,120,120);
for(int y=3;y<=19;y+=8)
for(int x=4;x<=36;x+=16)
print_square(x,y);
}
vector<pair<pair<int,int>,pair<int,int>>>getPossibleMoves()const{
vector<pair<pair<int,int>,pair<int,int>>>moves;
if(gameOver)return moves;
vector<pair<int,int>>bigBoardsToCheck;
if(nextBoardRow==-1||nextBoardCol==-1){
for(int i=0;i<3;i++)for(int j=0;j<3;j++)
if(boards[i][j].winner==EMPTY)bigBoardsToCheck.emplace_back(i,j);
}else bigBoardsToCheck.emplace_back(nextBoardRow,nextBoardCol);
for(const auto& bigPos:bigBoardsToCheck){
int bigRow=bigPos.first;
int bigCol=bigPos.second;
for(int smallRow=0;smallRow<3;smallRow++)
for(int smallCol=0;smallCol<3;smallCol++)
if(boards[bigRow][bigCol].board[smallRow][smallCol]==EMPTY)
moves.emplace_back(make_pair(bigRow,bigCol),make_pair(smallRow,smallCol));
}
return moves;
}
int evaluate()const{
if(gameOver)
if(ultimateWinner==PLAYER_X)return 1000;
else if(ultimateWinner==PLAYER_O)return -1000;
else return 0;
int score=0;
for(int i=0;i<3;i++)for(int j=0;j<3;j++)
if(boards[i][j].winner==PLAYER_X)score+=10;
else if(boards[i][j].winner==PLAYER_O)score-=10;
else for(int x=0;x<3;x++)for(int y=0;y<3;y++)
if(boards[i][j].board[x][y]==PLAYER_X)score+=1;
else if(boards[i][j].board[x][y]==PLAYER_O)score-=1;
return score;
}
};
class AI{
public:
pair<pair<int,int>,pair<int,int>>findBestMove(UltimateBoard& board,int depth,bool isMaximizing){
vector<pair<pair<int,int>,pair<int,int>>>bestMoves;
int bestValue=isMaximizing?-numeric_limits<int>::max():numeric_limits<int>::max();
vector<pair<pair<int,int>,pair<int,int>>>possibleMoves=board.getPossibleMoves();
for(const auto& move:possibleMoves){
UltimateBoard newBoard=board;
newBoard.makeMove(move.first.first,move.first.second,move.second.first,move.second.second);
int moveValue=minimax(newBoard,depth-1,
-numeric_limits<int>::max(),numeric_limits<int>::max(),!isMaximizing);
if((isMaximizing&&moveValue>bestValue)||(!isMaximizing&&moveValue<bestValue))
bestValue=moveValue,bestMoves.clear(),bestMoves.push_back(move);
else if(moveValue==bestValue)bestMoves.push_back(move);
}
if(!bestMoves.empty()){
uniform_int_distribution<int>dist(0,bestMoves.size()-1);
return bestMoves[dist(rng)];
}
return make_pair(make_pair(-1,-1),make_pair(-1,-1));
}
private:
int minimax(UltimateBoard& board,int depth,int alpha,int beta,bool isMaximizing){
if(depth==0||board.gameOver)
return board.evaluate();
if(isMaximizing){
int maxEval=-numeric_limits<int>::max();
vector<pair<pair<int,int>,pair<int,int>>>possibleMoves=board.getPossibleMoves();
for (const auto& move:possibleMoves){
UltimateBoard newBoard=board;
newBoard.makeMove(move.first.first,move.first.second,move.second.first,move.second.second);
int eval=minimax(newBoard,depth-1,alpha,beta,false);
maxEval=max(maxEval,eval);
alpha=max(alpha, eval);
if(beta<=alpha)break;
}
return maxEval;
}
else{
int minEval=numeric_limits<int>::max();
vector<pair<pair<int,int>,pair<int,int>>>possibleMoves=board.getPossibleMoves();
for(const auto& move:possibleMoves){
UltimateBoard newBoard=board;
newBoard.makeMove(move.first.first,move.first.second,move.second.first,move.second.second);
int eval=minimax(newBoard,depth-1,alpha,beta,true);
minEval=min(minEval, eval);
beta=min(beta,eval);
if(beta<=alpha)break;
}
return minEval;
}
}
};
void setsize(int col, int row){
char cmd[64];
sprintf(cmd,"mode con cols=%d lines=%d",col,row);
system(cmd);
}
int main() {
HideCursor();
setsize(50,29);
SetConsoleTitle("Tik Tak Toe - PLUS");
SetWindowLongPtrA(GetConsoleWindow(),GWL_STYLE,GetWindowLongPtrA(
GetConsoleWindow(),GWL_STYLE)&~WS_SIZEBOX&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX);
DWORD mode;GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode);
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
if(hOut==INVALID_HANDLE_VALUE)return GetLastError();DWORD dwMode=0;
if(!GetConsoleMode(hOut,&dwMode))return GetLastError();dwMode|=0x0004;
if(!SetConsoleMode(hOut,dwMode))return GetLastError();
UltimateBoard board;AI ai;
pair<pair<int,int>,pair<int,int>>bestMove;
board.currentPlayer=(rng()&1)?PLAYER_X:PLAYER_O;
while(!board.gameOver){
if(board.currentPlayer==PLAYER_X){
system("cls");
int z[3][3]={{1,2,3},{4,5,6},{7,8,9},};
int a,b,zl[10][2]={{0,0},{0,0},{0,1},
{0,2},{1,0},{1,1},{1,2},{2,0},{2,1},{2,2}};
color(230,230,230);
cout<<"AI在 ("<<z[bestMove.first.first][bestMove.first.second]<<" "
<<z[bestMove.second.first][bestMove.second.second]<<") 下棋"<<endl;
board.print();
gotoxy(0,25);color(230,230,230);
cout<<"你的回合: ";cin>>a>>b;
if(!board.makeMove(zl[a][0],zl[a][1],zl[b][0],zl[b][1])){
cout<<"无效的走法,请重试!"<<endl;
Sleep(1000);continue;
}
}
else bestMove=ai.findBestMove(board,DIFFICULTY,false),
board.makeMove(bestMove.first.first,bestMove.first.second,
bestMove.second.first,bestMove.second.second);
}
system("cls");
board.print();
gotoxy(0,25);color(230,230,230);
if(board.ultimateWinner==PLAYER_X)
cout<<"恭喜你赢了!"<<endl;
else if(board.ultimateWinner==PLAYER_O)
cout<<"连人机都赢不了,太逊了!"<<endl;
else cout<<"平局,还行!"<<endl;
Sleep(10000);
return 0;
}
小型UI版本
CPP#include<bits/stdc++.h>
#define DIFFICULTY 7
#include<windows.h>
using namespace std;
const char EMPTY='.';
const char PLAYER_X='X';
const char PLAYER_O='O';
const char TIE='T';
mt19937 rng(time(0));
void color(int r,int g,int b)
{wprintf(L"\x1b[38;2;%d;%d;%dm",r,g,b);}
void HideCursor(){
CONSOLE_CURSOR_INFO cursor_info={1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
using namespace std;
void gotoxy(int x, int y){
HANDLE hout;
COORD pos;
pos.X=x;
pos.Y=y;
hout=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hout, pos);
}
class SmallBoard{
public:
char board[3][3];
char winner;
SmallBoard(){
for(int i=0;i<3;i++)for(int j=0;j<3;j++)
board[i][j]=EMPTY;winner=EMPTY;
}
bool makeMove(int row,int col,char player){
if(row<0||row>=3||col<0||col>=3||board[row][col]
!=EMPTY||winner!=EMPTY)return false;
board[row][col]=player;checkWinner();
return true;
}
void checkWinner(){
for(int i=0;i<3;i++)
if(board[i][0]!=EMPTY&&board[i][0]==
board[i][1]&&board[i][0]==board[i][2]){
winner=board[i][0];return;}
for(int j=0;j<3;j++)
if(board[0][j]!=EMPTY&&board[0][j]==
board[1][j]&&board[0][j]==board[2][j]){
winner=board[0][j];return;}
if(board[0][0]!=EMPTY&&board[0][0]==
board[1][1]&&board[0][0]==board[2][2]){
winner=board[0][0];return;}
if(board[0][2]!=EMPTY&&board[0][2]==
board[1][1]&&board[0][2]==board[2][0]){
winner=board[0][2];return;}
bool isFull=true;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
if(board[i][j]==EMPTY){
isFull=false;break;}
if (!isFull)break;
}
if(isFull)winner=TIE;
}
};
class UltimateBoard{
public:
SmallBoard boards[3][3];
char currentPlayer;
int nextBoardRow;
int nextBoardCol;
bool gameOver;
char ultimateWinner;
UltimateBoard():currentPlayer(PLAYER_X),nextBoardRow(-1)
,nextBoardCol(-1),gameOver(false),ultimateWinner(EMPTY){}
bool makeMove(int bigRow,int bigCol,int smallRow,int smallCol){
if(gameOver)return false;
if(nextBoardRow!=-1&&nextBoardCol!=-1&&(bigRow!=
nextBoardRow||bigCol!=nextBoardCol))return false;
if(boards[bigRow][bigCol].winner!=EMPTY)return false;
if(!boards[bigRow][bigCol].makeMove
(smallRow,smallCol,currentPlayer))return false;
checkUltimateWinner();
nextBoardRow=smallRow;nextBoardCol=smallCol;
if(boards[nextBoardRow][nextBoardCol].winner!=EMPTY)
nextBoardRow=-1,nextBoardCol=-1;
currentPlayer=(currentPlayer==PLAYER_X)?PLAYER_O:PLAYER_X;
return true;
}
void checkUltimateWinner(){
for(int i=0;i<3;i++){
if(boards[i][0].winner==PLAYER_X&& boards[i][1].
winner==PLAYER_X&&boards[i][2].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[i][0].winner==PLAYER_O&& boards[i][1].
winner==PLAYER_O&&boards[i][2].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
}
for(int j=0;j<3;j++){
if(boards[0][j].winner==PLAYER_X&&boards[1][j].
winner==PLAYER_X&&boards[2][j].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[0][j].winner==PLAYER_O&&boards[1][j].
winner==PLAYER_O&&boards[2][j].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
}
if(boards[0][0].winner==PLAYER_X&&boards[1][1].
winner==PLAYER_X&&boards[2][2].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[0][2].winner==PLAYER_X&&boards[1][1].
winner==PLAYER_X&&boards[2][0].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[0][0].winner==PLAYER_O&&boards[1][1].
winner==PLAYER_O&&boards[2][2].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
if(boards[0][2].winner==PLAYER_O&&boards[1][1].
winner==PLAYER_O&&boards[2][0].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
bool isFull=true;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
if(boards[i][j].winner==EMPTY){
isFull=false;
break;
}
if(!isFull)break;
}
if(isFull){
gameOver=true;
ultimateWinner=TIE;
}
}
tuple<int,int,int> down(char w){
if(w==PLAYER_O)return make_tuple(200,10,10);
else if(w==PLAYER_X)return make_tuple(10,150,150);
else if(w==TIE)return make_tuple(120,120,120);
else return make_tuple(50,50,50);
}
void print_square(int x,int y){
int rol=(y-3)/6,col=(x-4)/12;
tuple<int,int,int>c;
gotoxy(x,y);
c=down(boards[rol][col].board[0][0]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[0][1]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[0][2]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
gotoxy(x,y+1);
c=down(boards[rol][col].board[1][0]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[1][1]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[1][2]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
gotoxy(x,y+2);
c=down(boards[rol][col].board[2][0]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[2][1]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[2][2]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
}
void print(){
color(200,200,200);
puts("\
\n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■■■■■■■■■■■■■■■■■\n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■■■■■■■■■■■■■■■■■\n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \
");
color(120,120,120);
for(int y=3;y<=15;y+=6)
for(int x=4;x<=28;x+=12)
print_square(x,y);
}
vector<pair<pair<int,int>,pair<int,int>>>getPossibleMoves()const{
vector<pair<pair<int,int>,pair<int,int>>>moves;
if(gameOver)return moves;
vector<pair<int,int>>bigBoardsToCheck;
if(nextBoardRow==-1||nextBoardCol==-1){
for(int i=0;i<3;i++)for(int j=0;j<3;j++)
if(boards[i][j].winner==EMPTY)bigBoardsToCheck.emplace_back(i,j);
}else bigBoardsToCheck.emplace_back(nextBoardRow,nextBoardCol);
for(const auto& bigPos:bigBoardsToCheck){
int bigRow=bigPos.first;
int bigCol=bigPos.second;
for(int smallRow=0;smallRow<3;smallRow++)
for(int smallCol=0;smallCol<3;smallCol++)
if(boards[bigRow][bigCol].board[smallRow][smallCol]==EMPTY)
moves.emplace_back(make_pair(bigRow,bigCol),make_pair(smallRow,smallCol));
}
return moves;
}
int evaluate()const{
if(gameOver)
if(ultimateWinner==PLAYER_X)return 1000;
else if(ultimateWinner==PLAYER_O)return -1000;
else return 0;
int score=0;
for(int i=0;i<3;i++)for(int j=0;j<3;j++)
if(boards[i][j].winner==PLAYER_X)score+=10;
else if(boards[i][j].winner==PLAYER_O)score-=10;
else for(int x=0;x<3;x++)for(int y=0;y<3;y++)
if(boards[i][j].board[x][y]==PLAYER_X)score+=1;
else if(boards[i][j].board[x][y]==PLAYER_O)score-=1;
return score;
}
};
class AI{
public:
pair<pair<int,int>,pair<int,int>>findBestMove(UltimateBoard& board,int depth,bool isMaximizing){
vector<pair<pair<int,int>,pair<int,int>>>bestMoves;
int bestValue=isMaximizing?-numeric_limits<int>::max():numeric_limits<int>::max();
vector<pair<pair<int,int>,pair<int,int>>>possibleMoves=board.getPossibleMoves();
for(const auto& move:possibleMoves){
UltimateBoard newBoard=board;
newBoard.makeMove(move.first.first,move.first.second,move.second.first,move.second.second);
int moveValue=minimax(newBoard,depth-1,
-numeric_limits<int>::max(),numeric_limits<int>::max(),!isMaximizing);
if((isMaximizing&&moveValue>bestValue)||(!isMaximizing&&moveValue<bestValue))
bestValue=moveValue,bestMoves.clear(),bestMoves.push_back(move);
else if(moveValue==bestValue)bestMoves.push_back(move);
}
if(!bestMoves.empty()){
uniform_int_distribution<int>dist(0,bestMoves.size()-1);
return bestMoves[dist(rng)];
}
return make_pair(make_pair(-1,-1),make_pair(-1,-1));
}
private:
int minimax(UltimateBoard& board,int depth,int alpha,int beta,bool isMaximizing){
if(depth==0||board.gameOver)
return board.evaluate();
if(isMaximizing){
int maxEval=-numeric_limits<int>::max();
vector<pair<pair<int,int>,pair<int,int>>>possibleMoves=board.getPossibleMoves();
for (const auto& move:possibleMoves){
UltimateBoard newBoard=board;
newBoard.makeMove(move.first.first,move.first.second,move.second.first,move.second.second);
int eval=minimax(newBoard,depth-1,alpha,beta,false);
maxEval=max(maxEval,eval);
alpha=max(alpha, eval);
if(beta<=alpha)break;
}
return maxEval;
}
else{
int minEval=numeric_limits<int>::max();
vector<pair<pair<int,int>,pair<int,int>>>possibleMoves=board.getPossibleMoves();
for(const auto& move:possibleMoves){
UltimateBoard newBoard=board;
newBoard.makeMove(move.first.first,move.first.second,move.second.first,move.second.second);
int eval=minimax(newBoard,depth-1,alpha,beta,true);
minEval=min(minEval, eval);
beta=min(beta,eval);
if(beta<=alpha)break;
}
return minEval;
}
}
};
void setsize(int col, int row){
char cmd[64];
sprintf(cmd,"mode con cols=%d lines=%d",col,row);
system(cmd);
}
int main() {
HideCursor();
setsize(38,24);
SetConsoleTitle("Tik Tak Toe - PLUS");
SetWindowLongPtrA(GetConsoleWindow(),GWL_STYLE,GetWindowLongPtrA(
GetConsoleWindow(),GWL_STYLE)&~WS_SIZEBOX&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX);
DWORD mode;GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode);
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
if(hOut==INVALID_HANDLE_VALUE)return GetLastError();DWORD dwMode=0;
if(!GetConsoleMode(hOut,&dwMode))return GetLastError();dwMode|=0x0004;
if(!SetConsoleMode(hOut,dwMode))return GetLastError();
UltimateBoard board;AI ai;
pair<pair<int,int>,pair<int,int>>bestMove;
board.currentPlayer=(rng()&1)?PLAYER_X:PLAYER_O;
while(!board.gameOver){
if(board.currentPlayer==PLAYER_X){
system("cls");
int z[3][3]={{1,2,3},{4,5,6},{7,8,9},};
int a,b,zl[10][2]={{0,0},{0,0},{0,1},
{0,2},{1,0},{1,1},{1,2},{2,0},{2,1},{2,2}};
color(230,230,230);
cout<<"AI在 ("<<z[bestMove.first.first][bestMove.first.second]<<" "
<<z[bestMove.second.first][bestMove.second.second]<<") 下棋"<<endl;
board.print();
gotoxy(0,20);color(230,230,230);
cout<<"你的回合: ";cin>>a>>b;
if(!board.makeMove(zl[a][0],zl[a][1],zl[b][0],zl[b][1])){
cout<<"无效的走法,请重试!"<<endl;
Sleep(1000);continue;
}
}
else bestMove=ai.findBestMove(board,DIFFICULTY,false),
board.makeMove(bestMove.first.first,bestMove.first.second,
bestMove.second.first,bestMove.second.second);
}
system("cls");
board.print();
gotoxy(0,20);color(230,230,230);
if(board.ultimateWinner==PLAYER_X)
cout<<"恭喜你赢了!"<<endl;
else if(board.ultimateWinner==PLAYER_O)
cout<<"连人机都赢不了,太逊了!"<<endl;
else cout<<"平局,还行!"<<endl;
Sleep(10000);
return 0;
}
局域网联机版本(支持randmin等虚拟局域网)
CPP#include<bits/stdc++.h>
#include<winsock2.h>
#include<ws2tcpip.h>
#include<windows.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
const char EMPTY='.';
const char PLAYER_X='X';
const char PLAYER_O='O';
const char TIE='T';
const int PORT = 55555;
const int BUFFER_SIZE = 1024;
mt19937 rng(time(0));
void color(int r,int g,int b)
{wprintf(L"\x1b[38;2;%d;%d;%dm",r,g,b);}
void HideCursor(){
CONSOLE_CURSOR_INFO cursor_info={1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
bool InitializeWinsock(){
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0){
cerr<<"WSAStartup failed."<<endl;
return false;
}
return true;
}
void setsize(int col, int row){
char cmd[64];
sprintf(cmd,"mode con cols=%d lines=%d",col,row);
system(cmd);
}
int InitializeUI(){
setsize(38,24);
SetConsoleTitle("Ultimate Tik Tak Toe - Online");
SetWindowLongPtrA(GetConsoleWindow(),GWL_STYLE,GetWindowLongPtrA(
GetConsoleWindow(),GWL_STYLE)&~WS_SIZEBOX&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX);
DWORD mode;GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode);
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
if(hOut==INVALID_HANDLE_VALUE)return GetLastError();DWORD dwMode=0;
if(!GetConsoleMode(hOut,&dwMode))return GetLastError();dwMode|=0x0004;
if(!SetConsoleMode(hOut,dwMode))return GetLastError();return 0;
}
void gotoxy(int x, int y){
HANDLE hout;
COORD pos;
pos.X=x;
pos.Y=y;
hout=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hout, pos);
}
class SmallBoard{
public:
char board[3][3];
char winner;
SmallBoard(){
for(int i=0;i<3;i++)for(int j=0;j<3;j++)
board[i][j]=EMPTY;winner=EMPTY;
}
bool makeMove(int row,int col,char player){
if(row<0||row>=3||col<0||col>=3||board[row][col]
!=EMPTY||winner!=EMPTY)return false;
board[row][col]=player;checkWinner();
return true;
}
void checkWinner(){
for(int i=0;i<3;i++)
if(board[i][0]!=EMPTY&&board[i][0]==
board[i][1]&&board[i][0]==board[i][2]){
winner=board[i][0];return;}
for(int j=0;j<3;j++)
if(board[0][j]!=EMPTY&&board[0][j]==
board[1][j]&&board[0][j]==board[2][j]){
winner=board[0][j];return;}
if(board[0][0]!=EMPTY&&board[0][0]==
board[1][1]&&board[0][0]==board[2][2]){
winner=board[0][0];return;}
if(board[0][2]!=EMPTY&&board[0][2]==
board[1][1]&&board[0][2]==board[2][0]){
winner=board[0][2];return;}
bool isFull=true;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
if(board[i][j]==EMPTY){
isFull=false;break;}
if (!isFull)break;
}
if(isFull)winner=TIE;
}
};
class UltimateBoard{
public:
SmallBoard boards[3][3];
char currentPlayer;
int nextBoardRow;
int nextBoardCol;
bool gameOver;
char ultimateWinner;
UltimateBoard():currentPlayer(PLAYER_X),nextBoardRow(-1)
,nextBoardCol(-1),gameOver(false),ultimateWinner(EMPTY){}
bool makeMove(int bigRow,int bigCol,int smallRow,int smallCol){
if(gameOver)return false;
if(nextBoardRow!=-1&&nextBoardCol!=-1&&(bigRow!=
nextBoardRow||bigCol!=nextBoardCol))return false;
if(boards[bigRow][bigCol].winner!=EMPTY)return false;
if(!boards[bigRow][bigCol].makeMove
(smallRow,smallCol,currentPlayer))return false;
checkUltimateWinner();
nextBoardRow=smallRow;nextBoardCol=smallCol;
if(boards[nextBoardRow][nextBoardCol].winner!=EMPTY)
nextBoardRow=-1,nextBoardCol=-1;
currentPlayer=(currentPlayer==PLAYER_X)?PLAYER_O:PLAYER_X;
return true;
}
void checkUltimateWinner(){
for(int i=0;i<3;i++){
if(boards[i][0].winner==PLAYER_X&& boards[i][1].
winner==PLAYER_X&&boards[i][2].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[i][0].winner==PLAYER_O&& boards[i][1].
winner==PLAYER_O&&boards[i][2].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
}
for(int j=0;j<3;j++){
if(boards[0][j].winner==PLAYER_X&&boards[1][j].
winner==PLAYER_X&&boards[2][j].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[0][j].winner==PLAYER_O&&boards[1][j].
winner==PLAYER_O&&boards[2][j].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
}
if(boards[0][0].winner==PLAYER_X&&boards[1][1].
winner==PLAYER_X&&boards[2][2].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[0][2].winner==PLAYER_X&&boards[1][1].
winner==PLAYER_X&&boards[2][0].winner==PLAYER_X){
gameOver=true;ultimateWinner=PLAYER_X;return;}
if(boards[0][0].winner==PLAYER_O&&boards[1][1].
winner==PLAYER_O&&boards[2][2].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
if(boards[0][2].winner==PLAYER_O&&boards[1][1].
winner==PLAYER_O&&boards[2][0].winner==PLAYER_O){
gameOver=true;ultimateWinner=PLAYER_O;return;}
bool isFull=true;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
if(boards[i][j].winner==EMPTY){
isFull=false;
break;
}
if(!isFull)break;
}
if(isFull){
gameOver=true;
ultimateWinner=TIE;
}
}
tuple<int,int,int> down(char w){
if(w==PLAYER_O)return make_tuple(200,10,10);
else if(w==PLAYER_X)return make_tuple(10,150,150);
else if(w==TIE)return make_tuple(120,120,120);
else return make_tuple(50,50,50);
}
void print_square(int x,int y){
int rol=(y-3)/6,col=(x-4)/12;
tuple<int,int,int>c;
gotoxy(x,y);
c=down(boards[rol][col].board[0][0]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[0][1]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[0][2]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
gotoxy(x,y+1);
c=down(boards[rol][col].board[1][0]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[1][1]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[1][2]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
gotoxy(x,y+2);
c=down(boards[rol][col].board[2][0]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[2][1]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
c=down(boards[rol][col].board[2][2]);
if(boards[rol][col].winner!=EMPTY)
c=down(boards[rol][col].winner);
color(get<0>(c),get<1>(c),get<2>(c));
cout<<"■";
}
void print(){
color(200,200,200);
puts("\
\n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■■■■■■■■■■■■■■■■■\n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■■■■■■■■■■■■■■■■■\n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \n\
■ ■ \
");
color(120,120,120);
for(int y=3;y<=15;y+=6)
for(int x=4;x<=28;x+=12)
print_square(x,y);
}
vector<pair<pair<int,int>,pair<int,int>>>getPossibleMoves()const{
vector<pair<pair<int,int>,pair<int,int>>>moves;
if(gameOver)return moves;
vector<pair<int,int>>bigBoardsToCheck;
if(nextBoardRow==-1||nextBoardCol==-1){
for(int i=0;i<3;i++)for(int j=0;j<3;j++)
if(boards[i][j].winner==EMPTY)bigBoardsToCheck.emplace_back(i,j);
}else bigBoardsToCheck.emplace_back(nextBoardRow,nextBoardCol);
for(const auto& bigPos:bigBoardsToCheck){
int bigRow=bigPos.first;
int bigCol=bigPos.second;
for(int smallRow=0;smallRow<3;smallRow++)
for(int smallCol=0;smallCol<3;smallCol++)
if(boards[bigRow][bigCol].board[smallRow][smallCol]==EMPTY)
moves.emplace_back(make_pair(bigRow,bigCol),make_pair(smallRow,smallCol));
}
return moves;
}
int evaluate()const{
if(gameOver)
if(ultimateWinner==PLAYER_X)return 1000;
else if(ultimateWinner==PLAYER_O)return -1000;
else return 0;
int score=0;
for(int i=0;i<3;i++)for(int j=0;j<3;j++)
if(boards[i][j].winner==PLAYER_X)score+=10;
else if(boards[i][j].winner==PLAYER_O)score-=10;
else for(int x=0;x<3;x++)for(int y=0;y<3;y++)
if(boards[i][j].board[x][y]==PLAYER_X)score+=1;
else if(boards[i][j].board[x][y]==PLAYER_O)score-=1;
return score;
}
};
class LAN{
public:
void RunServer(){
SOCKET listenSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(listenSocket==INVALID_SOCKET){
cerr<<"Error creating socket: "<<WSAGetLastError()<<endl;
return;
}
sockaddr_in serverAddr;
serverAddr.sin_family=AF_INET;
serverAddr.sin_addr.s_addr=INADDR_ANY;
serverAddr.sin_port=htons(PORT);
if(bind(listenSocket,(sockaddr*)&serverAddr,sizeof(serverAddr))==SOCKET_ERROR){
cerr<<"Bind failed: "<<WSAGetLastError()<<endl;
closesocket(listenSocket);return;
}
if(listen(listenSocket,1)==SOCKET_ERROR){
cerr<<"Listen failed: "<<WSAGetLastError()<<endl;
closesocket(listenSocket);return;
}
cout<<"Server is waiting for client connection..."<<endl;
SOCKET clientSocket=accept(listenSocket,NULL,NULL);
if(clientSocket==INVALID_SOCKET) {
cerr<<"Accept failed: "<<WSAGetLastError()<<endl;
closesocket(listenSocket);return;
}
closesocket(listenSocket);
cout<<"Client connected."<<endl;
UltimateBoard board;
pair<int,int>lastMove;
board.currentPlayer=(rng()&1)?PLAYER_X:PLAYER_O;
if(board.currentPlayer==PLAYER_X){
cout<<"You first."<<endl;string message="second";
send(clientSocket,message.c_str(),message.size()+1,0);
}
else{
cout<<"You second."<<endl;string message="first";
send(clientSocket,message.c_str(),message.size()+1,0);
}
Sleep(1500);
char buffer[BUFFER_SIZE];
while(!board.gameOver){
if(board.currentPlayer==PLAYER_X){
system("cls");
int a,b,zl[10][2]={{0,0},{0,0},{0,1},
{0,2},{1,0},{1,1},{1,2},{2,0},{2,1},{2,2}};
color(230,230,230);
cout<<"对方在 ("<<lastMove.first<<" "<<lastMove.second<<") 下棋"<<endl;
board.print();
gotoxy(0,20);color(230,230,230);
cout<<"你的回合: ";cin>>a>>b;
if(!board.makeMove(zl[a][0],zl[a][1],zl[b][0],zl[b][1])){
cout<<"无效的走法,请重试!"<<endl;
Sleep(1000);continue;
}
string message=to_string(a)+" "+to_string(b);lastMove=make_pair(a,b);
send(clientSocket,message.c_str(),message.size()+1,0);
}
else{
system("cls");
cout<<"你在 ("<<lastMove.first<<" "<<lastMove.second<<") 下棋"<<endl;
board.print();gotoxy(0,20);color(230,230,230);cout<<"等待对方走棋...... ";
int bytesReceived=recv(clientSocket,buffer,BUFFER_SIZE,0);
if(bytesReceived<=0){
cout<<"Client disconnected."<<endl;
board.ultimateWinner=PLAYER_X;
Sleep(1000);
break;
}
string receivedStr(buffer,bytesReceived);
size_t spacePos=receivedStr.find(' ');
if(spacePos!=std::string::npos){
int num1=stoi(receivedStr.substr(0,spacePos));
int num2=stoi(receivedStr.substr(spacePos+1));
int zl[10][2]={{0,0},{0,0},{0,1},{0,2},{1,0},{1,1},{1,2},{2,0},{2,1},{2,2}};
board.makeMove(zl[num1][0],zl[num1][1],zl[num2][0],zl[num2][1]);
lastMove=make_pair(num1,num2);
}
}
}
system("cls");board.print();closesocket(clientSocket);
gotoxy(0,20);color(230,230,230);
if(board.ultimateWinner==PLAYER_X)
cout<<"恭喜你赢了!"<<endl;
else if(board.ultimateWinner==PLAYER_O)
cout<<"竟然输了!"<<endl;
else cout<<"平局,还行!"<<endl;
Sleep(10000);
}
void RunClient(){
SOCKET clientSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (clientSocket==INVALID_SOCKET){
cerr<<"Error creating socket: "<<WSAGetLastError()<<endl;
return;
}
string serverIP;
cout<<"Enter server IP address: ";
cin>>serverIP;
sockaddr_in serverAddr;
serverAddr.sin_family=AF_INET;
serverAddr.sin_port=htons(PORT);
inet_pton(AF_INET,serverIP.c_str(),&serverAddr.sin_addr);
if(connect(clientSocket,(sockaddr*)&serverAddr,sizeof(serverAddr))==SOCKET_ERROR){
cerr<<"Connect failed: "<<WSAGetLastError()<<endl;
closesocket(clientSocket);return;
}
cout<<"Connected to server."<<endl;
char buffer[BUFFER_SIZE];UltimateBoard board;
int byteReceived=recv(clientSocket,buffer,BUFFER_SIZE,0);
string firstMsg(buffer,byteReceived);
if(firstMsg.find("first")!=string::npos){
board.currentPlayer=PLAYER_X;
cout<<firstMsg<<endl;
cout<<"You first."<<endl;
}
else{
board.currentPlayer=PLAYER_O;
cout<<"You second."<<endl;
}
pair<int,int>lastMove;
while(!board.gameOver){
if(board.currentPlayer==PLAYER_X){
system("cls");
int a,b,zl[10][2]={{0,0},{0,0},{0,1},
{0,2},{1,0},{1,1},{1,2},{2,0},{2,1},{2,2}};
color(230,230,230);
cout<<"对方在 ("<<lastMove.first<<" "<<lastMove.second<<") 下棋"<<endl;
board.print();
gotoxy(0,20);color(230,230,230);
cout<<"你的回合: ";cin>>a>>b;
if(!board.makeMove(zl[a][0],zl[a][1],zl[b][0],zl[b][1])){
cout<<"无效的走法,请重试!"<<endl;
Sleep(1000);continue;
}
string message=to_string(a)+" "+to_string(b);lastMove=make_pair(a,b);
send(clientSocket,message.c_str(),message.size()+1,0);
}
else{
system("cls");
cout<<"你在 ("<<lastMove.first<<" "<<lastMove.second<<") 下棋"<<endl;
board.print();gotoxy(0,20);color(230,230,230);cout<<"等待对方走棋...... ";
int bytesReceived=recv(clientSocket,buffer,BUFFER_SIZE,0);
if(bytesReceived<=0){
cout<<"Client disconnected."<<endl;
board.ultimateWinner=PLAYER_X;
Sleep(1000);
break;
}
string receivedStr(buffer,bytesReceived);
size_t spacePos=receivedStr.find(' ');
if(spacePos!=std::string::npos){
int num1=stoi(receivedStr.substr(0,spacePos));
int num2=stoi(receivedStr.substr(spacePos+1));
int zl[10][2]={{0,0},{0,0},{0,1},{0,2},{1,0},{1,1},{1,2},{2,0},{2,1},{2,2}};
board.makeMove(zl[num1][0],zl[num1][1],zl[num2][0],zl[num2][1]);
lastMove=make_pair(num1,num2);
}
}
}
system("cls");board.print();closesocket(clientSocket);
gotoxy(0,20);color(230,230,230);
if(board.ultimateWinner==PLAYER_X)
cout<<"恭喜你赢了!"<<endl;
else if(board.ultimateWinner==PLAYER_O)
cout<<"竟然输了!"<<endl;
else cout<<"平局,还行!"<<endl;
Sleep(10000);
}
};
int main() {
InitializeUI();
if(!InitializeWinsock()){return 1;}int choice;
while(true){
cout<<"Choose mode:\n1. Server\n2. Client\nEnter choice :";
cin>>choice;
if(choice==1||choice==2)break;
cout<<"Invalid choice."<<endl;
Sleep(1000);system("cls");
}
LAN lan;
if(choice==1)lan.RunServer();
else lan.RunClient();
return 0;
}
-lws2_32 只有小UI。。。因为作者喜欢。
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...