鱼C论坛

 找回密码
 立即注册
查看: 1970|回复: 0

[分享] java写的一个五子棋,求大佬们指点

[复制链接]
发表于 2020-10-9 19:45:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
棋盘类:
public class Board {
    protected static int rows;
    protected static int cols;
    protected static int size;
    protected static int margin;

    public static void main(String[] args){
        Board.init(6,6,30,20);
        CoordinateLogical c1 = new CoordinateLogical(2,3);
        CoordinatePhysical c2 = new CoordinatePhysical(10,20);

        CoordinateLogical c21 = Board.convert(c2);
        CoordinatePhysical c11 = Board.convert(c1);

        System.out.printf("(%d,%d)->(%d,%d)",c2.x,c2.y,c21.col,c21.row);
        System.out.printf("(%d,%d)->(%d,%d)",c1.col,c1.row,c11.x,c11.y);
    }

    public static void init(int n1,int n2,int n3,int n4){
        rows = n1;
        cols = n2;
        size = n3;
        margin = n4;
    }

    /**
     * 物理坐标转换为逻辑坐标
     * @param c
     * @return
     */
    public static CoordinateLogical convert(CoordinatePhysical c){
        CoordinateLogical c1 = new CoordinateLogical();
        c1.col = Math.round((c.x-margin)/(float)size);
        c1.row = Math.round((c.y - margin)/(float)size);

        return c1;
    }

    /**
     * 逻辑坐标转换为物理坐标
     * @param c
     * @return
     */
    public static CoordinatePhysical convert(CoordinateLogical c){
        CoordinatePhysical c1 = new CoordinatePhysical();
        c1.x = margin + size * c.col;
        c1.y = margin + size * c.row;
        return c1;
    }

    public static int getWidth() {
        return margin*2+size*(rows-1);
    }

    public static int getHeight() {
        return margin*2+size*(cols-1);
    }
}
棋局类:
public class Chess {
    int flag = 0;
    public static int NONE = 0;//无子
    public static int WHITE = 1;//白子
    public static int BLACK = -1;//黑子

    private int [][]chesses;//左右落点的状态
    private int turn;//当前轮到白方(1)/黑方(-1)落子

    public Chess(int rows,int cols){

        //创建所有的落点
        chesses = new int[rows][cols];

        //初始化每个落点为无子
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                chesses[row][col] = NONE;
            }
        }

        //黑方落子
        turn = BLACK;
    }

    /**
     * 判断某个位置是否有棋子
     * @param c 逻辑位置
     * @return 是否由棋子
     */
    public boolean exist(CoordinateLogical c){

        return chesses[c.row][c.col] != NONE;
    }

    /**
     * 落子
     * @param c 落子位置
     * @return 落子颜色
     */
    public int add(CoordinateLogical c){
        int color = turn;
        chesses[c.row][c.col] = color;
        turn = - turn;
        return color;
    }

    public int isWin1(CoordinateLogical c){
        int color = chesses[c.row][c.col];
        //垂直方向
        if(extend(c,0)+extend(c,4)>=4){
            return color;
        }
        //负对角线方向
        if(extend(c,1)+extend(c,5)>=4){
            return color;
        }
        //水平方向
        if(extend(c,2)+extend(c,6)>=4){
            return color;
        }
        //主对角线方向
        if(extend(c,3)+extend(c,7)>=4){
            return color;
        }
        return 0;
    }

    /**
     * 从指定位置往某个方向扩展
     * @param c 位置
     * @param direction 方向 0:上 1:右上 2:右 3:右下 4:下 5:左下 6:左 7:左上
     * @return
     */
    private int extend(CoordinateLogical c,int direction){
        int count = 0;
        int row = c.row;
        int col = c.col;
        int color = chesses[row][col];

        //一个方向拓展的次数不可能超过4
        for (int i = 0; i < 4; i++) {
            switch (direction){
                case 0:
                    row--;
                    break;
                case 1:
                    row--;
                    col++;
                    break;
                case 2:
                    col++;
                    break;
                case 3:
                    row++;
                    col++;
                    break;
                case 4:
                    row++;
                    break;
                case 5:
                    row++;
                    col--;
                    break;
                case 6:
                    col--;
                    break;
                case 7:
                    col--;
                    row--;
                    break;
            }
            if(row<0||row>=Board.rows||col<0||col>=Board.cols){
                break;
            }
            if(chesses[row][col]==color){
                count++;
            }else{
                break;
            }
        }
        return count;

    }

    /**
     * 判断在指定位置的周围是否形成了五个以上同色的棋子
     * @param p 位置
     * @return
     */
    public int isWin(CoordinateLogical p){

        if((count(p,0,-1,-turn)+count(p,0,1,-turn))-1>=5)
        {
            return -turn;
        }
        if((count(p,1,0,-turn)+count(p,-1,0,-turn))-1>=5)
        {
            return -turn;
        }
        if((count(p,1,-1,-turn)+count(p,-1,1,-turn))-1>=5){
            return -turn;
        }
        if((count(p,-1,-1,-turn)+count(p,1,1,-turn))-1>=5){
            return -turn;
        }

     return 0;
    }

    private int count(CoordinateLogical p,int movX,int movY,int turn){
        CoordinateLogical p1 = new CoordinateLogical(0,0);

            if (chesses[p.row][ p.col] == turn) {
                if ((p.row < 0 || p.row >= Board.rows) || p.col < 0 || p.col >= Board.cols) {
                    return 0;
                }
                p1.col = p.col + movX;
                p1.row = p.row + movY;
                return 1+count(p1,movX,movY,turn);

            } else {
                return 0;
            }


    }
}
逻辑坐标类
//逻辑坐标
public class CoordinateLogical {
    public int col;
    public int row;

