`
甘艳丽
  • 浏览: 51628 次
  • 性别: 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  
 

相关推荐

    python3五子棋人机大战和人人大战.zip

    Python3五子棋人机大战与人人大战是一款基于Python编程语言和Pygame库开发的桌面游戏。Pygame是Python的一个扩展模块,专门用于开发2D游戏和多媒体应用。在这个项目中,用户可以与计算机AI进行对弈,也可以与其他...

    JavaScript 五子棋人机大战

    总的来说,JavaScript五子棋人机大战项目涵盖了前端开发的多个方面,包括JavaScript编程、图形渲染以及基础的AI算法应用,是学习和实践这些技能的好实例。开发者可以通过这个项目提升自己的综合能力,并对Web游戏...

    c# csharp 五子棋 代码 人机大战 初级版

    c# csharp 五子棋 代码 人机大战 初级版 c# csharp 五子棋 代码 人机大战 初级版 c# csharp 五子棋 代码 人机大战 初级版 c# csharp 五子棋 代码 人机大战 初级版

    五子棋人机对战源代码

    根据给定的信息,我们可以分析并总结出以下与“五子棋人机对战源代码”相关的知识点: ### 一、程序结构与基本定义 #### 1. 基本头文件引入 - `&lt;stdio.h&gt;`:标准输入输出库,用于处理输入输出操作。 - `&lt;string.h&gt;...

    js实现AI五子棋人机大战

    【JavaScript实现AI五子棋人机大战】 在JavaScript中实现AI五子棋人机大战是一项有趣且具有挑战性的任务,涉及到编程、算法以及人工智能的基本应用。以下是对这一主题的详细阐述: 1. **游戏界面与布局**:首先,...

    C语言编写的人机大战五子棋趣味性强

    界面明了,趣味性强,提高学习语言的兴趣,引导人们走进编程的大门.

    人机大战五子棋

    极具智能的人机对战游戏,加上逼真的三维画面,实在是居家旅行必备软件。

    网页版人机对战五子棋

    【网页版人机对战五子棋】是一种在网页上实现的互动游戏,它允许玩家与计算机进行对弈。这个游戏的开发涉及到了多种技术,包括前端界面设计、后端逻辑处理以及人工智能算法的运用。 首先,前端部分是用户与游戏交互...

    java五子棋(人机对战、人人对战)总共三个还有算法!

    【标题】中的“java五子棋(人机对战、人人对战)”指的是一个用Java编程语言开发的五子棋游戏,它包含了两种模式:人机对战和人人对战。在人机对战模式中,玩家可以与计算机进行对抗;在人人对战模式下,两个玩家...

    VC++五子棋人人对战

    【VC++五子棋人人对战】是一款基于微软的Visual C++ 6.0开发环境构建的棋类游戏,它允许两位玩家通过人机交互进行五子棋对弈。五子棋是一种简单却富有策略性的游戏,目标是在棋盘上先连成五子直线(横、竖或斜线)的...

    scratch编程项目源代码文件案例素材-(开源)智能五子棋机器人.zip

    本压缩包中的"开源)智能五子棋机器人.sb2"文件是使用Scratch制作的一个项目,它包含了一个智能五子棋游戏的完整源代码,适合少儿编程学习者进行研究和模仿。 在这个项目中,用户可以与一个AI(人工智能)对手进行...

    python五子棋(双人对战)

    没有用到GUI控件;python3.6版本;实现了五子棋双人对战,后面会尝试加入电脑对战的;希望你们可以喜欢

    MaOC五子棋

    人机大战五子棋

    java入门之五子棋游戏

    (2) 可以实现两人PK和人机大战两大游戏功能; (3) 重新开始:在指定的游戏模式下,重新开始游戏; (4) 游戏说明:描述了五子棋游戏的规则。 解压导入项目后需要手动配置jar包(jre环境)

    JS+canvas实现的五子棋游戏【人机大战版】

    在本教程中,我们将探讨如何使用JavaScript和HTML5的Canvas API来实现一个五子棋游戏的人机大战版本。首先,我们需要了解Canvas API的基础知识,它是一个允许我们在网页上进行动态图形绘制的HTML5元素。 HTML部分:...

    五子棋大战 2.36.320

    五子棋大战是一款功能十分齐全的小游戏。支持双人对战和人机对战模式。您可以通过“操作者设备锁定”功能来使键盘和鼠标各执一方棋子操作,而不互相干扰,该功能在双人对战中很实用,在同类软件中领先。 支持反悔和...

    Gobang:人机五子棋大战

    《五子棋大战:JavaScript实现的人机对战详解》 五子棋,又称连珠,是一种深受人们喜爱的双人对弈策略游戏。在信息化时代,利用编程技术将这种传统游戏搬到网络上,让更多人可以随时随地享受五子棋的乐趣。本篇文章...

    java人机对战程序

    java人机对战五子棋,只是为了证明电脑思维是一种机械化的、愚蠢的、无情绪化的思维

    chess:人机大战五子棋——这是一个400K左右的jar包,它实现了简单的人机对战五子棋,并有美观的界面和音效!

    《五子棋人机对战程序详解》 五子棋是一种深受人们喜爱的智力游戏,其规则简单,但策略深奥。在这个数字化的时代,我们可以通过编程实现人与计算机的对战,让游戏体验更加丰富。本文将围绕一个400K左右的Java应用...

Global site tag (gtag.js) - Google Analytics