java五子棋程序的实现(人人对战)

java五子棋程序的实现(人人对战)

一,界面的实现

首先,我们还是来实现一个基本的界面,因为我们需要一块棋盘的区域还有一块功能区域,所以我们除了JFrame还需要用到JPanel和BorderLayout边框布局方式。代码如下:

public class Gobong extends JPanel implements Gobonginte{
	
	public static void main(String[] args){
		Gobong gb=new Gobong();
		gb.initUI();
	}
	public void initUI(){
		JFrame frame=new JFrame("五子棋");
		frame.setSize(800, 680);
		frame.setDefaultCloseOperation(3);
		frame.setLocationRelativeTo(null);
		
		JPanel jp=new JPanel();
		
		BorderLayout bl=new BorderLayout();//设置JFrame的布局方式
		frame.setLayout(bl);
					
		GobongListener gl=new GobongListener(this,jb);//实例化事件处理类对象
		
		frame.add(this,BorderLayout.CENTER);//添加中间面板
		
		jp.setBackground(Color.DARK_GRAY);
		jp.setPreferredSize(new Dimension(150,0));
				
		frame.add(jp,BorderLayout.EAST);//添加东边面板
		frame.setVisible(true);
		gl.setG(getGraphics());
		
	}

然后,我们需要画出一个棋盘,因为后面我们其他类也需要,初始坐标,棋子大小等一些数据,为了便于修改和赋值,我们定义一个接口:

public interface Gobonginte {
	public static final int x0=30,y0=30,SIZE=30,row=20,column=20;
	public static final int[][] chesses=new int[row][column];

}

为了方便我们后面进行重绘,我们这里在继承JPanel类之后重写paint方法:

public void paint(Graphics g){
		super.paint(g);
		this.draw(g);
		if(chesses!=null){		
		this.drawqizi(g);
		}
         }

画棋盘的方法:

public void draw(Graphics g){
		//画棋盘
		for(int i=0;i<row;i++){
			g.setColor(Color.black);
			g.drawLine(x0,y0+i*SIZE,x0+SIZE*(row-1),y0+i*SIZE);//画横线
			g.drawLine(x0+i*SIZE,y0 ,x0+i*SIZE,y0+SIZE*(column-1));//画横线
		}
	}

二,棋盘落子

我们现在基本的界面有了,现在需要的是将在棋盘上画棋子,并且是画在交叉点上。

这时为了得到点时的坐标点,我们需要添加监听器(MouseListener,ActionListener)这里我为了方便,选择继承了MouseAdapter类:

public class GobongListener extends MouseAdapter implements ActionListener,Gobonginte{

	public GobongListener(JPanel j,JComboBox<String> jb){
		this.jpanel=j;
		this.jb=jb;
	}
	
	
	public void mouseReleased(MouseEvent e) {
		x1=e.getX();
		y1=e.getY();
		
		if(x1>x0-SIZE/2&&x1<x0+SIZE*(column-1)+SIZE/2
			&&y1>y0-SIZE/2&&y1<y0+SIZE*(row-1)+SIZE/2){	
			if(item.equals("人人对战")){
				pvp(x1,y1);
			}
			else{
				pvc(x1,y1);
			}
		} 
	}
       

三,五子棋基本规则的实现

五子棋基本的我们需要去实现的是1.黑白棋2.棋盘必须要在交叉点3.存储棋子4.同一个位置上只能下一颗棋子5.棋子重绘6.判断输赢

黑白棋我们使用一个变量进行交替判断即可;交叉点则需要对获得的坐标值进行判断,在交叉点附近一定范围内的都视为交叉点的坐标;存储棋子我们使用二维数组进行存储;同一个位置不重下使用二维数组的值进行判断即可;重绘只需要在主函数中遍历二维数组中存储的棋子,然后将其重新绘制即可;判断输赢,在每下一颗棋子的时候,对该从棋子位置的四个方向(水平,竖直,左斜,右斜)进行对应棋子个数进行统计,如果为5个以上则返回一个值代表当前颜色棋子胜利。部分代码如下:

 public void pvp(int X1,int Y1){
		 for(int j=0;j<row;j++){
				for(int i=0;i<column;i++){
					//得到交叉点坐标
					 int x=x0+SIZE*i;//横坐标
					 int y=y0+SIZE*j;//纵坐标
				//如果与圆心的误差为SIZE/2
					if(x1<x+SIZE/2&&x1>x-SIZE/2&&y1>y-SIZE/2&&y1<y+SIZE/2){
						if(chesses[i][j]==0){
							if(flag){
								chesses[i][j]=1;//如果是黑子就为1
								g.setColor(Color.black);
								//以交叉点为圆心画圆
								g.fillOval(x-SIZE/2, y-SIZE/2,SIZE, SIZE);
								count++;
								list.add(new Point(i,j));
								
							}else{
								chesses[i][j]=2;//如果是白子就为1
								g.setColor(Color.white);
								//以交叉点为圆心画圆
								g.fillOval(x-SIZE/2, y-SIZE/2,SIZE, SIZE);
								count--;
								list.add(new Point(i,j));
							}
							
						
							if(GobongWin.validate(i, j)){
								if(flag)
									JOptionPane.showMessageDialog(jpanel, "黑棋胜利!");
								else
									JOptionPane.showMessageDialog(jpanel, "白棋胜利!");
								//移除监听方法
								jpanel.removeMouseListener(this);
								//设置对战方式能选择
								jb.setEnabled(true);
							}
							flag = !flag;
							return;
						}
					}
				}
	 }
	 }

判断输赢:

private static int countL(int r,int c){
		int count=1;//count默认为1,表示r,c位置的棋子已经计算了
		//往左上
		for(int r1=r-1,c1=c-1;r1>=0&&c1>=0;c1--,r1--){
			if(chesses[r][c] == chesses[r1][c1])
			count++;
			else
				break;
		}
		//往左下
		for(int c1=c-1,r1=r+1;c1>=0&&r1<chesses.length;c1--,r1++){
			if(chesses[r][c] == chesses[r1][c1])
			count++;
			else
				break;
		}
		
		return count;
	}

四,更多功能的实现

把我们的功能区用起来,加上开始新游戏,悔棋,认输,以及选择人人对战模式或者人机对战模式,这里我们需要的用到的类有JButton,ActionListener,JComboBox,ArrayList,Point,开始新游戏和认输,选择模式都只需要简单的判断,但是开始游戏和认输都需要移除或者添加监听方法和清空数组,并调用repaint方法,部分代码如下:

//添加监听方法
			 jpanel.addMouseListener(this);
			 jb.setEnabled(false);//禁用下拉框
			 z=0;
			  
			 for(int i=0;i<chesses.length;i++){
				 for(int j=0;j<chesses[i].length;j++){
//					 System.out.println(chesses[i][j]);
					 chesses[i][j]=0;
					 
				 }
			 }flag=true;
			 jpanel.repaint();

悔棋则需要使用ArrayList数组队列这样可以较为方便的存储棋子位置并倒退进行修改

if(list.size()>0){
				 Point point=list.remove(list.size()-1);
				 chesses[point.x][point.y]=0;
			 }
			 jpanel.repaint();//重画棋子

五,AI算法

实现机器与人对战可以用权值法,博弈树,机器学习。

目前正在研究权值法中...

未完待续...

猜你喜欢

转载自blog.csdn.net/qq_41819698/article/details/81984783