Java项目实训:五子棋

Java项目实训:五子棋v0.1

界面开发

  • 界面开发:
    • 界面类:
      • 创建接口,存储期盼上的固定数据
      • 棋盘面板:
        • 创建一个类继承JPanel重写面板控制方法paint
        • 绘制背景、网格线以及使用到的接口中的固定数据
        • 按键面板:
          • 添加按钮:
            • 采用遍历字符串形式创建多个按钮
            • 设置按钮尺寸等属性
    • 监听器类:
      • 实现鼠标监听:
        • 使用按下监听方法
        • 获取鼠标按下的坐标
        • 校准坐标
        • 判断范围
      • 实现按钮监听:
        • 获取按钮上的字符串及按钮对象

棋子数据化

  • 存在的问题:
    • 棋子绘制在棋盘会出现棋盘最小化再打开就消失
    • 可以在同一个地方可以重复绘制
    • 悔棋需要一个顺序数组 (坐标 先后顺序)
    • 判断输赢/回放都需要棋子的数据
  • 解决方法:
    • 使用 二维数组 来存储棋子的数据 可以解决棋子最小化、重复绘制等问题
      • 整数型二维数组,其中存储三个数值 0-无棋子 1-黑棋 2-白棋
      • 在下棋的位置时,将对应的二维数组的值设置为1或2
      • 在之前先判断这个位置上对应二维数组中是否为0,不为0则不允许下棋直接弹窗+return
      • 在ChessPanel中,将chessArray传过来,遍历二维数组绘制棋子
    • 可以使用 一维Chess数组 来存储棋子的数据 (r,c,chessFlag) 来解决悔棋操作

输赢判断

  • 原理:
    • 根据最后一颗棋子的六个方向进行判断
    • 判断连续的五颗棋子
  • 实现四个方法:判断四个方向上(从上到下、从左到右、从左上到右下、从右上到左下)是否有物资连棋
  • 一个方法实现判断,返回布尔值,从而发送提示窗

代码

  • 界面类:
package lyq0319;

import javax.swing.*;
import java.awt.*;

public class GoBangUI {

    GoListener goListener=new GoListener();
    public void initGoUI(){

        JFrame jf=new JFrame();
        jf.setSize(900,800);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setResizable(false);
        jf.setLocationRelativeTo(null);


        ChessPanel chessPanel = new ChessPanel();
        chessPanel.addMouseListener(goListener);
        chessPanel.setChessArray(goListener.getChessArray());
        goListener.setChessPanel(chessPanel);

        JPanel btnPanel = new JPanel();
        btnPanel.setBackground(Color.GRAY);
        btnPanel.setPreferredSize(new Dimension(110,0));
        this.initBtnPanel(btnPanel);

        jf.add(chessPanel,BorderLayout.CENTER);
        jf.add(btnPanel,BorderLayout.WEST);

        jf.setVisible(true);
        goListener.setGraphics(chessPanel.getGraphics());

    }

    public void initBtnPanel(JPanel btnPanel){
        String[] strs={"开始游戏","悔棋","退出游戏","历史记录"};
        for(int i=0;i< strs.length;i++){
            JButton btn=new JButton(strs[i]);
            btn.setBackground(Color.WHITE);
            btn.setPreferredSize(new Dimension(95,35));
            btnPanel.add(btn);
            btn.addActionListener(goListener);

        }
    }

    public static void main(String[] args) {
        new GoBangUI().initGoUI();
    }
}
  • 监听器类:
package lyq0319;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.SQLOutput;

public class GoListener extends MouseAdapter implements ActionListener,Godate {

    private Graphics g;
    public void setGraphics(Graphics g){
        this.g=g;

    }

    private int[][] chessArray = new int[ROWS][COLS];
    private Chess[] chessList = new Chess[ROWS*COLS];
    private int chessIndex = 0;
    public int[][] getChessArray(){
        return chessArray;
    }

