在“类与对象”实训课上,有一道附加题让我们用 OOP 做一个的井字棋模拟程序,要求中电脑是随机落子的,这样显然不是很优雅。回忆起以前学的对抗搜索(这里叫 MaxMin 算法),我继续给游戏中的电脑一方写了个 AI。由于井字棋游戏运算规模很小,大部分的剪枝手段变得比较鸡肋,但以此为引搜索了一些资料,了解一些有趣的计算机博弈论知识,有机会再继续探究一下。

极大极小(Minimax)算法

Minimax算法 又名极小化极大算法,是一种找出失败的最大可能性中的最小值的算法(即最小化对手的最大得益)。通常以递归形式来实现。

Minimax算法常用于棋类等由两方较量的游戏和程序。该算法是一个零总和算法,即一方要在可选的选项中选择将其优势最大化的选择,另一方则选择令对手优势最小化的一个,其输赢的总和为0(有点像能量守恒,就像本身两个玩家都有1点,最后输家要将他的1点给赢家,但整体上还是总共有2点)。很多棋类游戏可以采取此算法,例如tic-tac-toe。

Alpha-beta 剪枝

Alpha-beta剪枝是一种搜索算法,用以减少极小化极大算法(Minimax算法)搜索树的节点数。这是一种对抗性搜索算法,主要应用于机器游玩的二人游戏(如井字棋、象棋、围棋)。当算法评估出某策略的后续走法比之前策略的还差时,就会停止计算该策略的后续发展。该算法和极小化极大算法所得结论相同,但剪去了不影响最终决定的分枝。

待改进的点:

判定胜利的方法比较蠢,可以用循环代替

没有对搜索树的预计深度进行评估,使 AI 做出最 “快” 的策略

代码可读性不强,不符合工程代码规范

#include

using namespace std;

class MyChess {

private:

char A[3][3];

int step;

public:

MyChess();

void DispChessboard();

void PlayerMove();

void ComputerMove();

bool isFull();

int MaxSearch();

int MinSearch();

int checkWin();

};

MyChess::MyChess() {

memset(A,0,sizeof(A));

step=0;

}

void MyChess::DispChessboard() {

cout<

for (int i=0;i<3;i++) {

cout<

cout<

}

}

void MyChess::PlayerMove() {

int x,y;

cout<

cin>>x>>y;

while (A[x][y] || x>2 || x<0 || y>2 || y<0) {

cout<

cin>>x>>y;

}

A[x][y]='O';

}

void MyChess::ComputerMove() { // 模拟 AI 的选择过程

int x,y,score=1;

for (int i=0;i<3;i++) {

for (int j=0;j<3;j++) {

if (!A[i][j]) {

A[i][j]='X';

int temp=MaxSearch();

if (score>temp) x=i,y=j,score=temp;

A[i][j]=0;

}

}

}

A[x][y]='X';

}

int MyChess::MaxSearch() { // 人类执子时,希望找到权值最大的子节点

int ret=-1,sta=checkWin();

if (sta) return sta;

if (isFull()) return 0;

for (int i=0;i<3;i++) for (int j=0;j<3;j++)

if (!A[i][j]) A[i][j]='O',ret=max(ret,MinSearch()),A[i][j]=0;

return ret;

}

int MyChess::MinSearch() { // 电脑执子时,希望找找到权值最小的子节点

int ret=1,sta=checkWin();

if (sta) return sta;

if (isFull()) return 0;

for (int i=0;i<3;i++) for (int j=0;j<3;j++)

if (!A[i][j]) A[i][j]='X',ret=min(ret,MaxSearch()),A[i][j]=0;

return ret;

}

bool MyChess::isFull() { // 平局判定

for (int i=0;i<3;i++)

for (int j=0;j<3;j++)

if (!A[i][j]) return false;

return true;

}

int MyChess::checkWin() {

for (int i=0;i<3;i++) if (A[i][0]=='O' && A[i][1]=='O' && A[i][2]=='O') return 1;

for (int i=0;i<3;i++) if (A[0][i]=='O' && A[1][i]=='O' && A[2][i]=='O') return 1;

for (int i=0;i<3;i++) if (A[i][0]=='X' && A[i][1]=='X' && A[i][2]=='X') return -1;

for (int i=0;i<3;i++) if (A[0][i]=='X' && A[1][i]=='X' && A[2][i]=='X') return -1;

if (A[0][0]=='O' && A[1][1]=='O' && A[2][2]=='O') return 1;

if (A[2][0]=='O' && A[1][1]=='O' && A[0][2]=='O') return 1;

if (A[0][0]=='X' && A[1][1]=='X' && A[2][2]=='X') return -1;

if (A[2][0]=='X' && A[1][1]=='X' && A[0][2]=='X') return -1;

return 0;

}

