原文链接:https://www.dreamwings.cn/reversi/3013.html

到了考试周了佯,可是偏偏这个时候迎来了很多很多的课程设计,幸好教授把C语言的课程设计提前发出了,不然都在最后几周,加上数据结构的课程设计就没有时间做这个啦~

刚开始打算做成UWP应用的,可是网上的教程都是C#,并且用C++做的话某些功能和C#不一样,所以就这样拖了好多周,省赛前一点儿也没有开始做,等到省赛结束之后,别人都差不多完成啦!而我才开始准备查找资料……

然而一周过去了,进度还是0%。噫,1%吧!

眼看就要开始验收了,算了,还是用最简单的 EasyX 做吧!以后的 C# 课程设计再考虑 UWP。

周一开始敲代码,整整一周的课余时间,都在努力做这个,现在想起来,那个时候真的好累唉,居然没有感觉到~

最初做这个游戏是因为想起来 秦时明月 中的 墨攻棋阵 ,也就是黑白棋,努力还原动漫中的场景,周末的时候终于完成了。

先附图:

怎么说千千也都是新手呢!感觉做的还算满意吧!

人机对战中有三种模式哦!

简单、中等、困难

那么,接下来,我们一起来看看黑白棋中的AI是如何实现的。

对于我们来说,下棋的时候总是想着如何才能对自己最有利,当前最优?还是全局最优?

如果我们往后几步考虑的话,那便是全局最优啦!那当我们只看眼下哪一个位置的落子对自己最有利,这样便是当前最优,也是局部最优。

在黑白棋中,我们同样可以采用这样的思想。

首先来看看简单AI,因为简单呗,所以它返回的仅仅只是当前的最优解,再怎么说也不能让它随机返回坐标对吧!

那局部最优解又是以什么为评测标准的呢?

嗯,我们采用的是能够转换对方棋子最多的位置,这个可不是行动力哦!

POINT2 Easy()                        //人机对战简单AI
{POINT2 MAX;                    //定义以及初始化最优解MAX.INIT(0, 0);int maxx = 0;for (int i = 0; i < SIZE; ++i)for (int j = 0; j < SIZE; ++j){if (expect[i][j] >= maxx) //寻找可以转化棋子最多的点作为最优解{maxx = expect[i][j];MAX.INIT(i, j);}}if (ESCEXIT)gameStart();Sleep(800);                   //间歇return MAX;                 //返回最优解
}

呐,expect中便是每个点可以转换对方棋子的个数,这个AI 简单吧!

其他难度 AI:既然是简单以上的难度,就不能再像那样简单啦!不然一个中等AI被简单AI击败多没意思,O(∩_∩)O哈哈~

首先,我们应该知道一个估值表的问题,在黑白棋中,不同位置都有不同位置的估值,虽然这样的估值表的用处并不是很大,但却在某些细节中表现出至关重要的作用。

黑白棋的棋盘默认是8*8的,总共64格。

从游戏规则我们可以看出来,角上的子很重要,因为这里不会被对方转换,角边上的点很危险,它给了对方直接进角的机会。

边上中间的四个点比较重要,只能从一个方向被翻转……等等。

根据这样的经验,我们大致可以得到以下的估值表

A

B

C

D

E

F

G

H

1

90

-60

10

10

10

10

-60

90

2

-60

-80

5

5

5

5

-80

-60

3

10

5

1

1

1

1

5

10

4

10

5

1

1

1

1

5

10

5

10

5

1

1

1

1

5

10

6

10

5

1

1

1

1

5

10

7

-60

-80

5

5

5

5

-80

-60

8

90

-60

10

10

10

10

-60

90

有了这张表,AI 进行估值的时候就很简单了,不过仅凭这一点可不行哦

黑白棋的AI中,我们要考虑的除了估值表,还有稳定子。

稳定子,即不能被转换的棋子,稳定子的数量在游戏中是变化的,比如,一方占据整整一条边,那么这一条边上的所有棋子都是稳定子。

行动力,某方当前可走位置的个数,因为在黑白棋的游戏规则中,每一步的走棋都要形成转换,否则不能走棋,既然这样的话,我们在AI中便要尽可能让自己的行动力最大,而对方行动力最小,也就是尽可能让双方行动力差最大,这样的话,很容易AI便可以把玩家逼上绝路,玩笑而已……

除了这两个还有余裕手潜在行动力,虽然并不懂~

对电脑AI设定中,我们的原则是能走角就走角,不到万不得已的情况下不要走邻角点。

对其他情况下采用极大极小博弈树搜索:这里假设AI的对手都是最聪明的,会选择最优解,即会选择对AI最不利的选择。

搜出来的结果集是AI方的结果,那么要选择最终得分最高的那个位置搜出来的结果集是玩家方的结果,那么要选择最终得分最低的那个位置。

如下图

假设圆形代表的是AI节点,方形代表玩家节点。对于A2和A3这两种选择,AI显然是选择A2得10分。对于A4和A4这两种选择,AI显然是选择A4得20分。但是对于B1,B2来说,玩家如果下B2,使得AI可以得20分,下B1,使得AI只能得10分,那么玩家显然是下B1。所以最终A1这一步,AI只能得10分。

