`
甘艳丽
  • 浏览: 50887 次
  • 性别: Icon_minigender_2
  • 来自: 湖南
社区版块
存档分类
最新评论

五子棋(人机大战)

阅读更多

我们都知道,理论需要联系实践,实践是检验真理的唯一标准。学习知识何尝不是这样?老师讲的再好,如果自己不亲身去做,那知识永远是属于老师的。在学习中,我们常常有这种感觉:老师上课我们全部能够听懂,但当老师要我们做练习时,才发现很多知识我们并没有掌握,以前有人曾问我:你的专业到底是学什么?顿时哑口无言,因为我也不知道学了什么?我们并没有把我们学过的知识运用到具体实践中去,平时也很少做编程方面的练习。总之,一句话,在学习过程中,我们应尽可能多的实践,理论学得再好,那也只是空谈。我们应该在实践中找到自己有哪些知识还没掌握,及时补救,这样我们才能在专业领域中越走越好。好了,言归正传吧,讲一下我的五子棋设计思想吧。

1.首先我们应该想下,我们下五子棋,需要棋盘,需要棋子,那棋盘到底是什么?要得到棋盘,就必须要有窗体界面(这都是老生常谈的),所以呢我们首先要得到窗体界面

public void	showIU(){
		this.setTitle("五子棋");//给窗体命名
		//设置窗体的大小
		this.setSize(2*Config.XO+Config.CELL_SIZE*Config.CELL_X,2*Config.YO+Config.CELL_SIZE*Config.CELL_Y);
		//关闭窗体
		this.setDefaultCloseOperation(3);
		this.setVisible(true);//窗体可见
		Graphics graphics=this.getGraphics();//得到画布对象

 这样我们就得到了简单的界面,接下来就应该画棋盘了,但什么是棋盘?棋盘其实就是一个个方格子,是由横竖线构成的,画棋盘就等于画横竖线。(这个简单吧)

 public void drawChessTable(Graphics g){//绘制棋盘
    	for(int i=0;i<=Config.CELL_X;i++){//横向画直线
    		g.drawLine(Config.XO, Config.YO+Config.CELL_SIZE*i, Config.XO+Config.CELL_SIZE*Config.CELL_X,Config.YO+Config.CELL_SIZE*i);}
    		for(int j=0;j<=Config.CELL_Y;j++){
    			g.drawLine(Config.XO+Config.CELL_SIZE*j, Config.YO, Config.CELL_SIZE*j+Config.XO, Config.CELL_SIZE*Config.CELL_Y+Config.YO);
    		}
    }

 为了以后方便修改棋盘的大小,我另外写了个Config类,定义了一些属性的值

public class Config {
	public static final int XO=50;//棋盘的起始x坐标
	public static final int YO=50;//棋盘的起始y坐标
	public static final int CELL_X=10;//棋盘横向的格子数
	public static final int CELL_Y=10;//棋盘纵向的格子数
	public static final int CELL_SIZE=50;//棋盘格子的大小
	public static final int CHESS_SIZE=40;//棋子的大小

}

 这样写可以为了以后修改方便,只需改Config类中属性的值。现在运行时,可以得到棋盘了,那接下来就要放棋子了,要放旗子,就是要发生鼠标事件,所以我们应该给窗体界面添加鼠标监听器,然后我们就要另写一个类来实现鼠标事件,下过五子棋的人都知道,棋子是放在棋盘的交叉位置的,有时候我们为了方便,通常是点击距交叉点的1/3处,就认为点击有效。

 

public void mouseReleased(MouseEvent e) {
		int x = e.getX();// 得到鼠标的x位置
		int y = e.getY();// 得到鼠标的y位置
		suFa an=new suFa(a);
		for (int i = 0; i < a.length; i++) {// 取出交叉点的位置
			for (int j = 0; j < a[i].length; j++) {
				int x2 = Config.CELL_SIZE * j + Config.XO;
				int y2 = Config.CELL_SIZE * i + Config.YO;
				// 判断点击的点是否在指定的位置上
				if (Math.abs(x - x2) < Config.CELL_SIZE / 3
						&& Math.abs(y - y2) < Config.CELL_SIZE / 3) {
					if (a[i][j] == 0) {
						if (isBlack) {
							g.setColor(Color.BLACK);
							a[i][j] = 1;
						} else {
							g.setColor(Color.RED);
							a[i][j] = -1;
						}

						g.fillOval(x2 - Config.CELL_SIZE / 2, y2
								- Config.CELL_SIZE / 2, Config.CHESS_SIZE,
								Config.CHESS_SIZE);
						isBlack = !isBlack;}
}
}
}
}

 

 这里用到了a数组,a数组就相当于一个棋盘,a数组中的元素就相当于棋子,我们每次下棋子的时候,必须是下在没有棋子的地方,isBlack变量是用来更换颜色的,也就是说黑色棋子和红色棋子轮着下,符合我们下棋的思路。

2.虽然现在能够下两种不同颜色的棋子了,但是它并不能判断输赢,要判断输赢必须要检测黑色棋子或红色棋子的左边,右边,两个对角线的地方是否有5个与之颜色相同的棋子,而且是在每次下棋子的时候就要判断是否有5个相同颜色的棋子,如果有,则相应颜色的棋子就赢了。

public class suFa {
	private int [][] chess;//先定义一个二维数组
	public suFa(int [][] chess){//一个构造方法,用来传值的
		this.chess=chess;
	
		System.out.println(chess.length+"<><><>"+chess[0].length);
	}
	public int Row(int r,int c){//横向找是否有5个棋子是连起来的
	
		 int count=0;//定义一个计数器
		for(int i=c;i>=0;i--){//往指定位置的前面找
			if(chess[r][i]==chess[r][c]){
				count++;//若找到,则计数器加1
			}
			else{
				break;
			}
		}
		for(int i=c+1;i<chess[0].length;i++){//往指定位置的后面找
			if(chess[r][c]==chess[r][i]){
				count++;
			}
			else{
				break;
			}
		}
		return count;
	}
	public int Coloum(int r,int c){//纵向找是否有5个棋子是连在一起的
		 int count=0;//定义一个计数器
		for(int i=r;i>=0;i--){//从指定的位置
			if(chess[i][c]==chess[r][c]){
				count++;//若找到则加1
			}
			else{
				break;
			}
		}
		for(int i=r+1;i<chess.length;i++){
			if(chess[i][c]==chess[r][c]){//若找到,则加1
				count++;
			}
			else{
				break;
			}
		}
		return count;
}
	public int Duijiao(int r,int c){//沿着下对角找,是否有5个连着的棋子
		int count=0;//定义一个计数器
		for(int i=r+1,j=c+1;i<chess[0].length&&j <chess.length;i++,j++){//沿着指定的位置对角线的下方找
			if(chess[i][j]==chess[r][c]){//若找到,则加1
				count++;
			}
			else{
				break;
			}
		}
		for(int i=r,j=c;i>=0&&j>=0;i--,j--){//沿着指定的位置对角线的上方找
			if(chess[i][j]==chess[r][c]){//若找到,则加1
				count++;
			}
			else{
				break;
			}
		}
		return count;
		
	}
	public int shangDui(int r,int c){//沿着上对角线找,是否有5个连着的棋子
		int count=0;//定义一个计数器
		for(int i=r-1,j=c+1;r>=0&&j<chess[0].length;i--,j++){//沿着指定位置的上方找
			if(chess[i][j]==chess[r][c]){//若找到,则加1
				count++;
			}
			else{
				break;
			}
		}
		for(int i=r,j=c;r<chess.length&&j>=0;i++,j--){//沿着指定位置的下方找
			if(chess[i][j]==chess[r][c]){//若找到,则加1
				count++;
			}
			else{
				break;
			}
		}
		return count;
		
	}
}

 

 这就是一个算法类,用来寻找棋子左边,右边,两个对角线方向与之相应颜色的棋子的个数,然后我们应在放棋子的地方创建这个算法对象,每下一颗棋子,就用该算法对象调用相应的方法:

if(an.Row(i, j)>=5){//弹出对话框
							if(a[i][j]==1){
							javax.swing.JOptionPane.showMessageDialog(null,"黑色棋子赢了!");
						}
						else{
							javax.swing.JOptionPane.showMessageDialog(null,"红色棋子赢了");
						}
						}
						if(an.Coloum(i, j)>=5){//弹出对话框
							if(a[i][j]==1){
								javax.swing.JOptionPane.showMessageDialog(null,"黑色棋子赢了!");
							}
							else{
								javax.swing.JOptionPane.showMessageDialog(null,"红色棋子赢了");
							}
						}
						if(an.Duijiao(i, j)>=5){
							if(a[i][j]==1){
								javax.swing.JOptionPane.showMessageDialog(null,"黑色棋子赢了!");
							}
							else{
								javax.swing.JOptionPane.showMessageDialog(null,"红色棋子赢了");
							}
						}
						if(an.shangDui(i, j)>=5){
							if(a[i][j]==1){
								javax.swing.JOptionPane.showMessageDialog(null,"黑色棋子赢了!");
							}
							else{
								javax.swing.JOptionPane.showMessageDialog(null,"红色棋子赢了");
							}

 

 现在虽然可以判断输赢了,但当我们移动窗体时,就会发现原来下的棋子不见了,这时就需要重绘:棋子重绘其实跟我们画棋子的方法差不多,

  public void paint(Graphics g){//重写父类绘制窗体的方法
    	super.paint(g);//调用父类的paint方法
    	drawChessTable(g);//调用该方法绘制棋盘
    	for(int i=0;i<erw.length;i++){//重绘棋子
    		for(int j=0;j<erw[i].length;j++){
    				int x=Config.XO+Config.CELL_SIZE*j;//取出棋盘的棋子
    				int y=Config.YO+Config.CELL_SIZE*i;
    				if(erw[i][j]!=0){//说明这点已有棋子
    					if(erw[i][j]==1){//如果是黑子
    						g.setColor(Color.BLACK);
    					}
    					else{
    						g.setColor(Color.RED);
    					}
    					g.fillOval(x-Config.CELL_SIZE/2, y-Config.CELL_SIZE/2, Config.CHESS_SIZE, Config.CHESS_SIZE);
    			}
    		}
    	}
    	

 

 

 现在就可以重绘了,人人对机就已经完成了,有时可能我们希望每当我们点击一次鼠标时,就下两颗棋子,也就相当于人机对战.其实放棋子并不难,就是点击一次时,两次调用putChess()方法,

public  void putChess(Color color, int r, int c) {
		
		if (color.equals(java.awt.Color.RED)) {//如果颜色是红色
			flag=1;
			a[r][c] = -1;//标记这个位置,如果是-1,就是红棋子,重绘时,需要用到
			b[r][c]=-1;//
//			 chess=new Chess(r,c,1);
//			chessList.add(chess);
		} else {
			flag=0;
			a[r][c] = 1;//标记这个位置,如果是1,就是黑色棋子,重绘时,需要用到
			b[r][c]=1;
//			 chess=new Chess(r,c,0);
//			chessList.add(chess);
		}
		g.setColor(color);// 设置颜色
		
		//根据下标计算坐标
		int x2 = Config.CELL_SIZE * c + Config.XO;
		int y2 = Config.CELL_SIZE * r + Config.YO;
		
		g.fillOval(x2 - Config.CELL_SIZE / 2, y2 - Config.CELL_SIZE / 2,
				Config.CHESS_SIZE, Config.CHESS_SIZE);
		if (an.Row(r, c) >= 5) {// 弹出对话框
			if (a[r][c] == 1) {// 判断是不是黑色棋子
				javax.swing.JOptionPane.showMessageDialog(null,
						"黑色棋子赢了!");
			} else {
				javax.swing.JOptionPane.showMessageDialog(null,
						"红色棋子赢了");
			}
		}
		if (an.Coloum(r, c) >= 5) {// 弹出对话框
			if (a[r][c] == 1) {// 判断是不是黑色棋子//判断是不是黑色棋子
				javax.swing.JOptionPane.showMessageDialog(null,
						"黑色棋子赢了!");
			} else {
				javax.swing.JOptionPane.showMessageDialog(null,
						"红色棋子赢了");
			}
		}
		if (an.Duijiao(r, c) >= 5) {// 弹出对话框
			if (a[r][c ]== 1) {// 判断是不是黑色棋子
				javax.swing.JOptionPane.showMessageDialog(null,
						"黑色棋子赢了!");
			} else {
				javax.swing.JOptionPane.showMessageDialog(null,
						"红色棋子赢了");
			}
		}
		if (an.shangDui(r, c) >= 5) {// 弹出对话框
			if (a[r][c] == 1) {// 判断是不是黑色棋子
				javax.swing.JOptionPane.showMessageDialog(null,
						"黑色棋子赢了!");
			} else {
				javax.swing.JOptionPane.showMessageDialog(null,
						"红色棋子赢了");
			}
	}
	}

 

这较上面写的有条理一些。如果我们把代码写在一起,而没有分类,就是没有写在方法里面,让人感觉有点冗余,而且当我们出错时,也不好找错误,所以我们以后要注意,当要实现某个功能时,一定要单独写一个方法。

3.我们点击鼠标时,要得到两颗棋子,所以必须要两次调用putChess()方法,下棋的人调用putChess()方法,还比较好理解,因为每次调用时都知道他的位置,根据他的位置放棋子就可以了,但机器人又不知道它的位置在哪里?所以我们必须在定义一个二维数组用来存放权值,权值最大的位置就是机器人要下的位置,那怎样找权值最大呢?设定权值就是看它周围的棋子数,所以就必须要在写一个类来寻找机器人的棋子个数和下棋的人的棋子个数,

public class RobotMethod {
	private int [][] b;//定义一个二维数组
	public RobotMethod(int [][] b){
		this.b=b;//把二维数组传过来
	}
	public int [] Row (int r,int c){
		int [] bin=new int[2];//定义一个数组,用来存放红色和黑色棋子的个数
		for(int i=c+1;i<b[0].length;i++){//横向向右找
			if(b[r][i]==1){//如果是黑色棋子
				bin[0]++;//黑色棋子的计数器累加
			}
			else {break;}
			if(b[r][i]==0){//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
				break;
			}
		}
		for(int i=c+1;i<b[0].length;i++){//横向向右找
			if(b[r][i]==-1){//如果是红色棋子
				bin[1]++;//红色棋子的计数器累加
			}
			else {break;}
			if(b[r][i]==0){//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
				break;
			}
		}
		for(int i=c-1;i>=0;i--){//横向向左找
			
			 if(b[r][i]==1){//如果是黑色棋子
				bin[0]++;//黑色棋子的计数器累加
			}
			 else{break;}
			if(b[r][i]==0){//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
				break;
			}
		}
		
		for(int i=c-1;i>=0;i--){//横向向左找
			
			 if(b[r][i]==-1){//如果是红色棋子
				bin[1]++;//红色棋子的计数器累加
			}
			 else{break;}
			if(b[r][i]==0){//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
				break;
			}
		}
		return bin;
	}
	public int [] Coloum(int r,int c){
		int [] bin=new int[2];//定义一个数组,用来存放红色和黑色棋子的个数
		for(int i=r+1;i<b.length;i++){//纵向向下找
			if(b[i][c]==1){//如果是黑色棋子
				bin[0]++;//黑色棋子的计数器累加
			}
			else{break;}
			if(b[i][c]==0){//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
				break;
			}
		}
		for(int i=r+1;i<b.length;i++){//纵向向下找
			 if(b[i][c]==-1){//如果是红色棋子
				bin[1]++;//红色棋子的计数器累加
			}
			 else{break;}
			if(b[i][c]==0){//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
				break;
			}
		}
		for(int i=r-1;i>=0;i--){
			
			
			if(b[i][c]==1){//如果是黑色棋子
				bin[0]++;//黑色棋子的计数器累加
			}
			else {break;}
			if(b[i][c]==0){
				break;//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
			}
		}
		for(int i=r-1;i>=0;i--){
			
			 if(b[i][c]==-1){//如果是红色棋子
				bin[1]++;//红色棋子的计数器累加
			}
			 else{break;}
			if(b[i][c]==0){
				break;//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
			}
			
		}
		return bin;
	}
	public int [] Duijiao(int r,int c){
		int [] bin=new int[2];//定义一个数组,用来存放红色和黑色棋子的个数
		for(int i=r+1,j=c+1;i<b[0].length&&j <b.length;i++,j++){//沿着指定的位置对角线的下方找
	      if(b[i][j]==1){//如果是黑色棋子
	    	  bin[0]++;//黑色棋子的计数器累加
	      }
	      else{break;}
	      if(b[i][j]==0) {
	    	  break;//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
	      }
		}
		for(int i=r+1,j=c+1;i<b[0].length&&j<b.length;i++,j++){
	      
        if(b[i][j]==-1){//如果是红色棋子
	    	  bin[1]++;//红色棋子的计数器累加
	      }
	       else {break;}
	      if(b[i][j]==0) {
	    	  break;//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
	      }
		
		
		}
		for(int i=r-1,j=c-1;i>=0&&j>=0;i--,j--){//沿着指定的位置对角线的上方找
	     if(b[i][j]==1){//如果是黑色棋子
	    	 bin[0]++;//黑色棋子的计数器累加
	    	 }
	     else {break;}
	     if(b[i][j]==0) {
	    	 break;//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
	     }
		}
		for(int i=r-1,j=c-1;i>=0&&j>=0;i--,j--){//沿着指定的位置对角线的上方找
	     
	      if(b[i][j]==-1){//如果是红色棋子
	    	 bin[1]++;//红色棋子的计数器累加
	     }
	     else {break;}
	     if(b[i][j]==0) {
	    	 break;//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
	     }
	     }
		return bin;
}
	public int [] Shangdui(int r,int c){
		int [] bin=new int[2];//定义一个数组,用来存放红色和黑色棋子的个数
		for(int i=r-1,j=c+1;i>=0&&j<b[0].length;i--,j++){//沿着指定位置的上方找
			if(b[i][j]==1){//如果是黑色棋子
				bin[0]++;//黑色棋子的计数器累加
			}
			else {break;}
			if(b[i][j]==0)
			 {
				break;//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
			}
		}
		for(int i=r-1,j=c+1;i>=0&&j<b[0].length;i--,j++){//沿着指定位置的上方找
			
			 if(b[i][j]==-1){//如果是红色棋子
				bin[1]++;//红色棋子的计数器累加
			}
			 else {break;}
			 if(b[i][j]==0)
			 {
				break;//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
			}
		}
		for(int i=r+1,j=c-1;i<b.length&&j>=0;i++,j--){//沿着指定位置的下方找
			if(b[i][j]==1){//如果是黑色棋子
				bin[0]++;//黑色棋子的计数器累加
			}
			else {break;}
			if(b[i][j]==0) {
				break;//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
			}
		}
		for(int i=r+1,j=c-1;i<b.length&&j>=0;i++,j--){//沿着指定位置的下方找
			
			 if(b[i][j]==-1){//如果是红色棋子
				bin[1]++;//红色棋子的计数器累加
			}
			else {break;}
			if(b[i][j]==0) {
				break;//如果是空格,那说明穿过来的那一点不是我们要下的范围之内,因为它旁边没棋子
			}
		}
		
		return bin;
     }
}

 

这个类是用来找机器人和下棋的人周围棋子的个数的,下面这一步比较重要了,就是来设定权值,我写的设定权值方法不是很好,机器人只会堵棋,没有什么技术含量,希望高手们就直接跳过这里吧,呵呵。。。

public class Robot {
	private int[][] chess;// 定义一个存权值的棋盘
	private int MyFourZi = 1000000, YourFourZi = 100000;// 定义两个四个棋子连在一起权值的变量,一个是机器人的。
	private int MyThreeZi = 10000, YourThreeZi = 1000;// 定义两个三个棋子连在一起权值的变量,一个是机器人的。
	private int MyTwoZi = 100, YourTwoZi = 10;// 定义两个两个棋子连在一起权值的变量,一个是机器人的。
	private int MyOneZi=9,YourOneZi=2;//定义一个棋子的权值变量
	private int[] axi;

	private RobotMethod robot;

	public Robot(int[][] chess, int[] axi) {// 把棋盘传递过来
		this.chess = chess;
		this.axi = axi;

		robot = new RobotMethod(chess);//
	}

	public int[] FindMethod() {
		int [][] bin=new int[4][2];
		for (int i = 0; i < chess[0].length; i++) {
			for (int j = 0; j < chess.length; j++) {
				//System.out.println(chess[i][j]+"\t");
				if (chess[i][j]==0) {
					bin[0] = robot.Row(i, j);
					bin[1] = robot.Coloum(i, j);
					bin[2] = robot.Duijiao(i, j);
					bin[3] = robot.Shangdui(i, j);
				for(int k=0;k<4;k++){
					if(bin[k][1]==4){
						chess[i][j]+=MyFourZi;
					}
					 if(bin[k][0]==4){
						chess[i][j]+=YourFourZi;
					}
					 if(bin[k][1]==3){
						chess[i][j]+=MyThreeZi;
					}
					 if(bin[k][0]==3){
						chess[i][j]+=YourThreeZi;
					}
					 if(bin[k][1]==2){
						chess[i][j]+=MyTwoZi;
					}
					 if(bin[k][0]==2){
						chess[i][j]+=YourTwoZi;
					}
					 if(bin[k][1]==1){
						chess[i][j]+=MyOneZi;
					}
					 if(bin[k][0]==1){
						chess[i][j]+=YourOneZi;
					}
				}
				
		}
		}
		}
		//找出权值最大的位置
		int max = chess[0][0];
		int x = 0, y = 0;
		for (int i = 0; i < chess[0].length; i++) {
			for (int j = 0; j < chess.length; j++) {
				System.out.print(chess[i][j]+"   ");
				if (chess[i][j] >max) {
					max = chess[i][j];
					x = i;
					y = j;
				}
			}
			System.out.println();
		}
		//找到权值最大的位置后要将权值清0,否则会累加
		for(int i=0;i<chess[0].length;i++){
			for(int j=0;j<chess.length;j++){
				if(chess[i][j]>1){
					chess[i][j]=0;
				}
			}
		}
		axi[0] = x;
		axi[1] = y;
		return axi;

	}

 我觉得有个地方特别要引起我们的注意,当每一次找到权值最大时,一定要将先前设定的权值清0,不然我们后面得到的权值就不对了,因为它会累加。

4.这样简单的人机对战就已经完成了。也能够判断是机器人赢还是下棋的人赢了。但我们学了文件的基本操作时,我们就希望能够把它保存到硬盘中,或是从硬盘中把数据读出来,还有,可能我们不小心下错棋了,我们希望能够悔棋,下面就讲下这些功能吧。

要把数据保存到硬盘中实际上就是将数据写到硬盘中。

public class IOTest {
	public  static void writeFile(String path,ArrayList<Chess> list){
		File file=new File(path);
		try{
			//创建输出流
		FileOutputStream fos=new FileOutputStream(file);
		DataOutputStream dos=new DataOutputStream(fos);
		//写入队列的总长度
		int t=list.size();
		dos.writeInt(t);
		for(int i=0;i<t;i++){
			//得到队列的对象
			Chess chess=list.get(i);
			//将队列的颜色标记量写进去
			dos.writeByte(chess.flag);
			//将棋子的坐标写进去
			dos.writeInt(chess.r);
			dos.writeInt(chess.c);
		}
		dos.flush();
		dos.close();
		fos.close();
		}
	 catch(IOException e){
		e.getStackTrace();
	}

}

 

写到硬盘中必须要个队列来保存,而且还要确定类型,也就是说必须要在写个棋子类

public class Chess {

	int r, c;
	byte flag; 
	public Chess(int r,int c,int n){
		this.r=r;
		this.c=c;
		flag=(byte)n;
	}
}

 

通过棋子类就可以判断他是什么颜色的棋子,棋子的位置,这是把数据保存到硬盘中,那如果我们要把数据从硬盘中读出来呢?其实也差不多,就写个读写方法就可以了。由于和写的方法相似,我就不写这个方法了。

5.那现在我讲一下悔棋的方法吧,当点击悔棋按钮时,会把最后下的两颗棋子清除(一颗是下棋的人的,一颗是机器人的。)其实这也不难,只要当点击悔棋按钮时,把队列中最后两个棋子对象移除就可以了,但是需要注意的是,在重绘棋子时,首先必须将二维数组中的棋子清0.

当然写了这些功能,必须相应的要创建这些按钮,要实现我们需要的功能,就必须添加事件监听器,因为这个是我们后面才添加的,为了不修改以前写的代码,我们可以写个匿名类。

 ActionListener a=new ActionListener(){
	    	public void actionPerformed(ActionEvent e){
	    		if(e.getActionCommand().equals("保存")){
	    		IOTest.writeFile(path, ChessListener.chessList);
	    		}
	    		else if(e.getActionCommand().equals("打开")){//点击的是打开按钮
	    			ChessListener.chessList=IOTest.readFile(path);
	    	        
	    	        repaint();//重绘棋盘和棋子,
	    	        //将上次画过的重绘
	    			for(int i=0;i<ChessListener.chessList.size();i++){
	    				Chess ches=ChessListener.chessList.get(i);
	    				if(ches.flag==0){
	    					chess.putChess(Color.BLACK, ches.r, ches.c);
	    				}
	    				else if(ches.flag==1){
	    					chess.putChess(Color.red,ches.r , ches.c);
	    				}
	    			}
	    			
	    		}
	    		else if(e.getActionCommand().equals("悔棋")){
	    			int t=ChessListener.chessList.size();
	    	        Chess ch=ChessListener.chessList.get(t-1);
	    	        Chess chi=ChessListener.chessList.get(t-2);
	    	        ChessListener.chessList.remove(ch);
	    	        ChessListener.chessList.remove(chi);
	    	        //将画过的棋子清除
	    	        for(int i=0;i<erw.length;i++){
	    	    		for(int j=0;j<erw[i].length;j++){
	    	    			erw[i][j]=0;
	    	    		}
	    	    		}
	    	        //重绘棋盘和棋子
	    	        repaint();
	    	        
	    	        //每点击一次悔棋按钮时,将最后两个棋子清除,在重绘棋子
	    			for(int i=0;i<ChessListener.chessList.size();i++){
	    				Chess ches=ChessListener.chessList.get(i);
	    				if(ches.flag==0){
	    					chess.putChess(Color.BLACK, ches.r, ches.c);
	    				}
	    				else if(ches.flag==1){
	    					chess.putChess(Color.red,ches.r , ches.c);
	    				}
	    			}
	    			
	    		}
	    		else if(e.getActionCommand().equals("重来一局")){
	    			for(int i=0;i<ChessListener.chessList.size();i++){
	    	        	Chess c=ChessListener.chessList.get(i);
	    	        	ChessListener.chessList.remove(c);
	    	        }
	    			
	    			//将画过的棋子清除
	    	        for(int i=0;i<erw.length;i++){
	    	    		for(int j=0;j<erw[i].length;j++){
	    	    			erw[i][j]=0;
	    	    		}
	    	    		}
	    	        //重绘棋盘和棋子
	    	        repaint();
	    			
	    			
	    		}
	    		
	    	}
	    };

 然后在给这些按钮添加监听器,这样整个五子棋就已经完成了。

分享到:
评论
2 楼 风来过可风又吹走了 2016-11-11  
风来过可风又吹走了 写道
 

1 楼 风来过可风又吹走了 2016-11-11  
 

相关推荐

Global site tag (gtag.js) - Google Analytics