zl程序教程

您现在的位置是:首页 >  后端

当前栏目

五子棋Java课设

JAVA 五子棋 课设
2023-06-13 09:12:33 时间

大家好,又见面了,我是你们的朋友全栈君。

五子棋基本思路

第一步:要分俩个类,一个是五子棋本身主类(包括黑白棋下棋方式),一个是棋子类(包括构建画布进行棋盘的设计,使其构成等距离的格子,正方形棋盘15*15格式)。

第二步:开始设计棋盘与棋子 1.利用圆形BUTTON实现棋子类,圆形棋子,利用Mathl类画出棋子,长宽都相等。

2.利用paintComponent()函数,进行在正方格交叉处点击出现黑棋与白棋落子,否则的话将不会出现下棋子的标志

  1. 限制棋子的落子,如果下到棋盘外,不会落子

4.侦查区域是落子标志,点击落子区域,从白子变黑子交替落下

第三步:设计五子棋下棋方式,获胜判定等

  1. 设计黑白棋子的落下,首先的黑子B会在棋盘上方显示“黑方下棋”
  1. 利用JPanel(面板容器类)在界面中用来分别添加棋盘界面和按钮界面。显示的“黑方下棋”使用宋体18号字来显示。

3.设计棋盘类,整体规划棋盘的横纵方向,以Button(按钮组件类)在界面作为按键,如“重新开始”按键。

4.每下一步都会用find()函数进行查找棋子的落子位置,并记录方便在判定是去判断棋子周围是否有同类型棋子,包括判定获胜五子相连的情况

  1. 利用for循环函数进行各个方向上的查找,并在每次落子之后用if()函数来判断是否这一排上有五颗同类型棋子,这个是竖直方向上的,接下来是左上和右下方向,坐下和右上方向,和水平方向,同理可得。

6.与画布棋盘时相似,使用paintComponent()函数进行棋子落子的判定,鼠标点在格子十字交叉点的周围进行分析

  1. 在MouseEvent(鼠标监听事件类)里面包含鼠标被点击等事件的处理方法。当界面被点击时就放下一个棋子。点击会落下棋子,“黑方下棋”与“白方下棋”交替出现。 以下利用距离格子十字交叉点30%以内判定棋子落在哪里的位置,在点击的位置上已经有棋子不可再放置。

7.实现接口ActionListener (状态监听处理类) 当点击重新开始会清除棋盘上所有的棋子,否则将无法去下下一步棋,保持棋盘在结束时的整体,包括画布的棋盘组件都不会动。

第四步:主类(测试类)将棋盘与落子方式进行整体输出。

源代码:

