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.net.URL;

public class GobangGame {
    public static void main(String[] args) {
        GameF game = new GameF();
        game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        game.show();
    }
}

class GameF extends JFrame {
    public GameF() {
        Container contentPane = getContentPane();
        final Panel panel = new Panel();
        panel.setBackground(new Color(255, 182, 147));
        contentPane.setBackground(new Color(255, 182, 147));
        contentPane.add(panel);
        setSize(560, 560);
        setTitle("杨雷的五子棋游戏 版本1.0");
        setResizable(false);
        panel.setCursor(new Cursor(Cursor.HAND_CURSOR));
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("选项");
        JMenuItem menuStart = new JMenuItem("开始游戏");
        menuStart.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                panel.ResetGame();
                panel.repaint();
            }
        });
        JMenuItem menuExit = new JMenuItem("退出");
        menuExit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        menuBar.add(menu);
        menu.add(menuStart);
        menu.add(menuExit);
        this.setJMenuBar(menuBar);
    }
}

class Panel extends JPanel {
    private URL blackImgURL = GobangGame.class.getResource("black.gif");
    private ImageIcon black = new ImageIcon(blackImgURL);
    private URL whiteImgURL = GobangGame.class.getResource("white.gif");
    private ImageIcon white = new ImageIcon(whiteImgURL);
    private URL currentImgURL = GobangGame.class.getResource("current.gif");
    private ImageIcon current = new ImageIcon(currentImgURL);
    private int i, j, k, m, n, icount;
    private int[][] board = new int[16][16];
    private boolean[][][] ptable = new boolean[16][16][672];
    private boolean[][][] ctable = new boolean[16][16][672];
    private int[][] cgrades = new int[16][16];
    private int[][] pgrades = new int[16][16];
    private int cgrade, pgrade;
    private int[][] win = new int[2][672];
    private int oldx, oldy;
    private int bout = 1;
    private int pcount, ccount;
    private boolean player, computer, over, pwin, cwin, tie, start;
    private int mat, nat, mde, nde;

