// 编译器版本 g++8.1.0 // 编译参数 -Weffc++ -Wextra -Wall -std=c++11 #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> using namespace std; /** * 常量定义 **/ const int BOARDSIZE = 9; const int DX[8]= {1,1,0,-1,-1,-1,0,1}; const int DY[8]= {0,1,1,1,0,-1,-1,-1}; /** * 数据类型定义 **/ // 关卡数据类型 struct BoardType { int map[BOARDSIZE][BOARDSIZE]; // 棋盘,0表示空位,1表示玩家棋子,2表示电脑棋子 int weight[BOARDSIZE][BOARDSIZE]; // AI下棋的权重,权重取对AI最有利和对玩家最有害两者的最大值 }; /** * 全局变量定义 **/ BoardType Gboard; /** * 游戏初始化 **/ void InitGame() { // 初始化显示画面高度和宽度 system("mode con cols=40 lines=20"); system("cls"); // 初始化变量 memset(Gboard.map,0,sizeof(Gboard.map)); return; } /** * 更新画面 **/ void Update() { system("cls"); printf(" "); for(int i=0; i<BOARDSIZE; i++) printf("%c ",'a'+i); putchar('\n'); for(int i=0; i<BOARDSIZE; i++) { printf(" %2d ",i); for(int j=0; j<BOARDSIZE; j++) { if(Gboard.map[i][j]==1) printf(" B"); else if(Gboard.map[i][j]==2) printf(" W"); else printf(" ."); } putchar('\n'); } putchar('\n'); return; } /** * 胜利画面 **/ void UpdateWin() { printf("YOU WIN!\n"); system("pause"); return; } /** * 失败画面 **/ void UpdateLose() { printf("YOU LOSE!\n"); system("pause"); return; } /** * 用户回合 **/ void PlayerTurn() { char inputStr[255]; int x,y; printf("Input(a 1 / restart / exit):"); scanf("%s",inputStr); if(strcmp(inputStr,"restart")==0) { InitGame(); Update(); PlayerTurn(); return; } if(strcmp(inputStr,"exit")==0) { system("exit"); return; } scanf("%d",&x); y=inputStr[0]-'a'; if(Gboard.map[x][y]!=0) { printf("Error."); system("pause"); Update(); PlayerTurn(); } Gboard.map[x][y]=1; return; } /** * 更新下棋权重 **/ void UpdateAIWeight() { for(int x=0; x<BOARDSIZE; x++) for(int y=0; y<BOARDSIZE; y++) if(Gboard.map[x][y]!=0) Gboard.weight[x][y]=0; else { int aiWeight=0; int playerWeight=0; // 计算八个方向上的棋子个数 for(int i=0; i<8; i++) { // 对自己有利 int pX=x; int pY=y; int cnt=1; for(int j=0; j<4; j++) { pX+=DX[i]; pY+=DY[i]; if(pX>=0&&pX<BOARDSIZE&&pY>=0&&pY<BOARDSIZE&&2==Gboard.map[pX][pY]) cnt++; else break; } aiWeight+=pow(10,cnt)+1; // 对玩家有害 pX=x; pY=y; cnt=1; for(int j=0; j<4; j++) { pX+=DX[i]; pY+=DY[i]; if(pX>=0&&pX<BOARDSIZE&&pY>=0&&pY<BOARDSIZE&&1==Gboard.map[pX][pY]) cnt++; else break; } playerWeight+=pow(10,cnt); } // 更新权重,对自己最有利或者对玩家最有害,当相同时选择对自己最有利的 Gboard.weight[x][y]=aiWeight>playerWeight?aiWeight:playerWeight; } return; } /** * 电脑回合 **/ void ComputerTurn() { // 计算权重 UpdateAIWeight(); // 寻找权重最大的点 int maxX; int maxY; int maxWeight=-1; for(int i=0; i<BOARDSIZE; i++) for(int j=0; j<BOARDSIZE; j++) if(Gboard.weight[i][j]>maxWeight) { maxX=i; maxY=j; maxWeight=Gboard.weight[i][j]; } // 下棋 Gboard.map[maxX][maxY]=2; return; } /** * 判断胜利 **/ bool CheckWin(int x,int y) { // 从上方顺时针向八个方向判断 for(int i=0; i<8; i++) { int pX=x; int pY=y; int cnt=1; for(int j=0; j<4; j++) { pX+=DX[i]; pY+=DY[i]; if(pX>=0&&pX<BOARDSIZE&&pY>=0&&pY<BOARDSIZE&&Gboard.map[x][y]==Gboard.map[pX][pY]) cnt++; } if(cnt==5) return true; } return false; } /** * 判断玩家胜利 **/ bool CheckPlayerWin() { for(int i=0; i<BOARDSIZE; i++) for(int j=0; j<BOARDSIZE; j++) if(Gboard.map[i][j]==1&&CheckWin(i,j)) return true; return false; } /** * 判断电脑胜利 **/ bool CheckPlayerLose() { for(int i=0; i<BOARDSIZE; i++) for(int j=0; j<BOARDSIZE; j++) if(Gboard.map[i][j]==2&&CheckWin(i,j)) return true; return false; } /** * 程序入口 **/ int main() { // 初始化游戏 InitGame(); Update(); while(true) { // 用户输入 PlayerTurn(); if(CheckPlayerWin()) { UpdateWin(); InitGame(); Update(); } // 电脑输入 ComputerTurn(); if(CheckPlayerLose()) { UpdateLose(); InitGame(); Update(); } // 更新画面 Update(); } return 0; } |