这就是极大极小算法。

然后就是α-β剪枝:

现在A2,A3已经选出最大值10,B1的得分是10分。而对于B1,B2来说是要选最小值,既然B1的得分是10分,则B1,B2之间的最终结果是<=10的。而A4的得分是20分,对于A4,A5来说是选择最大值得,即A4,A5之间的最终结果是>=20的,说明B2的最终结果是>=20的。那么这种情况下肯定是选B1了,对于还没有搜索的A5节点来说,已经影响不到最终的选择结果了,所以就可以不用考虑了。

然后得分的计算:

这里每一步的得分,都是相对于AI来说的得分。

AI自己落子某一个位置,得一个正分,之后对手落子某一个位置,所得的分数对于AI来说就是一个负分(即玩家取得的优势,对于AI来说就是劣势)。

对于已经搜到最大深度的节点来说,它的得分就是这个位置的本身得分(因为后面已经不搜了)。

而对于中途节点来说,它的得分应该是这个位置的本身得分,加上下一步对方的选择结果的得分。

这里不能只以最后一步的结果逆推的。

举个例子:

如上图的左右两种情况。假设圆形代表的是AI节点,方形代表玩家节点。其中分值表示的是节点自身落子该位置所获得的在估值表中的得分,玩家节点取负分。

如果只是用最深层的节点的得分,来计算最上层的节点的得分,那么按照上面极大极小算法,AI最后的得分:左边是10分,右边是5分。

那么AI选择左边的10分这种情况。但是却造成了中间过程中,玩家可以得到50分的这样一个相对来说是比较好的分值。

而AI应该不让玩家取得这样一个比较好的优势。

所以要综合前后对方的落子位置以及得分来考虑最终得分:

AI最后的得分:左边是-30分,右边是-15分。最终选择为右边,而不是左边。

极大极小搜索就是这样了,难度的抉择取决于搜索的深度,不过要保证的是不要超时哦!

接下来附上我的 墨攻棋阵 中的AI算法,估计只有一点点的沾边吧!还有很多需要优化的地方惹

int difai(int x,int y,int mapnow[SIZE][SIZE],int expectnow[SIZE][SIZE],int depin,int depinmax)   //极大极小搜索
{if (depin >= depinmax)return 0;            //递归出口int maxx = -10005;               //最大权值POINT2 NOW;int expectnow2[SIZE][SIZE] , mapnow2[SIZE][SIZE],mapnext[SIZE][SIZE],expectlast[SIZE][SIZE];   //定义临时数组copymap(mapnow2, mapnow);           //复制当前棋盘mapnow2[x][y] = NOWCOLOR ? 1 : -1;     //模拟在当前棋盘上下棋int ME = MAPPOINTCOUNT[x][y] + expectnow[x][y];   //当前棋子权NOW.INIT(x,y);Change(NOW, mapnow2, false);           //改变棋盘AI结束int MAXEXPECT = 0, LINEEXPECT = 0, COUNT = 0;for (int i = 0; i < SIZE; ++i)for (int j = 0; j < SIZE; ++j){expectnow2[i][j] = Judge(i, j, !NOWCOLOR, mapnow2);//预判对方是否可以走棋if (expectnow2[i][j]){++MAXEXPECT;if ((i == 0 && j == 0) || (i == 0 && j == SIZE - 1) || (i == SIZE - 1 && j == SIZE - 1) || (i == SIZE - 1 && j == 0))return -1800;   //如果对方有占角的可能if ((i < 2 && j < 2) || (i < 2 && SIZE - j - 1 < 2) || (SIZE - 1 - i < 2 && j < 2) || (SIZE - 1 - i < 2 && SIZE - 1 - j < 2))++LINEEXPECT;}}if (LINEEXPECT * 10 > MAXEXPECT * 7)return 1400;//如果对方走到坏点状态较多 剪枝for (int i = 0; i < SIZE; i++)for (int j = 0; j < SIZE; j++)if (expectnow2[i][j])     //如果对方可以走棋{int YOU = MAPPOINTCOUNT[i][j] + expectnow2[i][j];//当前权值copymap(mapnext, mapnow2);  //拷贝地图mapnext[i][j] = (!NOWCOLOR) ? 1 : -1;        //模拟对方走棋NOW.INIT(i, j);Change(NOW, mapnext, false);         //改变棋盘for (int k = 0; k < SIZE; k++)for (int l = 0; l < SIZE; l++)expectlast[k][l] = Judge(k, l, NOWCOLOR, mapnext);   //寻找AI可行点for (int k = 0; k < SIZE; k++)for (int l = 0; l < SIZE;l++)if (expectlast[k][l]){int nowm = ME - YOU + difai(k, l, mapnext, expectlast, depin + 1, depinmax);maxx = maxx < nowm ? nowm : maxx;}}return maxx;
}

有关黑白棋AI极大极小搜索的算法也就这些了,希望本文能对你有一点帮助。

