Java五子棋

package com.yhs02;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;

@SuppressWarnings("all")
public class FiveChessFrame extends JFrame implements MouseListener, Runnable {

    String blackMessage = "无限制";
    String whiteMessage = "无限制";
    //保存黑方白方时间
    int whiteTime = 0;
    int blackTime = 0;
    Thread thread = new Thread(this); //倒计时的线程
    int maxTime = 0; //倒计时时间限制
    String nextGo = "黑子先手";
    int qc = 1; //记录白棋=2,黑棋=1
    int qn = 0; //判断棋子是否重复
    boolean startPlay = false;//判断是否开始游戏
    int[][] SavePoint = new int[14][13];
    int x = 0, y = 0; //棋子坐标
    int qx = 260, qy = 345, qw = 455, qh = 420; //棋盘宽高,位置
    int bw = 150, bh = 50, bx = 50, by = 500; //按钮宽高,位置
    int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
    int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;

    public FiveChessFrame() {
        int frameWidth = 780;
        int frameHeight = 800;
        this.setTitle("五子棋");
        this.setSize(frameWidth, frameHeight);
        this.setLocation((screenWidth - frameWidth) / 2, (screenHeight - frameHeight) / 2);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.addMouseListener(this);

    }

    @Override
    public void paint(Graphics g) {

        //可以添加双缓冲技术解决屏闪


        try {
            g.drawImage(ImageIO.read(new File("d:\\wzq.png")), 3, 2, this);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        g.setFont(new Font("华文行楷", Font.BOLD, 30));
        g.drawString("游戏信息", 50, 400);

        g.setFont(new Font("黑体", 0, 20));
        g.drawString("黑方时间: " + blackMessage, 45, 450);
        g.drawString("白方时间: " + whiteMessage, 45, 480);

        //开始按钮
        g.setColor(Color.BLACK);//设置画笔颜色
        g.fillRect(bx, by, bw, bh);//绘制开始按钮
        g.setFont(new Font("华文行楷", 10, 30));//设置字体
        g.setColor(Color.white);//设置画笔颜色
        g.drawString("开始", 95, 530);//绘制字符

        //悔棋按钮
        g.setColor(Color.BLUE);//设置画笔颜色
        g.fillRect(bx, by + 60, bw, bh);//绘制悔棋按钮
        g.setFont(new Font("华文行楷", 10, 30));//设置字体
        g.setColor(Color.WHITE);//设置画笔颜色
        g.drawString("悔棋", 95, 590);//绘制字符

        //认输按钮
        g.setColor(Color.CYAN);//设置画笔颜色
        g.fillRect(bx, by + 120, bw, bh);//绘制认输按钮
        g.setFont(new Font("华文行楷", 10, 30));//设置字体
        g.setColor(Color.BLACK);//设置画笔颜色
        g.drawString("认输", 95, 650);//绘制字符

        //游戏设置按钮
        g.setColor(Color.GREEN);//设置画笔颜色
        g.fillRect(bx, by + 180, bw, bh);//绘制认输按钮
        g.setFont(new Font("华文行楷", 10, 30));//设置字体
        g.setColor(Color.BLACK);//设置画笔颜色
        g.drawString("游戏设置", 70, 710);//绘制字符

        //绘制棋盘格子线
        g.setColor(Color.black);
        for (int x = 0; x <= qw; x += 35) {
            g.drawLine(qx, qy + x, qw + qx, x + qy);
            g.drawLine(qx + x, qy, qx + x, qh + qy);
        }


        //绘制棋子
        for (int i = 0; i < 14; i++) {
            for (int j = 0; j < 13; j++) {
                if (SavePoint[i][j] == 1) {//黑子
                    int sx = i * 35 + qx;
                    int sy = j * 35 + qy;
                    g.setColor(Color.BLACK);
                    g.fillOval(sx - 10, sy - 10, 20, 20);
                }
                if (SavePoint[i][j] == 2) { //白子
                    int sx = i * 35 + qx;
                    int sy = j * 35 + qy;
                    g.setColor(Color.WHITE);
                    g.fillOval(sx - 10, sy - 10, 20, 20);//绘制实心圆
                    g.setColor(Color.BLACK);
                    g.drawOval(sx - 10, sy - 10, 20, 20);//绘制空心圆
                }
            }
        }

        g.setColor(Color.BLACK);
        g.setFont(new Font("宋体", 20, 30));
        g.drawString(nextGo, 70, 360);
    }


    private boolean WinOrLose() {
        boolean flag = false; //输赢
        int chessColor = SavePoint[x][y]; //记录棋子颜色
        int count = this.chessCount(1, 0, chessColor);
        if (count >= 5) {
            flag =true;
        } else {
            count = this.chessCount(1, -1, chessColor);
            if (count >= 5) {
                flag = true;
            }else {
                count = this.chessCount(1, 1, chessColor);
                if (count >=5) {
                    flag = true;
                }
            }
        }
        return flag;
    }


    //判断棋子连接数量,也就是胜负
    private int chessCount(int xChange, int yChange, int chessColor) {
        int count = 1;
        int tempX = xChange;
        int tempY = yChange;
        while (x + xChange >= 0 && x + xChange <= 12
                && y + yChange >= 0 && y + yChange <= 11
                && chessColor == SavePoint[x + xChange][y + yChange]) {
            count++;
            if (xChange != 0) {
                xChange++;
            }
            if (yChange != 0) {
                if (yChange > 0) {
                    yChange++;
                } else {
                    yChange--;
                }
            }
        }
        xChange = tempX;
        yChange = tempY;
        while (x - xChange >= 0 && x - xChange <= 12
                && y - yChange >= 0 && y - yChange <= 11
                && chessColor == SavePoint[x - xChange][y - yChange]) {
            count++;
            if (xChange != 0) {
                xChange++;
            }
            if (yChange != 0) {
                if (yChange > 0) {
                    yChange++;
                } else {
                    yChange--;
                }
            }
        }
        return count;
    }


//    private boolean WinOrLose() {
//        boolean flag = false; //输赢
//        int conChess = 1; //相连数
//        int chessColor = SavePoint[x][y]; //记录棋子颜色

    //判断横向棋子是否相连
//        int i = 1; //迭代数
//        while (chessColor == SavePoint[x + i][y]) {
//            conChess++;
//            i++;
//        }
//        i = 1;
//        while (chessColor == SavePoint[x - i][y]) {
//            conChess++;
//            i++;
//        }
//        if (conChess == 5) {
//            flag = true;
//        }
//
//        //判断纵向棋子是否相连
//        conChess = 1;
//        i = 1;
//        while (chessColor == SavePoint[x][y + i]) {
//            conChess++;
//            i++;
//        }
//        i = 1;
//        while (chessColor == SavePoint[x][y - i]) {
//            conChess++;
//            i++;
//        }
//        if (conChess == 5) {
//            flag = true;
//        }
//
//        //判断左下右上是否相连
//        conChess = 1;
//        i = 1;
//        while (chessColor == SavePoint[x + i][y - i]) {
//            conChess++;
//            i++;
//        }
//        i = 1;
//        while (chessColor == SavePoint[x - i][y + i]) {
//            conChess++;
//            i++;
//        }
//        if (conChess == 5) {
//            flag = true;
//        }
//
//        //判断左上右下是否相连
//        conChess = 1;
//        i = 1;
//        while (chessColor == SavePoint[x - i][y - i]) {
//            conChess++;
//            i++;
//        }
//        i = 1;
//        while (chessColor == SavePoint[x + i][y + i]) {
//            conChess++;
//            i++;
//        }
//        if (conChess == 5) {
//            flag = true;
//        }
//        return flag;
//    }


    //初始化游戏封装到一个方法
    public void Initialize() {
        //遍历并初始化数组
        for (int i = 0; i < 14; i++) {
            for (int j = 0; j < 13; j++) {
                SavePoint[i][j] = 0;
            }
        }
        qc = 1;
        nextGo = "黑子先手";
        blackTime = maxTime;
        whiteTime = maxTime;
        if (maxTime > 0) {
            blackMessage = maxTime + "秒";
            whiteMessage = maxTime + "秒";
            if (startPlay == true) {
                thread.start(); //开启线程
            }
        }
        this.repaint();
    }


    @Override
    public void mouseClicked(MouseEvent e) {

    }

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

        if (startPlay == true) {
            if (x > qx && x < qx + qw && y > qy && y < qy + qh) {
                //计算点击位置最近的点
                if ((x - qx) % 35 > 17) {
                    x = (x - qx) / 35 + 1;
                } else {
                    x = (x - qx) / 35;
                }
                if ((y - qy) % 35 > 17) {
                    y = (y - qy) / 35 + 1;
                } else {
                    y = (y - qy) / 35;
                }

                //判断当前位置有没有棋子
                if (SavePoint[x][y] == 0) {
                    SavePoint[x][y] = qc;
                    qn = 0;
                } else {
                    JOptionPane.showMessageDialog(this, "当前位置有棋子");
                    qn = 1;
                }

                //切换棋子
                if (qn == 0) {
                    if (qc == 1) {
                        qc = 2;
                        nextGo = "轮到白子";
                    } else {
                        qc = 1;
                        nextGo = "轮到黑子";
                    }
                }

                this.repaint(); //重新执行依次paint方法

                //判断游戏是否结束
                boolean b = this.WinOrLose ();
                if (b) {
                    JOptionPane.showMessageDialog(this, "游戏结束" + (SavePoint[x][y] == 1 ? "黑棋win" : "白棋win"));
                    startPlay = false;
                }

            }
        }


        //实现开始按钮
        //判断是否点击开始按钮
        if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by && e.getY() < by + bh) {
            //判断游戏是否开始
            if (startPlay == false) {
                //游戏结束了,重新开始游戏
                startPlay = true;
                JOptionPane.showMessageDialog(this, "游戏开始");
                //初始化游戏
                Initialize();
                this.repaint();
            } else {
                //如果游戏正在进行,则重新开始
                int result = JOptionPane.showConfirmDialog(this, "是否确认重新开始游戏? ");
                if (result == 0) {
                    JOptionPane.showMessageDialog(this, "重新开始游戏");
                    Initialize();
                    this.repaint();
                }
            }
        }

