三子棋
来源:互联网 发布:民宿 知乎 编辑:程序博客网 时间:2024/06/15 05:26
摘要:同样是利用回溯算法计算模拟电脑下三子棋.
基本思路:
[1]电脑和人下棋,主要的一种思路就是去计算下一步每一个点的位置函数.如果下在这个点使得电脑获胜,那么将返回一个值(1),如果棋盘已满,则返回0,如果对手获胜,则返回-1.假如下的这一步棋不是决定的关键棋,那么电脑将要调用一个函数去模拟人的下棋轨迹.人下棋的时候总是要寻找使得下一步所在的位置函数最小,这样代表自己获胜或者平局.同样的如果这一步也不是最终的位置.那么模拟人的函数也要调用模拟电脑的函数去判断电脑会怎么下.这样直到遍历完所有的可能,则电脑总是可以保持不败.
[2]现在要做的是提高效率,因为有些时候,某些试探是不必要的.比如电脑已经找到了一个位置函数,它的值为a,那么当它调用人的函数时,人一定会返回它所能找到的最小的位置函数来确保自己的胜利.设人已经找到的位置函数值是b.很显然,如果a≥ b,那么人继续递归找到的值如果大于b将不会返回(人需要选取最小的位置函数).如果返回的值小于于b,那么返回给电脑的值将不会改变a.因此不需要继续递归.同时对人有着对应的情况.这称为αβ 裁剪.
[3]注意回溯的时候要将棋盘的状态复原.
#include "stdafx.h"#include "math.h"#define N 9#define draw 0#define compwin 1#define comploss -1#define comp 1#define human -1int FullBoard(int Board[]){ if(Board[0] == N) return 1; else return 0;}int Immediatewin(int Board[],int *Bestmove,int comporhuman){ int x,y,deltax = 0,deltay = 0; int tempx,tempy,Num[5] = {0}; for (int i = 1;i<=N;i++) { if (Board[i]==0) { y = i%3 > 0 ?i%3 : 3; x = (i-y)/3 + 1; for(int k = -4;k<=4;k++) { if(k==0) continue; switch(abs(k)) { case 1: deltax = -1; deltay = 0; break; case 2: deltax = -1; deltay = 1; break; case 3: deltax = 0; deltay = 1; break; case 4: deltax = -1; deltay = -1; break; }//end of switch if(k<0) { deltax = -deltax; deltay = -deltay; } tempx = (x+deltax); tempy = (y+deltay); while(tempx<=3&&tempy<=3&&tempx>=1&&tempy>=1) { if (Board[(tempx-1)*3 + tempy] == comporhuman)//相邻棋子是同类 Num[abs(k)]++; tempx += deltax; tempy +=deltay; } } for(int k = 1;k<=4;k++) { if (Num[abs(k)] == 2) { *Bestmove = i; return 1; } Num[k] = 0; } } } return 0;}void Findhumanmove(int Board[],int *Bestmove,int *value,int alpha,int beta);void FindCompmove(int Board[],int *Bestmove,int *value,int alpha,int beta);int _tmain(int argc, _TCHAR* argv[]){ int Bestmove = 0; int value = 0,x; int Board[N+1] = {0}; printf("Comp the Bestmove: %d \nthe humanmove: :",5); Board[5] = 1; for (int i = 1;i<=5;i++) { scanf(" %d",&x); Board[x] = human; FindCompmove(Board,&Bestmove,&value,-1,1); printf("Comp the Bestmove: %d :",Bestmove); Board[Bestmove] = comp; } return 0;}void Findhumanmove(int Board[],int *Bestmove,int *value,int alpha,int beta){ int Dc,Response; if (FullBoard(Board)) *value = draw; else if (Immediatewin(Board,Bestmove,human)) *value = comploss; else { *value = beta; if (*value <= alpha) return;//beta裁剪 for(int i = 1;i<=N;i++) { if (Board[i] == 0) { Board[i] = human;//Place(Board,i,comp); Board[0]++; FindCompmove(Board,&Dc,&Response,alpha,*value); Board[i] = 0; Board[0]--; if(Response < *value) { *value = Response; *Bestmove = i; } } } }}void FindCompmove(int Board[],int *Bestmove,int *value,int alpha,int beta){ int Dc,Response; if (FullBoard(Board)) { *value = draw; } else if (Immediatewin(Board,Bestmove,comp)) *value = compwin; else { *value = alpha; if (*value >= beta) return;//alpha裁剪 for(int i = 1;i<=N;i++) { if (Board[i] == 0) { Board[i] = comp;//Place(Board,i,comp); Board[0]++; Findhumanmove(Board,&Dc,&Response,*value,beta); Board[i] = 0; Board[0]--; if(Response > *value) { *value = Response; *Bestmove = i; } } } }}
0 0
- 三子棋
- 三子棋
- 三子棋
- 三子棋
- 三子棋
- 三子棋
- 三子棋
- 三子棋
- 三子棋
- 三子棋,
- 三子棋
- 三子棋
- 三子棋
- 三子棋
- 三子棋
- 三子棋
- 三子棋
- 三子棋
- SQL示例
- Mac 配置 Apache .php
- dom4j解析
- C++ 之 explicit,mutable,volatile 浅析
- UDP
- 三子棋
- android 默认锁屏界面没有紧急呼救入口如何解决
- pop 一个viewController时候会有键盘闪现出来又消失
- JS获取汉字首字母
- java基础—5.异常处理
- leetcode之Missing Number
- Native Wifi 中 WlanSetProfile 出现1206错误的几种可能及解决方法
- MySQL学习----MySQL 算术运算符----06MySQL 算术运算符
- Codeforces 575H Bots 组合恒等式+逆元法求组合数取模