博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[外挂7] 井字棋外挂 博弈算法
阅读量:5880 次
发布时间:2019-06-19

本文共 5211 字,大约阅读时间需要 17 分钟。

 

 

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

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

 

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

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

  1. win[2][8]分别保存计算机和外挂8种胜利情况的棋子数,如果值为5则表示此种情况不能胜利
  2. ptab[9][8]表示电脑第i号棋子在第j号胜利情况下是否有效
  3. 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 {      8     int count=0,i,k;  9     //设定外挂与计算机在各个获胜组合中的棋子数 10     for(i=0;i<8;i++) 11     { 12         win[0][i]=0; 13         win[1][i]=0; 14     } 15  16  17     //设定水平方向的获胜组合 18     for(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     //设定垂直方向的获胜组合 28     for(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     //设定对角线方向上的获胜组合 38     for(i=2;i<=6;i+=2){ 39         ptab[i][count]=true; 40         ctab[i][count]=true; 41     }count++; 42     for(i=0;i<=8;i+=4){ 43         ptab[i][count]=true; 44         ctab[i][count]=true; 45     } 46 } 47 void reup()//根据棋盘状态更新胜利表、外挂、电脑表 48 { 49     for(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]){ 55                         win[0][k]++; 56                         ctab[i*3+j][k]=false; 57                         win[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]){ 64                         win[1][k]++; 65                         ptab[i*3+j][k]=false; 66                         win[0][k]=5; 67                     } 68                 } 69             }             70         } 71     } 72 } 73 int getPos()//获取该下棋位置 74 { 75     int grades[2][9]; 76     int m,i,max=0; 77     int u; 78  79     for(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){ 87                         switch(win[0][i]){ 88                         case 0: 89                             grades[0][m]+=1; 90                             break; 91                         case 1: 92                             grades[0][m]+=2000; 93                             break; 94                         case 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]){103                         case 0:104                             grades[1][m]+=1;105                             break;106                         case 1:107                             grades[1][m]+=2001;108                             break;109                         case 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     }135     return u;136 }137 138 void CFewDlg::OnButton5() 139 {140     HWND gameh=::FindWindow(NULL,"井字棋");//获取窗口句柄141     //获取窗口进程ID142     DWORD processid;143     ::GetWindowThreadProcessId(gameh,&processid);144     HANDLE processH=::OpenProcess(PROCESS_ALL_ACCESS,false,processid);//打开指定进程145 146     //读指定进程 内存数据147     DWORD byread;148     LPCVOID pbase=(LPCVOID)0x00F5507C; //棋盘数据基址149     LPVOID  nbuffer=(LPVOID)&chessdata; //存放棋盘数据150     ::ReadProcessMemory(processH,pbase,nbuffer,3*3*4,&byread);//进程句柄|基址|存放数据缓冲区|要读取数据的字节数|实际读取的字节数151 152     //算法部分:自动走下一步153     init();154     reup();155     int pos=getPos();156 157     //鼠标点击158     int   x=50+pos%3*100,y=50+pos/3*100;   //定义座标点159     int lparam;                            //定义座标点变量160     lparam=(y<<16)+x;                      //表示指定格,Y<<16是左移16位,发消息用的Y座标点161     ::SendMessage(gameh,WM_LBUTTONDOWN,0,lparam);//鼠标按下消息162     ::SendMessage(gameh,WM_LBUTTONUP,0,lparam);  //鼠标抬起消息163 }

 

转载地址:http://lkcix.baihongyu.com/

你可能感兴趣的文章
Windows phone8 基础篇(三) 常用控件开发
查看>>
Oracle学习笔记之五,Oracle 11g的PL/SQL入门
查看>>
大叔手记(3):Windows Silverlight/Phone7/Mango开发学习系列教程
查看>>
Btrace使用教程
查看>>
IE6 IE7 不支持 JSON
查看>>
多功能表单填报系统V1.2.1-适用于在线报名系统、调查、数据收集等
查看>>
HotSpot VM GC 的种类
查看>>
Android ViewPager滑动背景渐变
查看>>
HDU 2072 单词数
查看>>
考拉消息中心消息盒子处理重构(策略模式)
查看>>
so easy 前端实现多语言
查看>>
【追光者系列】HikariCP源码分析之ConcurrentBag&J.U.C SynchronousQueue、CopyOnWriteArrayList...
查看>>
kafka之旅总览
查看>>
【2018年最新】iOS面试题之第三方框架
查看>>
拼音工具类PinyinUtils
查看>>
Compose函数作用
查看>>
获取url中参数
查看>>
[译] 别再对 Angular 表单的 ControlValueAccessor 感到迷惑
查看>>
在navicat中如何新建连接数据库
查看>>
canvas系列教程05-柱状图项目3
查看>>