    public Panel() {
        addMouseListener(new Xiazi());
        this.ResetGame();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < 16; i++)
            for (int j = 0; j < 16; j++) {
                g.drawLine(50, 50 + j * 30, 500, 50 + j * 30);
            }
        for (int i = 0; i < 16; i++)
            for (int j = 0; j < 16; j++) {
                g.drawLine(50 + j * 30, 50, 50 + j * 30, 500);
            }
        for (int i = 0; i < 16; i++) {
            String number = Integer.toString(i);
            g.drawString(number, 46 + 30 * i, 45);
        }
        for (int i = 1; i < 16; i++) {
            String number = Integer.toString(i);
            g.drawString(number, 33, 53 + 30 * i);
        }
        updatePaint(g);
    }

    class Xiazi extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            if (!over) {
                oldx = e.getX();
                oldy = e.getY();
                mouseClick();
                repaint();
            }
        }
    }

    //      游戏初始化
    public void ResetGame() {
        //初始化棋盘
        for (i = 0; i < 16; i++)
            for (j = 0; j < 16; j++) {
                this.pgrades[i][j] = 0;
                this.cgrades[i][j] = 0;
                this.board[i][j] = 2;
            }
        //遍历所有的五连子可能情况的权值
        //横
        for (i = 0; i < 16; i++)
            for (j = 0; j < 12; j++) {
                for (k = 0; k < 5; k++) {
                    this.ptable[j + k][i][icount] = true;
                    this.ctable[j + k][i][icount] = true;
                }
                icount++;
            }
        //竖
        for (i = 0; i < 16; i++)
            for (j = 0; j < 12; j++) {
                for (k = 0; k < 5; k++) {
                    this.ptable[i][j + k][icount] = true;
                    this.ctable[i][j + k][icount] = true;
                }
                icount++;
            }
        //右斜
        for (i = 0; i < 12; i++)
            for (j = 0; j < 12; j++) {
                for (k = 0; k < 5; k++) {
                    this.ptable[j + k][i + k][icount] = true;
                    this.ctable[j + k][i + k][icount] = true;
                }
                icount++;
            }
        //左斜
        for (i = 0; i < 12; i++)
            for (j = 15; j >= 4; j--) {
                for (k = 0; k < 5; k++) {
                    this.ptable[j - k][i + k][icount] = true;
                    this.ctable[j - k][i + k][icount] = true;
                }
                icount++;
            }
        for (i = 0; i <= 1; i++)  //初始化黑子白子上的每个权值上的连子数
            for (j = 0; j < 672; j++)
                this.win[i][j] = 0;
        this.player = true;
        this.icount = 0;
        this.ccount = 0;
        this.pcount = 0;
        this.start = true;
        this.over = false;
        this.pwin = false;
        this.cwin = false;
        this.tie = false;
        this.bout = 1;
    }

    public void ComTurn() {     //找出电脑(白子)最佳落子点
        for (i = 0; i <= 15; i++)     //遍历棋盘上的所有坐标
            for (j = 0; j <= 15; j++) {
                this.pgrades[i][j] = 0;  //该坐标的黑子奖励积分清零
                if (this.board[i][j] == 2)  //在还没下棋子的地方遍历
                    for (k = 0; k < 672; k++)    //遍历该棋盘可落子点上的黑子所有权值的连子情况,并给该落子点加上相应奖励分
                        if (this.ptable[i][j][k]) {
                            switch (this.win[0][k]) {
                                case 1: //一连子
                                    this.pgrades[i][j] += 5;
                                    break;
                                case 2: //两连子
                                    this.pgrades[i][j] += 50;
                                    break;
                                case 3: //三连子
                                    this.pgrades[i][j] += 180;
                                    break;
                                case 4: //四连子
                                    this.pgrades[i][j] += 400;
                                    break;
                            }
                        }
                this.cgrades[i][j] = 0;//该坐标的白子的奖励积分清零
                if (this.board[i][j] == 2)  //在还没下棋子的地方遍历
                    for (k = 0; k < 672; k++)     //遍历该棋盘可落子点上的白子所有权值的连子情况,并给该落子点加上相应奖励分
                        if (this.ctable[i][j][k]) {
                            switch (this.win[1][k]) {
                                case 1:  //一连子
                                    this.cgrades[i][j] += 5;
                                    break;
                                case 2:  //两连子
                                    this.cgrades[i][j] += 52;
                                    break;
                                case 3: //三连子
                                    this.cgrades[i][j] += 100;
                                    break;
                                case 4:  //四连子
                                    this.cgrades[i][j] += 400;
                                    break;
                            }
                        }
            }
        if (this.start) {      //开始时白子落子坐标
            if (this.board[4][4] == 2) {
                m = 4;
                n = 4;
            } else {
                m = 5;
                n = 5;
            }
            this.start = false;
        } else {
            for (i = 0; i < 16; i++)
                for (j = 0; j < 16; j++)
                    if (this.board[i][j] == 2) {  //找出棋盘上可落子点的黑子白子的各自最大权值,找出各自的最佳落子点
                        if (this.cgrades[i][j] >= this.cgrade) {
                            this.cgrade = this.cgrades[i][j];
                            this.mat = i;
                            this.nat = j;
                        }
                        if (this.pgrades[i][j] >= this.pgrade) {
                            this.pgrade = this.pgrades[i][j];
                            this.mde = i;
                            this.nde = j;
                        }
                    }
            if (this.cgrade >= this.pgrade) {   //如果白子的最佳落子点的权值比黑子的最佳落子点权值大,则电脑的最佳落子点为白子的最佳落子点,否则相反
                m = mat;
                n = nat;
            } else {
                m = mde;
                n = nde;
            }
        }
        this.cgrade = 0;
        this.pgrade = 0;
        this.board[m][n] = 1;  //电脑下子位置
        ccount++;
        if ((ccount == 50) && (pcount == 50))  //平局判断
        {
            this.tie = true;
            this.over = true;
        }
        for (i = 0; i < 672; i++) {
            if (this.ctable[m][n][i] && this.win[1][i] != 7)
                this.win[1][i]++;     //给白子的所有五连子可能的加载当前连子数
            if (this.ptable[m][n][i]) {
                this.ptable[m][n][i] = false;
                this.win[0][i] = 7;
            }
        }
        this.player = true;     //该人落子
        this.computer = false;  //电脑落子结束
    }

    public void mouseClick() {
        if (!this.over)
            if (this.player) {
                if (this.oldx < 520 && this.oldy < 520) {
                    int m1 = m, n1 = n;
                    m = (oldx - 33) / 30;
                    n = (oldy - 33) / 30;
                    if (this.board[m][n] == 2) {
                        this.bout++;
                        this.board[m][n] = 0;
                        pcount++;
                        if ((ccount == 50) && (pcount == 50)) {
                            this.tie = true;
                            this.over = true;
                        }
                        for (i = 0; i < 672; i++) {
                            if (this.ptable[m][n][i] && this.win[0][i] != 7)
                                this.win[0][i]++;     //给黑子的所有五连子可能的加载当前连子数
                            if (this.ctable[m][n][i]) {
                                this.ctable[m][n][i] = false;
                                this.win[1][i] = 7;
                            }
                        }
                        this.player = false;
                        this.computer = true;
                    } else {
                        m = m1;
                        n = n1;
                    }
                }
            }
    }

    public void updatePaint(Graphics g) {
        if (!this.over) {   //如果是轮到电脑下
            if (this.computer)
                this.ComTurn();  //得到最佳下子点
            //遍历当前棋盘上的五连子情况,判断输赢
            for (i = 0; i <= 1; i++)
                for (j = 0; j < 672; j++) {
                    if (this.win[i][j] == 5)
                        if (i == 0) {                //人赢
                            this.pwin = true;
                            this.over = true;    //游戏结束
                            break;
                        } else {
                            this.cwin = true;    //电脑赢
                            this.over = true;
                            break;
                        }
                    if (this.over)               //一遇到五连子退出棋盘遍历
                        break;
                }
            g.setFont(new Font("华文行楷", 0, 20));
            g.setColor(Color.RED);
            //画出当前棋盘所有棋子
            for (i = 0; i <= 15; i++)
                for (j = 0; j <= 15; j++) {   //如果board元素值为0,则该坐标处为黑子
                    if (this.board[i][j] == 0) {
                        g.drawImage(black.getImage(), i * 30 + 31, j * 30 + 31, black.getImage().getWidth(black.getImageObserver()) - 3, black.getImage().getHeight(black.getImageObserver()) - 3, black.getImageObserver());
                    }
                    //如果board元素值为1,则该坐标处为白子
                    if (this.board[i][j] == 1) {
                        g.drawImage(white.getImage(), i * 30 + 31, j * 30 + 31, white.getImage().getWidth(white.getImageObserver()) - 3, white.getImage().getHeight(white.getImageObserver()) - 3, white.getImageObserver());
                    }
                }
            //画出白子(电脑)当前所下子,便于辨认
            if (this.board[m][n] != 2)
                g.drawImage(current.getImage(), m * 30 + 31, n * 30 + 31, current.getImage().getWidth(current.getImageObserver()) - 4, current.getImage().getHeight(current.getImageObserver()) - 4, current.getImageObserver());
            //判断输赢情况
            //人赢
            if (this.pwin)
                g.drawString("您太厉害了!再来一次请重新开始游戏..", 20, 200);
            //电脑赢
            if (this.cwin)
                g.drawString("很遗憾,你输了!再来一次请重新开始游戏..", 84, 190);
            //平局
            if (this.tie)
                g.drawString("不分胜负!再来一次请重新开始游戏..", 80, 200);
            g.dispose();
        }
    }
}
最近下载更多
lhm789  LV6 9月23日
OCattttt  LV1 2023年12月27日
FanfanCHAN  LV1 2023年9月8日
284463383  LV1 2023年6月7日
fenghuijun  LV26 2023年3月30日
hainabian1977  LV2 2023年2月27日
刘鹏yyds  LV10 2022年12月20日
微信网友_6257338740510720  LV1 2022年12月11日
微信网友_6238964698468352  LV1 2022年11月28日
m1kasa  LV1 2022年11月17日
最近浏览更多
lhm789  LV6 9月23日
YYZQ编程  LV1 2023年12月28日
ClydeSon  LV5 2023年12月27日
OCattttt  LV1 2023年12月27日
大薯片子  LV1 2023年12月4日
FanfanCHAN  LV1 2023年9月8日
wangjialiang1  LV17 2023年8月20日
2385649653  LV7 2023年6月25日
284463383  LV1 2023年6月7日
shunjiann 2023年6月1日
暂无贡献等级
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友