赞
踩
- #include<iostream>
- #include<iomanip>
- #include<fstream>
- #include<string>
- #include<cstdio>
- #include<cstring>
- #include<cstdlib>
- #include<ctime>
- #include<queue>
- #include<conio.h>
- #include<windows.h>
- //#include <graphics.h>
- using namespace std;
-
- HANDLE hout=GetStdHandle(STD_OUTPUT_HANDLE),hin=GetStdHandle(STD_INPUT_HANDLE);//句柄
- INPUT_RECORD mouseRec;//控制台输入信息
- DWORD res;
-
- int qipan[8][8],tishi[8][8],huiqiqipan[8][8];
- int heiqi,baiqi,xxx,yyy;
-
- /*清屏函数*/
- inline void clear_screen()
- {
- COORD home= {0,0};
- DWORD dummy;
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- GetConsoleScreenBufferInfo(hout,&csbi);
- FillConsoleOutputCharacter(hout,' ',csbi.dwSize.X*csbi.dwSize.Y,home,&dummy);
- SetConsoleCursorPosition(hout,home);
- }
-
- /*隐藏光标*/
- inline void hide()
- {
- CONSOLE_CURSOR_INFO cursor_info= {1,0};
- SetConsoleCursorInfo(hout, &cursor_info);
- }
- inline COORD get_mouse()//鼠标位置
- {
- while(1)
- {
- COORD pos;
- ReadConsoleInput(hin,&mouseRec,1,&res);
- if (mouseRec.EventType==MOUSE_EVENT)
- {
- if (mouseRec.Event.MouseEvent.dwButtonState==FROM_LEFT_1ST_BUTTON_PRESSED)
- {
- pos=mouseRec.Event.MouseEvent.dwMousePosition;
- return pos;
- }
- }
- }
- }
- void jiluqipan() //记录棋盘的上一步
- {
- int i,j;
- for(i=0; i<8; i++)
- {
- for(j=0; j<8; j++)
- {
- huiqiqipan[i][j]=qipan[i][j];
- }
- }
-
- }
-
- void huiqi() //悔棋函数
- {
- int i,j;
- for(i=0; i<8; i++)
- {
- for(j=0; j<8; j++)
- {
- qipan[i][j]=huiqiqipan[i][j];
- }
- }
- }
-
- int tongji(int qipan[][8],int player)//统计棋子的个数
- {
- int i,j;
- int hei=0,bai=0;
- for(i=0; i<8; i++)
- {
- for(j=0; j<8; j++)
- {
- if(qipan[i][j]==1)
- {
- hei++;
- }
- if(qipan[i][j]==-1)
- {
- bai++;
- }
- }
- }
- heiqi=hei;
- baiqi=bai;
- if(player==1)
- {
- return heiqi;
- }
- else
- {
- return baiqi;
- }
- }
- int zhuanhuax(int x)
- {
- if(x>1 && x<5)
- {
- return 0;
- }
- if(x>5 && x<9)
- {
- return 1;
- }
- if(x>9 && x<13)
- {
- return 2;
- }
- if(x>13 && x<17)
- {
- return 3;
- }
- if(x>17 && x<21)
- {
- return 4;
- }
- if(x>21 && x<25)
- {
- return 5;
- }
- if(x>25 && x<29)
- {
- return 6;
- }
- if(x>29 && x<33)
- {
- return 7;
- }
- }
- int zhuanhuay(int x)
- {
- if(x>=1 && x<3)
- {
- return 0;
- }
- if(x>=3 && x<5)
- {
- return 1;
- }
- if(x>=5 && x<7)
- {
- return 2;
- }
- if(x>=7 && x<9)
- {
- return 3;
- }
- if(x>=9 && x<11)
- {
- return 4;
- }
- if(x>=11 && x<13)
- {
- return 5;
- }
- if(x>=13 && x<15)
- {
- return 6;
- }
- if(x>=15 && x<17)
- {
- return 7;
- }
- }
- void chushihua() //棋盘初始化
- {
- memset(qipan,0,sizeof(qipan));//0代表此位置没有棋子
- qipan[3][3]=qipan[4][4]=-1;//2代表此位置是白色棋子
- qipan[3][4]=qipan[4][3]=1;//1代表此位置是黑色棋子
- heiqi=baiqi=2;
- }
-
- int zhujiemian() //进入游戏的主界面
- {
- hide();
- printf("\n\n\n\n\n\n 黑 ");
- Sleep(1000);
- printf("白 ");
- Sleep(1000);
- printf("棋");
- Sleep(1000);
- printf("\n\n\n __ky\n");
- Sleep(1200);
- clear_screen();
- //initgraph(600,500);
- //loadimage(NULL,"主界面1.jpg");
- printf("\n\n\n 黑 白 棋\n\n");
- printf("\n\n\n 人机对战\n");
- printf("\n 人人对战\n");
- COORD pos;
- pos=get_mouse();
- if(pos.X>=31 && pos.X<=37 && pos.Y==8)
- {
- return 1; //人机对战
- }
- else if(pos.X>=31 && pos.X<=38 && pos.Y==10)
- {
- //人人对战
- return 2;
- }
- }
-
- void jiemian() //棋盘函数显示棋盘
- {
- int i,j;
- printf(" 1 2 3 4 5 6 7 8 \n");
- printf(" ┏━┳━┳━┳━┳━┳━┳━┳━┓\n");
- for(i=0; i<7; i++)
- {
- printf("%d┃",i+1);
- for(j=0; j<8; j++)
- {
- if(tishi[i][j]==1)
- {
- printf("╳┃"); //1 提示可以
- }
- else if(qipan[i][j]==0)
- {
- printf(" ┃"); //0是没有棋子
- }
- if(qipan[i][j]==-1)
- {
- printf("●┃"); //1 黑 (人)
- }
- if(qipan[i][j]==1)
- {
- printf("○┃"); //-1 白 ()
- }
-
-
- }
- if(i==5)
- printf("\n ┣━╋━╋━╋━╋━╋━╋━╋━┫ 黑 : %d\n",heiqi);
- else if(i==6)
- printf("\n ┣━╋━╋━╋━╋━╋━╋━╋━┫ 白 : %d\n",baiqi);
- else
- printf("\n ┣━╋━╋━╋━╋━╋━╋━╋━┫\n");
- }
- printf("8┃");
- for(j=0; j<8; j++)
- {
- if(tishi[7][j]==1)
- {
- printf("╳┃");
- }
- else if(qipan[7][j]==0)
- {
- printf(" ┃");
- }
- if(qipan[7][j]==-1)
- {
- printf("●┃");
- }
- if(qipan[7][j]==1)
- {
- printf("○┃");
- }
-
-
- }
- printf("\n ┗━┻━┻━┻━┻━┻━┻━┻━┛\n");
- printf(" 黑 ○ 白 ● 可下 ╳\n");
- }
-
- int tishiqipan(int qipan[][8],int tishi[][8],int player)
- {
- int rowdelta, coldelta, row, col, x, y = 0;//row行col列
- int iStep = 0;
- int opponent = (player == 1) ? -1 : 1; //对方棋子
- //printf("\n%d\n",opponent);
- int myplayer = -1 * opponent; //我方棋子
- //将tishi数组全部清0
- for (row = 0; row < 8; row++)
- {
- for (col = 0; col < 8; col++)
- {
- tishi[row][col] = 0;
- }
- }
- //循环判断棋盘中哪些单元格可以下子
- for (row = 0; row < 8; row++)
- {
- for (col = 0; col < 8; col++)
- {
- //若棋盘上对应位置不为空(表示已经有子)
- if (qipan[row][col] != 0)
- {
- continue;//继续处理下一个单元格
- }
- //循环检查上下行
- for (rowdelta = -1; rowdelta <= 1; rowdelta++)
- {
- //循环检查左右列
- for (coldelta = -1; coldelta <= 1; coldelta++)
- {
- //检查若坐标超过棋盘 或为当前单元格
- if (row + rowdelta < 0 || row + rowdelta >= 8
- || col + coldelta < 0 || col + coldelta >= 8
- || (rowdelta == 0 && coldelta == 0))
- {
- continue; //继续循环
- }
- //若(row,col)四周有对手下的子
- if (qipan[row + rowdelta][col + coldelta] == opponent)
- {
- //以对手下子位置为坐标
- x = row + rowdelta;
- y = col + coldelta;
- //对对手下子为起始点,向四周查找自己方的棋子,以攻击对方棋子
- while(1)
- {
- //对手下子的四周坐标
- x += rowdelta;
- y += coldelta;
- //超过棋盘
- if (x < 0 || x >= 8 || y < 0 || y >= 8)
- {
- break; //退出循环
- }
- //若对应位置为空
- if (qipan[x][y] == 0)
- {
- break;
- }
- //若对应位置下的子是当前棋手的
- if (qipan[x][y] == myplayer)
- {
- //设置移动数组中对应位置为1 (该位置可下子,形成向对手进攻的棋形)
- tishi[row][col] = 1;
- iStep++; //累加可下子的位置数量
- break;
- }
- }
- }
- }
- }
- }
- }
- //返回可下的位置数量(若返回值为0,表示没地方可下)
- //printf("%d\n",iStep);
- return iStep;
- }
-
- void xiaqi(int qipan[][8],int row, int col, int player) //指定位置下棋
- {
- int rowdelta = 0;
- int coldelta = 0;
- int x = 0;
- int y = 0;
- char opponent = (player == 1) ? -1 : 1; //对方棋子
- char myplayer = -1 * opponent; //我方棋子
- qipan[row][col] = myplayer; //保存所下的棋子
- //检查所下子四周的棋子
- for (rowdelta = -1; rowdelta <= 1; rowdelta++)
- {
- for (coldelta = -1; coldelta <= 1; coldelta++)
- {
- //若坐标超过棋盘界限
- if (row + rowdelta < 0 || row + rowdelta >= 8 || col + coldelta < 0
- || col + coldelta >= 8 || (rowdelta == 0 && coldelta == 0))
- {
- continue; //继续下一位置
- }
- //若该位置是对手的棋子
- if (qipan[row + rowdelta][col + coldelta] == opponent)
- {
- //以对手棋为坐标
- x = row + rowdelta;
- y = col + coldelta;
- //在对手棋子四周寻找我方棋子
- while(1)
- {
- x += rowdelta;
- y += coldelta;
- //若坐标超过棋盘
- if (x < 0 || x >= 8 || y < 0 || y >= 8)
- {
- break; //退出循环
- }
- //若对应位置为空
- if (qipan[x][y] == 0)
- {
- break; //退出循环
- }
- //若对应位置是我方模子
- if (qipan[x][y] == myplayer)
- {
- //循环处理
- while (qipan[x -= rowdelta][y -= coldelta] == opponent)
- {
- //将中间的棋子都变成我方棋子
- qipan[x][y] = myplayer;
- }
- break; //退出循环
- }
- }
- }
- }
- }
- }
- //获取最佳下子位置
- int BestPlay(int qipan[][8], int tishi[][8], int player)
- {
- int row, col, i, j;
- //定义一个临时数组
- int chessboard1[8][8] = { 0 };
- int MaxScore = 0; //保存最高分
- int Score = 0;
- int opponent = (player == 1) ? -1 : 1; //对手下的棋子
- //循环检查每个单元格
- for (row = 0; row < 8; row++)
- {
- for (col = 0; col < 8; col++)
- {
- //若该位置不可下子
- if (!tishi[row][col])
- {
- continue; //继续
- }
- //复制棋盘各单元格下子的状态到临时数组
- for (i = 0; i < 8; i++)
- {
- for (j = 0; j < 8; j++)
- {
- chessboard1[i][j] = qipan[i][j];
- }
- }
- //在临时数组中的指定行列下子
- xiaqi(chessboard1, row, col, player);
- //获取下子后可得到的分数
- Score = tongji(chessboard1, player);
- //若原方案得到的分数小于本次下子的分数
- if (MaxScore < Score)
- {
- MaxScore = Score; //保存最高分
- }
- }
- }
- return MaxScore;//返回得到的最高分
- }
-
- void renji(int qipan[][8],int tishi[][8],int player)//AI自动下子
- {
- int row, col, row1, col1, i, j;
- //对方可下子提到的分数和最小分数
- int Score = 0, MinScore = 100;
- //临时数组,保存棋盘下子位置
- int chessboard1[8][8];
- //临时数组,保存可下子位置
- int isDown1[8][8];
- char opponent = (player == 1) ? -1 : 1; //对手下的棋子
- for (row = 0; row < 8; row++) //循环检查棋盘每个单元格
- {
- for (col = 0; col < 8; col++)
- {
- //若不可下子
- if (tishi[row][col] == 0)
- {
- continue;//继续下一个位置
- }
- //将棋盘原来的棋子复制到临时数组中
- for (i = 0; i < 8; i++)
- {
- for (j = 0; j < 8; j++)
- {
- chessboard1[i][j] = qipan[i][j];
- }
- }
- //试着在临时棋盘中的一个位子下子
- xiaqi(chessboard1, row, col, player);
- //检查对手是否有地方可下子
- tishiqipan(chessboard1, isDown1, opponent);
- //获得临时棋盘中对方下子的得分情况
- Score = BestPlay(chessboard1, isDown1, opponent);
- //保存对方得分最低的下法
- if (Score < MinScore)
- {
- MinScore = Score;
- row1 = row;
- col1 = col;
- }
- }
- }
- //AI按最优下法下子
- xxx=row1+1;
- yyy=col1+1;
- xiaqi(qipan, row1, col1, player);
- }
-
-
-
- void renren()
- {
- int player1=1;
- printf("先手执黑,后手执白,点击屏幕开始人人对战\n");
- COORD pos;
- int t,t1;
- pos=get_mouse();
- clear_screen();
- int flag=0;
- while(1)
- {
- if(heiqi+baiqi>=64)
- {
- if(heiqi>baiqi)
- {
- MessageBox(0,"黑棋胜!","恭喜",MB_OK);
- break;
- }
- else
- {
- MessageBox(0,"白棋胜!","恭喜",MB_OK);
- break;
- }
- break;
- }
- if(player1==1)
- {
- t=tishiqipan(qipan,tishi,1);
- if(t==0 && t1==0)
- {
- printf(" 两者都没有位置可下\n");
- flag=1;
- break;
- }
- else if(t==0)
- {
-
- printf(" 黑棋没有位置可下,白棋下\n");
- player1=2;
- Sleep(2000);
- }
- else
- {
- hide();
- clear_screen();
- jiemian();
- COORD ps;
- ps=get_mouse();
- int x=int(ps.X);//x是列
- int y=int(ps.Y);//y是行
- x=zhuanhuax(x);
- y=zhuanhuay(y);
- if(tishi[y][x]==1)
- {
- xiaqi(qipan,y,x,1);
- tishiqipan(qipan,tishi,2);
- tongji(qipan,1);
- jiemian();
- player1=2;
- clear_screen();
- }
- }
-
- }
- if(player1==2)
- {
- t1=tishiqipan(qipan,tishi,2);
- if(t==0 && t1==0)
- {
- printf(" 两者都没有位置可下\n");
- flag=1;
- break;
- }
- else if(t1==0)
- {
-
- printf(" 黑棋没有位置可下,白棋下\n");
- player1=1;
- Sleep(2000);
- }
- else
- {
- hide();
- clear_screen();
- jiemian();
- COORD ps;
- ps=get_mouse();
- int x=int(ps.X);//x是列
- int y=int(ps.Y);//y是行
- x=zhuanhuax(x);
- y=zhuanhuay(y);
- if(tishi[y][x]==1)
- {
- xiaqi(qipan,y,x,2);
- tishiqipan(qipan,tishi,1);
- tongji(qipan,2);
- jiemian();
- player1=1;
- hide();
- clear_screen();
- }
- }
-
- }
-
- }
- tongji(qipan,1);
- if(heiqi>baiqi && flag)
- {
- MessageBox(0,"黑棋胜!","恭喜",MB_OK);
- }
- else if(flag)
- {
- MessageBox(0,"白棋胜!","恭喜",MB_OK);
- }
-
- }
- void renjijiemain()//人机
- {
- clear_screen();
- jiluqipan();//记录棋盘
- int player=1;
- int t=0,t1=0;
- int flag=0;
- printf("\n\n\n 请选择\n\n");
- printf("\n 新游戏\n\n");
- printf("\n 读取存档\n\n");
- COORD pos;
- pos=get_mouse();
- int x=int(pos.X);//x是列
- int y=int(pos.Y);//y是行
- if(x>=25 && x<=33 && y==6)
- {
- printf("您执黑,并且先手,点击屏幕开始人机对战,祝你好运\n");
- pos=get_mouse();
- }
- if(x>=27 && x<=34 && y==9)
- {
- FILE * f = 0;
- int i,j;
- f = fopen("D:\\heibaiqi.dat", "rb+");
- if(!f)
- {
- printf(" 游戏没有存档\n\n");
- }
- else
- {
- clear_screen();
- fread(qipan,sizeof(qipan),1,f);
- fclose(f);
- printf(" 读取存档成功!点击屏幕开始对战\n\n");
- pos=get_mouse();
- }
- }
- clear_screen();
- while(1)
- {
- if(heiqi+baiqi>=64)
- {
- if(heiqi>baiqi)
- {
- MessageBox(0,"你赢了!","恭喜",MB_OK);
- return ;
- }
- else
- {
- MessageBox(0,"你输了!","抱歉",MB_OK);
- return ;
- }
- break;
- }
- if(player==1)
- {
- t=tishiqipan(qipan,tishi,1);
- if(t==0 && t1==0)
- {
- printf(" 两者都没有位置可下\n");
- flag=1;
- break;
- }
- else if(t==0)
- {
-
- printf(" 黑棋没有位置可下,白棋下\n");
- player=2;
- }
- else
- {
- hide();
- tongji(qipan,1);
- clear_screen();
- jiemian();
- printf("电脑上一步走的位置< %d , %d> 悔棋(一步) 存档退出\n",xxx,yyy);
- COORD ps;
- ps=get_mouse();
- int x=int(ps.X);//x是列
- int y=int(ps.Y);//y是行
- //printf("%d %d\n",x,y);
- if(x>=35 && x<=44 && y==19)
- {
- huiqi();
- }
- else if(x>=51 && x<=58 && y==19)
- {
- FILE * f = 0;
- f = fopen("D:\\heibaiqi.dat", "wb+");
- fwrite(qipan,sizeof(qipan),1,f);
- fclose(f);
- exit(0);
- }
- else
- {
- x=zhuanhuax(x);
- y=zhuanhuay(y);
- if(tishi[y][x]==1)
- {
- jiluqipan();//记录棋盘
- xiaqi(qipan,y,x,1);
- tishiqipan(qipan,tishi,2);
- tongji(qipan,1);
- jiemian();
- player=2;
- clear_screen();
- }
- }
- }
-
- }
- if(player==2)
- {
- tongji(qipan,1);
- int t1=tishiqipan(qipan,tishi,2);
- if(t==0 && t1==0)
- {
- printf(" 两者都没有位置可下\n");
- flag=1;
- break;
- }
- else if(t1==0)
- {
- printf(" 白棋没有位置可下,黑棋下\n");
- player=1;
- }
- else
- {
- renji(qipan,tishi,2);
- player=1;
- }
-
- }
-
- }
- tongji(qipan,1);
- if(heiqi>baiqi && flag)
- {
- MessageBox(0,"你赢了!","恭喜",MB_OK);
- return ;
- }
- else if(flag)
- {
- MessageBox(0,"你输了!","抱歉",MB_OK);
- return ;
- }
-
- }
- void game()
- {
- int ch=0;
- chushihua();
- tishiqipan(qipan,tishi,1);
- ch=zhujiemian();
- if(ch==1)//人机对战
- {
- jiluqipan();//记录棋盘
- renjijiemain();
- }
- if(ch==2)
- {
- renren();//人人对战
- }
- }
- int main()
- {
- while(1)
- {
- clear_screen();
- clock_t start, finish;
- start = clock();
- game();
- finish = clock();
- double duration = (double)(finish - start) / CLOCKS_PER_SEC;
- int i;
- char str[99];
- sprintf(str,"%s%.2lf%s","总共用时",duration,"秒!是否再来一局?");
- i=MessageBox(NULL,str,"系统提示",MB_YESNO);
- COORD pos;
- pos=get_mouse();
- if (i!=6)
- {
- break;
- }
-
- }
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。