另外,墨攻棋阵的项目源码在我的 GitHub 里面,欢迎大家Fork ,发现Bug 后不要忘记给我留言哦!

墨攻棋阵源码: http://download.csdn.net/detail/qq_28954601/9668047

课程设计 --- 黑白棋中的 AI相关推荐

  1. Python之GUI:基于Python的GUI界面设计的一套AI课程学习(机器学习、深度学习、大数据、云计算等)推荐系统(包括语音生成、识别等前沿黑科技)

    Python之GUI:基于Python的GUI界面设计的一套AI课程学习(机器学习.深度学习.大数据.云计算等)推荐系统(包括语音生成.识别等前沿黑科技) 导读 基于Python的GUI界面设计的一套 ...

  2. c++课程设计——黑白棋(QT实现+minmax算法实现ai版)

    关联:NEU 东北大学 本篇将大致描述基础思路,后续会添加相应的演示视频和整个工程文件 首先我将大致描述一下我的创作进度 1.先完成棋盘的绘制(QT仅绘制棋盘) mainwindow.h #ifnde ...

  3. java中怎么编写围棋对弈_java课程设计围棋对弈(含代码).doc

    java课程设计围棋对弈(含代码).doc C:\ProgramFiles\Java\jdk1.8.0_45Java程序课程设计任务书1.主要任务与目标创建一个围棋对弈平台.基于Panel类定义一个面 ...

  4. 夜深深~帮别人做课程设计。。。

    /*** Answer.cpp 单项选择题标准化考试系统设计 ***/ #include <stdio.h> #include <stdlib.h> #include < ...

  5. 数据库课程设计结论_结论

    数据库课程设计结论 Living in the Pacific Northwest, the intertwined issues of salmon survival and river flow ...

  6. 燕山大学数字通信计算机仿真课程设计,燕山大学数字通信计算机仿真课程设计模板...

    燕山大学数字通信计算机仿真课程设计模板 数字通信计算机课设程序代码 //SigTranmit.cppimplementationoftheSigTranmitclass. // // includes ...

  7. 计算机硬件基础课设总结,计算机硬件基础课程设计报告.doc

    扬州大学广陵学院 课程设计报告 课程名称 <计算机硬件组成原理>课程设计 设计题目 计算机整机实验 组员 徐凯霞 110047129 孙小敏 110047123 李俊 110047113 ...

  8. 2016计算机课程设计,2016年ps课程设计心得体会范文

    课程设计的过程中涉及到很多方面的课程要素,最主要的课程要素包括课程目标.课程内容.学生的学习活动以及课程评价等.下面是小编整理的ps课程设计心得体会,欢迎借鉴! [1]ps课程设计心得体会 设计目的 ...

  9. 数据结构与算法课程设计之五子棋(人机)

    数据结构与算法课程设计之五子棋(人机) 五子棋是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏.通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连线者获胜. 这是 ...

最新文章

  1. 迅为4418/6818开发板实现最小Linux系统自动挂载SD/TF卡/U盘等存储设备
  2. 微软笔试题,机器人消砖块
  3. Linux命令行下关机【Ubuntu】
  4. 6年,终拿腾讯 offer!
  5. linux shell if 参数
  6. C语言实现随机快速排序random quick sort算法(附完整源码)
  7. 开始的一些知识和概念
  8. Java核心类库篇5——异常
  9. c# 低功耗蓝牙_C#建立从笔记本电脑内部蓝牙4.0到蓝牙低功耗(BLE)外设的流
  10. pythonnumpy详解_Python:Numpy详解
  11. python异常和错误(syntax errors 和 exceptions)
  12. java虚拟机:虚拟机栈
  13. Mac电脑 如何在任意目录快速打开终端并定位到当前目录
  14. 运放输入偏置电流方向_运算放大器+仪表放大器:如何为偏置电流提供直流回路?...
  15. 第五---七章 交换机和路由器的基本配置
  16. 使用openpose做的运动检测[附代码]
  17. 通过VBA宏合并Excel工作表
  18. c语言指数函数调用,【西科软件】用C语言求幂函数和指数函数的方法
  19. 葡,西两国发展史(大航海时代)启示
  20. vue 计数器_vuex实现简易计数器

热门文章

  1. java 绑定mac地址_如何JAVA实现使用TrueLicense在证书中绑定PC的MAC地址,防止止拷贝应用...
  2. 激扬巾帼风采,谱写美丽人生
  3. Hyperledger Fabric金融区块链项目总结 之一 概述
  4. 2017070506嵌入式开发系统概述和开发工具的使用
  5. 【C语言】函数:实现一个函数,打印乘法口诀表
  6. Go语言基础之网络编程
  7. 计算机专业的英文简历范文带翻译,计算机软件专业英文简历范文 英文简历范文带翻译...
  8. 我的本科回忆录:从迷茫自卑到保送华科
  9. 使用winfrom制作KTV排行榜点歌
  10. 二十三种设计模式(第十二种)-----代理模式(Proxy)