JAVA五子棋人人对战的实现

版权声明:版权声明:本文为博主原创文章,博客地址:http://blog.csdn.net/qq_37808895,未经博主允许不得转载。 https://blog.csdn.net/qq_37808895/article/details/88623611

此程序只实现了五子棋的人人对战功能,人机对战功能待完善算法问题后补充

棋子类

package FiveChess;

import java.awt.Color;

//棋子

public class Chess{
	private int x;
	private int y;
	private Color color;
	public static final int R=30;
	public Chess(int x,int y,Color color){
		this.x=x;
		this.y=y;
		this.color=color;
	}
	public int getX(){
		return x;
	}
	public int getY(){
		return y;
	}
	public Color getColor(){
		return color;
	}
}

棋盘类

这里包括算法的核心,获取棋子索引,判断是否达成获胜条件(4个方向任意一个方向累加至五子)

package FiveChess;

import java.awt.Color;  
import java.awt.Cursor;  
import java.awt.Dimension;  
import java.awt.Graphics;  
import java.awt.Graphics2D;  
import java.awt.Image;  
import java.awt.RadialGradientPaint;  
import java.awt.RenderingHints;  
import java.awt.Toolkit;  
import java.awt.event.MouseEvent;  
import java.awt.event.MouseListener;  
import java.awt.event.MouseMotionListener;  
import java.awt.geom.Ellipse2D;  
  

import javax.swing.*;  
/** 
 * 五子棋--棋盘类  
 */  
  
public class ChessBoard extends JPanel implements MouseListener {  
   public static final int MARGIN=30;//边距  
   public static final int GRID_SPAN=35;//网格间距  
   public static final int ROWS=15;//棋盘行数  
   public static final int COLS=15;//棋盘列数  
     
   Chess[] chessList=new Chess[(ROWS+1)*(COLS+1)];  
   boolean isBlack=true;//默认开始是黑棋先  
   boolean gameOver=false;//游戏是否结束  
   int chessCount;//当前棋盘棋子的个数  
   int xIndex,yIndex;//当前刚下棋子的索引  
     

   Color colortemp;  
   public ChessBoard(){  
        
       setBackground(Color.white); 
        
       addMouseListener(this);  
       addMouseMotionListener(new MouseMotionListener(){  
           public void mouseDragged(MouseEvent e){  
                 
           }  
             
           public void mouseMoved(MouseEvent e){  
             int x1=(e.getX()-MARGIN+GRID_SPAN/2)/GRID_SPAN;  
             //将鼠标点击的坐标位置转成网格索引  
             int y1=(e.getY()-MARGIN+GRID_SPAN/2)/GRID_SPAN;  
             //游戏已经结束不能下  
             //落在棋盘外不能下  
             //x,y位置已经有棋子存在,不能下  
             if(x1<0||x1>ROWS||y1<0||y1>COLS||gameOver||findChess(x1,y1))  
                 setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
             //设置成默认状态  
             else setCursor(new Cursor(Cursor.HAND_CURSOR));  
               
           }  
       });  
   }   
     
    
   
