放纵了三天了,之前写了一半懒得去动的墙棋,反而在这几天间隙断断续续完成了,也是挺可笑的。

简介-关于墙棋

路墙棋(Quoridor),或译墙棋、步步为营,是由Mirko Marchesi(米尔科·迈凯西)设计、Gigamic Games发行的两到四人对战的棋类游戏(桌面游戏),并在1997年被门萨国际评选为门萨推荐的游戏。1998年游戏杂志(Games Magazine)年度游戏大奖。

先将各棋子放置在棋盘各边的中间格。两人玩时,两子需放在相对侧。
轮到回合的玩家,须作以下两动作之一:
动子:移动至邻边四格之一。若有其他玩家的棋子相邻,则可跳过后者至后方格,但不能一次跳过两子以上的棋子。若跳过的棋子后方为木板,则可以跳至后者左方或右方。棋子不可穿过墙。
放墙:放木片至沟槽,需正对棋格边,也不可把棋子完全围住以至不能到达对边[2]。在游戏结束前,所有已被放置的木片不能再次移动或拿回。
以本方棋子先抵达对边为胜。
(cp于维基百科)

效果图

项目结构

GameView 游戏界面绘图部分
GameService 游戏逻辑部分
Robot AI部分
。。。 android项目的部分结构

GameService

游戏逻辑部分主要负责:

  1. 游戏信息:
    如玩家(电脑)的位置坐标,所剩墙的数量,已放墙的位置,游戏是否结束等等。
  2. 游戏规则
    这是比较棘手的一部分,首先来说走棋,有当对方棋子与自己相邻时、当旁边有墙时等等情况,不同情况下,可走的目标点不同。所以我实现了一个函数直接根据目标位置自身位置、对方位置、棋盘信息来判断走法是否合法来解决。
    再来说放墙,这个游戏之所以这么吸引人,最大的亮点在于墙,而墙的存在的一个很大的前提是不能将对方用墙堵死,也就是说放的墙不能令对方无法到达对面。所以每次放墙的时候都要进行判断,确定墙放的位置是否合法。这个问题我解决的方案是,每次放墙时,先假设墙合法更新棋盘信息,然后使用A*来计算双方棋子到达对面所花的最小步数,若无法到达,则返回-1,即放墙操作不合法

类的结构

public class GameService{//玩家棋子位置private int playerX;private int playerY;//电脑棋子位置private int robotX;private int robotY;//玩家墙数量public int playerWallCnt;//电脑墙数量public int robotWallCnt;//储存棋盘信息public boolean[][] boardA = new boolean[10][10];public boolean[][] boardB = new boolean[10][10];//标记游戏是否结束及胜方是电脑还是玩家public int isEnd;//AIpublic Robot robot;//判断走棋是否合法public boolean isChessMan(int x, int y, int userMeX, int userMeY, int otherX, int otherY) {//走棋public boolean putChessMan(boolean flag, int x, int y);//放墙Apublic boolean putWallA(boolean flag, int x, int y);//放墙Bpublic boolean putWallB(boolean flag, int x, int y);//判断墙是否合法public boolean isCanGo();//判断玩家是否可以到达终点int a_start(boolean flag);

GameView

这一部分是花费时间最多的部分,之前写五子棋时界面显示部分几乎不到一小时就完成了,而这个界面完成的时间是五子棋的好多倍。
原因很简单,五子棋的棋盘绘制时,确定棋盘的左上角,然后根据行列值直接就能确定到在何处绘制棋子。
而墙棋的棋盘中间的空隙要用于放墙,数值就比较繁琐,而且为了令项目可以根据不同屏幕自适应,所有的数值都是根据屏幕参数按比例动态计算而来,写的时候很让人烦心。
还有一个难点(对我来说)是放墙的操作,因为要让用户用手指可以将墙拖动到目标位置,在此同时,还要根据拖动的位置模糊匹配相邻的沟槽。因为android方面实在是半桶水,这部分实现起来还是挺麻烦的。

类的结构

/*** Created by shiyi on 16/7/3.*/
public class GameView extends View {//游戏逻辑层private GameService gameService;//定义画笔private Paint paint;//屏幕尺寸private int screenWidth;private int screenHeight;//棋盘格子尺寸private float d;private float e;//棋盘绘制起点private float startX;private float startY;//墙体绘制起点private float startAX;private float startAY;private float startBX;private float startBY;//是否放墙private boolean isWallA;private boolean isWallB;//是否走棋private boolean isGo;//触摸位置private int lastX;private int lastY;private int wallX;private int wallY;//触摸坐标private float nowX;private float nowY;//初始化控件坐标以及定义触屏事件监听函数public GameView(Context context, AttributeSet attrs);//重绘函数@Overrideprotected void onDraw(Canvas canvas);//绘制墙数量信息public void drawWallMess(Canvas canvas);//绘制棋子public void drawChessMan(Canvas canvas, int color, int x, int y);//绘制地图中的墙public void drawWall(Canvas canvas);//绘制横墙public void drawWallA(Canvas canvas, int x, int y);//绘制竖墙public void drawWallB(Canvas canvas, int x, int y);//绘制棋盘public void drawChess(Canvas canvas);

Robot

本部分只有个alpha_beta剪枝函数,就不贴类结构了

AI部分应该算是人机对战的灵魂所在。
我仍然是使用alpha_beta剪枝搜索加上评估函数来确定走法。
关于alpha_beta剪枝搜索这里不再赘述,有兴趣的可以看这篇文章。Alpha-Beta搜索
评估函数部分,我只用了简单的A*来求出棋子到达对面所需的最小步数,通过玩家与AI的评估值相减后的结果来作为局面评估值。
事实上这样做并不好,例如,如果一方一味的用墙来围堵对方,那么当它墙用光后且堵的效果并不好的话,几乎已经注定了它会输。
尝试了将剩余墙数联系到评估值中,但是效果并不好。
而且偶尔会出现AI棋子左右循环移动的情况,调试多次找不出原因,若有知晓原因的人看到,还望不吝告之
能力有限,AI部分实现的效果一般般,只能日后再说了。

小结

因为代码篇幅过多,已上传至git,有兴趣的可以去看。墙棋AI人机对战app
apk文件还没有进行真机测试,因为之前安装过的问题,可能是卸载不彻底的问题,再安装时总显示替换安装,但又无法替换,因为之前的已经卸载了,总之好乱好乱,等解决了,再在此处更新链接吧。

步步为营-墙棋AI人机对战(Android)相关推荐

