*一、项目需求*
五子棋是一种简单的黑白棋,历史悠久,起源于中国,后传入日本,在日本被称为“连珠”,是一种老少皆宜的益智游戏。
人工智能五子棋系统的目标用户是一切想致力于研究人机对弈算法理论的相关研究者和一切想通过此系统进行五子棋人机对弈游戏的人群。目标用户特点:范围广泛,知识储备门槛低,年龄跨度大,具备操作简单的人机交互界面即可。
我们计划实现人人对弈,人机对战以及机机对弈等三种模式以及一些基本游戏功能。
*二、设备要求*
编译语言:C语言
操作系统:windows 操作系统
开发工具:Microsoft Visual Studio 2019
本次实验是运用Microsoft Visual Studio 软件来进行一次智能五子棋游戏的设计, Microsoft Visual StudioVS是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具。Visual Studio是最流行的Windows平台应用程序的集成开发环境。最新版本为 Visual Studio 2019 版本。
人工智能五子棋属于人工智能中人机博弈的一种,人工智能应用广泛,人工智能是促进未来人类科技和生活重大改变的一门学科。
*三、项目设计*
本项目主要设计如下:
游戏用户接口:主界面以及基本框架:一共有四个页面,一个主菜单,两个副菜单以及一个棋盘界面。若是选择人人对弈,则调用棋盘,直接进行对弈,若是机器与机器对弈,则根据不同的难度调用不同难度的机器算发进行博弈。若是选择了机器与人的博弈,则会跳转去难度选择的页面,选择了困难之后,会跳转到选择先后手的页面,最后根据人选择的数据调用相应的函数与人进行博弈。
游戏操作规则:左键白子右键黑子。
设计能悔棋操作:即玩家在下棋子后能回到上一步。
提示鼠标的合法点击范围:若点击的位置不是棋盘或者功能键,则会有弹窗提示玩家,玩家需要点击关闭弹窗才能继续游戏。
限制每个棋子落下的规范:不能重复落子,仅能黑白子交替下子,若玩家点错,可触发弹窗提示玩家,玩家必须先关闭弹窗才能继续游戏。
游戏裁判算法:判断各个方向是否有五颗连起来的棋子,只要有一方先走成在在横、竖、斜方向上的五颗同色棋子就能赢得游戏,赢得游戏后,会有弹窗提示哪一方的棋子胜利并重新刷新一次棋盘,使玩家再次进行游戏。
实现算法对战模式:人机对战、人人对战、机机对战。
机器算法:利用估值函数,每下一颗棋子则在其周围加10,活二在其前后各加100,死二则在其为被堵住的地方的另一边加50,活三在其前后加1000,死三则在其为被堵住的地方的另一边加500,活四则在其前后分别加10000,死四则在其为被堵住的地方的另一边加上2000,找出棋盘上价值最大的点,并判断是进攻还是防守,从而使自身的每一步棋子的价值最大化。
*3.1、人机交互界面*
通过鼠标点击调用不同的函数,进而刷新屏幕使之进入不同的界面,让玩家选择自己想要的游戏模式,游戏难度以及先后手,让玩家有更好的游戏体验,为此,我特地添加了悔棋,重新开始,退出游戏等功能,让玩家在玩的过程中拥有更多机会。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yXXzU5bQ-1636549459002)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
图3.1.1 人机交互界面关系流程图
*3.2、系统结构设计*
*3.3、数据结构设计*
人工智能五子棋系统的每一个下棋格点用二维数组a[17][17]表示,数组内容分别为0,1,2代表未落子,黑子,白子。
初始化黑棋与白棋的估值函数表如下。
int Value_black / Value_white[ 17] [ 17] ={
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0},
{0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0},
{0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, 0},
{0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 4, 3, 2, 1, 0},
{0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 5, 4, 3, 2, 1, 0},
{0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0},
{0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0},
{0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 5, 4, 3, 2, 1, 0},
{0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 4, 3, 2, 1, 0},
{0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, 0},
{0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0},
{0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
以下是我定义的各种函数。
void menu(); //主菜单背景void Difficulty(); //选择人机难度void choseFrist(); //选择先后手void ChessBoard(); //棋盘void DropChess(MOUSEMSG m); //下棋bool Rules(int i, int j, int x); // 规则(落棋的合法性以及判断输赢)void Newa(); //重新开始后进行初始化void Regret(int x, int y); //悔棋void DropChess_People(); //人下棋void Low(); //初级难度void Medium(); //中级难度void Low_J();void Medium_J();void Judge_ML(int i,int j,int x); //判断棋盘模型void Renew_Value_shu(int i,int j,int x,int n); //更新价值表:竖直方向void Renew_Value_leftup(int i, int j, int x, int n); //更新价值表:左上往右下void Renew_Value_heng(int i, int j, int x, int n); //更新价值表:水平方向void Renew_Value_rightup(int i, int j, int x, int n); //更新价值表:右上到左下HWND chunchun = GetHWnd(); //窗口弹出;int flag = 0; //限制落棋的顺序以及赢棋之后无法再次落棋int a[20][20] = { 0 }; //存储数组的二维数组int level; //难度等级int order = 0; //顺序——先后手int close = 0; //使退出人机的程序。int e,f,c,d; //记录悔棋下标。int level1 = 0; //机器的int value_black[17][17] = { 0 }; //黑棋的价值表int value_white[17][17] = { 0 }; //白棋的价值表