AI五子棋算法实现
前面已经发过一个思路,常用的用于电脑下棋的思路。
个人AI五子棋算法思路
目前在gitee上找了个已经实现了简单的五子棋下棋功能的代码,功能实现了,写的也不错,不过没什么注释,代码要看半天,我在电脑下棋的部分添加了很多注释,便于观看,主要观看的就是这第三部分。我对于其的修改也是在第三部分。
实现有三个文件
gobangMain.java
gobangListener.java
robotQZ.java
电脑下棋部分在robotQZ.java文件中,另外两个部分是功能逻辑的实现,这一部分就是电脑的棋形的权值,去得到当前空点的权值和,思考下一步棋该怎么走。
五子棋有两个个关键部分
判断胜负函数
根据棋形得到当前点权值函数即评估函数
判断胜负函数
/********判断输赢返回赢家*****************************************************/
public int Judger() {
int count = 1;
//竖直
for (int i = 1; i < 5; i++) {
//没有越界,棋盘上连着的都是一个玩家的棋,连着的中间没有空格
//以当前位置为起始点
if (xp - i >= 0 && Board[xp - i][yp] % 2 == Current % 2 && Board[xp - i][yp] != 0) count++;
else break;
}
for (int i = 1; i < 5; i++) {
if (xp + i <= 20 && Board[xp + i][yp] % 2 == Current % 2 && Board[xp + i][yp] != 0) count++;
else break;
}
//上下均为一个整体,两处count自然要一起
if (count == 5) return 1;
//水平
count = 1;
for (int i = 1; i < 5; i++) {
if (yp - i >= 0 && Board[xp][yp - i] % 2 == Current % 2 && Board[xp][yp - i] != 0) count++;
else break;
}
for (int i = 1; i < 5; i++) {
if (yp + i <= 20 && Board[xp][yp + i] % 2 == Current % 2 && Board[xp][yp + i] != 0) count++;
else break;
}
if (count == 5) return 1;
//左上到右下
count = 1;
for (int i = 1; i < 5; i++)//右下
{
if (xp - i >= 0 && yp - i >= 0 && Board[xp - i][yp - i] % 2 == Current % 2 && Board[xp - i][yp - i] != 0)
count++;
else break;
}
for (int i = 1; i < 5; i++)//左下
{
if (xp + i <= 20 && yp + i <= 20 && Board[xp + i][yp + i] % 2 == Current % 2 && Board[xp + i][yp + i] != 0)
count++;
else break;
}
if (count == 5) return 1;
//右上到左下
count = 1;
for (int i = 1; i < 5; i++)//左下
{
if (xp - i >= 0 && yp + i <= 20 && Board[xp - i][yp + i] % 2 == Current % 2 && Board[xp - i][yp + i] != 0)
count++;
else break;
}
for (int i = 1; i < 5; i++)//右上
{
if (xp + i <= 20 && yp - i >= 0 && Board[xp + i][yp - i] % 2 == Current % 2 && Board[xp + i][yp - i] != 0)
count++;
else break;
}
if (count == 5) return 1;
return 0;
}
主函数
gobangMain.java
package example.testForJava;
import javax.swing.*;
import java.awt.*;
@SuppressWarnings("serial")
public class gobangMain extends JPanel {
public Graphics gr;
gobangListener gl = new gobangListener();
public static void main(String[] args) {
gobangMain gm = new gobangMain();
gm.initUI();
}
/*****************************************************************/
public void initUI() {
JFrame frame = new JFrame();
frame.setTitle("五子棋byHWJ");
frame.setLocation(300, 100);
frame.setSize(750, 600);
frame.setResizable(false);//窗口大小不可调
BorderLayout bl = new BorderLayout();//构造新的边框布局,组件之间没有缝隙
frame.setLayout(bl);
//左面板
this.setBackground(Color.lightGray);
this.setBackground(new Color(110, 200, 200));
this.setPreferredSize(new Dimension(600, 600));//设置组件首选大小
this.addMouseListener(gl);
frame.add(this, BorderLayout.CENTER);
//右面板
JPanel eastPanel = new JPanel();
eastPanel.setPreferredSize(new Dimension(150, 600));//设置组件首选大小
eastPanel.setBackground(frame.getBackground());
frame.add(eastPanel, BorderLayout.EAST);
String Array[] = {
"开始新一局", "悔棋", "认输", "退出", "对战模式:", "人机对战", "人人对战", "(均为黑子先下)"};
ButtonGroup bg = new ButtonGroup();
for (int i = 0; i < Array.length; i++) {
if (i < 4) {
//3步
JButton button = new JButton(Array[i]);
button.setPreferredSize(new Dimension(140, 60));
button.addActionListener(gl);
eastPanel.add(button);
} else if (i == 4) {
//人机
JLabel label = new JLabel(Array[i]);
label.setPreferredSize(new Dimension(140, 60));
eastPanel.add(label);
} else if (i == 7) {
//人人
JLabel label = new JLabel(Array[i]);
label.setPreferredSize(new Dimension(140, 60));
eastPanel.add(label);
} else {
JRadioButton button = new JRadioButton(Array[i]);
button.setPreferredSize(new Dimension(100, 60));
button.setOpaque(true);//是否透明
button.addActionListener(gl);
eastPanel.add(button);
bg.add(button);
button.setSelected(true);// 设置默认选中一个单选按钮人机或者人人
}
}
frame.setVisible(true);
gr = this.getGraphics();//获得画笔
gl.sendGraphics(gr);//listen里面得
for (int i = 0; i < Board.length; i++) {
//初始化两个棋盘数组
for (int j = 0; j < Board[i].length; j++) {
Board[i][j] = 0;//棋盘为空,未下子
Match[i][j] = new Point(xl + d * i, yl + d * j);//将屏幕坐标与棋盘坐标对应起来
}
}
gl.sendMatch(Match);
gl.sendBoard(Board);
gl.sendGobangMain(this);
gl.sendCurrent(Current)