1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > [外挂7] 井字棋外挂 博弈算法

[外挂7] 井字棋外挂 博弈算法

时间:2023-06-29 07:31:25

相关推荐

[外挂7] 井字棋外挂 博弈算法

>_<:本次是综合以上的学习,然后加入博弈算法,来实现井字棋的外挂[井字棋代码可以在[软件项目]里找到!]

>_<:首先还是要加一个按钮:即[自动对战]button5

>_<:这里包括博弈算法的初始函数init(),根据游戏状态表更新博弈计算相关表的函数reup(),还有博弈主体部分getPos()来获得下棋位置,然后在button-5的监听里模拟鼠标点击。

>_<:这里简单说一下该算法里的博弈思想:

win[2][8]分别保存计算机和外挂8种胜利情况的棋子数,如果值为5则表示此种情况不能胜利ptab[9][8]表示电脑第i号棋子在第j号胜利情况下是否有效ctab[9][8]表示外挂第i号棋子在第j号胜利情况下是否有效init()函数中主要将各组合状态的棋子数归零,将横竖对角线8种获胜情况置有效reup()函数中主要根据当前棋盘状态,更新每种组合状态的棋子数及电脑和外挂对应棋子在对应胜利情况的有效性更新getPos()函数中主要分别计算每个可以下棋的点对电脑和外挂的获胜权值来选择下棋的位置,注意这里相同情况下外挂的权值稍高

1 int chessdata[3][3];//a[y][x]棋盘状态0-1-2 2 int win[2][8];//PC和外挂在8种情况下的棋子数 3 bool ptab[9][8]; //电脑的获胜的状态表 4 bool ctab[9][8]; //外挂的获胜的状态表 5 6 void init() 7 {8int count=0,i,k; 9//设定外挂与计算机在各个获胜组合中的棋子数 10for(i=0;i<8;i++) 11{ 12 win[0][i]=0; 13 win[1][i]=0; 14} 15 16 17//设定水平方向的获胜组合 18for(i=0;i<=6;i+=3) 19{ 20 for(k=0;k<3;k++)//3个棋子1个获胜组合 21 { 22 ptab[i+k][count]=true; 23 ctab[i+k][count]=true; 24 } 25 count++; 26} 27//设定垂直方向的获胜组合 28for(k=0;k<3;k++) 29{ 30 for(i=0;i<=6;i+=3)//3个棋子1个获胜组合 31 { 32 ptab[i+k][count]=true; 33 ctab[i+k][count]=true; 34 } 35 count++; 36} 37//设定对角线方向上的获胜组合 38for(i=2;i<=6;i+=2){ 39 ptab[i][count]=true; 40 ctab[i][count]=true; 41}count++; 42for(i=0;i<=8;i+=4){ 43 ptab[i][count]=true; 44 ctab[i][count]=true; 45} 46 } 47 void reup()//根据棋盘状态更新胜利表、外挂、电脑表 48 { 49for(int i=0;i<3;i++){ 50 for(int j=0;j<3;j++){ 51 if(chessdata[i][j]==2){ 52 //改变胜利表和各外挂、PC各胜利组合的棋子数 53 for(int k=0;k<8;k++){ 54 if(ptab[i*3+j][k]){ 55win[0][k]++; 56ctab[i*3+j][k]=false; 57win[1][k]=5; 58 } 59 } 60 }else if(chessdata[i][j]==1){ 61 //改变胜利表和各外挂、PC各胜利组合的棋子数 62 for(int k=0;k<8;k++){ 63 if(ptab[i*3+j][k]){ 64win[1][k]++; 65ptab[i*3+j][k]=false; 66win[0][k]=5; 67 } 68 } 69 } 70 } 71} 72 } 73 int getPos()//获取该下棋位置 74 { 75int grades[2][9]; 76int m,i,max=0; 77int u; 78 79for(m=0;m<9;m++){ 80 grades[0][m]=0; 81 grades[1][m]=0; 82 83 if( chessdata[m/3][m%3]==0){ 84 for(i=0;i<8;i++){ 85 //计算PC在空棋格上的获胜分数 86 if(ptab[m][i] && win[0][i]!=5){ 87switch(win[0][i]){ 88case 0: 89 grades[0][m]+=1; 90 break; 91case 1: 92 grades[0][m]+=2000; 93 break; 94case 2: 95 grades[0][m]+=10000; 96 break; 97} 98 } 99 100 //计算外挂在空格上的获胜分数101 if(ctab[m][i] && win[1][i]!=5){102 switch(win[1][i]){103case 0:104 grades[1][m]+=1;105 break;106case 1:107 grades[1][m]+=2001;108 break;109case 2:110 grades[1][m]+=10001;111 break;112 }113 }114 }115 116 if(max==0)u=m;117 118 if(grades[0][m]>max){119 max=grades[0][m];120 u=m; 121 }122 else if(grades[0][m]==max){123 if(grades[1][m]>grades[1][u])u=m;124 }125 126 if(grades[1][m]>max){127 max=grades[1][m];128 u=m; 129 }130 else if(grades[1][m]==max){131 if(grades[0][m]>grades[0][u])u=m;132 }133 }134}135return u;136 }137 138 void CFewDlg::OnButton5() 139 {140HWND gameh=::FindWindow(NULL,"井字棋");//获取窗口句柄141//获取窗口进程ID142DWORD processid;143::GetWindowThreadProcessId(gameh,&processid);144HANDLE processH=::OpenProcess(PROCESS_ALL_ACCESS,false,processid);//打开指定进程145 146//读指定进程 内存数据147DWORD byread;148LPCVOID pbase=(LPCVOID)0x00F5507C; //棋盘数据基址149LPVOID nbuffer=(LPVOID)&chessdata; //存放棋盘数据150::ReadProcessMemory(processH,pbase,nbuffer,3*3*4,&byread);//进程句柄|基址|存放数据缓冲区|要读取数据的字节数|实际读取的字节数151 152//算法部分:自动走下一步153init();154reup();155int pos=getPos();156 157//鼠标点击158int x=50+pos%3*100,y=50+pos/3*100; //定义座标点159int lparam; //定义座标点变量160lparam=(y<<16)+x; //表示指定格,Y<<16是左移16位,发消息用的Y座标点161::SendMessage(gameh,WM_LBUTTONDOWN,0,lparam);//鼠标按下消息162::SendMessage(gameh,WM_LBUTTONUP,0,lparam); //鼠标抬起消息163 }

本文转自beautifulzzzz博客园博客,原文链接:/zjutlitao/p/3626226.html,如需转载请自行联系原作者

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。