java小游戏:五子棋人机大战

一、java小游戏:五子棋人机大战

1.绘制窗口

package wuziqi;

import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class GameWindow {
    private JFrame frame = new JFrame();
    private Chessboard chessboard = new Chessboard();
    private static int WINDOW_WIDTH = 518;
    private static int WINDOW_HEIGHT = 540;
    /**
     * 绘制五子棋窗体
     */
    public void init() {
        frame.setTitle("五子棋");
        frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(chessboard);
        //使窗体可见
        frame.setVisible(true);
        /**
         * 实现点击鼠标落子的功能
         * 1.给棋盘添加监听事件==>鼠标点击事件
         * @param args
         */
        chessboard.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                //调用画棋子的方法
                play(e);
            }
        });
    }

    /**
     * 处理鼠标点击事件的方法
     * @param e
     */
    private void play(MouseEvent e) {
        //先把格子的大小求出来
        int cellsize = chessboard.getCellSize();
        //将鼠标的位置转成棋盘坐标的位置
        int x = (e.getX() - 5) / cellsize;
        int y = (e.getY() - 5) / cellsize;
        if (chessboard.isLegal(x, y)) {
            //添加棋子
            chessboard.addChess(new Location(x, y, 1));
            //添加棋子后需要占用的棋盘上的位置
            chessboard.addChess(x, y, 1);
            //判断输赢
            if (chessboard.isWin(x, y, 1)) {
                //信息提示框
                JOptionPane.showMessageDialog(frame, "人类获胜了", "您获胜了", JOptionPane.PLAIN_MESSAGE);
            }
            //机器落子
            Location location = chessboard.searchLocation();
            chessboard.addChess(location);
            chessboard.addChess(location.getX(),location.getY(),location.getOwner());
            if(chessboard.isWin(location.getX(),location.getY(),location.getOwner())){
                JOptionPane.showMessageDialog(frame,"机器获胜","Congratulations,您输了",JOptionPane.PLAIN_MESSAGE);
            }
        }
    }

    public static void main(String[] args) {
        new GameWindow().init();
    }
}

2.这个类是实现功能的主要代码

package wuziqi;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 棋盘类
 */
public class Chessboard extends JPanel {
    //规定由15条横竖线组成
    private static final int SIZE = 15;
    private int margin = 20;//外边距
    //创建一个容器来保存棋子对象
    private List<Location> locationList = new ArrayList<>();
    //储存棋盘中棋子占用情况
    private int[][] location = new int[SIZE][SIZE];
    //棋盘个位置的分数
    private int[][] score = new int[SIZE][SIZE];

