五子棋的实现(一)

匿名 (未验证) 提交于 2019-12-03 00:38:01

前面在实现完一个JAVA的面板之后,就想着继续实现一个相较于面板更复杂一点的程序――五子棋。但是我在在搜索资料的时候,发现网上很多关于五子棋实现的博文都是一步到位,直接给个源代码,不是很适合新手学习。所以我这里打算记录一下自己实现五子棋的整个过程,大致会分为三四个阶段。今天我们先来实现第一个阶段的五子棋。同样的我们在着手写代码之前我们需要先做一些准备。

一、我们需要实现哪些东西

1.一个15*15的五子棋界面;

2.能够在界面上下黑白棋子;

3.需要把棋子下在交叉点上;

4.实现棋子重绘;――作用:当界面大小被改变时能够保持棋盘和棋盘上面的棋子消失;

5.相同位置不能下多个棋子;

6.只有当“开始新游戏”的按钮被点击时,才能开始下棋;

(判断输赢等其他部分我们放到后面实现)

二、根据我们要实现的功能确定我们所需要的API类

五子棋的大致界面如下:


实现五子棋界面需要的API类:


JFrame和JPanel的区别:JFrame是最底层的容器,JPanel放在它上面,同一个界面只有一个JFrame,但是一个JFrame上面可以有多个JPanel。相当于JFrame是一个大餐桌,JPanel是盘子,如果我们要对餐桌JFrame上的东西进行管理分类等,我们就需要使用这些JPanel盘子。

事件监听机制的类:

绘画所需要的类:


三、各个功能实现的思路

1.一个15*15的五子棋界面;

需要重写GoBangframe的重绘方法,使其在界面刚生成时就产生一个15*15的棋盘。(重绘方法会在每次页面大小被改变时执行,因此当你改变大小时,棋盘不会消失)。这里我们可以通过两个for循环画出15条行线和15条列线。

2.能够在界面上下黑白棋子;

实现这个功能需要定义一个变量turn表名当前轮到哪方下棋。如果turn=1表明轮到黑方,turn=2表明轮到白方。每次黑方下完棋之后turn+1,白方下完棋之后turn-1。

3.需要把棋子下在交叉点上;

如果鼠标点击在交叉点处的某个范围内,我们都把棋子下在这个交叉点上。在这个由于各自大小是40,我们定义的范围时以交叉点为中心的上下20的正方形。这样我们就能确保每一次点击都会落到某一个交叉点处,不会覆盖也不会出现没有落子的情况。

4.实现棋子重绘;――作用:当界面大小被改变时能够保持棋盘上面的棋子不消失;

前面的棋盘重绘,虽然15*15的棋盘不会消失,但是棋子会消失。因此我们在重绘出棋盘以后还要把棋子也重新画上去。这里用了一个二维数组isAvail[15][15]来保存棋子信息,如果isArray[i][j]=0,表明这个位置没有棋子,等于1表明是一个黑棋子,等于2表明是一个白棋子。我们根据这些信息,遍历isArray数组,把棋子重新绘制上去。

5.相同位置不能下多个棋子;

判断isArray[i][j]是不是等于0,如果是0就可以下,如果不是则提示玩家下在其它地方。

6.只有当“开始新游戏”的按钮被点击时,才能开始下棋;

下棋是通过监听棋盘界面来实现的,因此我们只需要监听“开始新游戏”这个按钮,如果这个按钮被点击了,我们在给棋盘界面添加监听方法,否则不添加。

四、代码部分

