接十六,今天重点完善AI下棋以及用户登录并解决一个小问题。
画个大纲(跟随慢慢开发过程不断完善)
1.用户
两个用户对战 一黑一白
用户可以是人,也可以是AI。对战模式支持人人,人机,机机。
人人对战的时候想象的场景是主用户(登录游戏的)要找一个对手进行对战,主用户要记录战局成绩,那另一方应该也记录成绩或者单纯简单玩一玩(需要满足这两种需求:对手可以是服内玩家<甚至可以考虑设计加好友功能在好友中找对手>,也可以是路人)
- 属性
本次比赛执棋颜色
用户名(不同用户的用户名不能一样)
密码
游戏得分(赢得局数)
存档棋盘信息(二维数组,chessShape类型数组,黑、白、总棋子个数,下一次下棋的棋权)
-
方法
下棋
输赢
设置、获取属性接口
2.比赛规则
一黑一白交替轮流下棋
可以决定哪个玩家先手
不可以重复下棋到同一个位置
不可以将棋子下到边界外
可以撤回刚刚下的棋,不可以撤回上一步的棋
哪一方横竖斜到达5个棋子赢一局
点击存档,当前用户储存当前棋面所有信息
读档读取当前用户保存的棋盘,一个用户只能存一个棋盘(人机模式加进来可以分开储存)
3.界面
- 登录界面
用户登录:
用户名、密码输入栏(带提示,密码隐藏,用户密码匹配检验),登录按键,注册按键(注册新建user储存到用户txt文档,并弹出储存成功界面选择是否直接登录);
登录图像。
小logo图标。
- 菜单界面
选择功能:
新游戏:对战模式 —— 人人,人机,机机
游戏积分 —— 获胜局数
退出游戏:关闭游戏
可以有设置按键:设置游戏背景音乐,音量等,添加用户设置棋子花色功能(现阶段默认登录用户为黑子)。
- 游戏界面
下棋主界面:
设置棋盘、背景板、菜单栏、棋子计数板、计分板、棋子、下棋指示器,刷新窗体后这些都不会消失。
选择游戏先手为黑棋还是白棋。
背景板、棋盘:17*17(16行,17根线,在中间画分界小黑点),棋盘在背景板之上。
菜单栏:撤回、清空、存档、帮助,还有大佬设计的认输功能(感觉有点意思)——撤回/清空时,计数器要跟着变化。
棋子计数板:记录当前棋盘上黑白棋子个数。(图像不重叠,随撤回清空等操作实时刷新)。
计分板:记录目前双方赢得局数。
棋子:下到交叉线(棋子校准)、不重复、不越出棋盘、刷新保存,可以撤回,可以识别获胜。
当前局数计时器:距离游戏开始的耗时。
- 获胜界面
当有一方获胜后弹出
显示哪方获胜
显示棋面棋子数
显示获胜图片
菜单:
再战一局:触发游戏界面(棋盘清空)
退出游戏:回到菜单界面(棋盘清空)
回顾棋局:显示重新下棋步骤(撤回步骤显示,回顾结束后弹窗返回)
乱七八糟的功能
存档
读档
软件使用日志
补一个听到的有意思的玩法(在人人下棋的时候可以叠加AIbuff<我的理解是可以指示当前最佳下棋位置>)
第六天 —— 完善AI下棋逻辑,棋面方法兼容,功能
实现AI下棋与人人下棋兼容,完善登录界面,构建储存用户txt。
实现方式解决问题与遇到的新问题
1.实现用户登录信息存入文件中
实现方式:
实现之前需要将对象序列化(实现按顺序取对象)
User aUser = new User(jTFUserStr,jTFPasswordStr,0,0);
//将用户信息写入文档
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("users.txt"));
oos.writeObject(aUser);
//从文件中读取一个用户
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("users.txt"));
user0 = (User) ois.readObject();
具体实现查资料:挂这里☞ 学习的文章
2.AI棋盘权值设置(让AI更加聪明)
value的设计思路:
连数越高,权值应该越大,同等连数活连要大于死连。
又因为8个方向是独立计算的,合并造成的关系应该也有数值大小关系。
后续数据关系思路:
解决遇到的问题:
1.AI棋盘和人人对战棋盘如何兼容
问题描述:
为了方便分清AI棋盘和人人棋盘功能就用两个Listener来分别实现功能,但是AI棋盘和人人棋盘外观是一模一样的,只是下棋功能不同,所以在UI方法里在人人棋盘的方法和AI的方法都用this来初始化界面。
但是出现一个问题由于无论AI还是人人都是同一个界面,但是在不同的方法中对应的应该是不同的监听器。但事实上,虽然我是调用方法一,想要只让监听器一工作,但是由于同样是这个界面启动,我监听器二也一直处于工作状态,呈现效果就是:人人棋盘会出现AI下棋,AI棋盘可能会出现人人下棋。处于一种混乱模式。
解决方法:
在某个方法加入监听器前,先将另一个监听器移除。确保始终只有对应的监听器工作。
this.removeMouseListener(mylis);
2.在下棋的时候,已经赢棋但是还可以动棋盘造成多次赢棋。
本次待解决的问题
1.因为代码设计问题,想要那个key——value对应的内容值储存一次就够,不用每次遍历都调用,目前设置方法来填充,然后再fill函数之前,调用一次填充函数。不知道还有没有更加自然的方式存疑。
2.用户注册之后可以以流的形式存入txt文档,登录的时候可以读取txt文档并检查用户名密码匹配。
3.设置用户登录之后,显示用户信息,将用户和下棋、棋局结果、存档读档等绑定,实现赢棋加分,战绩记录。
代码