接十二,今天重点搞定简单基础版本的AI下棋。

画个大纲(跟随慢慢开发过程不断完善)

1.用户

两个用户对战  一黑一白

用户可以是人,也可以是AI。对战模式支持人人,人机,机机。

  • 属性

本次比赛执棋颜色

用户名

密码

游戏得分(赢得局数)

存档棋盘信息(二维数组,chessShape类型数组,黑、白、总棋子个数,下一次下棋的棋权)

  • 方法

下棋

输赢

设置、获取属性接口

2.比赛规则

一黑一白交替轮流下棋

可以决定哪个玩家先手

不可以重复下棋到同一个位置

不可以将棋子下到边界外

可以撤回刚刚下的棋,不可以撤回上一步的棋

哪一方横竖斜到达5个棋子赢一局

点击存档,当前用户储存当前棋面所有信息

读档读取当前用户保存的棋盘,一个用户只能存一个棋盘(人机模式加进来可以分开储存)

3.界面

  • 登录界面

用户登录:

用户名、密码输入栏(带提示,密码隐藏,用户密码匹配检验),登录按键,注册按键(注册新建user储存到用户txt文档,并弹出储存成功界面选择是否直接登录);

登录图像。

小logo图标。

  • 菜单界面

选择功能:

新游戏:对战模式 —— 人人,人机,机机

游戏积分 —— 获胜局数

退出游戏:关闭游戏

可以有设置按键:设置游戏背景音乐,音量等,添加用户设置棋子花色功能(现阶段默认登录用户为黑子)

  • 游戏界面

下棋主界面:

设置棋盘、背景板、菜单栏、棋子计数板、计分板、棋子、下棋指示器,刷新窗体后这些都不会消失。

选择游戏先手为黑棋还是白棋。

背景板、棋盘:17*17(16行,17根线,在中间画分界小黑点),棋盘在背景板之上。

菜单栏:撤回、清空、存档、帮助功能——撤回/清空时,计数器要跟着变化。

棋子计数板:记录当前棋盘上黑白棋子个数。(图像不重叠,随撤回清空等操作实时刷新)。

计分板:记录目前双方赢得局数。

棋子:下到交叉线(棋子校准)、不重复、不越出棋盘、刷新保存,可以撤回,可以识别获胜。

当前局数计时器:距离游戏开始的耗时。

  • 获胜界面

当有一方获胜后弹出

显示哪方获胜

显示棋面棋子数

显示获胜图片

菜单:

再战一局:触发游戏界面(棋盘清空)

退出游戏:回到菜单界面(棋盘清空)