    private ChessPanel chessPanel;
    public void setChessPanel(ChessPanel chessPanel){
        this.chessPanel = chessPanel;
    }

    int chessFlag =0;


    @Override
    public void actionPerformed(ActionEvent e){
        String action = e.getActionCommand();
        Object source = e.getSource();
        JButton btn = (JButton) source;
        if(action.equals("开始游戏")){
            chessFlag=1;
            btn.setText("结束游戏");
        } else if (action.equals("结束游戏")) {
            chessFlag=0;
            btn.setText("开始游戏");
            this.cleanChessArray();
            chessPanel.paint(g);
        }else if(action.equals("悔棋")){
            this.rebackChess();
        }
        else if(action.equals("退出游戏")){
            System.exit(0);
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        int x= e.getX();
        int y=e.getY();
        System.out.println("x:"+x+"y:"+y);

        int r=(y-Y+SIZE/2)/SIZE;
        int c=(x-X+SIZE/2)/SIZE;
        System.out.println("r:"+r+"c:"+c);
        if(chessFlag==0){
            JOptionPane.showMessageDialog(null,"点击开始游戏 开始游戏!");
            return;
        }

        if(x<=X-SIZE/2||y<=Y-SIZE/2||r<0||r>16||c<0||c>16){
            JOptionPane.showMessageDialog(null,"此处不能下棋!");
            return;
        }
        if(chessArray[r][c]!=0){
            JOptionPane.showMessageDialog(null,"此处不能下棋啦!");
            return;
        }


        chessArray[r][c] = chessFlag;
        Chess chess = new Chess(r,c,chessFlag);
        chessList[chessIndex]=chess;
        chessIndex++;

        if (chessFlag == 1) {
            g.setColor(Color.BLACK);
            chessFlag=2;
        }else if(chessFlag == 2){
            g.setColor(Color.WHITE);
            chessFlag=1;
        }

        int cx=c*SIZE+X-SIZE/2;
        int cy=r*SIZE+Y-SIZE/2;

        g.fillOval(cx,cy,SIZE,SIZE);
        printChessArray();

    }

    public void printChessArray(){
        for(int i=0;i<chessArray.length;i++) {
            for (int j = 0; j < chessArray[i].length; j++) {
                System.out.print(chessArray[i][j] + " ");
            }
            System.out.println();
        }
    }

    public void cleanChessArray(){
        for(int i=0;i<chessArray.length;i++){
            for(int j=0;j<chessArray[i].length;j++){
                chessArray[i][j]=0;
            }
        }
    }

    public void rebackChess(){
        if(chessIndex<=1){
            JOptionPane.showMessageDialog(null,"不能再悔棋!");
            return;
        }
        Chess chess = chessList[chessIndex-1];
        chessArray[chess.r][chess.c] = 0;
        chessFlag = chess.chessFlag;
        chessList[chessIndex-1]=null;
        chessIndex--;
        chessPanel.paint(g);
    }
}
  • 重写控制面板的类
package lyq0319;

import javax.swing.*;
import java.awt.*;

public class ChessPanel extends JPanel implements  Godate{
    private int[][] chessArray;
    public void setChessArray(int[][] chessArray){
        this.chessArray=chessArray;
    }

    @Override
    public void paint(Graphics g) {
        g.setColor(new Color(200,150,30));
        g.fillRect(0,0,getWidth(),getHeight());

        g.setColor(Color.BLACK);
        for(int i=0;i<ROWS;i++){

            g.drawLine(X,Y+i*SIZE,X+GRID_NUM*SIZE,Y+i*SIZE);
            g.drawLine(X+i*SIZE,Y,X+i*SIZE,Y+GRID_NUM*SIZE);
        }
        for (int i=0;i<chessArray.length;i++){
            for(int j=0;j<chessArray[i].length;j++){
                int chessNum =  chessArray[i][j];
                if(chessNum!=0){
                    g.setColor(chessNum==1?Color.BLACK:Color.WHITE);
                    int cx =X+j*SIZE-SIZE/2;
                    int cy =Y+i*SIZE-SIZE/2;
                    g.fillOval(cx,cy,SIZE,SIZE);
                }
            }
        }



    }
}
  • 棋子属性接口
package lyq0319;

public interface Godate {
    int X=80;
    int Y=80;
    int SIZE=40;

