五子棋———完美注释版,免费分享!!!

来源:互联网 发布:java 费用报销系统 编辑:程序博客网 时间:2024/05/21 08:10

这是一个基于穷举算法的五子棋。人机大战时,计算机的算法是扫描穷举法。下面是核心类的代码。

import javax.swing.JOptionPane;import javax.swing.JPanel;//五子棋游戏的核心类public class GoGame {    // 棋盘的高度,宽度。chessModel代表棋盘的种类1为20*15,2为30*20,3为40*30    private int height, width, chessModel;    // 棋盘的横纵坐标,用于获取点击坐标的,初始化的值为零。    private int x = 0, y = 0;    // 棋盘对应的颜色,取1,2,3,-5。    // 1代表棋盘格上为黑子,2代表棋盘格上位白子,3代表棋盘格上没有棋子,-5代表棋盘格上不能下子//包括了边    private int[][] chessMapShow;    // isOdd交换棋手的标志,true是黑子(玩家)下,false是白子下,但是下完子之后,isodd马上会变成对方的标志。    // isExist某棋盘格子上是否有棋子的标识true代表有棋子。    private boolean isOdd, isExist;    // 无参数的构造方法    public GoGame() {    }    // 有参数的构造方法,初始化棋盘的数组,调用初始化棋盘的方法。    public GoGame(int chessModel) {        this.isOdd = true;        if (chessModel == 1) {            PanelInit(20, 15, chessModel);        }        if (chessModel == 2) {            PanelInit(30, 20, chessModel);        }        if (chessModel == 3) {            PanelInit(40, 30, chessModel);        }    }    // 构造好棋盘的布局,只有本类能够调用,因为只有在构造初始化的时候调用,外部类不需要调用    private void PanelInit(int width, int height, int chessModel) {        this.width = width;        this.height = height;        this.chessModel = chessModel;        this.chessMapShow = new int[width + 1][height + 1];        // 行数代表高度,列数代表宽度        for (int i = 0; i <= width; i++) {            for (int j = 0; j <= height; j++) {                chessMapShow[i][j] = -5;// 首先是不能下棋的            }        }    }    // 获取是否交换棋手的标识    public boolean getIsOdd() {        return this.isOdd;    }    // 设置交换棋手的标志。    public void setIsOdd(boolean isOdd) {        if (isOdd) {            this.isOdd = true;        }else {            this.isOdd =false;      }    }    // 获取该棋盘某一格子上是否有棋子的标识    public boolean getIsExist() {        return this.isExist;    }    // 获取棋盘高度    public int getHeight() {        return this.height;    }    // 获取棋盘宽度    public int getWidth() {        return this.width;    }    // 获取棋盘的种类    public int getChessModel() {        return this.chessModel;    }    // 获取棋盘的地图上的棋格子的信息。    public int[][] getChessMapShow() {        return this.chessMapShow;    }    // 判断是下子是否横向越界,或纵向越界。    public boolean overMap(int y, int x) {        // 横向越界        if (x >= width + 20 || x < 0)            return true;        // 纵向越界        return y >= height + 20 || y < 0;    }    // 判断是格子上是否有棋子了    public boolean chessExist(int i, int j) {        // 如果数组上已经有黑子和白子,就返回true        if (chessMapShow[i][j] == 1 || chessMapShow[i][j] == 2) {            return true;        }        return false;    }    // 准备下棋,把坐标xy的棋格上变成可以下棋的数字标志。    public void readyUp(int x, int y) {        // 如果坐标xy越界了棋盘数组,就退出方法。        if (overMap(x, y)) {            return;        }        // 如果坐标xy上已经有棋子了,就退出方法。        if (chessExist(x, y)) {            this.isExist = true;            return;        }        // 如果不存在棋子要没有越界,就把这个坐标的棋格上改为可以下棋        chessMapShow[x][y] = 3;    }    // 在某一位置上下棋    public void upChess(int x, int y) {        // 如果越界了,退出方法。        if (overMap(x, y)) {            return;        }        // 如果存在棋子了,设置isExist标志成为true        if (chessExist(x, y)) {            this.isExist = true;            return;        } else {            this.isExist = false;            if (getIsOdd()) {                // isOdd如果是true就下的是黑子,是false就下的是白子。                // 总是要把交换标识isOdd变成对方执手,让对方下棋。                setIsOdd(false);                this.chessMapShow[x][y] = 1;            } else {                setIsOdd(true);                this.chessMapShow[x][y] = 2;            }        }    }    // 记录电脑下子横向坐标    public void setX(int x) {        this.x = x;    }    // 记录电脑下子的纵向坐标    public void setY(int y) {        this.y = y;    }    // 获取电脑下子的横向坐标    public int getX() {        return this.x;    }    // 获取电脑下子的纵向坐标    public int getY() {        return this.y;    }    // 计算某一格子上的四个直线方向的棋子的最大值    // 左,右直线方向。    // 上下直线方向。    // 左上,右下直线方向。    // 右上,左下直线方向。    // black_or_write是传进的数值,1位黑,2为白。    public int checkMax(int x, int y, int black_or_write) {        // num是计棋子数。max_num是自大棋子数,最终的返回值。max_temp是临时的用来 记录临时的最大的棋子数。        int num = 0, max_num, max_temp = 0;        // 为了不破坏传进来的xy值,用来存储此刻棋子格子的坐标        int x_temp = x, y_temp = y;        // 指针,二维指向坐标xy为中心的八个方向,四条直线。        int x_temp1 = x_temp, y_temp1 = y_temp;        // 判断右边,接着就是判断右边。每次相对传入xy坐标循环四次。        for (int i = 1; i < 5; i++) {            x_temp1 += 1;            if (x_temp1 > this.width) {                break;            }            if (chessMapShow[x_temp1][y_temp1] == black_or_write) {                num++;            } else {                break;            }        }        // 判断左边,指针退指向原来的xy坐标位置        x_temp1 = x_temp;        for (int i = 1; i < 5; i++) {            x_temp1 -= 1;            if (x_temp1 < 0) {                break;            }            if (chessMapShow[x_temp1][y_temp1] == black_or_write) {                num++;            } else {                break;            }        }        if (num < 5) {            max_temp = num;        }        // 判断上边,同样要先复原指针恢复为xy的坐标位置        x_temp1 = x_temp;        y_temp1 = y_temp;        num = 0;        for (int i = 1; i < 5; i++) {            y_temp1 -= 1;            if (y_temp1 < 0) {                break;            }            if (chessMapShow[x_temp1][y_temp1] == black_or_write) {                num++;            } else {                break;            }        }        // 判断下边        y_temp1 = y_temp;        num = 0;        for (int i = 1; i < 5; i++) {            y_temp1 += 1;            if (y_temp1 > this.height) {                break;            }            if (chessMapShow[x_temp1][y_temp1] == black_or_write) {                num++;            } else {                break;            }        }        // 如果num大于上一次记录最大量。就把num的值传入max_num.        if (num > max_temp && num < 5) {            max_temp = num;        }        // 判断左上        x_temp1 = x_temp;        y_temp1 = y_temp;        num = 0;        for (int i = 1; i < 5; i++) {            x_temp1 -= 1;            y_temp1 -= 1;            if (y_temp1 < 0 || x_temp1 < 0) {                break;            }            if (chessMapShow[x_temp1][y_temp1] == black_or_write) {                num++;            } else {                break;            }        }        // 判断右下        x_temp1 = x_temp;        y_temp1 = y_temp;        for (int i = 1; i < 5; i++) {            x_temp1 += 1;            y_temp1 += 1;            if (y_temp1 > this.height || x_temp1 > this.width) {                break;            }            if (chessMapShow[x_temp1][y_temp1] == black_or_write) {                num++;            } else {                break;            }        }        if (num > max_temp && num < 5) {            max_temp = num;        }        // 判断右上        x_temp1 = x_temp;        y_temp1 = y_temp;        num = 0;        for (int i = 1; i < 5; i++) {            x_temp1 += 1;            y_temp1 -= 1;            if (y_temp1 < 0 || x_temp1 > this.width) {                break;            }            if (chessMapShow[x_temp1][y_temp1] == black_or_write) {                num++;            } else {                break;            }        }        // 判断左下        x_temp1 = x_temp;        y_temp1 = y_temp;        num = 0;        for (int i = 1; i < 5; i++) {            x_temp1 -= 1;            y_temp1 += 1;            if (y_temp1 > this.height || x_temp1 < 0) {                break;            }            if (chessMapShow[x_temp1][y_temp1] == black_or_write) {                num++;            } else {                break;            }        }        if (num > max_temp && num < 5) {            max_temp = num;        }        max_num = max_temp;        return max_num;    }    // 判断输赢,计算机和玩家下完棋之后都要调用的方法。    public boolean judgeSuccess(int x, int y, boolean isOdd) {        // 表示棋子在xy上有一颗棋子。        int num = 1;        int arrvalue;//是谁下的子。1为黑子,2为白子。        int x_temp = x, y_temp = y;        if (isOdd) {            arrvalue = 2;        } else {            arrvalue = 1;        }        //设置横纵的两个指针。        int x_temp1 = x_temp, y_temp1 = y_temp;        // 判断右边        for (int i = 1; i < 6; i++) {            x_temp1 += 1;            if (x_temp1 > width) {                break;            }            if (this.chessMapShow[x_temp1][y_temp1] == arrvalue) {                num++;            } else {                break;            }        }        // 判断左边        x_temp1 = x_temp;        for (int i = 1; i < 6; i++) {            x_temp1 -= 1;            if (x_temp1 < 0) {                break;            }            if (this.chessMapShow[x_temp1][y_temp1] == arrvalue) {                num++;            } else {                break;            }        }        if (num == 5) {            return true;        }        // 判断上面        x_temp1 = x_temp;        y_temp1 = y_temp;        num = 1;        for (int i = 1; i < 6; i++) {            y_temp1 -= 1;            if (y_temp1 < 0) {                break;            }            if (this.chessMapShow[x_temp1][y_temp1] == arrvalue) {                num++;            } else {                break;            }        }        // 判断下面        y_temp1 = y_temp;        for (int i = 1; i < 6; i++) {            y_temp1 += 1;            if (y_temp1 > this.height) {                break;            }            if (this.chessMapShow[x_temp1][y_temp1] == arrvalue) {                num++;            } else {                break;            }        }        if (num == 5) {            return true;        }        // 判断左上        x_temp1 = x_temp;        y_temp1 = y_temp;        num = 1;        for (int i = 1; i < 6; i++) {            x_temp1 -= 1;            y_temp1 -= 1;            if (y_temp1 < 0 || x_temp1 < 0) {                break;            }            if (this.chessMapShow[x_temp1][y_temp1] == arrvalue) {                num++;            } else {                break;            }        }        // 判断右下        x_temp1 = x_temp;        y_temp1 = y_temp;        for (int i = 1; i < 6; i++) {            y_temp1 += 1;            x_temp1 += 1;            if (y_temp1 > this.height || x_temp1 > this.width) {                break;            }            if (this.chessMapShow[x_temp1][y_temp1] == arrvalue) {                num++;            } else {                break;            }        }        if (num == 5) {            return true;        }        // 判断右上        x_temp1 = x_temp;        y_temp1 = y_temp;        num = 1;        for (int i = 1; i < 6; i++) {            x_temp1 += 1;            y_temp1 -= 1;            if (y_temp1 < 0 || x_temp1 > this.width) {                break;            }            if (this.chessMapShow[x_temp1][y_temp1] == arrvalue) {                num++;            } else {                break;            }        }        // 判断左下        x_temp1 = x_temp;        y_temp1 = y_temp;        for (int i = 1; i < 6; i++) {            y_temp1 += 1;            x_temp1 -= 1;            if (y_temp1 > this.height || x_temp1 < 0) {                break;            }            if (this.chessMapShow[x_temp1][y_temp1] == arrvalue) {                num++;            } else {                break;            }        }        if (num == 5) {            return true;        }        return false;    }    // 显示赢了之后的界面    public void showSuccess(JPanel jp) {        JOptionPane.showMessageDialog(jp, "你赢了,你好厉害", "win", JOptionPane.INFORMATION_MESSAGE);    }    // 显示输了之后的界面    public void showDefeat(JPanel jp) {        JOptionPane.showMessageDialog(jp, "你输了,好遗憾", "you lose", JOptionPane.INFORMATION_MESSAGE);    }    // 计算机走棋,使用穷举法计算每一个做标点的上下左右四个方向的最大棋子数,最后得出棋子数最大值的坐标,下子    public void computerUpchess(int width, int height) {        int max_black, max_write, max_temp, max = 0;        setIsOdd(true);// 先交换棋手,不然永远都是计算机下棋了,永远都是白子。true黑子才是黑子,是玩家下棋。        System.out.println("计算机走棋。。。。");        for (int i = 0; i <= this.width; i++) {            for (int j = 0; j <= this.height; j++) {                // 双重循环的中,如这一点上子多,就堵住                if (!chessExist(i, j)&&!overMap(i, j)) {// 判断是否下棋                    max_write = checkMax(i, j, 2);// 判断白子的最大值                    max_black = checkMax(i, j, 1);                    //把白子和黑子的最大值付给max_temp变量。                    max_temp = Math.max(max_write, max_black);                    if (max_temp > max) {                        //把最佳下子位置记录下来。                        max = max_temp;                        this.x = i;                        this.y = j;                    }                }            }        }        //下完棋一定要设置自己下棋的位置,为了计算机下棋之后判断输赢用。        //计算机下完棋之后,调用getX和getY来判断计算机输赢。        setX(this.x);        setY(this.y);        //下白子。        chessMapShow[this.x][this.y] = 2;    }}

