大家都应该知道五子棋吧,当自己和电脑打的时候有没有对电脑怎么下棋有过疑惑?为什么有时候连电脑都打不过呢,哈哈,那么这次我就来说一下自己制作五子棋这个小游戏的心得和领会吧。
首先先说一下简单的一些方面,要下五子棋,首先我们要把棋盘做出来对不对,那么大家都知道五子棋的棋盘是15*15的方格,那么有点java基础的就可以画出这个棋盘了是吧。不急,待会儿我们还要给出代码。另外说一下,我们在做一个东西的时候要先想好条件是什么,更具体的说就是那些条件是固定的。这样想的越多对我们的帮助就越大。因为我们做一个项目的时候,要写很多类的,类和类之间又有很多关系,如果知道了一些条件是固定的话,那么我们可以让所有的类继承这个接口,那么岂不是方便了很多,我们想想五子棋哪些条件是固定的,首先我们要存棋子,那么要有一个15*15的数组来存放吧,接下来我们要画棋子,那么棋子的大小也应该是固定的,对于画棋盘来说,边界的间距也是固定的等等,首先我们写出了一个接口,那么接下来我们在写类的时候就可以让类去继承这个接口,先贴出代码:
package GoBang;
public interface GoBangInterface
{
//棋子的大小
public static final int Size = 44;
public static final int X = 25;
public static final int Y = 25;
public static final int Row = 15;
public static final int Coloum = 15;
//存旗子的数组
public static final int[][] array = new int[Row][Coloum];
}
那么接下来我们可以画棋盘了,先贴出代码:
package GoBang;
import java.awt.*;
import javax.swing.*;
public class GoBangPanel extends JPanel implements GoBangInterface{
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GoBangPanel chesspanel = new GoBangPanel();
chesspanel.gobang();
}
public void gobang()
{
//设置版面
JFrame frame = new JFrame();
frame.setTitle("五子棋");
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(3);
frame.setSize(850,700);
//设置布局
frame.setLayout(new BorderLayout());
frame.add(this,BorderLayout.CENTER);
//在jpanel组件上画棋子
JPanel panel1 = new JPanel();
panel1.setBackground(Color.DARK_GRAY);
panel1.setPreferredSize(new Dimension(150,0));
frame.add(panel1,BorderLayout.EAST);
frame.setVisible(true);
GoBangListener listener = new GoBangListener(this);
this.addMouseListener(listener);
}
public void paint(Graphics g)
{
super.paint(g);
Graphics2D gg = (Graphics2D) g;
//画出整个棋盘
for(int i = 0; i < Row; i++)//行
{
gg.drawLine(X, Y+i*Size, X+Size*(Coloum-1), Y+i*Size);
}
for(int i = 0; i < Coloum; i++)//列
{
gg.drawLine(X+i*Size, Y, X+i*Size, Y+Size*(Row-1));
}
//画出棋子
for(int i = 0; i < array.length; i++)
for(int j = 0; j < array[i].length; j++)
{
if(array[i][j] != 0)
{
if(array[i][j]%2 != 0)
{
gg.setColor(Color.black);
}else
{
gg.setColor(Color.white);
}
int x = Y+j*Size-Size/2;
int y = X+i*Size-Size/2;
gg.fillOval(x, y, Size, Size);
}
}
}
}
在这里说明两点,第一个为什么布局用了BorderLayout,因为这个包括了东西南北四个方向,因为五子棋肯定有悔棋,开始等等这些按钮组件,所以,我们要去把这些按钮组件和整个棋盘分开,所以我用了jpanel这个组件单独画的棋盘。那么再说一下,我为什么对paint这个重绘方法做了修改,这是因为如果不在paint里面把棋盘画好的话,那么运行的开始你是看不到棋盘的,再就是如果你最小化窗口再打开的话,棋盘也是会不见的,所以就决定了在paint方法里面画出这个棋盘,并且里面还有一部分就是画棋子,因为如果棋盘上有了棋子,那么在画棋盘的时候当然要把棋子也画上,总不能重新下吧,哈哈。
那么这样我们接下来就要对jpanel组件添加监听方法了,因为我们要下棋呀,并且棋子不能乱下,要下在直线和直线的焦点上,但是我们每次点击并不能那么的准确,所以我们就需要动动脑筋来确定把棋子下在哪个焦点上。那么我们就要实现这个GoBangListener了,贴出代码:
package GoBang;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class GoBangListener extends MouseAdapter implements GoBangInterface
{
private Judge j;
private GoBangPanel panel;
private Graphics2D g;
private GoBangAn an;
private int x,y;
private int num = 1;
public GoBangListener(GoBangPanel panel)
{
this.panel = panel;
g = (Graphics2D)this.panel.getGraphics();
an = new GoBangAn(this.panel);
}
public void mouseReleased(MouseEvent e)
{
//取得坐标
x = e.getX();
y = e.getY();
//计算行列
int row = (y-Y+Size/2)/Size;
int coloum = (x-X+Size/2)/Size;
if(row < Row && coloum < Coloum)
{
if(array[coloum][row] == 0)
{
//确定在数组的位置
x = X+coloum*Size-Size/2;
y = Y+row*Size-Size/2;
// if(num%2 != 0 )
// {
g.setColor(Color.black);
// }else
// {
// g.setColor(Color.white);
// }
array[row][coloum] = num;
g.fillOval(x, y, Size, Size);
j = new Judge(row,coloum);
j.judge();
an.update(row,coloum);
num++;
an.anticipate(num);
num++;
}
}
}
}
这里还用到了其他类的一些方法,不过没关系,这些可以先不看,这里主要注意一下怎么确定棋子的位置,仔细想一下也是很简单的,但是提醒一下,电脑的0坐标是在左上角,以它为中心,x轴水平方向,远离0坐标的方向为正方向,y轴竖直方向,远离0坐标的方向为正方向。而且我们用数组来盛放棋子,数组的第一维是行也就是屏幕的y,第二位是列也就是屏幕的x,对于怎么计算棋子的位置根据棋盘的边界就可以确定了,很简单,看看代码就知道啦。
接下来我们说一下j是什么,这是一个类对象,那么,这个类是专门判断是不是游戏结束的,也就是有没有5个相同的棋子连在一块,这个怎么判断呢,很简单,暴力判断就可以,遍历整个数组,从四个大方向来判断就好了,分别是横竖,和两个斜着的方向,贴出代码:
package GoBang;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Judge implements GoBangInterface{
private JFrame frame;
private int x,y;
private int count;
public Judge(int x,int y)
{
this.x = x;
this.y = y;
count = 1;
frame = new JFrame();
frame.setTitle("结果");
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(3);
frame.setSize(450,300);
}
public void judge()
{
// System.out.println(array[x][y]);
count = 1;
//竖向检查
for(int i = x+1; i < Coloum; i++)
{
if(array[i][y] != 0 )
{
if((array[x][y]%2) == (array[i][y]%2))
{
count++;
}else break;
}else break;
}
for(int i = x-1; i >= 0; i--)
{
if(array[i][y] != 0 )
{
if((array[x][y]%2) == (array[i][y]%2))
count++;
else break;
}else break;
}
if(count>=5)
{
if(array[x][y]%2 != 0)
{
JLabel label = new JLabel("黑棋胜!!!!!");
label.setPreferredSize(new Dimension(400,250));
label.setFont(new Font("楷体",1,50));
frame.add(label);
frame.setVisible(true);
}else
{
JLabel label = new JLabel("白棋胜!!!!!");
label.setPreferredSize(new Dimension(400,250));
label.setFont(new Font("楷体",1,50));
frame.add(label);
frame.setVisible(true);
}
return ;
}
count = 1;
//横向检查
for(int i = y+1; i < Row; i++)
{
if(array[x][i] != 0 )
{
if((array[x][y]%2) == (array[x][i])%2)
count++;
else break;
}else break;
}
for(int i = y-1; i >= 0; i--)
{
if(array[x][i] != 0 )
{
if(array[x][y]%2 == array[x][i]%2)
count++;
else break;
}else break;
}
if(count>=5)
{
if(array[x][y]%2 != 0)
{
JLabel label = new JLabel("黑棋胜!!!!!");
label.setPreferredSize(new Dimension(400,250));
label.setFont(new Font("楷体",1,50));
frame.add(label);
frame.setVisible(true);
}else
{
JLabel label = new JLabel("白棋胜!!!!!");
label.setPreferredSize(new Dimension(400,250));
label.setFont(new Font("楷体",1,50));
frame.add(label);
frame.setVisible(true);
}
return ;
}
count = 1;
//斜向检查(从左上角到右下角)
for(int i = x-1,j = y-1;i>=0&&j>=0; i--,j--)
{
if(array[i][j] != 0 )
{
if((array[x][y]%2) == (array[i][j]%2))
count++;
else break;
}else break;
}
for(int i = x+1,j = y+1;i<Coloum&&j<Row; i++,j++)
{
if(array[i][j] != 0 )
{
if((array[x][y]%2) == (array[i][j]%2))
count++;
else break;
}else break;
}
if(count>=5)
{
if(array[x][y]%2 != 0)
{
JLabel label = new JLabel("黑棋胜!!!!!");
label.setPreferredSize(new Dimension(400,250));
label.setFont(new Font("楷体",1,50));
frame.add(label);
frame.setVisible(true);
}else
{
JLabel label = new JLabel("白棋胜!!!!!");
label.setPreferredSize(new Dimension(400,250));
label.setFont(new Font("楷体",1,50));
frame.add(label);
frame.setVisible(true);
}
return ;
}
count = 1;
//斜向检查(从左下角到右上角)
for(int i = x-1,j = y+1;i>=0&&j<Row; i--,j++)
{
if(array[i][j] != 0 )
{
if((array[x][y]%2) == (array[i][j]%2))
count++;
else break;
}else break;
}
for(int i = x+1,j = y-1;i<Coloum&&j>=0; i++,j--)
{
if(array[i][j] != 0 )
{
if((array[x][y]%2) == (array[i][j]%2))
count++;
else break;
}else break;
}
if(count>=5)
{
if(array[x][y]%2 != 0)
{
JLabel label = new JLabel("黑棋胜!!!!!");
label.setPreferredSize(new Dimension(400,250));
label.setFont(new Font("楷体",1,50));
frame.add(label);
frame.setVisible(true);
}else
{
JLabel label = new JLabel("白棋胜!!!!!");
label.setPreferredSize(new Dimension(400,250));
label.setFont(new Font("楷体",1,50));
frame.add(label);
frame.setVisible(true);
}
return ;
}
}
}
思路很简单,但是写起来还是比较麻烦的,那么到现在你已经可以下棋了,并且可以判断输赢,可以两个人玩一下,但是我们要实现人机大战,那怎么让电脑和你下棋呢?下篇文章我接着说,毕竟太长了,还是很两次比较好哈哈。