【Java】实现五子棋悔棋的两种方法:对象数组、数组队列

最近在写五子棋,悔棋部分遇到了点问题,本来想的是落子以后趁此时在鼠标监听器中得到的坐标 x = e.getX(); y = e.getY(); 还没被覆盖,点击悔棋按钮后,再把储存坐标的二维数组中这个坐标的值清零,然后调用重绘方法处理。没错这个确实可以实现,但是就不能多次悔棋。比如我想悔两步,就不能实现了,因为我不知道上上步下在哪个地方。

没错,我还得用某个方法储存每一步的落子位置才行。我就必须知道第几步有哪两个坐标,要有顺序,还要有坐标

对象数组方法

首先就想起可以用以前用过的对象数组。

先建一个 Position 类,有两个坐标属性:

public class Position {
	int listi;
	int listj;
}

在主界面获取一个大于总格子数的对象数组防止溢出:

public class chessUI extends JPanel {
	public Position[] ps = new Position[300];
	int counti;	//计数
}

在落子步骤后,每落一个棋子,将坐标按顺序存入对象数组:

Position p = new Position();	//如果不先创建Position对象会报空指针
ui.ps[ui.counti]=p;
ui.ps[ui.counti].listi = xp;
ui.ps[ui.counti].listj = yp;
ui.counti++;	//每存一次计数+1

这样每一步的坐标都按顺序存入这个对象数组了,悔棋的时候只要把最后存入的那个数组坐标取出,然后在存坐标的二维数组中将该坐标位置清零,调用重绘方法就行了。

if(counti>0){		//判断是否有棋子
	int x = ui.ps[ui.counti-1].listi;//取出前一步的x
	int y = ui.ps[ui.counti-1].listj;//取出前一步的y
	ui.point[x][y]=0;	//让二维数组这个坐标清零
	ui.counti--;		//计数-1
	if (turn==1){turn++;}	//回到上一轮
	else {turn--;}
	ui.repaint();		//重绘
}
else{
	JOptionPane.showMessageDialog(null, "不能悔棋!");
}

总体上看和我之前写的画图板通过存入取出对象数组中的数据,实现图形大小调节重绘的方法差不多。

数组队列方法

其实我刚开始就用的数组队列的方法写的,因为前两天刚刚接触这个东西,用到这里也刚刚好。

数组队列(ArrayList)类也是用来储存对象, 与数组不同,数组一旦创建,长度固定,但是数组队列的长度是动态的,不受限制,可以存储任意多的对象,但是只能存储对象,不能存储原生数据类型例如int

因为数组队列存入多少个数据长度就是多少,所以就不用专门弄个计数器。直接用list.size();方法就能得到长度了。

建一个 ChessPosition 类,里面有两个坐标属性(这里用的构造器传入坐标,用其他方法也行):

public class ChessPosition {
	public int Listi,Listj;
	public ChessPosition() {
	}
	public ChessPosition(int Listi,int Listj) {
		this.Listi=Listi;
		this.Listj=Listj;
	}
}

在主界面获取一个 ArrayList 类的对象 ChessPositonList:

public class chessUI extends JPanel {
	public ArrayList<ChessPosition> ChessPositonList=new ArrayList<ChessPosition>();
}

是泛型,表示这个数组队列只能存储 ChessPosition 类的对象。

在落子步骤后,每落一个棋子,将棋子坐标存入 ChessPosition 类然后用list.add();方法存入数组队列:

ui.ChessPositonList.add(new ChessPosition(xp,yp));

悔棋的时候,通过 list.remove();方法,取出前一步的对象的同时将它从数组队列里移除。然后在存坐标的二维数组中将该坐标位置清零,调用重绘方法就行了。

这里如果用list.get();方法,那么只将它取出来却没有移除,再次悔棋就不起作用了。

if (ui.ChessPositonList.size() >0){		//判断是否有棋子
    //取出前一步的 ChessPositon
	ChessPosition cp = new ChessPosition();
	cp = ui.ChessPositonList.remove(ui.ChessPositonList.size()-1);
    //让二维数组这个坐标清零
	ui.point[cp.Listi][cp.Listj]=0;
	if (turn==1){turn++;} 	//回到上一轮
	else {turn--;}
	ui.repaint();			//重绘
}
else{
	JOptionPane.showMessageDialog(null, "不能悔棋!");
}

我觉得这种时候用 ArrayList 比较好吧,因为落子数量不一定,数组队列可以动态变化长度,增删都比较方便。

刚开始写这篇博客是想通过悔棋操作来归纳总结 ArrayList 用法的,结果自己试着又把通过对象数组悔棋写出来了(虽然觉得可以,但是开始写这篇博客的时候没想过要真的来实现的)。

那就干脆把这篇写成了两种方法的对比和实现了(捂脸

你可能感兴趣的:(学/想/做,Java,五子棋,数组,队列,游戏)