Java 五子棋人人对战和人机对战简单实现
废话不多说,咱直接进入正题
首先,为了方便,咱们先用一个Java接口把一些全局要用的数据写到接口里,这样就不用传来传去了
package wuziqi;
public interface Gobang {
public static final int size = 40; // 设置格子大小为40
public static final int X = 20, Y = 20; // 设置棋盘右上角的位置
public static final int coloum = 15; //设置行数
public static final int row = 15; //设置列数
public static final int[][] array1 = new int[coloum][row]; //记录棋子位置的数组
public static final int[][] weightArray = new int[coloum][row]; //记录棋盘每个位置的权值
public static final boolean flag[] = new boolean[2]; //记录选择的模式
}
接下来,就是棋盘的实现了,由于棋盘要一开始就出现在界面上,并且要一直存在,不能消失,所以我们用重绘来画出棋盘
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i < coloum; i++) {
g.drawLine(X, Y + size * i, X + size * (coloum - 1), Y + size * i);// 横线 //格子40
g.drawLine(X + size * i, Y, X + size * i, Y + size * (coloum - 1));// 竖线 //格子40
}
}
这样我们就画好了棋盘,接下来我们要做的就是棋盘布局,加一些按钮。这里我用的是边界布局管理器(BorderLayout)把容器的的布局分为五个位置:CENTER、EAST、WEST、NORTH、SOUTH。依次对应为:上北(NORTH)、下南(SOUTH)、左西(WEST)、右东(EAST),中(CENTER)。
package wuziqi;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class GobangMain extends JPanel implements Gobang {
public static void main(String[] args) {
GobangMain gm = new GobangMain();
gm.initUI();
}
public void initUI() {
JFrame frame = new JFrame("五子棋");
frame.setSize(780, 635);
frame.setDefaultCloseOperation(3);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setLayout(new BorderLayout());
// 设置棋盘面板的背景颜色
this.setBackground(Color.LIGHT_GRAY);
// 将棋盘面板添加到窗体的中间部分
frame.add(this, BorderLayout.CENTER);
// 实例化JPanel面板对象,作为东边放置按钮的面板
JPanel eastPanel = new JPanel();
// 设置东边面板的布局方式为流式布局居中对齐
eastPanel.setLayout(new FlowLayout());
// 设置面板容器组件的宽度和高度
eastPanel.setPreferredSize(new Dimension(150, 0));
// 实例化单选按钮分组对象
ButtonGroup bg = new ButtonGroup();
// 定义数组,存储组件上要显示的文字信息
String[] array = { "开始新游戏", "悔棋", "认输", "对战模式:", "人人对战", "人机对战" };
for (int i = 0; i < array.length; i++) {
if (i < 3) {
JButton button = new JButton(array[i]);
button.setPreferredSize(new Dimension(140, 80));
eastPanel.add(button);
} else if (i == 3) {
JLabel label = new JLabel(array[i]);
eastPanel.add(label);
} else {
JRadioButton button = new JRadioButton(array[i]);
button.setSelected(false);
bg.add(button);
eastPanel.add(button);
}
}
// 将eastPanel添加到窗体上的东边
frame.add(eastPanel, BorderLayout.EAST);
frame.setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i < coloum; i++) {
g.drawLine(X, Y + size * i, X + size * (coloum - 1), Y + size * i);// 横线 //格子40
g.drawLine(X + size * i, Y, X + size * i, Y + size * (coloum - 1));// 竖线 //格子40
}
}
}
贴上效果图:
界面写好了,接下来就是下棋了,因为要根据鼠标点击的位置来下棋和选择的模式进行人人对战和人机对战,所以这里我们要用到Java里面自带鼠标监(MouseAdapter)和动作监听(ActionListener),要把棋子画到棋盘上,自然还要用到画笔(Graphics)
package wuziqi;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import javax.swing.JOptionPane;
public class GobangListener extends MouseAdapter implements ActionListener,Gobang{
private GobangMain gm; // 棋盘面板对象
private Graphics g; // 画笔对象
boolean cco=true; //记录下黑棋还是白棋
boolean fff=true; //记录是否能悔棋
boolean ggg=true; //记录是否能认输
private MyArrayList<Chess> array;
int coloum1,row1;
int xx,yy,max;
public GobangListener(GobangMain gm,MyArrayList<Chess> array) { //从GobangMain传窗体对象和记录棋子的数组
this.gm = gm;
this.array=array;
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("开始新游戏")) {
for(int i=0;i<array1.length;i++) {
Arrays.fill(array1[i], 0);
}
cco=true;
fff=true;
ggg=true;
gm.addMouseListener(this);
array.Reset();
gm.repaint();
}
if (e.getActionCommand().equals("悔棋")) {
if(flag[0]) { //人人对战悔棋
if(fff) {
if(array.getSize()>1) {
array1[coloum1][row1]=0;
Chess aaa=array.get(array.getSize()-2);
coloum1=aaa.coloum;
row1=aaa.row;
array.Delete();
cco=!cco;
gm.repaint();
}
}
}
if(flag[1]) { //人机对战悔棋
if(fff) {
if(cco) {
if(array.getSize()>2) {
array1[xx][yy]=0;
Chess aaa=array.get(array.getSize()-2);
coloum1=aaa.coloum;
row1=aaa.row;
array.Delete();
array1[coloum1][row1]=0;
Chess bbb=array.get(array.getSize()-2);
xx=bbb.coloum;
yy=bbb.row;
array.Delete();
gm.repaint();
}
}
}
}
}
if (e.getActionCommand().equals("认输")) {
if(ggg) {
if(cco) {
JOptionPane.showMessageDialog(gm, "白棋获胜");
}else {
JOptionPane.showMessageDialog(gm, "黑棋获胜");
}
gm.removeMouseListener(this);
fff=false;
ggg=false;
}
}
if (e.getActionCommand().equals("人人对战")) { //选择人人对战模式 flag[0]为true,flag[1]为false
flag[0]=true;
flag[1]=false;
for(int i=0;i<array1.length;i++) {
Arrays.fill(array1[i], 0);
}
cco=true;
fff=true;
ggg=true;
array.Reset();
gm.repaint();
}
if (e.getActionCommand().equals("人机对战")) { //选择人机对战模式 flag[0]为false,flag[1]为true
flag[0]=false;
flag[1]=true;
for(int i=0;i<array1.length;i++) {
Arrays.fill(array1[i], 0);
}
cco=true;
fff=true;
ggg=true;
array.Reset();
gm.repaint();
}
}
public void mouseReleased(MouseEvent e) { //鼠标松开的时候进行的操作
if(flag[0]) { //选择人人对战模式进行的操作
if (g == null)
g = gm.getGraphics();
int x = e.getX();
int y = e.getY();
coloum1 = (x-X+size/2)/size;
row1 = (y-Y+size/2)/size;
if(coloum1<coloum&&row1<row) {
if(array1[coloum1][row1]==0) {
if(cco) {
g.setColor(Color.BLACK);
g.fillOval(X+coloum1*size-size/2, Y+row1*size-size/2, size, size);
array1[coloum1][row1]=1;
Chess sh=new Chess(coloum1,row1,Color.BLACK); //创建棋子对象,将棋子的信息存储
array.add(sh); //将棋子加入数组队列
}
else {
g.setColor(Color.WHITE);
g.fillOval(X+coloum1*size-size/2, Y+row1*size-size/2, size, size);
array1[coloum1][row1]=-1;
Chess sh=new Chess(coloum1,row1,Color.WHITE);
array.add(sh);
}
Judge jd=new Judge(coloum1,row1);
if(jd.judge()) {
if(cco) {
JOptionPane.showMessageDialog(gm, "黑棋获胜");
}else {
JOptionPane.showMessageDialog(gm, "白棋获胜");
}
gm.removeMouseListener(this);
fff=false;
ggg=false;
}
cco=!cco;
}
}
}
if(flag[1]) { //选择人机对战进行的操作
if (g == null)
g = gm.getGraphics();
if(cco) { //若coo为true,则人下棋
int x = e.getX();
int y = e.getY();
coloum1 = (x-X+size/2)/size;
row1 = (y-Y+size/2)/size;
if(coloum1<coloum&&row1<row) {
if(array1[coloum1][row1]==0) {
g.setColor(Color.BLACK);
g.fillOval(X+coloum1*size-size/2, Y+row1*size-size/2, size, size);
array1[coloum1][row1]=1;
Chess sh=new Chess(coloum1,row1,Color.BLACK);
array.add(sh);
Judge jd=new Judge(coloum1,row1);
if(jd.judge()) {
if(cco) {
JOptionPane.showMessageDialog(gm, "黑棋获胜");
}else {
JOptionPane.showMessageDialog(gm, "白棋获胜");
}
gm.removeMouseListener(this);
fff=false;
ggg=false;
cco=!cco;
}
cco=!cco;
}
}
}
if(!cco) { //若coo为false,则机器下棋
AIX();
}
}
}
public void AIX() {
for(int i=0;i<weightArray.length;i++) {
for(int j=0;j<weightArray[i].length;j++) {
weightArray[i][j]=0;
}
}
max=-1;
AI.Quan();
for(int i=0;i<weightArray.length;i++) {
for(int j=0;j<weightArray[i].length;j++) {
if(i<5&&j<5) {
if(max<=weightArray[i][j]&&array1[i][j]==0) {
max=weightArray[i][j];
xx=i;yy=j;
}
}else {
if(max<weightArray[i][j]&&array1[i][j]==0) {
max=weightArray[i][j];
xx=i;yy=j;
}
}
}
}
if(array1[xx][yy]==0) {
g.setColor(Color.WHITE);
g.fillOval(X+xx*size-size/2, Y+yy*size-size/2, size, size);
array1[xx][yy]=-1;
Chess sh=new Chess(xx,yy,Color.WHITE);
array.add(sh);
Judge jd=new Judge(xx,yy);
if(jd.judge()) {
if(cco) {
JOptionPane.showMessageDialog(gm, "黑棋获胜");
}else {
JOptionPane.showMessageDialog(gm, "白棋获胜");
}
gm.removeMouseListener(this); //移除监听,这时将不能对棋盘进行操作
fff=false; //设置不能进行悔棋
ggg=false; //设置不能进行认输
}
cco=!cco;
}
}
}
棋子类
package wuziqi;
import java.awt.Color;
public class Chess extends Object implements Gobang{
int coloum,row;
Color color;
public Chess(int coloum,int row,Color color) {
this.coloum=coloum;
this.row=row;
this.color=color;
}
}
这个是我自己写的一个数组队列
package wuziqi;
public class MyArrayList<E> {
public Object[] array;
private int size=0;
public MyArrayList() {
array =new MyArrayList[0];
}
public void add(E e) {
Object[] a =new Object[array.length+1];
for(int i=0;i<array.length;i++) {
a[i]=array[i];
}
a[array.length]=e;
array=a;
size++;
}
@SuppressWarnings("unchecked")
public E remove(int index) {
if(index<=0||index>size) return null;
Object[] a=new Object[array.length-1];
for(int i=0;i<index;i++) {
a[i]=array[i];
}
Object e=array[index];
for(int i=index;i<a.length;i++) {
a[i]=array[i+1];
}
array=a;
return (E)e;
}
public void Delete() {
Object[] a=new Object[array.length-1];
for(int i=0;i<array.length-1;i++) {
a[i]=array[i];
}
array=a;
size--;
}
public int getSize() {
return size;
}
public void setA(int i) {
array[i]=null;
}
@SuppressWarnings("unchecked")
public E get(int index) {
Object e=array[index];
return (E)e;
}
public void Reset() {
Object[] a =new Object[0];
size=0;
array =a;
}
}
这时候运行代码,一点棋盘发现并没有反应,这是因为没有加上监听,这是需要在GobangMain里面对按钮加上监听,在for循环前面加上GobangListener gl = new GobangListener(this, array); 在eastPanel.add(button);后面加上button.addActionListener(gl)
现在可以下棋了,接下来就是判断输赢和人机算法了,判断输赢我用的是便利所有的棋子进行判断,有五个连在一起就结束游戏,人机算法我用的是比较垃圾的权值法,这个有点蠢,当然还有更好的博弈论算法、和机器学习算法,有兴趣的可以自行去了解
接下来贴出所有代码
接口类
package wuziqi;
public interface Gobang {
public static final int size = 40; // 设置格子大小为40
public static final int X = 20, Y = 20; // 设置棋盘右上角的位置
public static final int coloum = 15; //设置行数
public static final int row = 15; //设置列数
public static final int[][] array1 = new int[coloum][row]; //记录棋子位置的数组
public static final int[][] weightArray = new int[coloum][row]; //记录棋盘每个位置的权值
public static final boolean flag[] = new boolean[2]; //记录选择的模式
}
GoMain类
package wuziqi;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class GobangMain extends JPanel implements Gobang {
public static void main(String[] args) {
GobangMain gm = new GobangMain();
gm.initUI();
}
public void initUI() {
JFrame frame = new JFrame("五子棋");
frame.setSize(780, 635);
frame.setDefaultCloseOperation(3);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setLayout(new BorderLayout());
// 设置棋盘面板的背景颜色
this.setBackground(Color.LIGHT_GRAY);
// 将棋盘面板添加到窗体的中间部分
frame.add(this, BorderLayout.CENTER);
// 实例化JPanel面板对象,作为东边放置按钮的面板
JPanel eastPanel = new JPanel();
// 设置东边面板的布局方式为流式布局居中对齐
eastPanel.setLayout(new FlowLayout());
// 设置面板容器组件的宽度和高度
eastPanel.setPreferredSize(new Dimension(150, 0));
// 实例化单选按钮分组对象
ButtonGroup bg = new ButtonGroup();
// 实例化事件处理类的对象,然后将棋盘面板作为参数传递到GobangListener类的对象中
GobangListener gl = new GobangListener(this, array);
// 定义数组,存储组件上要显示的文字信息
String[] array = { "开始新游戏", "悔棋", "认输", "对战模式:", "人人对战", "人机对战" };
for (int i = 0; i < array.length; i++) {
if (i < 3) {
JButton button = new JButton(array[i]);
button.setPreferredSize(new Dimension(140, 80));
eastPanel.add(button);
button.addActionListener(gl);
} else if (i == 3) {
JLabel label = new JLabel(array[i]);
eastPanel.add(label);
} else {
JRadioButton button = new JRadioButton(array[i]);
button.setSelected(false);
bg.add(button);
eastPanel.add(button);
button.addActionListener(gl);
}
}
// 将eastPanel添加到窗体上的东边
frame.add(eastPanel, BorderLayout.EAST);
frame.setVisible(true);
}
private MyArrayList<Chess> array = new MyArrayList<Chess>();
public void paint(Graphics g) {
super.paint(g);
// System.out.println(">>>");
for (int i = 0; i < coloum; i++) {
g.drawLine(X, Y + size * i, X + size * (coloum - 1), Y + size * i);// 横线 //格子40
g.drawLine(X + size * i, Y, X + size * i, Y + size * (coloum - 1));// 竖线 //格子40
}
for (int i = 0; i < array.getSize(); i++) {
Chess e = array.get(i);
g.setColor(e.color);
g.fillOval(X + e.coloum * size - size / 2, Y + e.row * size - size / 2, size, size);
}
}
}
GobangListener类
package wuziqi;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import javax.swing.JOptionPane;
public class GobangListener extends MouseAdapter implements ActionListener,Gobang{
private GobangMain gm; // 棋盘面板对象
private Graphics g; // 画笔对象
boolean cco=true; //记录下黑棋还是白棋
boolean fff=true; //记录是否能悔棋
boolean ggg=true; //记录是否能认输
private MyArrayList<Chess> array;
int coloum1,row1;
int xx,yy,max;
public GobangListener(GobangMain gm,MyArrayList<Chess> array) { //从GobangMain传窗体对象和记录棋子的数组
this.gm = gm;
this.array=array;
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("开始新游戏")) {
for(int i=0;i<array1.length;i++) {
Arrays.fill(array1[i], 0);
}
cco=true;
fff=true;
ggg=true;
gm.addMouseListener(this);
array.Reset();
gm.repaint();
}
if (e.getActionCommand().equals("悔棋")) {
if(flag[0]) { //人人对战悔棋
if(fff) {
if(array.getSize()>1) {
array1[coloum1][row1]=0;
Chess aaa=array.get(array.getSize()-2);
coloum1=aaa.coloum;
row1=aaa.row;
array.Delete();
cco=!cco;
gm.repaint();
}
}
}
if(flag[1]) { //人机对战悔棋
if(fff) {
if(cco) {
if(array.getSize()>2) {
array1[xx][yy]=0;
Chess aaa=array.get(array.getSize()-2);
coloum1=aaa.coloum;
row1=aaa.row;
array.Delete();
array1[coloum1][row1]=0;
Chess bbb=array.get(array.getSize()-2);
xx=bbb.coloum;
yy=bbb.row;
array.Delete();
gm.repaint();
}
}
}
}
}
if (e.getActionCommand().equals("认输")) {
if(ggg) {
if(cco) {
JOptionPane.showMessageDialog(gm, "白棋获胜");
}else {
JOptionPane.showMessageDialog(gm, "黑棋获胜");
}
gm.removeMouseListener(this);
fff=false;
ggg=false;
}
}
if (e.getActionCommand().equals("人人对战")) { //选择人人对战模式 flag[0]为true,flag[1]为false
flag[0]=true;
flag[1]=false;
for(int i=0;i<array1.length;i++) {
Arrays.fill(array1[i], 0);
}
cco=true;
fff=true;
ggg=true;
array.Reset();
gm.repaint();
}
if (e.getActionCommand().equals("人机对战")) { //选择人机对战模式 flag[0]为false,flag[1]为true
flag[0]=false;
flag[1]=true;
for(int i=0;i<array1.length;i++) {
Arrays.fill(array1[i], 0);
}
cco=true;
fff=true;
ggg=true;
array.Reset();
gm.repaint();
}
}
public void mouseReleased(MouseEvent e) { //鼠标松开的时候进行的操作
if(flag[0]) { //选择人人对战模式进行的操作
if (g == null)
g = gm.getGraphics();
int x = e.getX();
int y = e.getY();
coloum1 = (x-X+size/2)/size;
row1 = (y-Y+size/2)/size;
if(coloum1<coloum&&row1<row) {
if(array1[coloum1][row1]==0) {
if(cco) {
g.setColor(Color.BLACK);
g.fillOval(X+coloum1*size-size/2, Y+row1*size-size/2, size, size);
array1[coloum1][row1]=1;
Chess sh=new Chess(coloum1,row1,Color.BLACK);
array.add(sh);
}
else {
g.setColor(Color.WHITE);
g.fillOval(X+coloum1*size-size/2, Y+row1*size-size/2, size, size);
array1[coloum1][row1]=-1;
Chess sh=new Chess(coloum1,row1,Color.WHITE);
array.add(sh);
}
Judge jd=new Judge(coloum1,row1);
if(jd.judge()) {
if(cco) {
JOptionPane.showMessageDialog(gm, "黑棋获胜");
}else {
JOptionPane.showMessageDialog(gm, "白棋获胜");
}
gm.removeMouseListener(this);
fff=false;
ggg=false;
}
cco=!cco;
}
}
}
if(flag[1]) { //选择人机对战进行的操作
if (g == null)
g = gm.getGraphics();
if(cco) { //若coo为true,则人下棋
int x = e.getX();
int y = e.getY();
coloum1 = (x-X+size/2)/size;
row1 = (y-Y+size/2)/size;
if(coloum1<coloum&&row1<row) {
if(array1[coloum1][row1]==0) {
g.setColor(Color.BLACK);
g.fillOval(X+coloum1*size-size/2, Y+row1*size-size/2, size, size);
array1[coloum1][row1]=1;
Chess sh=new Chess(coloum1,row1,Color.BLACK);
array.add(sh);
Judge jd=new Judge(coloum1,row1);
if(jd.judge()) {
if(cco) {
JOptionPane.showMessageDialog(gm, "黑棋获胜");
}else {
JOptionPane.showMessageDialog(gm, "白棋获胜");
}
gm.removeMouseListener(this);
fff=false;
ggg=false;
cco=!cco;
}
cco=!cco;
}
}
}
if(!cco) { //若coo为false,则机器下棋
AIX();
}
}
}
public void AIX() {
for(int i=0;i<weightArray.length;i++) {
for(int j=0;j<weightArray[i].length;j++) {
weightArray[i][j]=0;
}
}
max=-1;
AI.Quan();
for(int i=0;i<weightArray.length;i++) {
for(int j=0;j<weightArray[i].length;j++) {
if(i<5&&j<5) {
if(max<=weightArray[i][j]&&array1[i][j]==0) {
max=weightArray[i][j];
xx=i;yy=j;
}
}else {
if(max<weightArray[i][j]&&array1[i][j]==0) {
max=weightArray[i][j];
xx=i;yy=j;
}
}
}
}
if(array1[xx][yy]==0) {
g.setColor(Color.WHITE);
g.fillOval(X+xx*size-size/2, Y+yy*size-size/2, size, size);
array1[xx][yy]=-1;
Chess sh=new Chess(xx,yy,Color.WHITE);
array.add(sh);
Judge jd=new Judge(xx,yy);
if(jd.judge()) {
if(cco) {
JOptionPane.showMessageDialog(gm, "黑棋获胜");
}else {
JOptionPane.showMessageDialog(gm, "白棋获胜");
}
gm.removeMouseListener(this); //移除监听,这时将不能对棋盘进行操作
fff=false; //设置不能进行悔棋
ggg=false; //设置不能进行认输
}
cco=!cco;
}
}
}
Chess类
package wuziqi;
import java.awt.Color;
public class Chess extends Object implements Gobang{
int coloum,row;
Color color;
public Chess(int coloum,int row,Color color) {
this.coloum=coloum;
this.row=row;
this.color=color;
}
}
MyArrayList类
package wuziqi;
public class MyArrayList<E> {
public Object[] array;
private int size=0;
public MyArrayList() {
array =new MyArrayList[0];
}
public void add(E e) {
Object[] a =new Object[array.length+1];
for(int i=0;i<array.length;i++) {
a[i]=array[i];
}
a[array.length]=e;
array=a;
size++;
}
@SuppressWarnings("unchecked")
public E remove(int index) {
if(index<=0||index>size) return null;
Object[] a=new Object[array.length-1];
for(int i=0;i<index;i++) {
a[i]=array[i];
}
Object e=array[index];
for(int i=index;i<a.length;i++) {
a[i]=array[i+1];
}
array=a;
return (E)e;
}
public void Delete() {
Object[] a=new Object[array.length-1];
for(int i=0;i<array.length-1;i++) {
a[i]=array[i];
}
array=a;
size--;
}
public int getSize() {
return size;
}
public void setA(int i) {
array[i]=null;
}
@SuppressWarnings("unchecked")
public E get(int index) {
Object e=array[index];
return (E)e;
}
public void Reset() {
Object[] a =new Object[0];
size=0;
array =a;
}
}
判断输赢Judge类
package wuziqi;
public class Judge implements Gobang {
private int x, y;
private int count;
public Judge(int x, int y) {
this.x = x;
this.y = y;
}
boolean judge() {
if (judge1(x, y) >= 5)
return true;
return false;
}
public int judge1(int x1, int y2) {
// 横向检查
count = 1;
for (int i = x1 + 1; i < coloum; i++) {
if (array1[x1][y2] != 0) {
if (array1[x1][y2] == array1[i][y2]) {
count++;
} else
break;
} else
break;
}
for (int i = x1 - 1; i >= 0; i--) {
if (array1[x1][y2] != 0) {
if (array1[x1][y2] == array1[i][y2]) {
count++;
} else
break;
} else
break;
}
if (count >= 5)
return count;
// 纵向检查
count = 1;
for (int i = y2 + 1; i < row; i++) {
if (array1[x1][y2] != 0) {
if (array1[x1][y2] == array1[x1][i]) {
count++;
} else
break;
} else
break;
}
for (int i = y2 - 1; i >= 0; i--) {
if (array1[x1][y2] != 0) {
if (array1[x1][y2] == array1[x1][i]) {
count++;
} else
break;
} else
break;
}
if (count >= 5)
return count;
// 斜向检查
count = 1;
// 左上到右下
for (int i = x1 + 1, j = y2 + 1; i < coloum && j < row; i++, j++) {
if (array1[x1][y2] != 0) {
if (array1[x1][y2] == array1[i][j]) {
count++;
} else
break;
} else
break;
}
// 右下到左上
for (int i = x1 - 1, j = y2 - 1; i >= 0 && j >= 0; i--, j--) {
if (array1[x1][y2] != 0) {
if (array1[x1][y2] == array1[i][j]) {
count++;
} else
break;
} else
break;
}
if (count >= 5)
return count;
count = 1;
// 左下到右上
for (int i = x1 + 1, j = y2 - 1; i < coloum && j >= 0; i++, j--) {
if (array1[x1][y2] != 0) {
if (array1[x1][y2] == array1[i][j]) {
count++;
} else
break;
} else
break;
}
// 右上到左下
for (int i = x1 - 1, j = y2 + 1; i >= 0 && j < row; i--, j++) {
if (array1[x1][y2] != 0) {
if (array1[x1][y2] == array1[i][j]) {
count++;
} else
break;
} else
break;
}
return count;
}
}
用权值实现的AI算法
package wuziqi;
import java.util.HashMap;
public class AI implements Gobang {
static HashMap<String, Integer> map = new HashMap<String, Integer>();
static {
/**
* 权值
*/
// 防守权值
// 活1连
map.put("010", 20);
map.put("0-10", 10);
// 眠1连
map.put("-110", 1);
map.put("1-10", 1);
// 活2连
map.put("0110", 200);
map.put("0-1-10", 100);
// 眠2连
map.put("-1110", 20);
map.put("1-1-10", 10);
// 活3连
map.put("01110", 7000);
map.put("0-1-1-10", 5000);
// 眠3连
map.put("-11110", 50);
map.put("1-1-1-10", 30);
// 活4连
map.put("011110", 10000);
map.put("0-1-1-1-10", 10000);
// 眠4连
map.put("-111110", 10000);
map.put("1-1-1-1-10", 10000);
// 碰壁眠4连
map.put("11110", 10000);
map.put("-1-1-1-10", 10000);
// //进攻权值
// //活1连
// map.put("010",10);
// map.put("0-10",20);
// //眠1连
// map.put("-110",1);
// map.put("1-10",1);
// //活2连
// map.put("0110", 100);
// map.put("0-1-10",200);
// //眠2连
// map.put("-1110",10);
// map.put("1-1-10",20);
// //活3连
// map.put("01110", 5000);
// map.put("0-1-1-10",7000);
// //眠3连
// map.put("-11110",30);
// map.put("1-1-1-10",50);
// //活4连
// map.put("011110", 10000);
// map.put("0-1-1-1-10",10000);
// //眠4连
// map.put("-111110",10000);
// map.put("1-1-1-1-10",10000);
// //碰壁眠4连
// map.put("11110", 10000);
// map.put("-1-1-1-10", 15000);
}
static String code;
static Integer weight;
public static void Quan() {
for (int r = 0; r < array1.length; r++) {
for (int c = 0; c < array1[r].length; c++) {
if (array1[r][c] == 0) {// 如果该位置没有棋子则开始统计
code = countHL(r, c);// 调用水平向左统计的方法
weight = map.get(code);// 根据棋子相连情况获取对应的权值
if (weight != null) {// 判断是否有该种棋子相连的情况
weightArray[r][c] += weight;// 累加权值
}
// 把另外七个方向统计完毕后,就完成权值统计
code = countHR(r, c);// 调用水平向左统计的方法
weight = map.get(code);// 根据棋子相连情况获取对应的权值
if (weight != null) {// 判断是否有该种棋子相连的情况
weightArray[r][c] += weight;// 累加权值
}
code = countHT(r, c);// 调用水平向左统计的方法
weight = map.get(code);// 根据棋子相连情况获取对应的权值
if (weight != null) {// 判断是否有该种棋子相连的情况
weightArray[r][c] += weight;// 累加权值
}
code = countHB(r, c);// 调用水平向左统计的方法
weight = map.get(code);// 根据棋子相连情况获取对应的权值
if (weight != null) {// 判断是否有该种棋子相连的情况
weightArray[r][c] += weight;// 累加权值
}
code = countHZXS(r, c);// 调用水平向左统计的方法
weight = map.get(code);// 根据棋子相连情况获取对应的权值
if (weight != null) {// 判断是否有该种棋子相连的情况
weightArray[r][c] += weight;// 累加权值
}
code = countHYXS(r, c);// 调用水平向左统计的方法
weight = map.get(code);// 根据棋子相连情况获取对应的权值
if (weight != null) {// 判断是否有该种棋子相连的情况
weightArray[r][c] += weight;// 累加权值
}
code = countHZXX(r, c);// 调用水平向左统计的方法
weight = map.get(code);// 根据棋子相连情况获取对应的权值
if (weight != null) {// 判断是否有该种棋子相连的情况
weightArray[r][c] += weight;// 累加权值
}
code = countHYXX(r, c);// 调用水平向左统计的方法
weight = map.get(code);// 根据棋子相连情况获取对应的权值
if (weight != null) {// 判断是否有该种棋子相连的情况
weightArray[r][c] += weight;// 累加权值
}
// 判断两个2连在一条直线但中间有一个空位的情况
if ((countHL(r, c) + countHR(r, c) == "01100110")
|| (countHL(r, c) + countHR(r, c) == "0-1-100-1-10")
|| (countHL(r, c) + countHR(r, c) == "-11100110")
|| (countHL(r, c) + countHR(r, c) == "1-1-100-1-10")
|| (countHL(r, c) + countHR(r, c) == "0110-1110")
|| (countHL(r, c) + countHR(r, c) == "0-1-101-1-10")
|| (countHL(r, c) + countHR(r, c) == "-1110-1110")
|| (countHL(r, c) + countHR(r, c) == "1-1-101-1-10")) {
weightArray[r][c] = weightArray[r][c] + 5000;
}
if ((countHT(r, c) + countHB(r, c) == "01100110")
|| (countHT(r, c) + countHB(r, c) == "0-1-100-1-10")
|| (countHT(r, c) + countHB(r, c) == "-11100110")
|| (countHT(r, c) + countHB(r, c) == "1-1-100-1-10")
|| (countHT(r, c) + countHB(r, c) == "0110-1110")
|| (countHT(r, c) + countHB(r, c) == "0-1-101-1-10")
|| (countHT(r, c) + countHB(r, c) == "-1110-1110")
|| (countHT(r, c) + countHB(r, c) == "1-1-101-1-10")) {
weightArray[r][c] = weightArray[r][c] + 5000;
}
if ((countHZXS(r, c) + countHYXX(r, c) == "01100110")
|| (countHZXS(r, c) + countHYXX(r, c) == "0-1-100-1-10")
|| (countHZXS(r, c) + countHYXX(r, c) == "-11100110")
|| (countHZXS(r, c) + countHYXX(r, c) == "1-1-100-1-10")
|| (countHZXS(r, c) + countHYXX(r, c) == "0110-1110")
|| (countHZXS(r, c) + countHYXX(r, c) == "0-1-101-1-10")
|| (countHZXS(r, c) + countHYXX(r, c) == "-1110-1110")
|| (countHZXS(r, c) + countHYXX(r, c) == "1-1-101-1-10")) {
weightArray[r][c] = weightArray[r][c] + 5000;
}
if ((countHYXS(r, c) + countHZXX(r, c) == "01100110")
|| (countHYXS(r, c) + countHZXX(r, c) == "0-1-100-1-10")
|| (countHYXS(r, c) + countHZXX(r, c) == "-11100110")
|| (countHYXS(r, c) + countHZXX(r, c) == "1-1-100-1-10")
|| (countHYXS(r, c) + countHZXX(r, c) == "0110-1110")
|| (countHYXS(r, c) + countHZXX(r, c) == "0-1-101-1-10")
|| (countHYXS(r, c) + countHZXX(r, c) == "-1110-1110")
|| (countHYXS(r, c) + countHZXX(r, c) == "1-1-101-1-10")) {
weightArray[r][c] = weightArray[r][c] + 5000;
}
// 判断一个活2连和一个活1连在一条直线上但中间有一个空位的情况
if ((countHL(r, c) + countHR(r, c) == "0100110") || (countHL(r, c) + countHR(r, c) == "0-100-1-10")
|| (countHL(r, c) + countHR(r, c) == "0110010")
|| (countHL(r, c) + countHR(r, c) == "0-1-100-10")) {
weightArray[r][c] = weightArray[r][c] + 3000;
}
if ((countHT(r, c) + countHB(r, c) == "0100110") || (countHT(r, c) + countHB(r, c) == "0-100-1-10")
|| (countHT(r, c) + countHB(r, c) == "0110010")
|| (countHT(r, c) + countHB(r, c) == "0-1-100-10")) {
weightArray[r][c] = weightArray[r][c] + 3000;
}
if ((countHZXS(r, c) + countHYXX(r, c) == "0100110")
|| (countHZXS(r, c) + countHYXX(r, c) == "0-100-1-10")
|| (countHZXS(r, c) + countHYXX(r, c) == "0110010")
|| (countHZXS(r, c) + countHYXX(r, c) == "0-1-100-10")) {
weightArray[r][c] = weightArray[r][c] + 3000;
}
if ((countHYXS(r, c) + countHZXX(r, c) == "0100110")
|| (countHYXS(r, c) + countHZXX(r, c) == "0-100-1-10")
|| (countHYXS(r, c) + countHZXX(r, c) == "0110010")
|| (countHYXS(r, c) + countHZXX(r, c) == "0-1-100-10")) {
weightArray[r][c] = weightArray[r][c] + 3000;
}
// 眠3连的一端被堵了
// "1-1-1-10"&"010" "0-1-1-10"&"010"
if ((countHL(r, c) + countHR(r, c) == "1-1-1-10010")
|| (countHL(r, c) + countHR(r, c) == "0101-1-1-10")
|| (countHL(r, c) + countHR(r, c) == "1-1-1-100")
|| (countHL(r, c) + countHR(r, c) == "01-1-1-10")
|| (countHL(r, c) + countHR(r, c) == "1-1-1-100110")
|| (countHL(r, c) + countHR(r, c) == "01101-1-1-10")) {
weightArray[r][c] = 1;
}
if ((countHT(r, c) + countHB(r, c) == "1-1-1-10010")
|| (countHT(r, c) + countHB(r, c) == "0101-1-1-10")
|| (countHT(r, c) + countHB(r, c) == "1-1-1-100")
|| (countHT(r, c) + countHB(r, c) == "01-1-1-10")
|| (countHT(r, c) + countHB(r, c) == "1-1-1-100110")
|| (countHT(r, c) + countHB(r, c) == "01101-1-1-10")) {
weightArray[r][c] = 1;
;
}
if ((countHZXS(r, c) + countHYXX(r, c) == "1-1-1-10010")
|| (countHZXS(r, c) + countHYXX(r, c) == "0101-1-1-10")
|| (countHZXS(r, c) + countHYXX(r, c) == "1-1-1-100")
|| (countHZXS(r, c) + countHYXX(r, c) == "01-1-1-10")
|| (countHZXS(r, c) + countHYXX(r, c) == "1-1-1-100110")
|| (countHZXS(r, c) + countHYXX(r, c) == "01101-1-1-10")) {
weightArray[r][c] = 1;
}
if ((countHYXS(r, c) + countHZXX(r, c) == "1-1-1-10010")
|| (countHYXS(r, c) + countHZXX(r, c) == "0101-1-1-10")
|| (countHYXS(r, c) + countHZXX(r, c) == "1-1-1-100")
|| (countHYXS(r, c) + countHZXX(r, c) == "01-1-1-10")
|| (countHYXS(r, c) + countHZXX(r, c) == "1-1-1-100110")
|| (countHYXS(r, c) + countHZXX(r, c) == "01101-1-1-10")) {
weightArray[r][c] = 1;
}
// 3连和1连在一条线上差一个棋位
if ((countHL(r, c) + countHR(r, c) == "0-1-1-100-10")
|| (countHL(r, c) + countHR(r, c) == "0-101-1-1-10")
|| (countHL(r, c) + countHR(r, c) == "01110010")
|| (countHL(r, c) + countHR(r, c) == "010-11110")
|| (countHL(r, c) + countHR(r, c) == "0-100-1-1-10")
|| (countHL(r, c) + countHR(r, c) == "1-1-1-100-10")
|| (countHL(r, c) + countHR(r, c) == "01001110")
|| (countHL(r, c) + countHR(r, c) == "-11110010")) {
weightArray[r][c] = weightArray[r][c] + 4000;
}
if ((countHT(r, c) + countHB(r, c) == "0-1-1-100-10")
|| (countHT(r, c) + countHB(r, c) == "0-101-1-1-10")
|| (countHT(r, c) + countHB(r, c) == "01110010")
|| (countHT(r, c) + countHB(r, c) == "010-11110")
|| (countHT(r, c) + countHB(r, c) == "0-100-1-1-10")
|| (countHT(r, c) + countHB(r, c) == "1-1-1-100-10")
|| (countHT(r, c) + countHB(r, c) == "01001110")
|| (countHT(r, c) + countHB(r, c) == "-11110010")) {
weightArray[r][c] = weightArray[r][c] + 4000;
}
if ((countHZXS(r, c) + countHYXX(r, c) == "0-1-1-100-10")
|| (countHZXS(r, c) + countHYXX(r, c) == "0-101-1-1-10")
|| (countHZXS(r, c) + countHYXX(r, c) == "01110010")
|| (countHZXS(r, c) + countHYXX(r, c) == "010-11110")
|| (countHZXS(r, c) + countHYXX(r, c) == "0-100-1-1-10")
|| (countHZXS(r, c) + countHYXX(r, c) == "1-1-1-100-10")
|| (countHZXS(r, c) + countHYXX(r, c) == "01001110")
|| (countHZXS(r, c) + countHYXX(r, c) == "-11110010")) {
weightArray[r][c] = weightArray[r][c] + 4000;
}
if ((countHYXS(r, c) + countHZXX(r, c) == "0-1-1-100-10")
|| (countHYXS(r, c) + countHZXX(r, c) == "0-101-1-1-10")
|| (countHYXS(r, c) + countHZXX(r, c) == "01110010")
|| (countHYXS(r, c) + countHZXX(r, c) == "010-11110")
|| (countHYXS(r, c) + countHZXX(r, c) == "0-100-1-1-10")
|| (countHYXS(r, c) + countHZXX(r, c) == "1-1-1-100-10")
|| (countHYXS(r, c) + countHZXX(r, c) == "01001110")
|| (countHYXS(r, c) + countHZXX(r, c) == "-11110010")) {
weightArray[r][c] = weightArray[r][c] + 4000;
}
}
}
}
}
// 水平向左统计的方法
public static String countHL(int r, int c) {
String code = "0";
int chess = 0;// 存储第一颗出现的棋子
// 循环遍历
for (int r1 = r - 1; r1 >= 0; r1--) {
if (array1[r1][c] == 0) {// 表示空位沒有棋子
if (r1 + 1 == r) {// 相邻
break;
} else {
code = array1[r1][c] + code;// 记录棋子相连情况
break;
}
} else {// 表示该位置有棋子
if (chess == 0) {// 第一次出现棋子
chess = array1[r1][c];// 记录棋子
code = array1[r1][c] + code;// 记录棋子相连情况
} else if (chess == array1[r1][c]) {
code = array1[r1][c] + code;// 记录棋子相连情况
} else {
code = array1[r1][c] + code;// 记录棋子相连情况
break;
}
}
}
return code;
}
// 水平向右统计的方法
public static String countHR(int r, int c) {
String code = "0";
int chess = 0;// 存储第一颗出现的棋子
// 循环遍历
for (int r1 = r + 1; r1 < coloum; r1++) {
if (array1[r1][c] == 0) {// 表示空位沒有棋子
if (r1 - 1 == r) {// 相邻
break;
} else {
code = array1[r1][c] + code;// 记录棋子相连情况
break;
}
} else {// 表示该位置有棋子
if (chess == 0) {// 第一次出现棋子
chess = array1[r1][c];// 记录棋子
code = array1[r1][c] + code;// 记录棋子相连情况
} else if (chess == array1[r1][c]) {
code = array1[r1][c] + code;// 记录棋子相连情况
} else {
code = array1[r1][c] + code;// 记录棋子相连情况
break;
}
}
}
return code;
}
// 竖直向上统计的方法
public static String countHT(int r, int c) {
String code = "0";
int chess = 0;// 存储第一颗出现的棋子
// 循环遍历
for (int c1 = c - 1; c1 >= 0; c1--) {
if (array1[r][c1] == 0) {// 表示空位沒有棋子
if (c1 + 1 == r) {// 相邻
break;
} else {
code = array1[r][c1] + code;// 记录棋子相连情况
break;
}
} else {// 表示该位置有棋子
if (chess == 0) {// 第一次出现棋子
chess = array1[r][c1];// 记录棋子
code = array1[r][c1] + code;// 记录棋子相连情况
} else if (chess == array1[r][c1]) {
code = array1[r][c1] + code;// 记录棋子相连情况
} else {
code = array1[r][c1] + code;// 记录棋子相连情况
break;
}
}
}
return code;
}
// 竖直向下统计的方法
public static String countHB(int r, int c) {
String code = "0";
int chess = 0;// 存储第一颗出现的棋子
// 循环遍历
for (int c1 = c + 1; c1 < row; c1++) {
if (array1[r][c1] == 0) {// 表示空位沒没有棋子
if (c1 - 1 == c) {// 相邻
break;
} else {
code = array1[r][c1] + code;// 记录棋子相连情况
break;
}
} else {// 表示该位置有棋子
if (chess == 0) {// 第一次出现棋子
chess = array1[r][c1];// 记录棋子
code = array1[r][c1] + code;// 记录棋子相连情况
} else if (chess == array1[r][c1]) {
code = array1[r][c1] + code;// 记录棋子相连情况
} else {
code = array1[r][c1] + code;// 记录棋子相连情况
break;
}
}
}
return code;
}
// 左斜向上统计的方法
public static String countHZXS(int r, int c) {
String code = "0";
int chess = 0;// 存储第一颗出现的棋子
// 循环遍历
for (int r1 = r - 1, c1 = c - 1; r1 >= 0 && c1 >= 0; r1--, c1--) {
if (array1[r1][c1] == 0) {// 表示空位沒有棋子
if (c1 + 1 == c && r1 + 1 == r) {// 相邻
break;
} else {
code = array1[r1][c1] + code;// 记录棋子相连情况
break;
}
} else {// 表示该位置有棋子
if (chess == 0) {// 第一次出现棋子
chess = array1[r1][c1];// 记录棋子
code = array1[r1][c1] + code;// 记录棋子相连情况
} else if (chess == array1[r1][c1]) {
code = array1[r1][c1] + code;// 记录棋子相连情况
} else {
code = array1[r1][c1] + code;// 记录棋子相连情况
break;
}
}
}
return code;
}
// 右斜向上统计的方法
public static String countHYXS(int r, int c) {
String code = "0";
int chess = 0;// 存储第一颗出现的棋子
// 循环遍历
for (int r1 = r + 1, c1 = c - 1; c1 >= 0 && r1 < coloum; r1++, c1--) {
if (array1[r1][c1] == 0) {// 表示空位沒有棋子
if (r1 - 1 == r && c1 + 1 == c) {// 相邻
break;
} else {
code = array1[r1][c1] + code;// 记录棋子相连情况
break;
}
} else {// 表示该位置有棋子
if (chess == 0) {// 第一次出现棋子
chess = array1[r1][c1];// 记录棋子
code = array1[r1][c1] + code;// 记录棋子相连情况
} else if (chess == array1[r1][c1]) {
code = array1[r1][c1] + code;// 记录棋子相连情况
} else {
code = array1[r1][c1] + code;// 记录棋子相连情况
break;
}
}
}
return code;
}
// 左斜向下统计的方法
public static String countHZXX(int r, int c) {
String code = "0";
int chess = 0;// 存储第一颗出现的棋子
// 循环遍历
for (int r1 = r - 1, c1 = c + 1; c1 < row && r1 >= 0; c1++, r1--) {
if (array1[r1][c1] == 0) {// 表示空位沒有棋子
if (c1 - 1 == c && r1 + 1 == r) {// 相邻
break;
} else {
code = array1[r1][c1] + code;// 记录棋子相连情况
break;
}
} else {// 表示该位置有棋子
if (chess == 0) {// 第一次出现棋子
chess = array1[r1][c1];// 记录棋子
code = array1[r1][c1] + code;// 记录棋子相连情况
} else if (chess == array1[r1][c1]) {
code = array1[r1][c1] + code;// 记录棋子相连情况
} else {
code = array1[r1][c1] + code;// 记录棋子相连情况
break;
}
}
}
return code;
}
// 右斜向下统计的方法
public static String countHYXX(int r, int c) {
String code = "0";
int chess = 0;// 存储第一颗出现的棋子
// 循环遍历
for (int r1 = r + 1, c1 = c + 1; r1 < coloum && c1 < row; r1++, c1++) {
if (array1[r1][c1] == 0) {// 表示空位沒有棋子
if (c1 - 1 == c && r1 - 1 == r) {// 相邻
break;
} else {
code = array1[r1][c1] + code;// 记录棋子相连情况
break;
}
} else {// 表示该位置有棋子
if (chess == 0) {// 第一次出现棋子
chess = array1[r1][c1];// 记录棋子
code = array1[r1][c1] + code;// 记录棋子相连情况
} else if (chess == array1[r1][c1]) {
code = array1[r1][c1] + code;// 记录棋子相连情况
} else {
code = array1[r1][c1] + code;// 记录棋子相连情况
break;
}
}
}
return code;
}
}
好了,运行之后选择模式,点击开始游戏就可以下棋了!
下一篇: 人人对战五子棋