下面是为了界面化面板类的代码:实现了点击下棋和画出棋盘和棋子。

import java.awt.Color;import java.awt.Graphics;import java.awt.color.CMMException;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseMotionListener;import javax.swing.JOptionPane;import javax.swing.JPanel;/** * @author 王爷 此类主要是完成如下的功能 1.构建一个面板,并在面板上画棋盘。 2.处理该面板上的事件 */public class ChessPanel extends JPanel implements MouseListener, MouseMotionListener {    // 棋盘的高度和宽度    private int width, height;    // 为了从核心类获取棋盘的信息来画数组,这里设置一个引用。在构造方法里传入对象。    private GoGame goGame;    // 构造方法,传入核心对象,并从核心对象获取高度和宽度的属性。    public ChessPanel(GoGame goGame) {        this.goGame = goGame;        this.width = goGame.getWidth();        this.height = goGame.getHeight();        addMouseListener(this);// 为整个花瓣添加点击事件。    }    // 设置gogame的高度和宽度    public void setGoGame(GoGame goGame) {        this.goGame = goGame;        width = goGame.getWidth();        height = goGame.getHeight();    }    // 根据坐标计算出棋盘每一个棋格的信息(如是黑子还是白子)    // 然后调用draw方法上画出棋子。draw之后自己定义。    @Override    protected void paintComponent(Graphics g) {        super.paintComponent(g);        // 画出出边界之外 的棋盘。遍历数组时一定要从0开始便利,        //不然计算机下棋不会显示,自己下棋也不能下在第一列和第一行!!!我调试过很久才调出来。        //忘要参考的读者莫要饭错误        for (int i = 0; i <= this.width; i++) {            for (int j = 0; j <= this.height; j++) {                int v = goGame.getChessMapShow()[i][j];                // i是横坐标,j是纵坐标。                draw(g, i, j, v);            }        }    }    // 根据提供的xy坐标画出棋子和棋盘。    private void draw(Graphics g, int i, int j, int v) {        //背景随便什么颜色都行,如果用常量值不爽,可以自己实例化一个Color对象出来,然后传入rgb数值。        setBackground(Color.CYAN);        // 这样画的棋盘就不会从面板边缘开始。        int x = 20 * i + 20;        int y = 20 * j + 20;        // 先把画布都画成白色的矩形框。        if (i != width && j != height) {            g.setColor(Color.white);            g.fillRect(x, y, 20, 20);            g.setColor(Color.BLACK);            g.drawRect(x, y, 20, 20);        }        // 画黑子        if (v == 1) {            g.setColor(Color.black);            g.fillOval(x - 8, y - 8, 16, 16);            g.setColor(Color.gray);            // 绘制椭圆,分别根据左上角的横纵坐标,椭圆的高度和宽度椭圆            g.drawOval(x - 8, y - 8, 16, 16);        }        // 画白子        if (v == 2) {            g.setColor(Color.white);            g.fillOval(x - 8, y - 8, 16, 16);            g.setColor(Color.gray);            g.drawOval(x - 8, y - 8, 16, 16);        }        if (v == 3) {            // 设置为青色            g.setColor(Color.cyan);            g.drawOval(x - 8, y - 8, 16, 16);        }    }    // 棋盘画布的点击事件    @Override    public void mousePressed(MouseEvent e) {        // 获取鼠标点击的坐标xy        // 因为在ChessBoard类中的MapSize()方法中,高度和宽度是width*20+50和height*20+100,所以坐标要除以20        // 而在画棋子的时候,我们为了让边缘不是在窗口的界面边缘,我们加上了一个矩形的宽度,所以下棋时要减去半个矩形的宽度。        int x = (e.getX() - 10) / 20;        int y = (e.getY() - 10) / 20;        System.out.println("横坐标:" + x + "纵坐标:" + y);        // 如果获取的是鼠标的事件的掩码。则下棋        if (e.getModifiers() == MouseEvent.BUTTON1_MASK) {            goGame.upChess(x, y);        }        System.out.println(goGame.getIsOdd() + "" + goGame.getChessMapShow()[x][y]);        repaint();        // 下完棋之后我,我们根据这个坐标来判断玩家的输赢        // 用户判断输赢时是根据鼠标获取的位置对映的数组坐标来判断的。        if (goGame.judgeSuccess(x, y, goGame.getIsOdd())) {            goGame.showSuccess(this);            // 不能让鼠标继续下棋了。鼠标点击面板没有用了。所以销毁传入的鼠标对象            e.consume();            // 把状态量改为false,表示不是计算机下棋。            ChessBoard.isComputer = false;        }        // 判断是否为人机对弈,如果是人机对弈而且棋子不存在。,就计算机下棋        if (ChessBoard.isComputer && !goGame.getIsExist()) {            goGame.computerUpchess(goGame.getWidth(), goGame.getHeight());            repaint();            // 计算机下棋,他会记录自己下的坐标,所以在判断输赢时,要用getX和getY方法判断。            System.out.println(goGame.getIsOdd());            System.out.println(goGame.getX()+" "+goGame.getY());            if (goGame.judgeSuccess(goGame.getX(), goGame.getY(), goGame.getIsOdd())) {                goGame.showDefeat(this);                // 计算机赢了也不能下棋了。所以销毁传入的鼠标对象                e.consume();            }        }    }    // 鼠标拖动事件    @Override    public void mouseMoved(MouseEvent e) {        int x = (e.getX() - 10) / 20;        int y = (e.getY() - 10) / 20;        // 鼠标移动到哪一点,数组就会响应的变为可以下棋状态。        goGame.readyUp(x, y);        repaint();    }    // 显示赢了之后的界面    public void showSuccess(JPanel jp) {        JOptionPane.showMessageDialog(jp, "你赢了,你好厉害", "win", JOptionPane.INFORMATION_MESSAGE);    }    // 显示输了之后的界面    public void showDefeat(JPanel jp) {        JOptionPane.showMessageDialog(jp, "你输了,好遗憾", "you lose", JOptionPane.INFORMATION_MESSAGE);    }    @Override    public void mouseDragged(MouseEvent e) {    }    @Override    public void mouseClicked(MouseEvent e) {    }    @Override    public void mouseEntered(MouseEvent e) {    }    @Override    public void mouseExited(MouseEvent e) {    }    @Override    public void mouseReleased(MouseEvent e) {    }}

下面是窗口类。用于实现窗口话和点击菜单会激发不同的事件。如:关闭窗口时系统也退出。游戏棋盘的选择,游戏模式的选择。游戏窗口视图的选择。

import java.awt.Container;import java.awt.Graphics;import java.awt.Window;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import javax.swing.ButtonGroup;import javax.swing.JFrame;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JOptionPane;import javax.swing.JRadioButton;import javax.swing.JRadioButtonMenuItem;import javax.swing.SwingUtilities;import javax.swing.UIManager;//这个类主要是加载五子棋的整个窗口以及菜单public class ChessBoard extends JFrame implements ActionListener {    // 可选的棋盘大小    private String[] strSize = { "20*15", "30*20", "40*30" };    // 可选的对战模式    private String[] strModel = { "人机对战", "人人对战" };    // 用连个boolean 来判断是人机还是人人,isComputer和checkcomputer为true是为了默认开局方式为人机。    public static boolean isComputer = true, checkComputer = true;    // 窗口的宽和高    private int height, width;    // 核心类对象    private GoGame goGame;    // 棋盘对象    private ChessPanel chessPanel;    // 构造五子棋的窗体    public ChessBoard() {        this.setTitle("五子棋---个人制作");        // 初始化核心类的对对象。        goGame = new GoGame(1);        // 使用核心类,初始化面板对象。        chessPanel = new ChessPanel(goGame);        // 获取本窗口的容器。        Container con = this.getContentPane();        // 容器里加入面板,并设置布局为中心。        con.add(chessPanel, "Center");        //把窗口设置为大小不可调整。        this.setResizable(false);        //添加一个窗口监听事件,主要是实现按关闭按钮能够关闭系统,退出虚拟机。为了精简代码,这里使用了匿名内部类。        this.addWindowListener(new WindowAdapter() {            @Override            public void windowClosing(WindowEvent e) {                System.exit(0);            }        });        // 先使用类内部的设置窗口的方法来初始化窗口大小        this.MapSize(20, 15);        // 创建窗口的菜单条,一方便        JMenuBar mbar = new JMenuBar();        this.setJMenuBar(mbar);        // 创建游戏菜单        JMenu gameMenu = new JMenu("游戏");        // 将菜单加入到菜单条,自己创建一个方法反回一个已经构造好的菜单。加在菜单条上。        mbar.add(makeMenu(gameMenu, new Object[] {                "开局", "棋盘", "模式", null, "退出" }, this));        // 创建视图菜单        JMenu lookMenu = new JMenu("视图");        // 将菜单添加到菜单条        mbar.add(makeMenu(lookMenu, new Object[] {                 "Metal", "Motif", "Windows" }, this));        // 创建帮助菜单        JMenu helpMenu = new JMenu("帮助");        // 将菜单添加到菜单条        mbar.add(makeMenu(helpMenu, new Object[] {                 "关于" }, this));    }    // 获取人机iscompputer    public boolean getIsComputer() {        return this.isComputer;    }    // 构造五子棋的主菜单,第一步是要创建一个菜单的引用,以便之后创建菜单实例返回。    public JMenu makeMenu(Object parent, Object items[], Object target) {        //创建一个菜单引用。        JMenu m = null;        //如果传入的本来就是菜单,则直接强制转换。如果是字符串,则使用字符创建菜单。        if (parent instanceof JMenu) {            m = (JMenu) parent;        } else if (parent instanceof String) {            m = new JMenu((String) parent);        } else {            return null;        }        //下面是为菜单构建菜单项。还是使用方法返回。        for (int i = 0; i < items.length; i++) {            if (items[i] == null) {                m.addSeparator();            } else if (items[i] == "棋盘") {                JMenu jm = new JMenu("棋盘");                ButtonGroup group = new ButtonGroup();                JRadioButtonMenuItem rmenu;                for (int j = 0; j < strSize.length; j++) {                    rmenu = makeRadioButtonMenuItem(strSize[j], target);                    if (j == 0) {                        rmenu.setSelected(true);                    }                    //先把多按钮加入到菜单中,再把多按钮加入到按钮组里,这样才能实现单选。                    jm.add(rmenu);                    group.add(rmenu);                }                m.add(jm);            } else if (items[i] == "模式") {                JMenu jm = new JMenu("模式");                ButtonGroup group = new ButtonGroup();                JRadioButtonMenuItem rmenu;                for (int h = 0; h < strModel.length; h++) {                    rmenu = makeRadioButtonMenuItem(strModel[h], target);                    if (h == 0) {                        rmenu.setSelected(true);                    }                    jm.add(rmenu);                    group.add(rmenu);                }                //记住,一定要是加入菜单条里的菜单                m.add(jm);            } else {                //如果菜单项没有在包含多选项,则用方法直接构造一个菜单项返回并添加到菜单里。                m.add(makeMenuItem(items[i], target));            }        }        return m;    }    // 构造五子棋的菜单项,构造方法和上面构造菜单的不部分类似。不过 得添加监听事件    private JMenuItem makeMenuItem(Object item, Object target) {        JMenuItem menuItem = null;        if (item instanceof String) {            menuItem = new JMenuItem((String) item);        } else if (item instanceof JMenuItem) {            menuItem = (JMenuItem) item;        } else {            return null;        }        if (target instanceof ActionListener) {            menuItem.addActionListener((ActionListener) target);        }        return menuItem;    }    // 构造五子棋的单选按钮式菜单项,和上面的方法非常类似。不再赘述。    private JRadioButtonMenuItem makeRadioButtonMenuItem(Object item, Object target) {        JRadioButtonMenuItem jRadioButtonMenuItem = null;        if (item instanceof String) {            jRadioButtonMenuItem = new JRadioButtonMenuItem((String) item);        } else if (item instanceof JRadioButtonMenuItem) {            jRadioButtonMenuItem = (JRadioButtonMenuItem) item;        } else {            return null;        }        if (target instanceof ActionListener) {            jRadioButtonMenuItem.addActionListener((ActionListener) target);        }        return jRadioButtonMenuItem;    }    // 设置界面大小    public void MapSize(int w, int h) {        //这里设置的宽度和高度,和鼠标点击时获取坐标值有很大的关联。        setSize(w * 20 + 50, h * 20 + 100);        if (this.checkComputer) {            this.isComputer = true;        } else {            this.isComputer = false;        }        chessPanel.setGoGame(goGame);        chessPanel.repaint();    }    // 重新开始    public void restart() {        int modelChess = goGame.getChessModel();        if (modelChess <= 3 && modelChess >= 1) {            goGame = new GoGame(modelChess);            MapSize(goGame.getWidth(), goGame.getHeight());        } else {            System.out.println("\u81EA\u5B9A\u4E49");        }    }    @Override    // 实现ActionListenner的主要方法。    public void actionPerformed(ActionEvent e) {        String arg = e.getActionCommand();        try {            if (arg.equals("Windows")) {                UIManager.setLookAndFeel(                        "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");            } else if (arg.equals("Motif")) {                UIManager.setLookAndFeel(                        "com.sun.java.swing.plaf.motif.MotifLookAndFeel");            } else {                UIManager.setLookAndFeel(                        "javax.swing.plaf.metal.MetalLookAndFeel");            }            SwingUtilities.updateComponentTreeUI(this);        } catch (Exception e2) {        }        if (arg.equals("20*15")) {            this.width = 20;            this.height = 15;            goGame = new GoGame(1);            MapSize(this.width, this.height);            SwingUtilities.updateComponentTreeUI(this);        }        if (arg.equals("30*20")) {            this.width = 30;            this.height = 20;            goGame = new GoGame(2);            MapSize(this.width, this.height);            SwingUtilities.updateComponentTreeUI(this);        }        if (arg.equals("40*30")) {            this.width = 40;            this.height = 30;            goGame = new GoGame(3);            MapSize(this.width, this.height);            SwingUtilities.updateComponentTreeUI(this);        }        if (arg.equals("人机对弈")) {            this.checkComputer = true;            this.isComputer = true;            goGame = new GoGame(goGame.getChessModel());            MapSize(goGame.getWidth(),goGame.getHeight());            SwingUtilities.updateComponentTreeUI(this);        }        if (arg.equals("人人对弈")) {            this.checkComputer = true;            this.isComputer = true;            goGame = new GoGame(goGame.getChessModel());            MapSize(goGame.getWidth(),goGame.getHeight());            SwingUtilities.updateComponentTreeUI(this);        }        if (arg.equals("开局")) {            restart();        }        if (arg.equals("关于")){            JOptionPane.showMessageDialog(this, "五子棋游戏测试版本", "关于", 0);        }        if (arg.equals("退出")) {            System.exit(0);        }    }}

这里是为了练习项目。为大家提供的代码和注释,应该是一看就能看懂的,非常适合初学者。

3 0
原创粉丝点击