    /**
     * 绘图工具
     * @param g 画笔工具
     */
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        //调用画棋盘的方法
        drawChessBoard(g);
        drawChess(g);
    }

    /**
     * 画棋盘的方法
     */
    private void drawChessBoard(Graphics g) {
        g.setColor(new Color(240, 210, 160));
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.BLACK);
        int cellsize = (getWidth() - 2 * margin) / (SIZE - 1);
        for (int i = 0; i < SIZE; i++) {
            //画横线
            g.drawLine(margin, margin + cellsize * i, getWidth() - 20, margin + (cellsize * i));
            //画竖线
            g.drawLine(margin + cellsize * i, margin, margin + cellsize * i, getHeight() - margin);
        }
    }

    /**
     * 画棋子的方法
     */
    public void drawChess(Graphics g) {
        for (int i = 0; i < locationList.size(); i++) {
            //如何辨别棋子的颜色
            Location loc = locationList.get(i);
            if (loc.getOwner() == 1) {
                g.setColor(Color.BLACK);//设置颜色为黑色
            } else {
                g.setColor(Color.WHITE);//设置颜色为白色
            }
            int cellsize = (getWidth() - 2 * margin) / (SIZE - 1);
            //画棋子
            g.fillOval(loc.getX() * cellsize + margin - cellsize / 2, loc.getY() * cellsize + margin - cellsize / 2, cellsize, cellsize);
            if (i == locationList.size() - 1) {
                //在最后一颗棋子外边绘制红色方框
                g.setColor(Color.red);
                g.drawRect(loc.getX() * cellsize + margin - cellsize / 2, loc.getY() * cellsize + margin - cellsize / 2, cellsize, cellsize);
            }
        }
    }

    /**
     * 落子的方法
     */
    public void addChess(Location location) {
        locationList.add(location);
        repaint();
    }

    /**
     * 获取格子的大小
     */
    public int getCellSize() {
        return (getWidth() - 2 * margin) / (SIZE - 1);
    }

    /**
     * 判断是否可以落子
     */
    public boolean isLegal(int x, int y) {
        if (x >= 0 && x <= SIZE && y >= 0 && y <= SIZE && location[x][y] == 0) {
            return true;
        }
        return false;
    }

    /**
     * 落子后占用棋盘的位置
     */
    public void addChess(int x, int y, int owner) {
        location[x][y] = owner;
    }

    /**
     * 判断输赢
     */
    public boolean isWin(int x, int y, int owner) {
        //创建一个变量用来记录,同一方向相同棋子的个数
        int sum = 0;
        //判断水平
        for (int i = x - 1; i >= 0; i--) {
            if (location[i][y] == owner) {
                sum++;
            } else {
                break;
            }
        }
        for (int i = x + 1; i < SIZE; i++) {
            if (location[i][y] == owner) {
                sum++;
            } else {
                break;
            }
        }
        if (sum >= 4) {
            return true;
        }
        //判断垂直
        sum = 0;
        for (int i = y - 1; i >= 0; i--) {
            if (location[x][i] == owner) {
                sum++;
            } else {
                break;
            }
        }
        for (int i = y + 1; i < SIZE; i++) {
            if (location[x][i] == owner) {
                sum++;
            } else {
                break;
            }
        }
        if (sum >= 4) {
            return true;
        }
        //判断左上方
        sum = 0;
        for (int i = x - 1, j = y - 1; i >= 0 && j >= 0; i--, j--) {
            if (location[i][j] == owner) {
                sum++;
            } else {
                break;
            }
        }
        for (int i = x + 1, j = y + 1; i < SIZE && j < SIZE; i++, j++) {
            if (location[i][j] == owner) {
                sum++;
            } else {
                break;
            }
        }
        if (sum >= 4) {
            return true;
        }
        //判断右上方
        sum = 0;
        for (int i = x + 1, j = y - 1; i < SIZE && j >= 0; i++, j--) {
            if (location[i][j] == owner) {
                sum++;
            } else {
                break;
            }
        }
        for (int i = x - 1, j = y + 1; i >= 0 && j < SIZE; i--, j++) {
            if (location[i][j] == owner) {
                sum++;
            } else {
                break;
            }
        }
        if (sum >= 4) {
            return true;
        }
        return false;
    }

    /**
     * 机器落子
     */
    public Location searchLocation() {
        //每次初始化score评分数组
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                score[i][j] = 0;
            }
        }
        int humanChessmanNum = 0;
        int machineChessmanNum = 0;
        int tupleScoreTmp = 0;

        int goalX = -1;
        int goalY = -1;
        int maxScore = -1;

        //扫描纵向15个行
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE - 4; j++) {
                int k = j;
                while (k < j + 5) {
                    if (location[i][k] == -1) machineChessmanNum++;
                    else if (location[i][k] == 1) humanChessmanNum++;
                    k++;
                }
                tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);
                for (k = j; k < j + 5; k++) {
                    score[i][k] += tupleScoreTmp;

                }
                humanChessmanNum = 0;
                machineChessmanNum = 0;
            }
        }