import javax.swing.*;
	import java.awt.*;
	import java.awt.event.*;
	import java.awt.geom.*;
	import java.util.*;
	public class FiveChess extends JFrame{
		private char whoseTurn='w';//黑方为B,白方为W
		private JLabel jlblStatus=new JLabel("黑方下棋");	
		JPanel showWhoseTurn=new JPanel();
		public FiveChess(){			
			ChessConvas ChessPanel=new ChessConvas();
			add(ChessPanel,BorderLayout.CENTER);
			//add(jlblStatus,BorderLayout.NORTH);	
			jlblStatus.setFont(new Font("宋体",Font.BOLD,18));	
			showWhoseTurn.add(jlblStatus,new GridLayout(1,3));	
			add(showWhoseTurn,BorderLayout.NORTH);	
		}
		public static void main(String[] args){	
			JFrame fr=new FiveChess();	
			fr.setLocationRelativeTo(null);
			fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			fr.setTitle("FiveChess");
			fr.setVisible(true);
			fr.setResizable(false);
			fr.setSize(650,650);
		}
	 
	//棋盘类
	 	class ChessConvas extends JPanel{
	 		//to move the ChessConvas by xMove and yMove
	 		private int xMove=60;
	 		private int yMove=60;
	 		//to set the position chess
	 		private int xPosition;
	 		private int yPosition; 		
	 		//private RoundButton1 []roundButtonArray=new RoundButton1[256];
	 		private ArrayList rbList=new ArrayList(); 		
	 		private char chessSide=' ';//执棋的一方 
	 		private JPanel btPanel=new JPanel();
	 		private JButton btReset=new JButton("重新开始");
	 		//private JLabel jlblBackImage=new JLabel(new ImageIcon("chessFive.gif"));		
			public ChessConvas(){			
				addMouseListener(new MouseListener());			
				//jlblBackImage.setBounds(0,0,650,650);
				//add(jlblBackImage);	
				//btPanel.setBounds(new Rectangle(0,0,650,100));
				//btPanel.setLocation(0,5);		
				//btPanel.setBackground(Color.RED);
				//btPanel.setLayout(new GridLayout(1,3,5,5));
				//btPanel.add(btReset);
				//btReset.setLocation(490,10);为什么这个不行呢?那它又有什么用呢?它与setBounds有什么不同呢?
				btReset.setBounds(new Rectangle(440,40,100,30));
				btReset.addActionListener(new ResetEvent());
				add(btReset);		
				setLayout(null);//很关键,以在坐标上画组件,不然默认的是FlowLayout布局			
			}	
			public void setChessSide(char c){
				chessSide=c;
				repaint();
			}
			public char gerChessColor(){
				return chessSide;
			}
			public void setXPosition(int xp){
				xPosition=xp;
				repaint();
			}
			public int getXPosition(){
				return xPosition;
			}
			public void setYPosition(int yp){
				yPosition=yp;
				repaint();
			}
			public int getYPosition(){
				return yPosition;
			}	
		public boolean find(ArrayList rbList,int x,int y,Color bakColor){		
			for(int i=0;i<rbList.size();i++){			
				if((((RoundButton1)rbList.get(i)).getX()==x )&&(((RoundButton1)rbList.get(i)).getY()==y)&&(((RoundButton1)rbList.get(i)).getBackground()==bakColor)){
					return true;
					}			
			}
				return false;
		}
		public boolean isWinner(ArrayList rbList,int x,int y,Color bakColor){				
			for(int i=0,k=0;i<6;i++){
					//竖直方向				
				if(find(rbList,x+0*i,y+30*i,bakColor))k++;
				if(find(rbList,x+0*i,y-30*i,bakColor)){
						if(i!=0)k++;										
				 }
					System.out.println("竖直方向  k= "+k);
				if(!find(rbList,x+0*i,y+30*i,bakColor)&&!find(rbList,x+0*i,y-30*i,bakColor))
							break;//若竖直两个方向都走不通则跳出循环							
				if(k==5){
						jlblStatus.setText((bakColor==Color.BLACK)?"黑方获胜!!!":"白方获胜!!!");				
						return true;
				}			
			}
			for(int i=0,k=0;i<6;i++){
				//左上至右下方向				
				if(find(rbList,x-30*i,y-30*i,bakColor))k++;
				if(find(rbList,x+30*i,y+30*i,bakColor)){
						if(i!=0)k++;										
				}
				System.out.println("左上至右下方向 k= "+k);	
				if(!find(rbList,x-30*i,y-30*i,bakColor)&&!find(rbList,x+30*i,y+30*i,bakColor))
						break;	//若左上与右下两个方向都走不通则跳出循环				
					if(k==5){
						jlblStatus.setText((bakColor==Color.BLACK)?"黑方获胜!!!":"白方获胜!!!");
						return true;
					}			
				
			}
			
			for(int i=0,k=0;i<6;i++){
				//左下至右上方向
				if(find(rbList,x-30*i,y+30*i,bakColor))k++;
				if(find(rbList,x+30*i,y-30*i,bakColor)){
					if(i!=0)k++;
				}
				System.out.println("左下至右上方向k= "+k);	
				if(!find(rbList,x-30*i,y+30*i,bakColor)&&!find(rbList,x+30*i,y-30*i,bakColor))
				        break;//若左下至右上两个方向都走不通则跳出循环				
					if(k==5){
						jlblStatus.setText((bakColor==Color.BLACK)?"黑方获胜!!!":"白方获胜!!!");
						return true;
					}			
				
			}
			
			for(int i=0,k=0;i<6;i++){		
				//水平方向
				if(find(rbList,x-30*i,y+0*i,bakColor))k++;			
				if(find(rbList,x+30*i,y-0*i,bakColor)){
					if(i!=0)k++;
				}	
				System.out.println("水平方向  k= "+k);
				if(!find(rbList,x-30*i,y+0*i,bakColor)&&!find(rbList,x+30*i,y-0*i,bakColor))
				      break;		//若水平的两个方向都走不通则跳出循环
								
					if(k==5){
						jlblStatus.setText((bakColor==Color.BLACK)?"黑方获胜!!!":"白方获胜!!!");
						return true;
					}			
				
			}
			return false;
		}
		
			protected void paintComponent(Graphics g){
				super.paintComponent(g);
				Graphics2D g2 = (Graphics2D)g;
				for(int i=1;i<=16;i++){
				 g2.draw(new Line2D.Double(30+xMove,30*i+yMove,16*30+xMove,30*i+yMove));
				 g2.draw(new Line2D.Double(30*i+xMove,30+yMove,30*i+xMove,16*30+yMove));
				}		
			}
			private class MouseListener extends MouseAdapter{
				public void mouseClicked(MouseEvent e){
					if(chessSide==' '&&whoseTurn!=' '){
						setChessSide(whoseTurn);//set ChessSide in the chessCovas
					}					
					xPosition=e.getX();
					yPosition=e.getY();	
					
					if(xPosition > 30+xMove && xPosition < 16*30+xMove && yPosition>30+yMove && yPosition< 16*30+yMove) {
	         	jlblStatus.setText((whoseTurn=='B')?"黑方下棋":"白方下棋");
						whoseTurn=(whoseTurn=='B')?'W':'B';	         
	         int X = xPosition/30;
	         int Y = yPosition/30;
	         
	         int centerX ;
	         int centerY ;
	         //棋子落点的判断
	         if(xPosition%30>30/2){
	         		centerX=(X+1)*30;
	         		if(yPosition%30>30/2)
	         			centerY=(Y+1)*30;
	         		else
	         			centerY=Y*30;
	         	 }
	         else{
	         		centerX=X*30;
	         		if(yPosition%30>30/2)
	         			centerY=(Y+1)*30;
	         		else
	         			centerY=Y*30;
	         		}         
	         RoundButton1 rb=new RoundButton1("");
	        
	         //roundButtonArray[i]=rb;
	          //i++;         
	         rbList.add(rb);
	          add(rb);          
	         //棋子大小         
	         rb.setBounds(new Rectangle(centerX-10,centerY-10,20,20));
	         if(whoseTurn=='B'){
	         		rb.setBackground(Color.BLACK);
	         		System.out.println("黑棋  x: "+rb.getX()+"  y: "+rb.getY());
	         		boolean flag=isWinner(rbList,rb.getX(),rb.getY(),Color.BLACK);
	         		System.out.println(flag);
	         		if(flag==true){
	         			removeMouseListener(this);//当一方获胜后则不再响应鼠标事件
	         		 }         	
	         	}
	         else{          	   	
	         		rb.setBackground(Color.WHITE);
	         		System.out.println("白棋  x: "+rb.getX()+"  y: "+rb.getY());
	         		boolean flag=isWinner(rbList,rb.getX(),rb.getY(),Color.WHITE);
	         		System.out.println(flag); 
	         		if(flag==true){
	         			removeMouseListener(this);//当一方获胜后则不再响应鼠标事件
	         		 }         	         	
					}          
	         repaint();         
					}
				}
			}
		private class ResetEvent implements ActionListener{
			public void actionPerformed(ActionEvent e){
				for(int i=0;i<rbList.size();i++){
					remove((RoundButton1)rbList.get(i));
				}			
				rbList.clear();
				repaint();//若不加repaint(),组件不会自动消失,等窗体稍有改动才会消失,为什么?
			addMouseListener(new MouseListener());//以便重新开始后重新响应鼠标事件
			}
		}
	 }
	}
	//用圆形BUTTON实现棋子类
	 class RoundButton1 extends JButton {
	 	
	 		  
	   public RoundButton1(){}
	    public RoundButton1(String label) {
	        super(label);
	       
	        //下面的语句讲述这个按钮变为一个圆形而不是椭圆形
	        Dimension size = getPreferredSize();
	        size.width = size.height = Math.max(size.width, size.height);
	        setPreferredSize(size);
	        //不让JButton画背景而允许我们去画一个圆背景
	        setContentAreaFilled(false);
	 
	    }
		
	    // 画出圆的背景和标签
	    protected void paintComponent(Graphics g) {
	        if (getModel().isArmed()) {
	            g.setColor(Color.lightGray);
	        } else {
	            g.setColor(getBackground());
	        }
	        g.fillOval(0, 0, getSize().width-1, getSize().height-1);
	        // 在焦点上画出一个标签
	        super.paintComponent(g);
	 
	    }
	 
	 
	    // 画出一个边框
	    protected void paintBorder(Graphics g) {
	        g.setColor(getForeground());
	        g.drawOval(0, 0, getSize().width-1, getSize().height-1);
	    }
	 
	 
	 
	    // 侦察单击区域
	    Shape shape;
	 
	    public boolean contains(int x, int y) {
	        // 如果按钮改变了尺寸将重新创建一个Shape
	        if (shape == null || !shape.getBounds().equals(getBounds())) {
	            shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());
	        }
	        return shape.contains(x, y);
	    } 
	  }   

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/158180.html原文链接:https://javaforall.cn