    public CoordinateLogical(int col,int row){
        this.col = col;
        this.row = row;
    }

    public CoordinateLogical(){
        this.col = 0;
        this.row = 0;
    }
}
物理坐标类:
//物理坐标
public class CoordinatePhysical {
    public int x;
    public int y;

    public CoordinatePhysical(int x,int y){
        this.x = x;
        this.y = y;
    }
    public CoordinatePhysical(){
        this.x = 0;
        this.y = 0;
    }
}
游戏控制类:
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Game {
    private static Frame frame;//窗体
    private static Canvas canvas;//画布
    private static Graphics graphics;//绘图对象
    private static Button button;//按钮


    private static Chess chess;

    /**
     * 构造函数
     *
     * @param rows
     * @param cols
     * @param size
     * @param margin
     */
    public Game(int rows, int cols, int size, int margin) {
        Board.init(rows, cols, size, margin);
        chess = new Chess(rows, cols);
    }

    public static void main(String[] args) {
        Game game = new Game(19, 19, 30, 20);

        //初始化窗体
        int width = Board.getWidth();
        int height = Board.getHeight() + 100;
        frame = new Frame("我的五子棋");
        frame.setSize(width, height);
        frame.setLayout(new FlowLayout());
        //关闭窗口
        frame.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e) {
                System.exit(0);//退出
            }});
        //准备画布
        canvas = new Canvas();
        canvas.setSize(width, height);
        frame.add(canvas);

        button = new Button("Start");
        button.setSize(100, 40);
        frame.add(button);


        button.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent mouseEvent) {
                graphics = canvas.getGraphics();
                drawBoard();
                super.mouseClicked(mouseEvent);
            }
        });

        //鼠标响应事件
        canvas.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                CoordinatePhysical c = new CoordinatePhysical(e.getX(), e.getY());
                int result = handle(c);
                if (result != Chess.NONE) {
                    String actor = result==Chess.BLACK?"黑方":"白方";
                    String msg = String.format("恭喜%s获胜",actor);
                    JOptionPane.showMessageDialog(null, msg, "游戏结束", JOptionPane.OK_CANCEL_OPTION, null);
                    //System.exit(1);
                    graphics = canvas.getGraphics();
                    drawBoard();
                }

                super.mouseClicked(e);
            }
        });

        frame.setVisible(true);//显示窗体

    }


    /**
     * 画棋盘
     */
    public static void drawBoard(){

        graphics.setColor(Color.ORANGE);
        graphics.fillRect(0,0,Board.getWidth(),Board.getHeight());
        //绘制纬线
        graphics.setColor(Color.BLACK);
        int x1 = Board.margin;
        int y1 = Board.margin;
        int x2 = x1+Board.size*(Board.cols-1);
        int y2 = y1;
        for (int i = 0; i < Board.rows; i++) {
            graphics.drawLine(x1,y1,x2,y2);
            y1 += Board.size;
            y2 += Board.size;
        }

        //绘制经线
        x1 = Board.margin;
        y1 = Board.margin;
        x2 = x1;
        y2 = y1+Board.size*(Board.rows-1);
        for (int i = 0; i < Board.rows; i++) {
            graphics.drawLine(x1,y1,x2,y2);
            x1 += Board.size;
            x2 += Board.size;
        }

    }

    /**
     * 画棋子
     * @param c 坐标
     * @param color 颜色
     */
    public static void drawChess(CoordinateLogical c,int color){
        int r = (int)(Board.size*0.3);

        CoordinatePhysical c1 = Board.convert(c);
        int x = c1.x - r;
        int y = c1.y - r;
        int width = 2*r;
        int height = 2*r;
        graphics.setColor(color==-1?Color.BLACK:Color.WHITE);
        graphics.fillArc(x,y,width,height,0,360);
        graphics.drawArc(x,y,width,height,0,360);
    }

    /**
     * 在棋盘上单击的逻辑处理
     * @param c 单击的位置
     * @return 输赢结果
     */
    public static int handle(CoordinatePhysical c){
        int result;
        CoordinateLogical c1 = Board.convert(c);

        //如果该位置已经有棋子,则直接忽略本次操作
        if(chess.exist(c1)){
            return Chess.NONE;
        }


        int color = chess.add(c1);
        drawChess(c1,color);
        result = chess.isWin1(c1);


        return result;
    }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 13:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表