   public void paintComponent(Graphics g){  
       
       super.paintComponent(g);//画棋盘  
       
       
       int FWidth=getWidth();  
       int FHeight=getHeight();  
      
         
       for(int i=0;i<=ROWS;i++){//画横线  
           g.drawLine(MARGIN, MARGIN+i*GRID_SPAN, MARGIN+COLS*GRID_SPAN, MARGIN+i*GRID_SPAN);  
       }  
       for(int i=0;i<=COLS;i++){//画竖线  
           g.drawLine(MARGIN+i*GRID_SPAN, MARGIN, MARGIN+i*GRID_SPAN, MARGIN+ROWS*GRID_SPAN);  
             
       }  
         
       //画棋子  
       for(int i=0;i<chessCount;i++){  
           //网格交叉点x,y坐标  
           int xPos=chessList[i].getX()*GRID_SPAN+MARGIN;  
           int yPos=chessList[i].getY()*GRID_SPAN+MARGIN;  
           g.setColor(chessList[i].getColor());//设置颜色  
          // g.fillOval(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2,  
                           //Point.DIAMETER, Point.DIAMETER);  
           //g.drawImage(shadows, xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2, Point.DIAMETER, Point.DIAMETER, null);  
           colortemp=chessList[i].getColor();  
           if(colortemp==Color.black){  
               RadialGradientPaint paint = new RadialGradientPaint(xPos-Chess.R/2+25, yPos-Chess.R/2+10, 20, new float[]{0f, 1f}  
               , new Color[]{Color.WHITE, Color.BLACK});  
               ((Graphics2D) g).setPaint(paint);  
               ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);  
               ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);  
  
           }  
           else if(colortemp==Color.white){  
               RadialGradientPaint Paint = new RadialGradientPaint(xPos-Chess.R/2+25, yPos-Chess.R/2+10, 70, new float[]{0f, 1f}  
               , new Color[]{Color.WHITE, Color.BLACK});  
               ((Graphics2D) g).setPaint(Paint);  
               ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);  
               ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);  
  
           }  
           
           Ellipse2D e = new Ellipse2D.Float(xPos-Chess.R/2, yPos-Chess.R/2, 34, 35);  
           ((Graphics2D) g).fill(e);  
           //标记最后一个棋子的红矩形框  
             
           if(i==chessCount-1){//如果是最后一个棋子  
               g.setColor(Color.red);  
               g.drawRect(xPos-Chess.R/2, yPos-Chess.R/2,  
                           34, 35);  
           }  
       }  
   }  
     
   public void mousePressed(MouseEvent e){//鼠标在组件上按下时调用  
         
       //游戏结束时,不再能下  
       if(gameOver) return;  
         
       String colorName=isBlack?"黑棋":"白棋";  
         
       //将鼠标点击的坐标位置转换成网格索引  
       xIndex=(e.getX()-MARGIN+GRID_SPAN/2)/GRID_SPAN;  
       yIndex=(e.getY()-MARGIN+GRID_SPAN/2)/GRID_SPAN;  
         
       //落在棋盘外不能下  
       if(xIndex<0||xIndex>ROWS||yIndex<0||yIndex>COLS)  
           return;  
         
       //如果x,y位置已经有棋子存在,不能下  
       if(findChess(xIndex,yIndex))return;  
         
       //可以进行时的处理  
       Chess ch=new Chess(xIndex,yIndex,isBlack?Color.black:Color.white);  
       chessList[chessCount++]=ch;  
        repaint();//通知系统重新绘制  
        
         
       //如果胜出则给出提示信息,不能继续下棋  
         
       if(isWin()){  
           String msg=String.format("恭喜,%s赢了!", colorName);  
           JOptionPane.showMessageDialog(this, msg);  
           gameOver=true;  
       }  
       isBlack=!isBlack;  
     }  
   //覆盖mouseListener的方法  
   public void mouseClicked(MouseEvent e){  
       //鼠标按键在组件上单击时调用  
   }  
     
   public void mouseEntered(MouseEvent e){  
       //鼠标进入到组件上时调用  
   }  
   public void mouseExited(MouseEvent e){  
       //鼠标离开组件时调用  
   }  
   public void mouseReleased(MouseEvent e){  
       //鼠标按钮在组件上释放时调用  
   }  
   //在棋子数组中查找是否有索引为x,y的棋子存在  
   private boolean findChess(int x,int y){  
       for(Chess c:chessList){  
           if(c!=null&&c.getX()==x&&c.getY()==y)  
               return true;  
       }  
       return false;  
   }  
     
     
   private boolean isWin(){  
       int continueCount=1;//连续棋子的个数  
        
       //横向向西寻找  
       for(int x=xIndex-1;x>=0;x--){  
           Color c=isBlack?Color.black:Color.white;  
           if(getChess(x,yIndex,c)!=null){  
               continueCount++;  
           }else  
               break;  
       }  
      //横向向东寻找  
       for(int x=xIndex+1;x<=COLS;x++){  
          Color c=isBlack?Color.black:Color.white;  
          if(getChess(x,yIndex,c)!=null){  
             continueCount++;  
          }else  
             break;  
       }  
       if(continueCount>=5){  
             return true;  
       }else   
       continueCount=1;  
         
       //继续另一种搜索纵向  
       //向上搜索  
       for(int y=yIndex-1;y>=0;y--){  
           Color c=isBlack?Color.black:Color.white;  
           if(getChess(xIndex,y,c)!=null){  
               continueCount++;  
           }else  
               break;  
       }  
       //纵向向下寻找  
       for(int y=yIndex+1;y<=ROWS;y++){  
           Color c=isBlack?Color.black:Color.white;  
           if(getChess(xIndex,y,c)!=null)  
               continueCount++;  
           else  
              break;  
         
       }  
       if(continueCount>=5)  
           return true;  
       else  
           continueCount=1;  
         
         
       //继续另一种情况的搜索:斜向  
       //东北寻找  
       for(int x=xIndex+1,y=yIndex-1;y>=0&&x<=COLS;x++,y--){  
           Color c=isBlack?Color.black:Color.white;  
           if(getChess(x,y,c)!=null){  
               continueCount++;  
           }  
           else break;  
       }  
       //西南寻找  
       for(int x=xIndex-1,y=yIndex+1;x>=0&&y<=ROWS;x--,y++){  
           Color c=isBlack?Color.black:Color.white;  
           if(getChess(x,y,c)!=null){  
               continueCount++;  
           }  
           else break;  
       }  
       if(continueCount>=5)  
           return true;  
       else continueCount=1;  
         
         
       //继续另一种情况的搜索:斜向  
       //西北寻找  
       for(int x=xIndex-1,y=yIndex-1;x>=0&&y>=0;x--,y--){  
           Color c=isBlack?Color.black:Color.white;  
           if(getChess(x,y,c)!=null)  
               continueCount++;  
           else break;  
       }  
       //东南寻找  
       for(int x=xIndex+1,y=yIndex+1;x<=COLS&&y<=ROWS;x++,y++){  
           Color c=isBlack?Color.black:Color.white;  
           if(getChess(x,y,c)!=null)  
               continueCount++;  
           else break;  
       }  
       if(continueCount>=5)  
           return true;  
       else continueCount=1;  
         
       return false;  
     }  
     
     
   private Chess getChess(int xIndex,int yIndex,Color color){  
       for(Chess p:chessList){  
           if(p!=null&&p.getX()==xIndex&&p.getY()==yIndex  
                   &&p.getColor()==color)  
               return p;  
       }  
       return null;  
   }  
     
     
   public void restartGame(){  
       //清除棋子  
       for(int i=0;i<chessList.length;i++){  
           chessList[i]=null;  
       }  
       //恢复游戏相关的变量值  
       isBlack=true;  
       gameOver=false; //游戏是否结束  
       chessCount =0; //当前棋盘棋子个数  
       repaint();  
   }  
     
   //悔棋 
   public void goback(){  
       if(chessCount==0)  
           return ;  
       chessList[chessCount-1]=null;  
       chessCount--;  
       if(chessCount>0){  
           xIndex=chessList[chessCount-1].getX();  
           yIndex=chessList[chessCount-1].getY();  
       }  
       isBlack=!isBlack;  
       repaint();  
   }  
     
   //矩形Dimension  
  
   public Dimension getPreferredSize(){  
       return new Dimension(MARGIN*2+GRID_SPAN*COLS,MARGIN*2  
                            +GRID_SPAN*ROWS);  
   }  
     
     
     
}  

