人机五子棋
近期整理代码的时候,发现大二的时候(目前大三)做的几个课程设计还不错,所以把这部分的代码以及设计文档都开源出来,以供后者参考学习使用。
完整代码以及本文的word都在放在了Github上,你可以下载或使用它:人机五子棋项目地址,如果喜欢的话,就去点个Star
吧
具体效果如下图,我是黑方(先手),机器是白方,本局机器胜。
从图中大概可以看出,它已经具备了一点点的智能,想了解它是如何被创造出来的吗?请继续…
任务设计书
本项目要实现的是五子棋人机版,通过制定棋型的评分表使机器能够对棋盘局势评估。五子棋玩家双方分别称为“人”、“机器” ,当人落子后,机器对棋盘扫描获取可行棋的位置集合,然后遍历该集合,利用评估函数对每个空位依次估分,得分最高的位置即为机器要落子的位置,在使用评估函数对空位打分时,为了避免机器只攻不守,需要使用“换位思考”的思想,也就是说打分时不仅考虑自身,还要考虑对方。
类与对象的设计
位置实体类Location
Location类封装棋盘上的一个位置,AI对局势分析时会对位置打分,所以位置实体类应该有个字段保存位置分数,Location类的设计如图1所示。
1)public Location(int x, int y)
构造函数。x:横坐标,y:纵坐标
2)public Location(int x, int y, int player)
构造函数。x:横坐标,y:纵坐标,player:位置所有者
3)public Location(int x, int y, int player, int score)
构造函数。x:横坐标,y:纵坐标,player:位置所有者,score:位置分数
4)public void setX(int x)
设置横坐标的值
5)public void setY(int y)
设置纵坐标的值
6)public void setScore(int score)
设置位置分数
7)public void setPlayer(int player)
设置该位置由玩家player落子,player可取:Chess.PLAYER、Chess.AI
8)public int getX()
获取对象的横坐标
9)public int getY()
获取对象的纵坐标
10)public int getPlayer()
获取该位置是由哪位玩家所有
11)public int getScore()
获取该位置的分数
自定义棋盘类ChessPanel
ChessPanel类负责视图上的事情,如棋盘以及棋子的绘制、棋盘状态的保存、落子、清空等事件,ChessPanel类的设计如图2所示。
1)public void paint(Graphics g1)
重写该方法,绘制棋盘、棋子
2)public void drawBoard(Graphics2D g)
绘制棋盘
3)public void drawChessman(Graphics2D g)
绘制棋子
4)public void clearBoard()
清空棋盘
5)public void doPlay(int row, int col, int player)
玩家在视图上落子
控制器类Chess
Chess类主要负责逻辑上的各个事件,如逻辑上落子、AI局势分析、胜负判定等,Chess类的设计如图3所示。
1)public void setFirst(int first)
设置先手的玩家
2)public Chess()
构造函数,进行棋局的初始化
3)public void restart()
棋局初始化
4)public Location start()
AI先手时调用,决策第一手棋位置
5)public boolean play(int x, int y, int player)
玩家落子。x,y是落子坐标,player的取值:Chess.AI、Chess.PLAYER,返回值表示是否落子成功
6)public void showToConsole()
显示棋盘信息到控制