回顾棋局:显示重新下棋步骤(撤回步骤显示回顾结束后弹窗返回

乱七八糟的功能

存档

读档

软件使用日志



第五天 —— 完善AI下棋逻辑,界面功能

实现AI判断合适的下棋位置,完善登录界面,构建储存用户txt。

实现方式以及一些大佬的优秀小tips

1.AI下棋:

计算棋盘上每个空位上的权值,权值越大,越有可能下在这个位置。

权值如何设计:

下棋特点:

棋子最容易下在同色棋子周围,最容易下在连棋长度最长的地方,最容易堵别人的活三连……

一个棋点周围有8路(8个方向)与其有关,列出这8个方向的所有可能,并根据情况赋予不同权值而达到计算权值做出最佳决策的效果。

在初始阶段我们并不考虑垂直、水平这种同一方向(感觉情况会复杂很多),将8个方向先分开考虑,每个方向的思路都一样,所以共用。

从这个要计算权值的点出发朝某一个方向算棋,先分为两类:

ps:从这个点朝某个方向出发,如果没连到棋就不算权值直接为0。

活棋:

从这个点朝某个方向出发,连到几个同色棋子之后是空棋。代码为010,0110,01110,011110等等。

活棋有一、二、三、四连。

死棋:

从这个点朝某个方向出发,连到几个同色棋子之后是空另一方的棋或者边界。代码为01,011,0111,01111等等。

死棋有一、二、三、四连。

图示:

从左上方向顺时针分别是:活棋一、二、三、四连,死棋一、二、三、四连。

给这8种情况一次赋权值,并以HashMap这种数据结构储存。key为符号编码例如010,011等;value的设计思路:

连数越高,权值应该越大,同等连数活连要大于死连。

又因为8个方向是独立计算的,合并造成的关系应该也有数值大小关系。

为了测试可以先大致设,后续数据关系思路:

棋面权值如何统计:

因为是棋盘上每一个空着的棋点都有可能是放置下一个棋子的位置,因此要遍历棋盘计算权值。

首先这个位置必须是空位置才有可能下棋。

其次这个位置有8个延伸方向,因此需要写8个方向的循环。每个方向最多有四个棋子连棋的延伸。

对某个方向来说周围有棋子才可能连棋,如果周围第一个地方就没有棋子,那么直接认为权值为0,不进入连棋判断的循环;有棋子的话要先记录这颗棋子的颜色,为了后面连棋判断(会突然发现并没有区别己方和敌方,仔细想想好像可以放一起,因为己方、敌方连棋都是我们要放的位置。但再仔细想发现也有区别,可以设置优先级,后面升级再设置)

记录颜色之后进入4个的循环(因为最多四子连棋,否则上次就赢了)——查看棋子颜色计算有多少子连棋,每次循环结果三种情况:

没有棋子:记录连棋记录,break,是活棋,不必再循环下去。

同色:记录连棋记录,继续。

异色:break,直接为死棋。

每个方向的连棋记录生成后(就是key),通过HashMap的据key查值方法,将值叠加起来,8次值的和就是最终这个点的最后权值分数。

代码:

public void fillChessMap(){//考虑在最一开始就加入,没用每次计算都重新添加一遍this.chessHashMap.addCode();//为了检测棋盘输出System.out.println("chesses棋盘:");for(int i=0;i<=ROW;i++){for(int j=0;j<=LINE;j++){System.out.print(goBangUI.chesses[i][j]+"\t");}System.out.println();}System.out.println();//System.out.println(this.chessHashMap.getCodeWeight("010"));//算法开始遍历棋盘for(int i=0;i<=ROW;i++){for(int j=0;j<=LINE;j++){if(goBangUI.chesses[i][j]==0){     //这个位置首先必须是个空位子才有可能放棋子int score=0;                   //分数随棋盘算的位置才更新一次for(int l=0;l<8;l++) {         //8个方向循环if(i+this.changeLocation[l][0]>ROW || j+this.changeLocation[l][1]>LINE || i+this.changeLocation[l][0]<0 || j+this.changeLocation[l][1]<0){System.out.println("i:"+i+this.changeLocation[l][0]+" j:"+j+this.changeLocation[l][1]);continue;}                      //先判断是否出了边界,出边界跳过String strCode="0";    //没出就开始记录int chessColor = goBangUI.chesses[i+changeLocation[l][0]][j+changeLocation[l][1]];                      //记录某方向第一个棋子的颜色System.out.println("chessColor:"+chessColor);if(chessColor!=0) {for (int k = 1; k <= 4; k++) {    //连棋循环int nowX=i + k * changeLocation[l][0];   //记录连到的棋子坐标int nowY=j + k * changeLocation[l][1];if (nowX > ROW || nowY > LINE || nowX < 0 || nowY < 0) {   //边界==死棋 breakbreak;                                }if (goBangUI.chesses[nowX][nowY] == chessColor) { //同色,记录strCode += chessColor;}else if(goBangUI.chesses[nowX][nowY] == 0){  //空棋 记录,breakstrCode += "0";break;}else           //异色==死棋 breakbreak; }}System.out.println("提前str:"+strCode);if(!strCode.equals("0")) {       //因为没有 0 的单独编码所以要避开,否则或中断异常结束System.out.println("str:"+strCode);score += this.chessHashMap.getCodeWeight(strCode);   //8个方向分数相加System.out.println("score:"+score);}}System.out.println("外面要加的score:"+score); this.chessWeight[i][j]=score;      //最终分数}}}}

怎么下棋:

遍历棋盘,权值最大的地方就是本次最下下棋位置。

记录最权值,对应坐标。遍历完之后,下载这个最大位置即可。

代码:

 public void paintChess(){int maxWeight=0,maxI=0,maxJ=0;for (int i=0;i<=ROW;i++){for(int j=0;j<=LINE;j++){if(chessWeight[i][j]>maxWeight){maxI=i;maxJ=j;}}}//pen.fillOval(X+maxJ*SIZE-SIZE/2,Y+maxI*SIZE-SIZE/2,SIZE,SIZE);}

2.一点小tips:

  • 在棋盘上画小点点——类似这种

实现思路:就是在画完棋盘格之后再像画小棋子一样画上去就可以,位置自行设计,大小控制一下就可以。

  • 当棋盘回放的棋盘有撤回的时候,调用的是paint函数实现的,就会有卡顿的感觉,为了使它更加流畅

实现思路:不要调用paint方法,直接将paint方法内容放在调用的这个位置(我的理解是没有刷新的那个过程?直接摞上去了)

本次待解决的问题

1.因为代码设计问题,想要那个key——value对应的内容值储存一次就够,不用每次遍历都调用,目前设置方法来填充,然后再fill函数之前,调用一次填充函数。不知道还有没有更加自然的方式存疑。

2.用户注册之后可以以流的形式存入txt文档,登录的时候可以读取txt文档并检查用户名密码匹配。

3.设置用户登录之后,显示用户信息,将用户和下棋、棋局结果、存档读档等绑定,实现赢棋加分,战绩记录。

代码

太长啦放github

Java学习笔记(十六)—— 开发个小项目(GoBang4.0)相关推荐

  1. Polyworks脚本开发学习笔记(十六)-用C#进行Polyworks二次开发

    Polyworks脚本开发学习笔记(十六)-用C#进行Polyworks二次开发 Polyworks支持C#二次开发,用对应的SDK文档试着做一下开发样例. 新建一个C#项目,在解决方案中右键添加引用 ...

  2. 电脑安装python3.74_python3.4学习笔记(十六) windows下面安装easy_install和pip教程

    python3.4学习笔记(十六) windows下面安装easy_install和pip教程 easy_install和pip都是用来下载安装Python一个公共资源库PyPI的相关资源包的 首先安 ...

  3. Java学习系列(十六)Java面向对象之基于TCP协议的网络通信

    TCP/IP的网络分层模型:应用层(HTTP/FTP/SMTP/POPS...),传输层(TCP协议),网络层(IP协议,负责为网络上节点分配唯一标识),物理层+数据链路层). IP地址用于标识网络中 ...

  4. Polyworks脚本开发学习笔记(十)-互动式开发及出错控制

    Polyworks脚本开发学习笔记(十)-互动式开发及出错控制 第八章组合的各种命令,完成了一个对所选的测点名称进行命名的任务.但是,由于任务中没有交互环节,只能机械地将 曲面点 - 包边点改为Flu ...

  5. Mr.J-- jQuery学习笔记(十六)--展开和收起动画折叠菜单的实现

    之前写过动画的隐藏与显示:Mr.J-- jQuery学习笔记(十四)--动画显示隐藏 动画隐藏与显示的一个小demo--对联广告:Mr.J-- jQuery学习笔记(十五)--实现页面的对联广告 与动 ...

  6. C语言结构体变量和结构体数组-学习笔记(十六)

    一.结构体变量 1.结构体概念 将不同类型的数据组合成一个有机的整体即为结构体.结构体由许多组织在一起的数据项组成,这些数据项不需要属于同一类型. 2.结构体类型及结构体变量定义 (1)结构体类型声明 ...

  7. python编程计算器_Python学习笔记:用Python开发一个计算器项目

    最近抽空看了下python的学习文档,发现开发工具以及资料支持对开发者相当的友好,相比之下,以前用TCL&Tk做的项目主要缺点有两个:1,开发难度大,调试手段只有靠print一种,而且语法错误 ...

  8. MOGRE学习笔记(3)--MOGRE小项目练习

    学习OGRE有一段时间了,领导为了检测学习效果,根据已有C++项目,弄一个类似的用c#语言编写的小项目. 配置:win7,DirectX2009,vs2010. 项目要求: 1.有Ogre窗口(尺寸1 ...

  9. Java学习笔记十:Java的数组以及操作数组

    Java的数组以及操作数组 一:什么是数组: 数组可以理解为是一个巨大的"盒子",里面可以按顺序存放多个类型相同的数据,比如可以定义 int 型的数组 scores 存储 4 名学 ...

  10. MonoRail学习笔记十六:AJax在MonoRail中的使用

    AJax几乎成了web2.0的一个代表,Java和Asp.net中都提供了一些AJax操作的控件.在MonoRail中也同样提供了AJax操作的共通类:AJaxHelper AJaxHelper可以指 ...

最新文章

  1. Objective-C中的block块语法
  2. 如何使用Hibernate批处理INSERT和UPDATE语句
  3. linux 查看设备 中断号,查看powerpc linux 软件中断号 硬件中断号映射关系
  4. 新能源界首陷“漏电门”奥迪将召回1644辆电动车e-tron
  5. Ceph使用块设备完整操作流程
  6. ftp pam mysql_ftp+pam基于mysql的认证
  7. toad可以连接mysql吗_配置Toad链接远程Oracle数据库
  8. 如何在 Mac 上输入带重音符的字符?
  9. win7安装SQL2005图文教程
  10. Python进阶练习题,新手快码起来
  11. 怪物之心无法触发_《勇者斗恶龙 怪兽篇:旅团之心》怪物生方法及生规则研究 - 电玩巴士...
  12. 【Luogu】P7995 [USACO21DEC] Walking Home B
  13. 在Windows上安装Elasticsearch v5.4.2
  14. odoo服务器设置说明
  15. 业界 | 阿里获杭州首张无人驾驶路测牌照,打造“智能高速公路”
  16. c语言实验--九九乘法表,C语言程序设计实验四 参考答案.doc
  17. mysql的reorg_DB2 runstats和reorg操作
  18. 【雅思写作】第一章:写作基础
  19. 关于第一期SWTC社区开发者大赛赛果的公告
  20. 使用RM2006电机进行麦克纳姆底盘设计(一)

热门文章

  1. phpword 模板替换并导出教程
  2. html中word-wrap无效,你未必知道的CSS小知识:word-wrap和overflow-wrap是等效的
  3. linux终端炫酷命令,炫酷的Linux终端命令大全-1
  4. 小程序scroll设置(滚动轴样式、真机测试不能滑动)
  5. html相对定位和绝对定位
  6. Qt Installer Framework应用总结
  7. hbuilder HTML页面跳转,基于HBuilder开发手机APP-主页/跳转页面/切换选项卡(示例代码)...
  8. datax之txtfilereader
  9. (成功解决)ros的rvize使用oint_state_publisher报错:[joint_state_publisher_gui-5] process has died
  10. 用 Python 写了个简单的股票量化交易框架