Java实现五子棋

一、一个项目需要一下要素

  1. 用户交互部分

  1. 数据模型部分

  1. 业务逻辑处理部分

  1. 数据存储部分

二、五子棋

  1. 用户交互部分

  • 五子棋下棋的界面

  • 棋盘绘制

  • 界面上相关功能的按钮——按钮添加

  • 开始游戏

  • 悔棋

  • 暂停游戏

  • 退出游戏

  • 回放

  • 用户通过点击按钮调用对应的业务功能

  • ActionListener

  • 用户通过鼠标点击棋盘下棋

  • MouseListener

  1. 数据模型部分

  • 黑白棋子的数据模型

  • 棋子:坐标,棋子落子顺序,棋子的黑白标识

  1. 业务逻辑处理部分

  • 鼠标点击下棋,黑白交替下棋

  • 判断棋子的落子范围,重复落子

  • 判断输赢,悔棋,控制游戏进程(开始游戏)

  1. 数据存储部分

  • 显示到棋盘上

  • 重新绘制

  • 二维数组

  • 线性表

  • 回放-->存储到本地文件中

三、五子棋开发

  • 界面开发

  • 界面类

  • 创建了一个接口普,存储了一些棋盘上的固定数据

  • 棋盘面板:自己创建了一个类继承JPanel重写了面板绘制的方法paint

  • 绘制背景以及网格线,使用到的接口中的固定数据

  • 按钮面板:设置null布局

  • 添加相关按钮

  • 采用遍历字符串数组形式创建多个按钮

  • 设置按钮的位置以及尺寸

  • 监听器类:

  • 实现鼠标监听

  • 使用按下监听方法

  • 获取鼠标按下时的坐标

  • 实现按钮监听

  • 获取按钮上的字符串以及按钮对象

1.实现基本的功能

  • 创建一个界面

  • 不能直接设置棋盘所在面板的背景颜色,所以要新建一个类,继承JPanel,重写里面的paint方法

  • 添加棋盘面板与按钮面板

  • 棋盘画线:接口当中定义的属性是常量,所以我们创建一个接口(interface)把棋盘的固定数据定义在此

  • 在ChessPanel中继承(implements)创建的GoData接口,开始画棋盘

运行效果:

  • 添加按钮

运行效果:

  • 如果觉得按钮位置太高,想让按钮的位置下来一些,可以把面板设置为空布局(面板默认流式布局),然后再设置按钮的位置与大小

运行效果:

  • 设置监听器:

MouseAdapter:把所有MouseListener中的方法都实现,可以继承它对其中的某一个方法进行重写,就可以不用写MouseListener中全部的方法

添加监听器

面板实现监听

按钮实现监听

  • 获取棋盘上的画笔对象

运行效果:

  • 虽然现在可以“下棋”,但是在棋盘面板的任何地方都可以“下棋”,而且并没有黑白交替下棋

  • 设置黑白交替下棋:(在GoListener中)

运行效果:

  • 校正棋子的坐标(算法题)

已知:棋盘左上角坐标,网格宽度,格子数,鼠标点击的坐标

(鼠标点击的位置-棋盘左上角坐标)/网格宽度

但是起始点并不是棋盘左上角,而是棋盘左上角加上一个棋子的半径

判断下棋的范围

运行效果:(鼠标点击棋盘外的位置都会有弹窗出现)

利用行列值还原标准坐标

运行效果:(随意点击棋子都可以出现在棋盘的交点上)

  • 这样五子棋的基本功能就实现啦,但是还是存在许多的问题:可以重复落子,窗体最小化之后再打开棋子都消失了,按钮没有设置功能……

  1. 棋子数据化

  1. 棋子绘制在棋盘上会出现棋盘最小化之后再打开就消失

  1. 棋子可以在同一个地方重复落子

  1. 悔棋、判断输赢、回放都需要棋子的数据(坐标,先后顺序)

解决a,b问题可以使用二维数组来存储棋子的数据

整数型二维数组,其中存储三个数值:0-无棋子,1-黑旗,2-白旗

将二维数组输出看看结果:

这样棋子的位置就被存入二维数组当中了

  • 不能重复落子

运行效果:

  • 重绘实现

如果储存数据的二维数组是私有的,则要写一个对应的返回函数

对应要更改:

在ChessPanel中画棋子:

这样下棋之后最小化再点开棋子就不会消失了

  • 按钮功能的设置

  1. 设置开始游戏按钮功能:必须先点击开始游戏按钮才可以开始下棋,按下之后变成结束游戏

2.结束游戏之后需要清空棋盘

  1. 删除二维数组中的数据

(封装一个函数)

调用此函数

  1. 刷新面板

GoBangUI中:

回到GoListener中:

这样就实现了按下“开始游戏”才可以开始,按下“结束游戏”之后自动清空面板

最后这个重绘的代码可以用蓝色框里的代替

3.退出游戏

4.悔棋功能

新建一个Chess类,包含行列值以及棋子的黑白标识

把每一个棋子创建成一个对象,把这些对象按照顺序存进去

创建一个新的对象

6.判断输赢:

方法一:根据最后一颗棋子的位置 八个方向查找

方法二:五元组:遍历棋盘上可以赢棋的所有的五个格子

方法一:

  • 新建一个类用来存储查找的方法

  • 判断横向

  • 判断纵向

  • 判断左上到右下

  • 判断右上到左下

  • 判断

  • 在监听器里

这样就实现了输赢判断

7.AI下棋

  • 流程

  • 人人下棋以及人机下棋按钮

  • 人机下棋的算法:

  • 通过下棋找到适合下棋的位置

AI下棋:

  • 分析游戏中有几种棋局情况:

  • 活连:

  • 活一连 010 10

  • 活二连 0110 100

  • 活三连 01110 1000

  • 活四连 011110 5000

  • 活一连 020 10

  • 活二连 0220 100

  • 活三连 02220 1000

  • 活四连 022220 5000

  • 半活连:

  • 一连 01 8

  • 二连 011 80

  • 三连 0111 800

  • 四连 01111 4000

  • 一连 02 8

  • 二连 022 80

  • 三连 0222 800

  • 四连 02222 4000

  • AI算法的逻辑:

  1. 查询每个空位可以下棋的情况

  1. 计算每个空位的分数

  1. 每个空位有八个方向,八个方向对应的连子情况的分数进行累加

  1. 统计所有空位中,分数最高的空位

  1. 如果多个空位的分数一致:随机取一个

  • 添加按钮

在监听器里传入按钮

创建一个新的JButton类型的数组,把按钮存进去

为了让数组可以从外部访问,所以要把void改成JButton[ ]数组

拿到这个数组

监听器中:

结束游戏之后恢复两个按键的功能

显示是人机下棋还是人人下棋(改变按钮颜色)

按下结束游戏时恢复

  • AI下棋的代码

  1. 将所有的连子情况以及分数存入数据结构

  1. HashMap 哈希表结构

  1. 实现K-V存储 键值对(Key Value)

  1. 可以K不能重复,唯一,Value可以重复

  1. 通过K 查找V

HashMap<Srting,Integer>map = new HashMap<>( );

  1. 存数据:map.put("010",10);

  1. 取数据:int code = map.get("010") ;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值