//        扫描横向15个行
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE - 4; j++) {
                int k = j;
                while (k < j + 5) {
                    if (location[k][i] == -1) machineChessmanNum++;
                    else if (location[k][i] == 1) humanChessmanNum++;
                    k++;
                }
                tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);
                for (k = j; k < j + 5; k++) {
                    score[k][i] += tupleScoreTmp;
                }
                humanChessmanNum = 0;
                machineChessmanNum = 0;
            }
        }
        //扫描右上角到左下角上侧部分
        for (int i = SIZE - 1; i >= 4; i--) {
            for (int k = i, j = 0; j < SIZE && k >= 0; j++, k--) {
                int m = k;
                int n = j;
                while (m > k - 5 && k - 5 >= -1) {
                    if (location[m][n] == -1) machineChessmanNum++;
                    else if (location[m][n] == 1) humanChessmanNum++;
                    m--;
                    n++;
                }
                if (m == k - 5) {
                    tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);
                    for (m = k, n = j; m > k - 5; m--, n++) {
                        score[m][n] += tupleScoreTmp;
                    }
                }
                humanChessmanNum = 0;
                machineChessmanNum = 0;
            }
        }
        for (int i = 1; i < SIZE; i++) {
            for (int k = i, j = SIZE - 1; j >= 0 && k < SIZE; j--, k++) {
                int m = k;
                int n = j;
                while (m < k + 5 && k + 5 <= SIZE) {
                    if (location[n][m] == -1) machineChessmanNum++;
                    else if (location[n][m] == 1) humanChessmanNum++;
                    m++;
                    n--;
                }
                if (m == k + 5) {
                    tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);
                    for (m = k, n = j; m < k + 5; m++, n--) {
                        score[n][m] += tupleScoreTmp;
                    }
                }
                humanChessmanNum = 0;
                machineChessmanNum = 0;
            }
        }


        //↖
        for (int i = 0; i < SIZE - 4; i++) {
            for (int k = i, j = 0; j < SIZE - 4 && k < SIZE - 4; j++, k++) {
                int m = k;
                int n = j;
                while (m < k + 5 && n < j + 5) {
                    if (location[m][n] == -1) machineChessmanNum++;
                    else if (location[m][n] == 1) humanChessmanNum++;
                    m++;
                    n++;
                }
                if (m == k + 5) {
                    tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);
                    for (m = k, n = j; m < k + 5; m++, n++) {
                        score[m][n] += tupleScoreTmp;
                    }
                }
                humanChessmanNum = 0;
                machineChessmanNum = 0;
            }
        }

        for (int i = 0; i < SIZE - 4; i++) {
            for (int k = i, j = 0; j < SIZE - 4 && k < SIZE - 4; j++, k++) {
                if (j == k) break;
                int m = k;
                int n = j;
                while (m < k + 5 && n < j + 5) {
                    if (location[n][m] == -1) machineChessmanNum++;
                    else if (location[n][m] == 1) humanChessmanNum++;
                    m++;
                    n++;
                }
                if (m == k + 5) {
                    tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);
                    for (m = k, n = j; m < k + 5; m++, n++) {
                        score[n][m] += tupleScoreTmp;
                    }
                }
                humanChessmanNum = 0;
                machineChessmanNum = 0;
            }
        }


        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                if (location[i][j] == 0 && score[i][j] > maxScore) {
                    goalX = i;
                    goalY = j;
                    maxScore = score[i][j];
                }
            }
        }
        if (goalX != -1 && goalY != -1) {
            return new Location(goalX, goalY, -1);
        }
        return new Location(-1, -1, -1);
    }

    /**
     * 判断得分
     */
    public int tupleScore(int humanCHessNum, int machineChessNum) {
        if (humanCHessNum > 0 && machineChessNum > 0) {
            return 0;
        }
        if (humanCHessNum == 0 && machineChessNum == 0) {
            return 7;
        }
        if (machineChessNum == 1) {
            return 35;
        }
        if (machineChessNum == 2) {
            return 800;
        }
        if (machineChessNum == 3) {
            return 3000;
//            return 15000;
        }
        if (machineChessNum == 4) {
            return 800000;
        }
        if (humanCHessNum == 1) {
            return 15;
        }
        if (humanCHessNum == 2) {
            return 400;
        }
        if (humanCHessNum == 3) {
            return 2000;
        }
        if (humanCHessNum == 4) {
            return 100000;
        }
        return -1;
    }
}

3.棋子对象类

package wuziqi;

public class Location {
    private int x;//棋盘上x坐标
    private int y;//棋盘上y坐标
    private int owner;//1:人类:-1:机器 0:空

    public Location(int x, int y, int owner) {
        this.x = x;
        this.y = y;
        this.owner = owner;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getOwner() {
        return owner;
    }

    public void setOwner(int owner) {
        this.owner = owner;
    }
}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值