界面类

package FiveChess;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;


//五子棋主框架
public class ChessJFrame extends JFrame{
	private ChessBoard chessboard;
	private JPanel toolbar;//工具栏
	private JButton button_start,button_back,button_exit;
	
	private JMenuBar menubar;//菜单栏
	private JMenu Menu;
	private JMenuItem startItem,backItem,exitItem;//菜单项
	public ChessJFrame(){
		setTitle("五子棋");
		chessboard=new ChessBoard();
		
		menubar=new JMenuBar();
		Menu=new JMenu("选项");
		startItem=new JMenuItem("重新开始");
		backItem=new JMenuItem("悔棋");
		exitItem=new JMenuItem("退出");
		Menu.add(startItem);
		Menu.add(backItem);
		Menu.add(exitItem);
		//内部监听类
		MyItemListener lis=new MyItemListener();
		this.startItem.addActionListener(lis);
		this.backItem.addActionListener(lis);
		this.exitItem.addActionListener(lis);
		menubar.add(Menu);
		setJMenuBar(menubar);//设置菜单栏
		toolbar=new JPanel();//工具面板实例化
		button_start=new JButton("重新开始");
		button_back=new JButton("悔棋");
		button_exit=new JButton("退出");
		toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));
		toolbar.add(button_start);
		toolbar.add(button_back);
		toolbar.add(button_exit);
		button_start.addActionListener(lis);
		button_back.addActionListener(lis);
		button_exit.addActionListener(lis);
		add(toolbar,BorderLayout.SOUTH);
		add(chessboard);//添加面板对象
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Dimension dim=getToolkit().getScreenSize();
		this.setLocation(520, 200);
	    pack();
	}
	private class MyItemListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			if(e.getSource()==startItem||e.getSource()==button_start){
				System.out.println("重新开始");
				chessboard.restartGame();
			}
			else if(e.getSource()==exitItem||e.getSource()==button_exit){
				System.exit(0);
			}
			else if(e.getSource()==backItem||e.getSource()==button_back){
				System.out.println("悔棋...");
				chessboard.goback();
			}
		}
	}
	public static void main(String[] args) {  
        ChessJFrame j=new ChessJFrame();
        j.setVisible(true);
    }  
	
}

总结

对棋子的绘制采用了awt的Ellipse2D功能使其更有3D感,菜单栏实现的功能和按键相同,下面附上程序图
人机对战要用到二叉树等数据结构问题,以后将进行更新
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_37808895/article/details/88623611