int main() {

MyChess Ch; int now=1;

Ch.DispChessboard();

while (!Ch.isFull()) {

if (now&1) {

Ch.PlayerMove();

if (Ch.checkWin()==1) { Ch.DispChessboard(),cout<

else if (Ch.isFull()) { Ch.DispChessboard(),cout<

}

else {

Ch.ComputerMove();

Ch.DispChessboard();

if (Ch.checkWin()==-1) { cout<

}

now^=1;

}

return 0;

}

java井字棋ai_简单的井字棋 AI DEMO | Minimax 算法相关推荐

  1. 用Unity3D实现简单的井字棋小游戏

    用Unity3D实现简单的井字棋小游戏 项目地址 井字棋小游戏 完成效果图 实现思路 首先定义游戏的数据部分: /* 井字棋中每一个棋格中的逻辑控制常量,代表这个棋格的状态 */ private co ...

  2. python井字棋ai_[Python100行系列]-井字棋游戏

    博客:Hzy的博客 | Hzy Blog​hzeyuan.cn一些学习python的小项目,小游戏.python小项目​github.com 话不多说,今天尝试用turtle库来写一个井字棋游戏.1. ...

  3. python井字棋ai_实现AI下井字棋的alpha-beta剪枝算法(python实现)

    代码参考自中国大学mooc上人工智能与信息社会陈斌老师的算法,我在原来的基础上增加了玩家输入的异常捕获 AlphaBeta剪枝算法是对Minimax方法的优化,能够极大提高搜索树的效率,如果对这个算法 ...

  4. 圈叉棋、套娃圈叉棋、嵌套圈叉棋、九个井字棋

    目录 一,圈叉棋(Tic-Tac-Toe) 二,套娃圈叉棋 1,规则 2,解空间分析 1,节点 2,解空间结构 3,复杂度分析 1,总节点数目 2,思路一--关键节点 3,思路二--对称性 4,数据结 ...

  5. MiniMax算法实现井字棋

    使用MiniMax算法实现井字棋,下面是问题的记录 源代码地址:gitee仓库地址 python中列表的浅复制和深复制 在函数传递中,如果实参传递可变数据类型(list.set.dict)实际上传递的 ...

  6. oracle 列 显示井号,“在excel打完字后为什么显示一堆井号#######?该怎么办?“excle表显示井号...

    Excel单元格中的数据显示为井号(#)是怎么回事 excel表格,单元格格式为日期的,如果单元格列宽过小,显示的内容就会变为"#"解决方法:增大列宽 在excel打完字后为什么显 ...

  7. 用C语言实现简单的一字棋游戏

    问题分析设计目录 棋盘显示和标记以及棋盘的设计 搜索树叶子节点设计 搜索树设计 节点静态估值计算 完整代码 总结 棋盘显示和标记以及棋盘的设计 用int一维数组表示一字棋的棋盘位置,0~8,数组位置i ...

  8. java基础知识点_「Java面试题/知识点精华集」20000+字的Java基础知识篇(2020最新版) !

    " 本文已经收录进我的 79K Star 的 Java 开源项目 JavaGuide:https://github.com/Snailclimb/JavaGuide (「Java学习+面试指 ...

  9. 斗兽棋 java_AnimalGame 一个简单的斗兽棋代码实现,基本功能 现了,支持人人对战 JavaScript 238万源代码下载- www.pudn.com...

    文件名称: AnimalGame下载 收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 2257 KB 上传时间: 2015-01-26 下载次数: 0 提 供 者: 盛 ...

最新文章

  1. 所有mysql变量都以 开头对不对_PHP复习题(选择题)
  2. ant读书之使用ant进行java开发--第二章
  3. linux虚拟网络设备之veth(二)
  4. 解决 /usr/share/git-cola/bin/ssh-askpass: 3: exec: wish: not found
  5. html内联框上下重叠,如何解决IOS端两个内联块元素无法上下对齐的问题?
  6. 上海师范大学计算机作业网址,新SQL——SERVER实验练习答案.doc
  7. 46、练习:输出指定目录下的所有文件名称
  8. 定了!这 35 所高校将设人工智能本科专业!
  9. yii2 错误处理
  10. 网上流传的继承RandomAccessFile缓冲办法并不可靠
  11. PNP三极管限流电路分析
  12. Linux怎么把硬盘ex2改为ex4,linux磁盘管理和文件系统创建
  13. 位运算bitwise_and和bitwise_not函数
  14. Snipaste截图贴图软件安装包下载免费的超级强大截图软件
  15. html轮播图jquery,原生js和jquery实现图片轮播特效
  16. python数据分析用到的库_用python进行数据分析的五个最常用库
  17. cv2将图片拼接为视频
  18. 力扣(66.67)补8.27
  19. python关于 unittest的常见用法:前置条件与后置条件
  20. 人月神话(五)未雨绸缪、干将莫邪、整体部分

热门文章

  1. 关于相似度计算方法的python实现
  2. VLC组播推流播放实操
  3. ubuntu启动php-fpm_重启php-fpm
  4. 泛型类与泛型方法的说明
  5. ctfshow_web1-17_信息搜集
  6. 华为 Eth-trunk 配置IP
  7. VB实现USB摄像头视频图像的监控、截图、录像
  8. XAML形状转CSS
  9. 「 每日一练,快乐水题 」1331. 数组序号转换
  10. 高等数学学习笔记——第十四讲——函数极限的概念(1. 函数在无穷远处极限定义)