zoukankan      html  css  js  c++  java
  • Java实现五子棋小游戏(对新手极为友好的版本)

    写在前面的话:“ 你现在的状态,是过去的你用努力换来的,而你未来的状态,是现在的你用努力决定的。”
    九月你好,还未还得及感受,你就要离去。以前总是担心着未来的未发生的事情,前几天听完bilibi架构师学长对我问题的回答后。有所感触。我想,现在的我,规划好以后要做的事情,把目前手里的事情做好,不好高骛远,脚踏实地,充实自己,机会是留给有准备的人的。我是梦阳辰,快和我一起加油吧!

    效果预览:
    在这里插入图片描述

    系统设计:

    1.设计棋盘类用来构建棋盘。

    2.设计棋局类,用来保存棋局情况(用二维数组存储)。

    3.设计物理地址类用来表示物理地址。

    4.设计逻辑地址类用来表示棋盘上逻辑坐标。

    5.系统游戏类,也为主类。用来绘制棋盘,绘制棋子,并对用户单击鼠标(下棋)进行响应(做相应的处理)。

    6.因为监听鼠标单击一直在进行,所以游戏可以一直运行,知道用户主动退出游戏。

    判断输赢的核心算法:
    通过判断当前所下棋子是否与周围(米字方向)同色棋子组成五连珠。

     /**S
         * 判断棋局是否获胜(落点位置周围是否有5个相同颜色的棋子
         * @return -1黑色方赢  0平局 1白色方赢
         */
        public int isWin(CoordinateLogical c,int color){
            //竖直方向
            int count=-1;//初值为-1的原因:(当前所下棋子算了两次)
            for(int i=c.getRow();i>=0;i--){
                if(situation[i][c.getCol()]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            for(int i=c.getRow();i<Chessboard.getRows();i++){
                if(situation[i][c.getCol()]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            if(count==5){
                return color;
            }
    
            //水平方向
            count=-1;
            for(int i=c.getCol();i>=0;i--){
                if(situation[c.getRow()][i]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            for(int i=c.getCol();i<Chessboard.getCols();i++){
                if(situation[c.getRow()][i]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            if(count==5){
                return color;
            }
            //斜左下到右上方向
            count=-1;
            for(int i=c.getRow(),j=c.getCol();i>=0&&j<=Chessboard.getCols()-1;i--,j++){//右上
                if(situation[i][j]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            for(int i=c.getRow(),j=c.getCol();j>=0&&i<=Chessboard.getRows()-1;i++,j--){//左下
                if(situation[i][j]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            if(count==5){
                return color;
            }
    
            //斜左上到右下方向
            count=-1;
            for(int i=c.getRow(),j=c.getCol();i>=0&&j>=0;i--,j--){//左上
                if(situation[i][j]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            for(int i=c.getRow(),j=c.getCol();i<=Chessboard.getRows()-1&&j<=Chessboard.getCols()-1;i++,j++){//右下
                if(situation[i][j]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            if(count==5){
                return color;
            }
            return 0;
        }
    

    在这里插入图片描述

    01.设计棋局类

    属性

    1.属性situation:用二维数组存储棋局每个点位的情况。

    2.棋子属性:定义黑棋(black),白棋的属性(white)。

    3.先手属性:定义当前移动方(mover)。

    方法

    1.判断逻辑地址是否存在棋子(exist)

    2.落子(add)

    3.判断棋局是否获胜(isWin)

    程序代码:

    package GoBang_Game;
    
    //棋局类
    public class ChessSituation {
    
        public  final static int BLACK = -1;//黑色棋子
        public  final static int NONE = 0;//无棋子
        public  final static int WHITE = 1;//白色棋子
    
        private int[][] situation;//棋局所有落点的情况
        private  int mover;//表示当前谁落子,1为白子,-1为黑子
    
        /**
         * 确定落点
         * 构造函数
         */
        public ChessSituation(int rows,int cols) {
            situation = new int[rows][cols];//默认值为0
            mover = BLACK;//黑方先动
        }
    
        /**
         * 判断逻辑地址是否存在棋子
         * @return true or false
         */
        public  boolean exist(CoordinateLogical c){
            return situation[c.getRow()][c.getCol()]!=ChessSituation.NONE;
        }
    
        /**
         * 落子
         * @param c 落子的位置
         * @return 落子的颜色
         */
        public int add(CoordinateLogical c){
            int color = mover;
            situation[c.getRow()][c.getCol()] = color;//存储了颜色,也就代表了哪一方
            mover = -mover;//切换谁下棋
            return  color;
        }
    
        /**S
         * 判断棋局是否获胜(落点位置周围是否有5个相同颜色的棋子
         * @return -1黑色方赢  0平局 1白色方赢
         */
        public int isWin(CoordinateLogical c,int color){
            //竖直方向
            int count=-1;
            for(int i=c.getRow();i>=0;i--){
                if(situation[i][c.getCol()]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            for(int i=c.getRow();i<Chessboard.getRows();i++){
                if(situation[i][c.getCol()]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            if(count==5){
                return color;
            }
    
            //水平方向
            count=-1;
            for(int i=c.getCol();i>=0;i--){
                if(situation[c.getRow()][i]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            for(int i=c.getCol();i<Chessboard.getCols();i++){
                if(situation[c.getRow()][i]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            if(count==5){
                return color;
            }
            //斜左下到右上方向
            count=-1;
            for(int i=c.getRow(),j=c.getCol();i>=0&&j<=Chessboard.getCols()-1;i--,j++){//右上
                if(situation[i][j]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            for(int i=c.getRow(),j=c.getCol();j>=0&&i<=Chessboard.getRows()-1;i++,j--){//左下
                if(situation[i][j]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            if(count==5){
                return color;
            }
    
            //斜左上到右下方向
            count=-1;
            for(int i=c.getRow(),j=c.getCol();i>=0&&j>=0;i--,j--){//左上
                if(situation[i][j]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            for(int i=c.getRow(),j=c.getCol();i<=Chessboard.getRows()-1&&j<=Chessboard.getCols()-1;i++,j++){//右下
                if(situation[i][j]==color){
                    count++;
                }
                else {
                    break;
                }
            }
            if(count==5){
                return color;
            }
            return 0;
        }
    
        public int[][] getSituation() {
            return situation;
        }
    
        public void setSituation(int[][] situation) {
            this.situation = situation;
        }
    
        public int getMover() {
            return mover;
        }
    
        public void setMover(int mover) {
            this.mover = mover;
        }
    }
    
    

    02.棋盘类

    属性

    1.行数(rows)
    2.列数(cols)
    3.间距(size)
    4.棋盘的位置(margin)

    方法

    1.初始化棋盘(init)

    2.将物理地址转换为逻辑坐标(convert)。
    注意:将物理地址转换成逻辑坐标时:
    横坐标转化成列号。
    纵坐标转换成行号。

    3.将逻辑坐标转换成物理地址(convert)。
    目的是为了在物理地址画棋子。

    程序代码:

    package GoBang_Game;
    
    //棋盘类
    public class Chessboard {
        private static int rows;//行数
        private static int cols;//列数
        private static int size;//间距
        private static int margin;//棋盘的位置
    
        /**
         * 初始化
         * @param n1 行数
         * @param n2 列数
         * @param n3 间距
         * @param n4 外边距
         */
        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.setCol(Math.round((float)(c.getX()-margin)/size));//行号
            c1.setRow(Math.round((float)(c.getY()-margin)/size));//列号
            return c1;
        }
    
        /**
         * 将逻辑坐标装换成物理地址
         * @param c 逻辑坐标
         * @return 物理坐标
         */
        public static CoordinatePhysical convert(CoordinateLogical c){//便于画棋子
            CoordinatePhysical c1 = new CoordinatePhysical();
            c1.setX(c.getCol()*size+margin);//横坐标
            c1.setY(c.getRow()*size+margin);//纵坐标
            return c1;
        }
    
        public static int getRows() {
            return rows;
        }
    
        public static void setRows(int rows) {
            Chessboard.rows = rows;
        }
    
        public static int getCols() {
            return cols;
        }
    
        public static void setCols(int cols) {
            Chessboard.cols = cols;
        }
    
        public static int getSize() {
            return size;
        }
    
        public static void setSize(int size) {
            Chessboard.size = size;
        }
    
        public static int getMargin() {
            return margin;
        }
    
        public static void setMargin(int margin) {
            Chessboard.margin = margin;
        }
    
        public static int getWidth() {
            return (margin*2+size*(cols-1));
        }
    
        public static int getHight() {
            return (margin*2+size*(rows-1));
        }
    }
    
    

    03.物理地址类

    属性

    1.横坐标(x)

    2.纵坐标(y)

    程序代码:

    package GoBang_Game;
    
    public class CoordinatePhysical {
        private int x;//横坐标
        private int y;//纵坐标
    
        public CoordinatePhysical() {
        }
    
        public CoordinatePhysical(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        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;
        }
    }
    
    

    04.逻辑坐标类

    属性

    1.行号(row)

    2.列号(col)

    程序代码:

    package GoBang_Game;
    
    public class CoordinateLogical {
        private int row;//行号
        private int col;//列号
    
        public CoordinateLogical() {
        }
    
        public CoordinateLogical(int row, int col) {
            this.row = row;
            this.col = col;
        }
    
        public int getRow() {
            return row;
        }
    
        public void setRow(int row) {
            this.row = row;
        }
    
        public int getCol() {
            return col;
        }
    
        public void setCol(int col) {
            this.col = col;
        }
    }
    
    

    05.系统游戏类

    属性:

    1.窗体

    2.画布

    3.绘图对象

    4.按钮

    5.棋局属性

    方法

    1.主方法:(main)
    创建游戏对象

    2.构造方法:(Game)
    创建窗口,画布,增加按钮,响应按钮,并响应鼠标做对应处理。

    3.绘制棋盘(drawBoard)

    4.绘制棋子(drawChess)

    5.处理鼠标单击(下棋)

    程序代码:

    package GoBang_Game;
    
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    public class Game {
        private static Frame frame;//窗体
        private static Canvas canvas;//画布
        private Graphics graphics;//绘图对象
        private Button button;//按钮
        private ChessSituation chessSituation;//棋局
    
    
        public static void main(String[] args) {
            Game game = new Game(15,15,50,50);
        }
    
        public Game(int rows, int cols, int size , int margin){
    
            Chessboard.init(rows,cols,size,margin);
            chessSituation = new ChessSituation(rows,cols);
            //初始化窗口
            int width = Chessboard.getWidth();
            int height = Chessboard.getHight()+100;
            frame = new Frame("五子棋-梦阳辰");
            frame.setSize(width,height);
            frame.setLayout(new FlowLayout());
            frame.setVisible(true);//显示窗体
    
            //准备画布
            canvas = new Canvas();
            canvas.setSize(width,height);//指定尺寸
            frame.add(canvas);
    
            //画布单击响应
            canvas.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
    
                    CoordinatePhysical c  = new CoordinatePhysical(e.getX(),e.getY());
                    int a =handle(c);
                    if(a==1){
                        JOptionPane.showMessageDialog(null, "白色方赢了", "游戏结束",JOptionPane.INFORMATION_MESSAGE);
                        drawBoard();//重新绘制棋盘
                        chessSituation.setSituation(new int [Chessboard.getRows()][Chessboard.getCols()]);//将棋局情况 清0
                        chessSituation.setMover(chessSituation.BLACK);//设置黑色方为先手
                    }
                    else if(a==-1){
                        JOptionPane.showMessageDialog(null, "黑色方赢了", "游戏结束",JOptionPane.INFORMATION_MESSAGE);
                        drawBoard();//重新绘制棋盘
                        chessSituation.setSituation(new int [Chessboard.getRows()][Chessboard.getCols()]);//将棋局情况 清0
                        chessSituation.setMover(chessSituation.BLACK);//设置黑色方为先手
                    }
                    super.mouseClicked(e);
                }
            });
    
            //增加按钮
            button = new Button("Start Game");
            button.setSize(130,80);
            frame.add(button);
    
            //响应按钮
            button.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent mouseEvent) {
                    graphics = canvas.getGraphics();
                    drawBoard();//绘制棋盘
                    chessSituation.setSituation(new int [Chessboard.getRows()][Chessboard.getCols()]);//将棋局情况 清0
                    chessSituation.setMover(chessSituation.BLACK);//设置黑色方为先手
                    super.mouseClicked(mouseEvent);
                }
            });
    
            //增加按钮
            button = new Button("Exit Game");
            button.setSize(130,80);
            frame.add(button);
    
            //响应按钮
            button.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent mouseEvent) {
                    graphics = canvas.getGraphics();
                    frame.setVisible(false);//退出窗体
                    System.exit(0);//退出程序
                    super.mouseClicked(mouseEvent);
                }
            });
    
    
        }
    
    
        /**
         * 绘制棋盘
         */
        public void drawBoard(){
            graphics.setColor(Color.YELLOW);
            graphics.fillRect(0,0,Chessboard.getWidth(),Chessboard.getHight());
            graphics.setColor(Color.BLACK);
            //绘制纬线
            int x1 = Chessboard.getMargin();
            int y1 = Chessboard.getMargin();
            int x2 = x1+(Chessboard.getSize()*(Chessboard.getCols()-1));
            int y2 = y1;
            for(int i=0;i<Chessboard.getRows();i++){
                graphics.drawLine(x1,y1,x2,y2);
                y1 += Chessboard.getSize();
                y2 += Chessboard.getSize();
            }
            //绘制纬线
             x1 = Chessboard.getMargin();
             y1 = Chessboard.getMargin();
             x2 = x1;
             y2 = y1+(Chessboard.getSize()*(Chessboard.getRows()-1));
            for(int i=0;i<Chessboard.getCols();i++){
                graphics.drawLine(x1,y1,x2,y2);
                x1 += Chessboard.getSize();
                x2 += Chessboard.getSize();
            }
        }
    
        /**
         * 绘制棋子
         * @param c
         * @param color 颜色(1黑色,-1白色)
         */
        public  void drawChess(CoordinateLogical c, int color){
            int r = (int) (Chessboard.getSize()*0.4);
            CoordinatePhysical c1= Chessboard.convert(c);//得到物理坐标
            //计算外切正方形的起点和宽高
            int x = c1.getX() -r ;
            int y = c1.getY() -r ;
            int width  = 2*r;
            int heigth = 2*r;
            graphics.setColor(color==chessSituation.BLACK?Color.BLACK:Color.WHITE);
            graphics.fillArc(x,y,width,heigth,0,360);
        }
    
        /**
         * 用户在棋盘上单击之后的处理
         * @param c 单击的位置
         * @return  输赢结果
         */
        public  int handle(CoordinatePhysical c) {
            CoordinateLogical c1 = Chessboard.convert(c);
            if(!chessSituation.exist(c1)){
                //落子
                int color = chessSituation.add(c1);
                //绘制棋子
                drawChess(c1,color);
                //返回落子后的输赢
                return chessSituation.isWin(c1,color);
            }
            return chessSituation.NONE;
        }
    }
    

    关注公众号【轻松玩编程】回复关键字“电子书”,“计算机资源”,“Java从入门到进阶”,”JavaScript教程“,“算法”,“Python学习资源”,“人工智能”等即可获取学习资源。

    喜欢就争取,得到就珍惜,生活就是这样,脚长在自己身上,往前走就对了,直到向往的风景,变成走过的地方。

    在这里插入图片描述

    以梦为马,不负韶华。
  • 相关阅读:
    Girls and Boys
    妹子图.py
    requests的常用的方法和bs4的常用的方法:
    爬天极网线程池和进程池.py
    爬天极网多线程.py
    爬天极网多线程.py
    java实现遍历树形菜单方法——service层
    java实现遍历树形菜单方法——Dao层
    java实现遍历树形菜单方法——Dao层
    java实现遍历树形菜单方法——映射文件VoteTree.hbm.xml
  • 原文地址:https://www.cnblogs.com/huangjiahuan1314520/p/13743555.html
Copyright © 2011-2022 走看看