  1. Bombermaaan-最好的开源炸弹人游戏(支持AI人机对战,SFC复刻版)

    关键词:炸弹人源代码,炸弹人AI算法 目录 一.游戏截图 二.基本信息 三.游戏设计介绍 四.道具说明 五.下载 一.游戏截图       二.基本信息 语言:C++ 平台:Windows / Lin ...

  2. python小游戏井字棋(人机对战)

    游戏简介:在九宫格内进行,如果一方抢先于另一方向(横.竖.斜)连成3子,则获得胜利.游戏中输入方格位置代号的形式如下: 设计前的思路: 游戏中,board棋盘存储玩家.计算机的落子信息,未落子处未EM ...

  3. python井字棋游戏人机对战_用Python做一个井字棋小游戏

    井字棋是一个经典的小游戏,在九宫格上玩家轮流画OXO,当每列或每行或是两个对角成一线时便是获胜. 今天就用Python编写一个井字棋小游戏,与电脑对战. 程序执行画面如下图所示: 程序提供了两种人工智 ...

  4. python井字棋ai,python 井字棋(Tic Tac Toe)

    说明 用python实现了井字棋,整个框架是本人自己构思的,自认为比较满意.另外,90%+的代码也是本人逐字逐句敲的. minimax算法还没完全理解,所以参考了这里的代码,并作了修改. 特点 可以选 ...

  5. 实现五子棋的简单人人对战和人机对战的万字详细教程

    创建一个窗体来承载五子棋 如何创建一个窗体,以及如何在窗体上添加必要的按钮组件等操作,可以查看我的第一篇文章,里面有详细的讲解,这里就不在重新累述.具体的代码如下: public class Draw ...

  6. python人机对战的实验步骤_人机对战初体验:Python实现四子棋游戏

    继去年3月人机大战引发全球瞩目以来,围棋AI(人工智能)再度引发跨领域的关注:一个叫Master的围棋AI,几天时间,面对中日韩顶尖职业围棋选手,已取得60胜0败的恐怖战绩,展现出的围棋技艺已经到了人 ...

  7. C语言 AI智能,五子棋 人机对战,人人对战

    C语言五子棋,人机对战,人人对战 chunli@Linux:~$ cat main.c # include<stdio.h> # include<string.h> # inc ...

  8. C++实现基于博弈树的5x5一子棋人机对战

    基于博弈树的5x5一子棋人机对战 这是智能计算三个课程实验的第二个实验,即博弈树搜索 .我之前对博弈树的了解不多,所以实现起来比较的简略,仅仅是基本达到了要求 实验语言 C++ 实验内容 实践博弈树搜 ...

  9. JAVA五子棋AI(人机对战 颜色选择 悔棋等 可直接使用)

    五子棋是全国智力运动会竞技项目之一,容易上手,老少皆宜,而且趣味横生,引人入胜,不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性.当然,用 JAVA 语言编写五子棋 AI 小游戏也是一件非常 ...

最新文章

  1. 量子信息技术研究现状与未来——郭光灿
  2. memmove函数使用时注意的问题
  3. 游戏设计与计算机,RPG游戏设计与实现-数学与计算机系.doc
  4. 57张PPT彻底搞清楚区块链技术。。
  5. FE助手 json格式化 reslet client
  6. 【原】StreamInsight 浅入浅出(四)—— 例子
  7. iOS 端容器之 WKWebView 那些事
  8. 要成为一个 Java 架构师得学习哪些知识?
  9. Python的解析式与生成器
  10. 内核并发控制---原子操作(来自网易)
  11. mysql 并发_mysql 的读写锁与并发控制
  12. SQL大圣之路笔记——SQL 行转列,列转行
  13. 【论文阅读】Self-Knowledge Distillation with Progressive Refinement of Targets
  14. 事务处理:概念与技术
  15. Java面试题全集(三)
  16. 搭建家庭影音媒体中心 --公网远程连接Jellyfin流媒体服务器
  17. HTML5讲解与演示转载整理
  18. MiCO系统开发MiCoder-IDE安装遇到的坑
  19. CC2640R2F UART
  20. 工作经验|lambada处理集合的常用10种实战骚操作,我都记录下来了

热门文章

  1. C++黑客编程:键盘记录器,HOOK技术实现
  2. matlab中true()函数的用法
  3. 看雪2W课-Frida逆向与利用自动化 Frida开发和调试环境搭建 课时1
  4. java trim函数的使用方法_java trim的用法实例详解
  5. python导入自己的类型_如何将使用导入模块的我自己的类导入jupyter noteb
  6. docker 中文乱码解决
  7. 2015.09.07 活着就是一种召唤——《活着》余华
  8. DHTML乌托邦:使用JavaScript和DOM的现代Web设计
  9. 读代码比写代码难,真的吗?
  10. 全景解密量子信息技术:高层集中学习,国家战略,三大领域一文看懂