简单五子棋的实现

简单五子棋开发

这次要做的项目是一个简单的五子棋项目,模仿QQ版的五子棋进行制作,整体分为几大功能的实现:开始游戏、悔棋、认输、人人大战、人机大战等模式,当任意一方的棋子达到连续的五颗棋子时,就需要判断输赢,并向用户告知比赛结果。过程中要用到的API类有:JFrame,BorderLayout,JPanel,Dimension,FlowLayout,JButton,JRadioButton,ButtonGroup,JCheckBox,ActionListener,ActionEvent,MouseListener| MouseAdapter,MouseEvent,Graphics | Graphics2D,Color等。
具体的操作如下:

一、 五子棋棋盘界面的开发

首先需要要做一个像画图板一样的界面,以便存放棋盘和功能功能板块,定义一个ChessMain类来继承JFrame,重写其中的抽象方法paint(Graphics g),来绘制棋盘和棋子,

public class ChessMain extends JPanel implements Data{

	public static void main(String [] args) {
		ChessMain chess = new ChessMain();
		chess.initUI();	
	}
	
	public void initUI() {
		JFrame frame = new JFrame("五子棋");
		frame.setSize(720,630);
		frame.setDefaultCloseOperation(3);
		frame.setLocationRelativeTo(null);
		frame.setResizable(false);
		this.setPreferredSize(new Dimension(500,600));
		this.setBackground(Color.GRAY);
		frame.add(this, BorderLayout.CENTER);
		frame.setVisible(true);
	}
	public void paint (Graphics g) {
		super.paint(g);
		drawChessBorder(g);
	}

	public void drawChessBorder(Graphics g) {
		for (int i = 0;i < Row; i++)	//画棋盘的横线
			g.drawLine( X, Y + i * SIZE, X + (Colum -1) * SIZE, Y + i * SIZE );
		for (int i =0;i < Colum;i++)	//画棋盘的竖线
			g.drawLine(X + SIZE * i, Y, X + SIZE * i, Y + SIZE * (Row - 1));
	}
}

如果在画横竖线时,直接输入长宽和线的数目,在后期想要修改格子大小时会很不方便,为了增强代码的灵活性,则要另外定义一个接口Data,把需要用到的数值定义为常量,在调用时直接调用常量就ok了,这样在修改棋盘或妻子大小时就会方便很多,ps.顺便别忘了让ChessMain类实现Data接口:

public interface Data {
	public static final int X = 50;	//左边框宽度
	public static final int Y = 50;	//上边框宽度
	public static final int SIZE = 35;		//格子的大小
	public static final int Chess_SIZE = 35;	//棋子的大小
	public static final int Row = 15;	//横线的数目
	public static final int Colum = 15;	//竖线的数目
	public static final int [][] arrays = new int [Row][Colum];	//数组用来存放下过棋子的位置信息
}

在这里插入图片描述
二、 棋盘上绘制棋子

当鼠标在棋盘上点击以下时,需要在棋盘相应的位置画上一颗棋子,这个功能的实现就需要用到鼠标事件监听机制,用来监听鼠标上的动作信息。由于MouseListener中的抽象方法没有全部用到,所以不必把所有方法全部重写,为了简洁,让ChessListener鼠标事件监听方法继承MouseAdapter监听类,就只需要重写用到的方法,而不用一股脑儿都重写出来。

public class ChessListener extends MouseAdapter implements Data , ActionListener {

	private ChessMain chessmain;
	public  Graphics g;
	
	public  ChessListener(Graphics g) {
	this.g = g;
	}

	public void mouseClicked(MouseEvent e) {
		g = chessmain.getGraphics();
		int x = e.getX();
		int y = e.getY();
		//必须确保鼠标点击的点在棋盘范围内才会下棋,如果点击在了棋盘外,就不会画出棋子
		if (x >= X && y >= Y && x <= X + (Colum -1) * SIZE && y <= Y + (Row -1) * SIZE) {
			int  r = (y - Y + SIZE / 2) / SIZE;
			int  c = (x - X + SIZE / 2) / SIZE;
			x = c * SIZE + X - Chess_SIZE /2;
			y = r * SIZE + Y - Chess_SIZE /2;
			g.fillOval(x, y, Chess_SIZE, Chess_SIZE);
		}
	}
}

在下棋时,不仅要判断棋子的颜色,还要在下过一个颜色的棋子后,自动跳转到领完一种颜色的棋子上再画,因此需要定义一个Boolean类型的标志物flag来记录是黑子还是白子,给他默认定为true表示黑子。

现在还有一个问题就是,在已经下过棋子的位置继续下棋,后下的颜色会覆盖掉之前的棋子颜色,这个显然不符合现实情况,所以要再定义一个二维数组,用来记录棋盘上可以下棋的位置,初始化数组的值为0,如果落子为黑色,则将值改为1,如果落子为白色,则将值改为2,这样在下棋前,只需要判断一下该位置的数组值是否为0即可知道这个位置能不能下棋了。

三、 判断五子棋输赢

现在已经能正确下棋子了,接下来要做的就是如何判断输赢,大体分为四个方向:可以水平方向、竖直方向、左上右下、左下右上,重新定义一个ChessWin类,里面沿着每个方向进行移动,依次判断相同颜色的棋子是否连续,如果连续,则返回连续棋子的个数,连续个数小于5时返回false,否则返回true,用于输出下棋胜利的结果。

public class ChessWin implements Data {

	public static boolean victory(int r, int c) {
		if (countH(r,c) >= 5 || countV(r,c) >= 5 || countX1(r,c) >= 5 || countX2(r,c) >=5) 
			return true ;
		else 
			return false;
	}

	//检查水平方向上的连续棋子个数
	public  static int  countH(int r,int c) {
		int num = 1;
		//往左
		for (int c1 = c-1 ;c1 > 0;c1--) {
			if (arrays[r][c] == arrays[r][c1])
				num++;
			else 
				break;
		}

		//往右
		for (int c1 = c+1;c1 < arrays[r].length;c1++) {
			if (arrays[r][c] == arrays[r][c1])
				num++;
			else 
				break;
		}
		return num;
	}	//其余三个方向上的代码在这里就省略不重复给出了
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值