    int ROWS=16;
    int COLS=16;

    int GRID_NUM=15;

}
  • 存储棋子数据的一维数组类
package lyq0319;

public class Chess {

    int r,c,chessFlag;

    public Chess(int r,int c,int chessFlag){
        this.r=r;
        this.c=c;
        this.chessFlag=chessFlag;
    }
}

  • 输赢判断类
package lyq0319;

public class GoWin {
    public static void main(String[] args) {
        int[][] chessArray = {
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        };
        isWin(chessArray,1,2);
    }

    public static boolean isWin(int[][] chessArray,int r,int c){
        if(row(chessArray,r,c)>=5||
                column(chessArray,r,c)>=5||
                leftUpToRightDown(chessArray,r,c)>=5||
                RightUpToLeftDown(chessArray,r,c)>=5){
            return true;
        }
        return  false;
        }


    //判断横向
    public static int row(int[][] chessArray,int r,int c){
        int count=1;
        //当前所下棋子
        int cnum=chessArray[r][c];
        //向右
        for(int i=c+1;i<chessArray.length;i++){
            if(cnum==chessArray[r][i]){
                count++;
            }else {
                break;
            }
        }
        System.out.println("横向上向右查找到:count="+count);
        //向左
        for(int i=c-1;i>=0;i--){
            if(cnum==chessArray[r][i]){
                count++;
            }else {
                break;
            }
        }
        System.out.println("横向上查找到:count="+count);

        return count;
    }
    //判断纵向
    public static int column(int[][] chessArray,int r,int c) {
        int count=1;
        //当前所下棋子
        int cnum=chessArray[r][c];
        //向右
        for(int i=r+1;i<chessArray.length;i++){
            if(cnum==chessArray[i][c]){
                count++;
            }else {
                break;
            }
        }
        System.out.println("纵向上向右查找到:count="+count);
        //向左
        for(int i=r-1;i>=0;i--){
            if(cnum==chessArray[i][c]){
                count++;
            }else {
                break;
            }
        }
        System.out.println("纵向上查找到:count="+count);

        return count;
   }

   public static int leftUpToRightDown(int[][] chessArray,int r,int c){
        int count=1;
        int cnum=chessArray[r][c];
        //向左上角找 行列都变小 i-- j--
        for(int i=r-1,j=c-1;i>=0&&j>=0;i--,j--){
            if(cnum==chessArray[i][j]){
                count++;
            }else{
                break;
            }
        }
       System.out.println("从左上:count"+count);
        //向右下角找 行列式变大 i++ j++
       for(int i=r+1,j=c+1;i<chessArray.length&&j< chessArray.length;i++,j++){
           if(cnum==chessArray[i][j]){
               count++;
           }else{
               break;
           }
       }
       System.out.println("从左上到右下:count"+count);
       return count;
   }

    public static int RightUpToLeftDown(int[][] chessArray,int r,int c){
        int count=1;
        int cnum=chessArray[r][c];
        //向左下角找 行列都变小 i-- j--
        for(int i=r-1,j=c+1;i>=0&&j<chessArray.length;i--,j++){
            if(cnum==chessArray[i][j]){
                count++;
            }else{
                break;
            }
        }
        System.out.println("从左上:count"+count);
        //向右上角找 行列式变大 i++ j++
        for(int i=r+1,j=c-1;i<chessArray.length&&j>=0;i++,j--){
            if(cnum==chessArray[i][j]){
                count++;
            }else{
                break;
            }
        }
        System.out.println("从左上到右下:count"+count);
        return count;
    }
}

运行结果

初始界面
点击开始游戏开始下棋
点击悔棋悔棋
点击结束游戏刷新界面
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值