//构建五子棋界面GoBangframe类  import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JComboBox; import java.awt.Dimension; import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.event.ActionListener; import java.awt.event.MouseListener;  public class GoBangframe extends JPanel implements GoBangconfig{ 	public Graphics g;//定义一支画笔 	public int[][] isAvail=new int [15][15];//定义一个二维数组来储存棋盘的落子情况 	 	//主函数入口 	public static void main(String args[]) { 		GoBangframe gf=new GoBangframe();//初始化一个五子棋界面的对象 		gf.initUI();//调用方法进行界面的初始化 	} 	 	public void initUI() { 		//初始化一个界面,并设置标题大小等属性 		JFrame jf=new JFrame(); 		jf.setTitle("五子棋"); 		jf.setSize(800,650); 		jf.setLocationRelativeTo(null); 		jf.setDefaultCloseOperation(3); 		 		jf.setLayout(new BorderLayout());//设置顶级容器JFrame为框架布局 		 		Dimension dim1=new Dimension(150,0);//设置右半部分的大小 		Dimension dim3=new Dimension(550,0);//设置左半部分的大小 		Dimension dim2=new Dimension(140,40);//设置右边按钮组件的大小 		 		//实现左边的界面,把GoBangframe的对象添加到框架布局的中间部分 		GoBangframe jpwest=new GoBangframe(); 		jpwest.setPreferredSize(dim3);//设置下棋界面的大小 		jpwest.setBackground(Color.LIGHT_GRAY);//设置下棋界面的颜色 		//这里的话直接把左边的画板添加上去,指明是在框架布局的中间版块 		//若放在其他版块会有一些小问题 		jf.add(jpwest,BorderLayout.CENTER);//添加到框架布局的中间部分 		 		//实现右边的JPanel容器界面 		JPanel jp=new JPanel(); 		jp.setPreferredSize(dim1);//设置JPanel的大小 		jp.setBackground(Color.white);//设置右边的界面颜色为白色 		jf.add(jp,BorderLayout.EAST);//添加到框架布局的东边部分 		jp.setLayout(new FlowLayout());//设置JPanel为流式布局 		 		//接下来我们需要把按钮等组件依次加到那个JPanel上面 		//设置按钮数组 		String[] butname= {"开始新游戏","悔棋","认输"}; 		JButton[] button=new JButton[3]; 		 		//依次把三个按钮组件加上去 		for(int i=0;i<butname.length;i++) { 			button[i]=new JButton(butname[i]); 			button[i].setPreferredSize(dim2); 			jp.add(button[i]); 		} 		 		//按钮监控类 		ButtonListener butListen=new ButtonListener(jpwest); 		//对每一个按钮都添加状态事件的监听处理机制 		for(int i=0;i<butname.length;i++) { 			button[i].addActionListener(butListen);//添加发生操作的监听方法 		} 		 		//设置选项按钮 		String[] boxname= {"人人对战","人机对战"}; 		JComboBox box=new JComboBox(boxname); 		jp.add(box); 				 		jf.setVisible(true); 	} 	 	 	//重写重绘方法,这里重写的是第一个大的JPanel的方法 	public void paint(Graphics g) { 		super.paint(g); 		 		//重绘出棋盘 		g.setColor(Color.black); 		for(int i=0;i<row;i++) { 			g.drawLine(x, y+size*i, x+size*(column-1), y+size*i); 		} 		for(int j=0;j<column;j++) { 			g.drawLine(x+size*j, y, x+size*j, y+size*(row-1)); 		} 		 		//重绘出棋子 		for(int i=0;i<row;i++) { 			for(int j=0;j<column;j++) { 				if(isAvail[i][j]==1) { 					int countx=size*i+20; 					int county=size*j+20; 					g.setColor(Color.black); 					g.fillOval(countx-size/2, county-size/2, size, size); 				} 				else if(isAvail[i][j]==2) { 					int countx=size*i+20; 					int county=size*j+20; 					g.setColor(Color.white); 					g.fillOval(countx-size/2, county-size/2, size, size); 				} 			} 		} 	} 	 } 
//设置按钮监听方法ButttonLitener类 import java.awt.event.ActionListener; import java.awt.event.ActionEvent;  //实现对JPanel的监听接口处理 public class ButtonListener implements GoBangconfig,ActionListener{ 	public GoBangframe gf; 	 	public ButtonListener(GoBangframe gf) { 		this.gf=gf;//获取左半部分的画板 	} 	 	//当界面发生操作时进行处理 	public void actionPerformed(ActionEvent e) { 		//获取当前被点击按钮的内容,判断是不是"开始新游戏"这个按钮 		if(e.getActionCommand().equals("开始新游戏")) { 			//如果是开始新游戏的按钮,再为左半部分设置监听方法 			frameListener fl=new frameListener(); 			fl.setGraphics(gf);//获取画笔对象 			gf.addMouseListener(fl); 		} 	} 	 } 
//定义GoBangconfig接口 //定义与棋盘数据相关的接口,保存棋盘的起点,格子大小,行数列数等信息 public interface GoBangconfig { 	int x=20,y=20,size=40,row=15,column=15; }  
import java.awt.event.ActionListener; import java.awt.event.MouseListener; import java.awt.event.ActionEvent; import java.awt.Graphics; import java.awt.Color;  //实现对GoBangframe下棋界面的监听接口处理 public class frameListener implements GoBangconfig,MouseListener{ 	public GoBangframe gf; 	public int turn=1;//判断当前轮到谁了,1表示黑方,2表示白方 	 	public void setGraphics(GoBangframe gf) { 		this.gf=gf; 	} 	 	 	  public void mouseClicked(java.awt.event.MouseEvent e) { 		  int x=e.getX(); 		  int y=e.getY(); 		  //计算棋子要落在棋盘的哪个交叉点上 		  int countx=(x/40)*40+20; 		  int county=(y/40)*40+20; 		  Graphics g=gf.getGraphics(); 		   		  if(gf.isAvail[(countx-20)/40][(county-20)/40]!=0) { 			  System.out.println("此处已经有棋子了,请下在其它地方"); 		  } 		  else { 			  //当前位置可以落子,先计算棋盘上棋子在数组中相应的位置 			  int colu=(countx-20)/40; 			  int ro=(county-20)/40; 			   			  if(turn==1) { 				  //先设置颜色 				  g.setColor(Color.black); 				  //落子 				  g.fillOval(countx-size/2, county-size/2, size, size); 				  //设置当前位置已经有棋子了,棋子为黑子 				  gf.isAvail[colu][ro]=1; 				  turn++; 			  } 			  else { 				  g.setColor(Color.white); 				  g.fillOval(countx-size/2, county-size/2, size, size); 				  //设置当前位置已经有棋子了,棋子为白子  				  gf.isAvail[colu][ro]=2; 				  turn--; 			  } 		  } 	  } 	   	   	  // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V 	  public void mousePressed(java.awt.event.MouseEvent e) { 		   	  } 	   	  // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V 	  public void mouseReleased(java.awt.event.MouseEvent e) { 		   	  } 	   	  // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V 	  public void mouseEntered(java.awt.event.MouseEvent e) { 		   	  } 	   	  // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V 	  public void mouseExited(java.awt.event.MouseEvent e) { 		   	  } } 
至此,我们已经初步实现了五子棋的界面和落子,后面我们会继续完善这个五子棋,包括输赢的判断和悔棋等操作。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!