蒟蒻的五子棋ai

逃离地球

2019-01-29 16:20:01

Personal

这是本蒟蒻的第一篇博客qwq(上一篇不算) 这次来讲一讲我才很久以前编的一个project——五子棋AI(刚从我的U盘里翻出来) 实际上我还是可以下赢这个AI的,因为这个AI不会下三三、三四这样的棋(不懂的可以去网上搜一搜,很好理解),也有一些奇奇怪怪的bug。 主要思路就是用**dfs**给每个没有下棋的点进行评分,从进攻、防守两个方面进行评分,看四周的棋子的数量,周围对方或自己的棋子连得越长,评分就越高,再把棋下在评分最高的位置。 那就直接上代码吧 ```cpp /* project:五子棋 作者:杨千睿 */ #include<iostream> #include<windows.h> #include<time.h> #include<conio.h> using namespace std; #define MAX_SIZE 14 int flag1=0; char a[MAX_SIZE][MAX_SIZE],ai1,ai2; unsigned long b[MAX_SIZE][MAX_SIZE]={0}; void gotoxy(int x, int y) { COORD coord; HANDLE hscr; coord.X = x; coord.Y = y; hscr = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hscr, coord); } void gotoqp(int x, int y) { gotoxy(4*x+7,2*y); } //-----------------------------------------------------------------------ai int Random(int start, int end){ int dis = end - start; return rand()%dis + start; } int setplayer2(unsigned long &s, int &ps,int step=2) { ps+=step; if(ps==2) s+=10; if(ps==3) s+=20; if(ps==4) s+=50; if(ps==5) s+=70; if(ps==6) s+=100; if(ps==7) s+=200; if(ps==8) s+=1000; if(ps==10) s+=10000; } int setplayer1(unsigned long &s, int &ps,int step=2) { ps+=step; if(ps==2) s+=11; if(ps==3) s+=21; if(ps==4) s+=51; if(ps==5) s+=71; if(ps==6) s+=101; if(ps==7) s+=201; if(ps==8) s+=2001; if(ps==10) s+=10001; } void point(unsigned long &s,int x,int y,int player,int dir,int ps){ int oldps; if(dir==0){ if(x+1<MAX_SIZE&&a[x+1][y]=='O'){ oldps=ps; setplayer2(s,ps); point(s,x+1,y,2,1,ps); ps=oldps; } if(y+1<MAX_SIZE&&a[x][y+1]=='O'){ oldps=ps; setplayer2(s,ps); point(s,x,y+1,2,2,ps); ps=oldps; } if(x-1>0&&a[x-1][y]=='O'){ oldps=ps; setplayer2(s,ps); point(s,x-1,y,2,3,ps); ps=oldps; } if(y-1>0&&a[x][y-1]=='O'){ oldps=ps; setplayer2(s,ps); point(s,x,y-1,2,4,ps); ps=oldps; } if(x+1<MAX_SIZE&&y+1<MAX_SIZE&&a[x+1][y+1]=='O'){ oldps=ps; setplayer2(s,ps); point(s,x+1,y+1,2,5,ps); ps=oldps; } if(x-1>0&&y-1>0&&a[x-1][y-1]=='O'){ oldps=ps; setplayer2(s,ps); point(s,x-1,y-1,2,6,ps); ps=oldps; } if(x+1<MAX_SIZE&&y-1>0&&a[x+1][y-1]=='O'){ oldps=ps; setplayer2(s,ps); point(s,x+1,y-1,2,7,ps); ps=oldps; } if(y+1<MAX_SIZE&&x-1>0&&a[x-1][y+1]=='O'){ oldps=ps; setplayer2(s,ps); point(s,x-1,y+1,2,8,ps); ps=oldps; }//连自己 if(x+1<MAX_SIZE&&a[x+1][y]=='X'){ oldps=ps; setplayer1(s,ps); point(s,x+1,y,1,1,ps); ps=oldps; } if(y+1<MAX_SIZE&&a[x][y+1]=='X'){ oldps=ps; setplayer1(s,ps); point(s,x,y+1,1,2,ps); ps=oldps; } if(x-1>0&&a[x-1][y]=='X'){ oldps=ps; setplayer1(s,ps); point(s,x-1,y,1,3,ps); ps=oldps; } if(y-1>0&&a[x][y-1]=='X'){ oldps=ps; setplayer1(s,ps); point(s,x,y-1,1,4,ps); ps=oldps; } if(x+1<MAX_SIZE&&y+1<MAX_SIZE&&a[x+1][y+1]=='X'){ oldps=ps; setplayer1(s,ps); point(s,x+1,y+1,1,5,ps); ps=oldps; } if(x-1>0&&y-1>0&&a[x-1][y-1]=='X'){ oldps=ps; setplayer1(s,ps); point(s,x-1,y-1,1,6,ps); ps=oldps; } if(x+1<MAX_SIZE&&y-1>0&&a[x+1][y-1]=='X'){ oldps=ps; setplayer1(s,ps); point(s,x+1,y-1,1,7,ps); ps=oldps; } if(y+1<MAX_SIZE&&x-1>0&&a[x-1][y+1]=='X'){ oldps=ps; setplayer1(s,ps); point(s,x-1,y+1,1,8,ps); ps=oldps; }//防守 } if(player==2)//进攻 { if(x+1<MAX_SIZE&&a[x+1][y]!='X'&&dir==1){ oldps=ps; if(a[x+1][y]=='O') { setplayer2(s,ps); point(s,x+1,y,player,dir,ps); }else if(0==ps%2) { setplayer2(s,ps,1); point(s,x+1,y,player,dir,ps); } ps=oldps; } if(y+1<MAX_SIZE&&a[x][y+1]!='X'&&dir==2){ oldps=ps; if(a[x][y+1]=='O') { setplayer2(s,ps); point(s,x,y+1,player,dir,ps); }else if(0==ps%2) { setplayer2(s,ps,1); point(s,x,y+1,player,dir,ps); } ps=oldps; } if(x-1>0&&a[x-1][y]!='X'&&dir==3){ oldps=ps; if(a[x-1][y]=='O') { setplayer2(s,ps); point(s,x-1,y,player,dir,ps); } else if(0==ps%2) { setplayer2(s,ps,1); point(s,x-1,y,player,dir,ps); } ps=oldps; } if(y-1>0&&a[x][y-1]!='X'&&dir==4){ oldps=ps; if(a[x][y-1]=='O') { setplayer2(s,ps); point(s,x,y-1,player,dir,ps); } else if(0==ps%2) { setplayer2(s,ps,1); point(s,x,y-1,player,dir,ps); } ps=oldps; } if(x+1<MAX_SIZE&&y+1<MAX_SIZE&&a[x+1][y+1]!='X'&&dir==5){ oldps=ps; if(a[x+1][y+1]=='O') { setplayer2(s,ps); point(s,x+1,y+1,player,dir,ps); } else if(0==ps%2) { setplayer2(s,ps,1); point(s,x+1,y+1,player,dir,ps); } ps=oldps; } if(x-1>0&&y-1>0&&a[x-1][y-1]!='X'&&dir==6){ oldps=ps; if(a[x-1][y-1]=='O') { setplayer2(s,ps); point(s,x-1,y-1,player,dir,ps); } else if(0==ps%2) { setplayer2(s,ps,1); point(s,x-1,y-1,player,dir,ps); } ps=oldps; } if(x+1<MAX_SIZE&&y-1>0&&a[x+1][y-1]!='X'&&dir==7){ oldps=ps; if(a[x+1][y-1]=='O'){ setplayer2(s,ps); point(s,x+1,y-1,player,dir,ps); } else if(0==ps%2) { setplayer2(s,ps,1); point(s,x+1,y-1,player,dir,ps); } ps=oldps; } if(y+1<MAX_SIZE&&x-1>0&&a[x-1][y+1]!='X'&&dir==8){ oldps=ps; if(a[x-1][y+1]=='O') { setplayer2(s,ps); point(s,x-1,y+1,player,dir,ps); } else if(0==ps%2) { setplayer2(s,ps,1); point(s,x-1,y+1,player,dir,ps); } ps=oldps; } } else if(player==1)//防守 { if(x+1<MAX_SIZE&&a[x+1][y]!='O'&&dir==1){ oldps=ps; if(a[x+1][y]=='X') { setplayer1(s,ps); point(s,x+1,y,player,dir,ps); } else if(0==ps%2) { setplayer1(s,ps,1); point(s,x+1,y,player,dir,ps); } ps=oldps; } if(y+1<MAX_SIZE&&a[x][y+1]!='O'&&dir==2){ oldps=ps; if(a[x][y+1]=='X') { setplayer1(s,ps); point(s,x,y+1,player,dir,ps); } else if(0==ps%2) { setplayer1(s,ps,1); point(s,x,y+1,player,dir,ps); } ps=oldps; } if(x-1>0&&a[x-1][y]!='O'&&dir==3){ oldps=ps; if(a[x-1][y]=='X') { setplayer1(s,ps); point(s,x-1,y,player,dir,ps); } else if(0==ps%2) { setplayer1(s,ps,1); point(s,x-1,y,player,dir,ps); } ps=oldps; } if(y-1>0&&a[x][y-1]!='O'&&dir==4){ oldps=ps; if(a[x][y-1]=='X') { setplayer1(s,ps); point(s,x,y-1,player,dir,ps); } else if(0==ps%2) { setplayer1(s,ps,1); point(s,x,y-1,player,dir,ps); } ps=oldps; } if(x+1<MAX_SIZE&&y+1<MAX_SIZE&&a[x+1][y+1]!='O'&&dir==5){ oldps=ps; if(a[x+1][y+1]=='X') { setplayer1(s,ps); point(s,x+1,y+1,player,dir,ps); } else if(0==ps%2) { setplayer1(s,ps,1); point(s,x+1,y+1,player,dir,ps); } ps=oldps; } if(x-1>0&&y-1>0&&a[x-1][y-1]!='O'&&dir==6){ oldps=ps; if(a[x-1][y-1]=='X') { setplayer1(s,ps); point(s,x-1,y-1,player,dir,ps); } else if(0==ps%2) { setplayer1(s,ps,1); point(s,x-1,y-1,player,dir,ps); } ps=oldps; } if(x+1<MAX_SIZE&&y-1>0&&a[x+1][y-1]!='O'&&dir==7){ oldps=ps; if(a[x+1][y-1]=='X') { setplayer1(s,ps); point(s,x+1,y-1,player,dir,ps); } else if(0==ps%2) { setplayer1(s,ps,1); point(s,x+1,y-1,player,dir,ps); } ps=oldps; } if(y+1<MAX_SIZE&&x-1>0&&a[x-1][y+1]!='O'&&dir==8){ oldps=ps; if(a[x-1][y+1]=='X') { setplayer1(s,ps); point(s,x-1,y+1,player,dir,ps); } else if(0==ps%2) { setplayer1(s,ps,1); point(s,x-1,y+1,player,dir,ps); } ps=oldps; } } } void ai(){ int max=0,m,n; for(int i=1;i<MAX_SIZE;i++){ for(int j=1;j<MAX_SIZE;j++){ b[i][j]=0; } } ai1=0;ai2=0; for(int i=1;i<MAX_SIZE;i++){ for(int j=1;j<MAX_SIZE;j++){ if(a[i][j]==' '){ point(b[i][j],i,j,0,0,0); } } } for(int i=1;i<MAX_SIZE;i++){ for(int j=1;j<MAX_SIZE;j++){ if(b[i][j]>max&&a[i][j]==' '){ max=b[i][j]; ai1=i; ai2=j; } else if(b[i][j]==max&&a[i][j]==' '){ if(Random(0,2)==1) { max=b[i][j]; ai1=i; ai2=j; } } } cout<<endl; } } //-----------------------------------------------------------------------ai int panduan(char player){ //是否下满 int flag=0; for(int i=1;i<MAX_SIZE;i++){ for(int j=1;j<MAX_SIZE;j++){ if(a[i][j]==' '){ flag=1; break; } } } if(flag==0) return 2; //是否获胜 for(int i=1;i<MAX_SIZE;i++){ for(int j=1;j<MAX_SIZE;j++){ if(a[i][j]==player){ if(i-5>=0){ if(a[i-1][j]==player&&a[i-2][j]==player&&a[i-3][j]==player&&a[i-4][j]==player) return 1; } if(j-5>=0){ if(a[i][j-1]==player&&a[i][j-2]==player&&a[i][j-3]==player&&a[i][j-4]==player) return 1; } if(i<=6){ if(a[i+1][j]==player&&a[i+2][j]==player&&a[i+3][j]==player&&a[i+4][j]==player) return 1; } if(j<=6){ if(a[i][j+1]==player&&a[i][j+2]==player&&a[i][j+3]==player&&a[i][j+4]==player) return 1; } if(i-5>=0&&j-5>0){ if(a[i-1][j-1]==player&&a[i-2][j-2]==player&&a[i-3][j-3]==player&&a[i-4][j-4]==player) return 1; } if(i-5>=0&&j<=6){ if(a[i-1][j+1]==player&&a[i-2][j+2]==player&&a[i-3][j+3]==player&&a[i-4][j+4]==player) return 1; } if(i<=6&&j<=6){ if(a[i+1][j+1]==player&&a[i+2][j+2]==player&&a[i+3][j+3]==player&&a[i+4][j+4]==player) return 1; } if(i<=6&&j-5>=0){ if(a[i+1][j-1]==player&&a[i+2][j-2]==player&&a[i+3][j-3]==player&&a[i+4][j-4]==player) return 1; } } } } return 0; } void qipan(int x,int y,int flag){ cout<<" "<<1<<" "<<2<<" "<<3<<" "<<4<<" "<<5<<" "<<6<<" "<<7<<" "<<8<<" "<<9<<" "<<10<<" "<<11<<" "<<12<<" "<<13<<endl; for(int i=1;i<MAX_SIZE;i++){ cout<<"\t "; for(int m=5;m<4*MAX_SIZE;m++) cout<<"-"; cout<<endl<<i<<"\t"; cout<<" | "; for(int j=1;j<MAX_SIZE;j++){ if(i==x&&j==y&&flag==1){ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED); cout<<a[i][j]; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY); cout<<" | "; } else cout<<a[i][j]<<" | "; } cout<<endl; } cout<<" "; for(int m=5;m<4*MAX_SIZE;m++) cout<<"-"; }//画棋盘 int jisuan(){ int aa[MAX_SIZE][MAX_SIZE],result=0; unsigned long bb[MAX_SIZE][MAX_SIZE]; for(int i=1;i<MAX_SIZE;i++){ for(int j=1;j<MAX_SIZE;j++){ aa[i][j]=a[i][j]; bb[i][j]=b[i][j]; } }//初始化 while(1){ ai(); int x=ai1,y=ai2; a[x][y]='X'; if(panduan('X')==1){ result=1; } if(panduan('X')==2){ result=2; } ai(); x=ai1;y=ai2; a[x][y]='O'; if(panduan('O')==1){ result=0; } if(panduan('O')==2){ result=2; } } for(int i=1;i<MAX_SIZE;i++){ for(int j=1;j<MAX_SIZE;j++){ a[i][j]=aa[i][j]; b[i][j]=bb[i][j]; } } return result; } int newai() { int max=0,m,n; ai1=0;ai2=0; for(int i=1;i<MAX_SIZE;i++){ for(int j=1;j<MAX_SIZE;j++){ b[i][j]=0; } } for(int i=1;i<MAX_SIZE;i++){ for(int j=1;j<MAX_SIZE;j++){ if(a[i][j]==' '){ point(b[i][j],i,j,0,0,0); } } } for(int i=1;i<MAX_SIZE;i++){ for(int j=1;j<MAX_SIZE;j++){ if(b[i][j]>max&&a[i][j]==' '){ max=b[i][j]; ai1=i; ai2=j; } else if(b[i][j]==max&&a[i][j]==' '){ if(Random(0,2)==1) { max=b[i][j]; ai1=i; ai2=j; } } } } } int main(){ srand( (unsigned)time( NULL ) ); system("cls"); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY); int x=8,y=8,caidan=0; system("Color A"); for(int i=1;i<MAX_SIZE;i++){ for(int j=1;j<MAX_SIZE;j++){ a[i][j]=' '; } }//初始化 qipan(0,0,0); gotoqp(x,y); while(1){ //x: gotoqp(1,MAX_SIZE); cout<<endl<<"请按方向键控制光标位置,按空格键确定下棋"<<endl<<"作者:杨千睿"<<endl; gotoqp(y,x); int ch; ch=getch(); if(ch==224) ch=getch(); while (ch!=32) { if(ch==75)//left { if(y>1)y--; gotoqp(y,x); } if(ch==77)//right { if(y<MAX_SIZE-1)y++; gotoqp(y,x); } if(ch==72)//up { if(x>1)x--; gotoqp(y,x); } if(ch==80)//down { if(x<MAX_SIZE-1)x++; gotoqp(y,x); } ch=getch(); if(ch==224) ch=getch(); } /*ai(); x=ai1;y=ai2;*/ if(a[x][y]!=' '||x>MAX_SIZE||x<1||y>MAX_SIZE||y<1){ caidan++; if(caidan==5){ gotoqp(1,MAX_SIZE); cout<<"这里有棋,别点了"<<endl; gotoqp(y,x); } continue; } else{ caidan=0; a[x][y]='X'; gotoqp(y,x); cout<<a[x][y]; gotoqp(y,x); } if(panduan('X')==1){ gotoqp(1,MAX_SIZE); cout<<endl<<endl<<endl<<"您赢了"<<endl; flag1=1; break; } if(panduan('X')==2){ gotoqp(1,MAX_SIZE); cout<<endl<<endl<<endl<<"平局"<<endl; flag1=1; break; } o: ai(); x=ai1;y=ai2; if(a[x][y]!=' '||x>MAX_SIZE||x<1||y>MAX_SIZE||y<1){ goto o; } else{ a[x][y]='O'; gotoqp(y,x); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED); cout<<a[x][y]; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN); gotoqp(y,x); } if(panduan('O')==1){ gotoqp(1,MAX_SIZE); cout<<endl<<endl<<endl<<"电脑赢了"<<endl; flag1=1; break; } if(panduan('O')==2){ gotoqp(1,MAX_SIZE); cout<<endl<<endl<<endl<<"平局"<<endl; flag1=1; break; } } system("pause"); return 0; } ``` 有点长,大家不愿意看的就不用看了,可以下下来运行试一下(~~可以在机房里玩五子棋并在被发现时向教练解释说自己在调试程序~~),遇到一些bug也可以私信我 现在已知的bug有: 1. 在棋下在五个子的中间连成五个子后胜负判断出错 2. ai会在靠近边界的地方试图连成五个棋,实际上连不成。 这两个bug我 ~~懒得改了~~ 有时间再改 代码风格可能比较奇怪,毕竟是我去年写的,那时还是一个蒟蒻 ~~现在也是~~,所以用了goto语句,注释也比较少,大家有看不懂的地方可以私信我,~~我可能也看不懂~~,那就这样吧,感谢各位巨佬阅读我的文章,祝你们akioi ~~好吧你们早就ak了~~ [我的洛谷主页](https://www.luogu.org/space/show?uid=63951) # updated on 2021/1/27 ## 闲得无聊修了一下这玩意,以前写的东西真的不能看。。。 ### 进度:修完了除了 AI 的部分(然而 AI 有 300 多行。。。) **代码:** ```cpp #include <conio.h> #include <windows.h> #include <ctime> #include <iostream> const int MAXSIZE = 14; char chessBoard[MAXSIZE][MAXSIZE]; namespace AI { char ai1, ai2; int b[MAXSIZE][MAXSIZE] = {0}; #define random(m, n) rand() % (n - m + 1) + m void setplayer1(int &s, int &ps, int step = 2) { ps += step; if (ps == 2) s += 11; if (ps == 3) s += 21; if (ps == 4) s += 51; if (ps == 5) s += 71; if (ps == 6) s += 101; if (ps == 7) s += 201; if (ps == 8) s += 2001; if (ps == 10) s += 10001; } void setplayer2(int &s, int &ps, int step = 2) { ps += step; if (ps == 2) s += 10; if (ps == 3) s += 20; if (ps == 4) s += 50; if (ps == 5) s += 70; if (ps == 6) s += 100; if (ps == 7) s += 200; if (ps == 8) s += 1000; if (ps == 10) s += 10000; } void point(int &s, int x, int y, int player, int dir, int ps) { int oldps; if (dir == 0) { if (x + 1 < MAXSIZE && chessBoard[x + 1][y] == 'O') { oldps = ps; setplayer2(s, ps); point(s, x + 1, y, 2, 1, ps); ps = oldps; } if (y + 1 < MAXSIZE && chessBoard[x][y + 1] == 'O') { oldps = ps; setplayer2(s, ps); point(s, x, y + 1, 2, 2, ps); ps = oldps; } if (x - 1 > 0 && chessBoard[x - 1][y] == 'O') { oldps = ps; setplayer2(s, ps); point(s, x - 1, y, 2, 3, ps); ps = oldps; } if (y - 1 > 0 && chessBoard[x][y - 1] == 'O') { oldps = ps; setplayer2(s, ps); point(s, x, y - 1, 2, 4, ps); ps = oldps; } if (x + 1 < MAXSIZE && y + 1 < MAXSIZE && chessBoard[x + 1][y + 1] == 'O') { oldps = ps; setplayer2(s, ps); point(s, x + 1, y + 1, 2, 5, ps); ps = oldps; } if (x - 1 > 0 && y - 1 > 0 && chessBoard[x - 1][y - 1] == 'O') { oldps = ps; setplayer2(s, ps); point(s, x - 1, y - 1, 2, 6, ps); ps = oldps; } if (x + 1 < MAXSIZE && y - 1 > 0 && chessBoard[x + 1][y - 1] == 'O') { oldps = ps; setplayer2(s, ps); point(s, x + 1, y - 1, 2, 7, ps); ps = oldps; } if (y + 1 < MAXSIZE && x - 1 > 0 && chessBoard[x - 1][y + 1] == 'O') { oldps = ps; setplayer2(s, ps); point(s, x - 1, y + 1, 2, 8, ps); ps = oldps; } //连自己 if (x + 1 < MAXSIZE && chessBoard[x + 1][y] == 'X') { oldps = ps; setplayer1(s, ps); point(s, x + 1, y, 1, 1, ps); ps = oldps; } if (y + 1 < MAXSIZE && chessBoard[x][y + 1] == 'X') { oldps = ps; setplayer1(s, ps); point(s, x, y + 1, 1, 2, ps); ps = oldps; } if (x - 1 > 0 && chessBoard[x - 1][y] == 'X') { oldps = ps; setplayer1(s, ps); point(s, x - 1, y, 1, 3, ps); ps = oldps; } if (y - 1 > 0 && chessBoard[x][y - 1] == 'X') { oldps = ps; setplayer1(s, ps); point(s, x, y - 1, 1, 4, ps); ps = oldps; } if (x + 1 < MAXSIZE && y + 1 < MAXSIZE && chessBoard[x + 1][y + 1] == 'X') { oldps = ps; setplayer1(s, ps); point(s, x + 1, y + 1, 1, 5, ps); ps = oldps; } if (x - 1 > 0 && y - 1 > 0 && chessBoard[x - 1][y - 1] == 'X') { oldps = ps; setplayer1(s, ps); point(s, x - 1, y - 1, 1, 6, ps); ps = oldps; } if (x + 1 < MAXSIZE && y - 1 > 0 && chessBoard[x + 1][y - 1] == 'X') { oldps = ps; setplayer1(s, ps); point(s, x + 1, y - 1, 1, 7, ps); ps = oldps; } if (y + 1 < MAXSIZE && x - 1 > 0 && chessBoard[x - 1][y + 1] == 'X') { oldps = ps; setplayer1(s, ps); point(s, x - 1, y + 1, 1, 8, ps); ps = oldps; } //防守 } if (player == 2) //进攻 { if (x + 1 < MAXSIZE && chessBoard[x + 1][y] != 'X' && dir == 1) { oldps = ps; if (chessBoard[x + 1][y] == 'O') { setplayer2(s, ps); point(s, x + 1, y, player, dir, ps); } else if (0 == ps % 2) { setplayer2(s, ps, 1); point(s, x + 1, y, player, dir, ps); } ps = oldps; } if (y + 1 < MAXSIZE && chessBoard[x][y + 1] != 'X' && dir == 2) { oldps = ps; if (chessBoard[x][y + 1] == 'O') { setplayer2(s, ps); point(s, x, y + 1, player, dir, ps); } else if (0 == ps % 2) { setplayer2(s, ps, 1); point(s, x, y + 1, player, dir, ps); } ps = oldps; } if (x - 1 > 0 && chessBoard[x - 1][y] != 'X' && dir == 3) { oldps = ps; if (chessBoard[x - 1][y] == 'O') { setplayer2(s, ps); point(s, x - 1, y, player, dir, ps); } else if (0 == ps % 2) { setplayer2(s, ps, 1); point(s, x - 1, y, player, dir, ps); } ps = oldps; } if (y - 1 > 0 && chessBoard[x][y - 1] != 'X' && dir == 4) { oldps = ps; if (chessBoard[x][y - 1] == 'O') { setplayer2(s, ps); point(s, x, y - 1, player, dir, ps); } else if (0 == ps % 2) { setplayer2(s, ps, 1); point(s, x, y - 1, player, dir, ps); } ps = oldps; } if (x + 1 < MAXSIZE && y + 1 < MAXSIZE && chessBoard[x + 1][y + 1] != 'X' && dir == 5) { oldps = ps; if (chessBoard[x + 1][y + 1] == 'O') { setplayer2(s, ps); point(s, x + 1, y + 1, player, dir, ps); } else if (0 == ps % 2) { setplayer2(s, ps, 1); point(s, x + 1, y + 1, player, dir, ps); } ps = oldps; } if (x - 1 > 0 && y - 1 > 0 && chessBoard[x - 1][y - 1] != 'X' && dir == 6) { oldps = ps; if (chessBoard[x - 1][y - 1] == 'O') { setplayer2(s, ps); point(s, x - 1, y - 1, player, dir, ps); } else if (0 == ps % 2) { setplayer2(s, ps, 1); point(s, x - 1, y - 1, player, dir, ps); } ps = oldps; } if (x + 1 < MAXSIZE && y - 1 > 0 && chessBoard[x + 1][y - 1] != 'X' && dir == 7) { oldps = ps; if (chessBoard[x + 1][y - 1] == 'O') { setplayer2(s, ps); point(s, x + 1, y - 1, player, dir, ps); } else if (0 == ps % 2) { setplayer2(s, ps, 1); point(s, x + 1, y - 1, player, dir, ps); } ps = oldps; } if (y + 1 < MAXSIZE && x - 1 > 0 && chessBoard[x - 1][y + 1] != 'X' && dir == 8) { oldps = ps; if (chessBoard[x - 1][y + 1] == 'O') { setplayer2(s, ps); point(s, x - 1, y + 1, player, dir, ps); } else if (0 == ps % 2) { setplayer2(s, ps, 1); point(s, x - 1, y + 1, player, dir, ps); } ps = oldps; } } else if (player == 1) //防守 { if (x + 1 < MAXSIZE && chessBoard[x + 1][y] != 'O' && dir == 1) { oldps = ps; if (chessBoard[x + 1][y] == 'X') { setplayer1(s, ps); point(s, x + 1, y, player, dir, ps); } else if (0 == ps % 2) { setplayer1(s, ps, 1); point(s, x + 1, y, player, dir, ps); } ps = oldps; } if (y + 1 < MAXSIZE && chessBoard[x][y + 1] != 'O' && dir == 2) { oldps = ps; if (chessBoard[x][y + 1] == 'X') { setplayer1(s, ps); point(s, x, y + 1, player, dir, ps); } else if (0 == ps % 2) { setplayer1(s, ps, 1); point(s, x, y + 1, player, dir, ps); } ps = oldps; } if (x - 1 > 0 && chessBoard[x - 1][y] != 'O' && dir == 3) { oldps = ps; if (chessBoard[x - 1][y] == 'X') { setplayer1(s, ps); point(s, x - 1, y, player, dir, ps); } else if (0 == ps % 2) { setplayer1(s, ps, 1); point(s, x - 1, y, player, dir, ps); } ps = oldps; } if (y - 1 > 0 && chessBoard[x][y - 1] != 'O' && dir == 4) { oldps = ps; if (chessBoard[x][y - 1] == 'X') { setplayer1(s, ps); point(s, x, y - 1, player, dir, ps); } else if (0 == ps % 2) { setplayer1(s, ps, 1); point(s, x, y - 1, player, dir, ps); } ps = oldps; } if (x + 1 < MAXSIZE && y + 1 < MAXSIZE && chessBoard[x + 1][y + 1] != 'O' && dir == 5) { oldps = ps; if (chessBoard[x + 1][y + 1] == 'X') { setplayer1(s, ps); point(s, x + 1, y + 1, player, dir, ps); } else if (0 == ps % 2) { setplayer1(s, ps, 1); point(s, x + 1, y + 1, player, dir, ps); } ps = oldps; } if (x - 1 > 0 && y - 1 > 0 && chessBoard[x - 1][y - 1] != 'O' && dir == 6) { oldps = ps; if (chessBoard[x - 1][y - 1] == 'X') { setplayer1(s, ps); point(s, x - 1, y - 1, player, dir, ps); } else if (0 == ps % 2) { setplayer1(s, ps, 1); point(s, x - 1, y - 1, player, dir, ps); } ps = oldps; } if (x + 1 < MAXSIZE && y - 1 > 0 && chessBoard[x + 1][y - 1] != 'O' && dir == 7) { oldps = ps; if (chessBoard[x + 1][y - 1] == 'X') { setplayer1(s, ps); point(s, x + 1, y - 1, player, dir, ps); } else if (0 == ps % 2) { setplayer1(s, ps, 1); point(s, x + 1, y - 1, player, dir, ps); } ps = oldps; } if (y + 1 < MAXSIZE && x - 1 > 0 && chessBoard[x - 1][y + 1] != 'O' && dir == 8) { oldps = ps; if (chessBoard[x - 1][y + 1] == 'X') { setplayer1(s, ps); point(s, x - 1, y + 1, player, dir, ps); } else if (0 == ps % 2) { setplayer1(s, ps, 1); point(s, x - 1, y + 1, player, dir, ps); } ps = oldps; } } } void ai() { int Max = 0; for (int i = 1; i < MAXSIZE; i++) { for (int j = 1; j < MAXSIZE; j++) { b[i][j] = 0; } } ai1 = 0; ai2 = 0; for (int i = 1; i < MAXSIZE; i++) { for (int j = 1; j < MAXSIZE; j++) { if (chessBoard[i][j] == ' ') { point(b[i][j], i, j, 0, 0, 0); } } } for (int i = 1; i < MAXSIZE; i++) { for (int j = 1; j < MAXSIZE; j++) { if (b[i][j] > Max && chessBoard[i][j] == ' ') { Max = b[i][j]; ai1 = i; ai2 = j; } else if (b[i][j] == Max && chessBoard[i][j] == ' ') { if (random(0, 2) == 1) { Max = b[i][j]; ai1 = i; ai2 = j; } } } std::cout << std::endl; } } } // namespace AI namespace chess { void gotoxy(int x, int y) { COORD coord; HANDLE hscr; coord.X = x, coord.Y = y; hscr = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hscr, coord); } void gotoqp(int x, int y) { gotoxy(4 * x + 7, 2 * y); } namespace checker { bool checkPos(int x) { return (x > 0) && (x <= MAXSIZE); } bool checkRow(int x, int y, char player) { int dx[] = {0, 0, 0, 1, -1, 1, -1, 1, -1}, dy[] = {0, 1, -1, 0, 0, 1, -1, -1, 1}, cnt[9] = {0}; if (chessBoard[x][y] != player) return 0; for (int i = 1; i <= 8; ++i) { int nx = x, ny = y; while (checkPos(nx) && checkPos(ny) && chessBoard[nx][ny] == player) cnt[i]++, nx += dx[i], ny += dy[i]; } for (int i = 1; i <= 4; ++i) if (cnt[i * 2 - 1] + cnt[i * 2] - 1 >= 5) return 1; return 0; } int checkResult(char player) { int flag = 0; for (int i = 1; i < MAXSIZE; i++) for (int j = 1; j < MAXSIZE; j++) if (chessBoard[i][j] == ' ') { flag = 1; break; } if (flag == 0) return 2; // draw for (int i = 1; i < MAXSIZE; i++) for (int j = 1; j < MAXSIZE; j++) { if (checkRow(i, j, player)) return 1; // win } return 0; // nothing happened } bool print(char player) { if (player == 'X') { if (checkResult('X') == 1) { gotoxy(0, MAXSIZE * 2 + 3), std::cout << "您赢了" << std::endl; return 1; } if (checkResult('X') == 2) { gotoxy(0, MAXSIZE * 2 + 3), std::cout << "平局" << std::endl; return 1; } } else { if (checker::checkResult('O') == 1) { gotoxy(0, MAXSIZE * 2 + 3), std::cout << "电脑赢了" << std::endl; return 1; } if (checker::checkResult('O') == 2) { gotoxy(0, MAXSIZE * 2 + 3), std::cout << "平局" << std::endl; return 1; } } return 0; } } // namespace checker void draw(int x, int y, char ch) { gotoqp(x, y), chessBoard[x][y] = ch; if (ch == 'X') std::cout << chessBoard[x][y]; if (ch == 'O') SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED), std::cout << chessBoard[x][y], SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN); } int x = 7, y = 7; void initialize() { srand(time(0)), system("cls"); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY), system("Color A"); for (int i = 1; i < MAXSIZE; i++) for (int j = 1; j < MAXSIZE; j++) chessBoard[i][j] = ' '; std::string title = " 1 2 3 4 5 6 7 8 9 10 11 12 13"; std::cout << title << std::endl; for (int i = 1; i < MAXSIZE; i++) { std::cout << "\t "; for (int m = 5; m < 4 * MAXSIZE; m++) std::cout << "-"; std::cout << std::endl << i << "\t" << " | "; for (int j = 1; j < MAXSIZE; j++) { if (i == 0 && j == 0) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED); std::cout << chessBoard[i][j]; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY); std::cout << " | "; } else std::cout << chessBoard[i][j] << " | "; } std::cout << std::endl; } std::cout << " "; for (int m = 5; m < 4 * MAXSIZE; m++) std::cout << "-"; gotoxy(0, MAXSIZE * 2 + 1); std::cout << "请按方向键控制光标位置,按空格键确定下棋,按 Shift+e 退出。" << std::endl << "作者:杨千睿" << std::endl; gotoqp(x, y); } void getMovement() { int ch = getch(); if (ch == 224) ch = getch(); while (ch != 32) { if (ch == 72) if (y > 1) y--, gotoqp(x, y); if (ch == 80) if (y < MAXSIZE - 1) y++, gotoqp(x, y); if (ch == 75) if (x > 1) x--, gotoqp(x, y); if (ch == 77) if (x < MAXSIZE - 1) x++, gotoqp(x, y); if (ch == 69) gotoxy(0, MAXSIZE * 2 + 4), system("pause"), exit(0); ch = getch(); if (ch == 224) ch = getch(); } } void playerMove() { int errorClickCnt = 0; getMovement(); while (chessBoard[x][y] != ' ') { errorClickCnt++; if (errorClickCnt == 5) { gotoxy(0, MAXSIZE * 2 + 4), std::cout << "这里有棋,别点了……" << std::endl; gotoqp(x, y); } getMovement(); } draw(x, y, 'X'); if (checker::print('X')) system("pause"), exit(0); } void aiMove() { while (chessBoard[x][y] != ' ' || !checker::checkPos(x) || !checker::checkPos(y)) AI::ai(), x = AI::ai1, y = AI::ai2; draw(x, y, 'O'); if (checker::print('O')) system("pause"), exit(0); } } // namespace chess int main() { chess::initialize(); while (1) chess::playerMove(), chess::aiMove(); return 0; } ```