        //实现悔棋按钮
        //判断是否点击悔棋按钮
        if (e.getX() > bx && e.getX() < bx + bw && e.getY() >= by + 50 && e.getY() <= by + bh + 50) {
            //判断游戏是否开始
            if (startPlay == true) {
                //遍历棋盘上的所有棋子
                int z = 0;
                for (int i = 0; i < 14; i++) {
                    for (int j = 0; j < 13; i++) {
                        if (SavePoint[i][j] != 0) {
                            z++;
                        }
                    }
                }
                //判断是否有棋子
                if (z != 0) {
                    JOptionPane.showMessageDialog(this, "不能悔棋");
                } else {
                    JOptionPane.showMessageDialog(this, "棋盘上无棋子");
                }
            } else {
                JOptionPane.showMessageDialog(this, "请先开始游戏");
            }
        }

        //实现认输按钮
        //判断是否点击认输按钮
        if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by + 100 && e.getY() < by + 100 + bh) {
            //判断游戏是否开始
            if (startPlay == true) {
                int anws = JOptionPane.showConfirmDialog(this, "是否确定认输? ");
                if (anws == 0) {
                    //判断是谁认输
                    if (qc == 1) {
                        JOptionPane.showMessageDialog(this, "黑方认输,白方获胜");
                        startPlay = false;
                        Initialize();
                    } else if (qc == 2) {
                        JOptionPane.showMessageDialog(this, "白方认输,黑方获胜");
                        startPlay = false;
                        Initialize();
                    }
                }
            } else {
                JOptionPane.showMessageDialog(this, "请先开始游戏");
            }
        }

        //实现游戏设置按钮
        if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by + 150 && e.getY() < by + 150 + bh) {
            String input = JOptionPane.showInputDialog("请输入游戏的最大时间(单位分钟) 如果输入0表示无限制时间");
            maxTime = Integer.parseInt(input) * 60;
            if (maxTime < 0) {
                JOptionPane.showMessageDialog(this, "输入错误,时间不可以为负数");
            }
            if (maxTime > 0) {
                int result = JOptionPane.showConfirmDialog(this, "设置成功,是否重新开始游戏?");
                if (result == 0) {
                    Initialize();
                    this.repaint();
                }
            }
            if (maxTime == 0) { //输入零表示没有时间限制
                int result = JOptionPane.showConfirmDialog(this, "无时间限制成功,是否重新开始游戏?");
                if (result == 0) {
                    Initialize();
                    this.repaint();
                }
            }
        }
    }


    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    @Override
    public void run() {
        //判断maxTime是否大于0
        //首先先判断是否有时间限制
        if (maxTime > 0) {
            while (true) {
                if (qc == 1) {
                    //黑棋,开启黑棋的时间线程,所以需要定义变量,保存黑方剩余时间
                    blackTime--;
                    if (blackTime == 0) {
                        JOptionPane.showMessageDialog(this, "黑方时间耗尽,结束游戏");
                        Initialize();
                    }
                } else {
                    whiteTime--;
                    if (whiteTime == 0) {
                        JOptionPane.showMessageDialog(this, "白方时间耗尽,结束游戏");
                        Initialize();
                    }
                }
                blackMessage = blackTime + "秒";
                whiteMessage = whiteTime + "秒";

                this.repaint();
                try {
                    thread.sleep(1000); //睡眠1000毫秒,因为倒计时是按1秒一秒减少
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        //没有时间限制不需要线程

    }
}

## 测试类
public class Test_ {
    public static void main(String[] args) {
        FiveChessFrame fiveChessFrame = new FiveChessFrame();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值