JavaSE-十分钟写个五子棋

 

1.设计说明

1.1 简介

其实很久之前就写过五子棋,当时拿AWT写的界面,后面通过socket通信实现了联机对战操作,当时写五子棋写的可费劲了,现在又要写一次五子棋,不过是简单版的哈哈,一会就写完了。

描述:基于Java类和对象以及数组开发的一个小型五子棋游戏程序。游戏开始时,选择黑棋、白棋开局,将一枚棋子落在棋盘一坐标上,然后轮番落子,如此轮流下子,直到某一方首先在棋盘的竖、横或方向上的五子连成线,则该方该局获胜。

1.2 游戏说明

功能列表如下:

(1)输出棋盘;

(2)提示用户下子;

(3)查看用户是否出界或者落子位置是否被占用

(4)轮番黑棋白棋选择坐标位置进行下子

(5)判断游戏是否输赢;

(6)判断是否进入下一局;

(7)退出游戏。

 

2. 实现思路

  1. 棋盘设计为10*10,棋盘类型Chess[][] 二维数组,所含属性String chessType; 棋盘首先chessType值是
  2. 初始化二维数组
  3. 玩家选择黑白后,开始下棋。输入要下棋子的行列坐标黑白棋子轮流落子,当一方连成五子或下满棋盘时,游戏结束(连成五子的一方获胜,下满棋盘为和棋)。
  4. 每一次落子成功后,马上判断以该位置为中心的八个方向:上、下、左、右、左上、左下、右上、右下是否有相同颜色的棋子连成五子,如果连成五子,则游戏结束,输出相应的信息。
  5. 当游戏一方胜利后显示胜利信息。从程序表面看,这是一个二维平面图,所以数据用二维数组来表示,数组两个下标可以表示棋盘上的位置,数组元素的值代表棋格上的状态,共有三种情况,分别是,代表白棋,代表黑棋代表格子

 

3. 实现流程

由于时间原因,写的很仓促,说是十分钟写,其实思考加编写加调试前后花了差不多半个小时,老标题党了,hiahia。

3.1 棋子类

首先要写一个棋子类用于存放棋子信息,它的属性主要是chessType(这枚棋子的种类,黑棋还是白棋),flag(棋盘对应的这个位置是否有棋,有棋给true,没棋就给false),每次将棋子下到棋盘上之后,要把flag给置true,表示已经有棋子了,如果还往这个位置下棋就报错。另外两个属性row,colum是我顺手写习惯写上的,没有用到可以省略。

package com.fiveChess;

/**
 * Description :
 * Created by Resumebb
 * Date :2020/10/31
 */
public class ChessNode {
    private String chessType;
    private int row;
    private int colum;
    private boolean flag;

    public ChessNode(String chessType, int row, int colum, boolean flag) {
        this.chessType = chessType;
        this.row = row;
        this.colum = colum;
        this.flag = flag;
    }

    public String getChessType() {
        return chessType;
    }

    public void setChessType(String chessType) {
        this.chessType = chessType;
    }

    public int getRow() {
        return row;
    }

    public void setRow(int row) {
        this.row = row;
    }

    public int getColum() {
        return colum;
    }

    public void setColum(int colum) {
        this.colum = colum;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

3.2操作类

1.run函数

首先上一个run,用来控制操作流程,尽可能做高内聚低耦合,让每一个函数各司其职,专精一件事情。

这个run方法就是最开始进入的界面控制,先直接开始一次游戏,完成后判断用户输入,1重开一盘,0退出游戏。

    public void run(){
        int choice = 0;
        boolean flag = false;
        do {
            initChessBoard();
            show();
            playChess();
            System.out.println("继续扣1,退出扣0");
            Scanner in = new Scanner(System.in);
            choice = in.nextInt();
            if(choice == 1){
                flag = true;
            }
        }while (flag);
    }

2.initChessBoard函数

该函数用于初始化棋盘,所有的chessType给置+,需求是给定10*10大小棋盘,也可以自己增加两个变量,生成自定义大小的棋盘

   private void initChessBoard(){
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                chessNodes[i][j] = new ChessNode("➕",i,j,false);
            }
        }
        System.out.println("初始化完成。");
    }

  3.show函数

用于打印棋盘信息

    private void show(){
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                System.out.print(chessNodes[i][j].getChessType()+" ");
            }
            System.out.println();
        }
        System.out.println();
    }

4.playChess函数

根据需求,要判断先手棋子,然后开始下棋。获取用户输入的xy坐标,先进行安全型检查,然后通过chessNode的flag属性可以判断该位置是否有棋,有棋重新输入坐标,没棋的话就将该位置的flag置true,并将chessType改为first,然后检查是否和棋,是否获胜,都不满足的话,交换棋子类型,继续循环,直至和棋或者一方胜出。

 private void playChess(){
        Scanner in = new Scanner(System.in);
        boolean flag = false;
        String first = "", second = "", temp = "";

        //先手判断
        do {
        System.out.println("请选择:黑棋● | 白棋⭕");
        String choice = in.next();
        if(choice.equals("黑棋")){
            first = "●";
            second = "⭕";
            flag = true;
        }
        else if(choice.equals("白棋")){
            first = "⭕";
            second = "●";
            flag = true;
        }
        else{
            System.out.println("输入有误,请重输:");
        }}while (!flag);

        //下棋操作
        int x = 0, y = 0;
        while(true) {
            System.out.println("请输入"+first+"x,y坐标:");
            x = in.nextInt()-1;
            y = in.nextInt()-1;

            //参数安全检查
            if(x<0 || x>9 || y<0 || y>9){
                System.out.println("输入有误,x:1-10,y:1-10,请重新输入:");
                continue;
            }
            //判断原位置是否有棋
            if (chessNodes[x][y].isFlag() == true) {
                System.out.println("原位置已有棋,请重新输入x,y坐标:");
            }
            else {
                chessNodes[x][y].setChessType(first);
                chessNodes[x][y].setFlag(true);
                size++;
                //判和
                if(peace()){
                    System.out.println("和棋!");
                    break;
                }
                if(judgeVectory(x,y,first)){
                    break;
                }
                //不满足胜利条件,交换顺序继续下
                temp = first;
                first = second;
                second = temp;
                show();
            }
        }
    }

4. judgeVectory函数

首先用四个变量来分别存储水平,垂直,左右俩斜线四个大方向上的棋子数量。然后每次调用函数,以当前给定的x,y坐标下的棋子位置为中心,分别计算八个小方向上的 棋子数量,最后判断只要四个大方向的棋子数量和大于等于4就胜利,因为自身有一个棋子了,所以加上就是大于等于5。整个项目唯一要注意的点就是计算八个小方向上的棋子数量,比如我计算90°方向的数量,首先不能改变x,y坐标的值,否则会影响其他7个小方向的判断,然后判断该棋子正右是否由棋子,应该是x不变,y向右移动,我开始想当然的判断右边,x+1,明显不对,而且每次+1也不行,最好就是利用循环的i去加,减少变量使用,同时还要注意检查x坐标+i后是否越界,越界也不行。

    private boolean judgeVectory(int x, int y, String chessType){
        int vertical = 0;	//垂直方向棋子数量
        int level = 0;	//水平方向棋子数量
        int bevelLeft = 0; //正北为0,-45°斜线上棋子数量
        int bevelRight = 0; //正北为0,45°斜线上棋子数量

        //计算90°方向棋子数量
        for (int i=1; i<5; i++) {
            if (y+i < 10 && chessNodes[x][y+i].getChessType().equals(chessType)) {
                level++;
            } else {
                break;
            }
        }

        //计算-90°方向棋子数量
        for (int i=1; i<5; i++) {
            if (y-i >= 0 && chessNodes[x][y-i].getChessType().equals(chessType)){
                level++;
            } else {
                break;
            }
        }

        //计算0°方向棋子数量
        for (int i=1; i<5; i++) {
            if (x+i < 10 && chessNodes[x+i][y].getChessType().equals(chessType)){
                vertical++;
            } else {
                break;
            }
        }

        //计算180°方向棋子数量
        for (int i=1; i<5; i++) {
            if (x-i >= 0 && chessNodes[x-i][y].getChessType().equals(chessType)){
                vertical++;
            } else {
                break;
            }
        }

        //计算45°方向棋子数量
        for (int i=1; i<5; i++) {
            if (x+i >= 0 && y+i >= 0 && chessNodes[x+i][y+i].getChessType().equals(chessType)){
                bevelRight++;
            } else {
                break;
            }
        }

        //计算225°方向棋子数量
        for (int i=1; i<5; i++) {
            if (x-i >= 0 && y-i >= 0 && chessNodes[x-i][y-i].getChessType().equals(chessType)){
                bevelRight++;
            } else {
                break;
            }
        }

        //计算-45°方向棋子数量
        for (int i=1; i<5; i++) {
            if (y-i >= 0 && x+i >= 0 && chessNodes[x+i][y-i].getChessType().equals(chessType)){
                bevelLeft++;
            } else {
                break;
            }
        }

        //计算135°方向棋子数量
        for (int i=1; i<5; i++) {
            if (x-i >= 0 && y+i >= 0 && chessNodes[x-i][y+i].getChessType().equals(chessType)){
                bevelLeft++;
            } else {
                break;
            }
        }

        //获胜条件
        if(vertical >= 4 || level >=4 || bevelLeft >= 4 || bevelRight >= 4){
            System.out.println(chessType+"胜利!");
            return true;
        }
        return false;
    }

5.chess类完整代码

package com.fiveChess;

import java.util.Scanner;

/**
 * Description :
 * Created by Resumebb
 * Date :2020/10/31
 */
public class Chess {
    private ChessNode[][] chessNodes;
    private static int size;
    public Chess(){
        chessNodes = new ChessNode[10][10];
    }

    //棋盘初始化填值➕,10*10大小
    private void initChessBoard(){
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                chessNodes[i][j] = new ChessNode("➕",i,j,false);
            }
        }
        System.out.println("初始化完成。");
    }

    //显示棋盘
    private void show(){
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                System.out.print(chessNodes[i][j].getChessType()+" ");
            }
            System.out.println();
        }
        System.out.println();
    }


    //下棋操作
    private void playChess(){
        Scanner in = new Scanner(System.in);
        boolean flag = false;
        String first = "", second = "", temp = "";

        //先手判断
        do {
        System.out.println("请选择:黑棋● | 白棋⭕");
        String choice = in.next();
        if(choice.equals("黑棋")){
            first = "●";
            second = "⭕";
            flag = true;
        }
        else if(choice.equals("白棋")){
            first = "⭕";
            second = "●";
            flag = true;
        }
        else{
            System.out.println("输入有误,请重输:");
        }}while (!flag);

        //下棋操作
        int x = 0, y = 0;
        while(true) {
            System.out.println("请输入"+first+"x,y坐标:");
            x = in.nextInt()-1;
            y = in.nextInt()-1;

            //参数安全检查
            if(x<0 || x>9 || y<0 || y>9){
                System.out.println("输入有误,x:1-10,y:1-10,请重新输入:");
                continue;
            }
            //判断原位置是否有棋
            if (chessNodes[x][y].isFlag() == true) {
                System.out.println("原位置已有棋,请重新输入x,y坐标:");
            }
            else {
                chessNodes[x][y].setChessType(first);
                chessNodes[x][y].setFlag(true);
                size++;
                //判和
                if(peace()){
                    System.out.println("和棋!");
                    break;
                }
                if(judgeVectory(x,y,first)){
                    break;
                }
                //不满足胜利条件,交换顺序继续下
                temp = first;
                first = second;
                second = temp;
                show();
            }
        }
    }

    //判断胜利
    private boolean judgeVectory(int x, int y, String chessType){
        int vertical = 0;	//垂直方向棋子数量
        int level = 0;	//水平方向棋子数量
        int bevelLeft = 0; //正北为0,-45°斜线上棋子数量
        int bevelRight = 0; //正北为0,45°斜线上棋子数量

        //计算90°方向棋子数量
        for (int i=1; i<5; i++) {
            if (y+i < 10 && chessNodes[x][y+i].getChessType().equals(chessType)) {
                level++;
            } else {
                break;
            }
        }

        //计算-90°方向棋子数量
        for (int i=1; i<5; i++) {
            if (y-i >= 0 && chessNodes[x][y-i].getChessType().equals(chessType)){
                level++;
            } else {
                break;
            }
        }

        //计算0°方向棋子数量
        for (int i=1; i<5; i++) {
            if (x+i < 10 && chessNodes[x+i][y].getChessType().equals(chessType)){
                vertical++;
            } else {
                break;
            }
        }

        //计算180°方向棋子数量
        for (int i=1; i<5; i++) {
            if (x-i >= 0 && chessNodes[x-i][y].getChessType().equals(chessType)){
                vertical++;
            } else {
                break;
            }
        }

        //计算45°方向棋子数量
        for (int i=1; i<5; i++) {
            if (x+i >= 0 && y+i >= 0 && chessNodes[x+i][y+i].getChessType().equals(chessType)){
                bevelRight++;
            } else {
                break;
            }
        }

        //计算225°方向棋子数量
        for (int i=1; i<5; i++) {
            if (x-i >= 0 && y-i >= 0 && chessNodes[x-i][y-i].getChessType().equals(chessType)){
                bevelRight++;
            } else {
                break;
            }
        }

        //计算-45°方向棋子数量
        for (int i=1; i<5; i++) {
            if (y-i >= 0 && x+i >= 0 && chessNodes[x+i][y-i].getChessType().equals(chessType)){
                bevelLeft++;
            } else {
                break;
            }
        }

        //计算135°方向棋子数量
        for (int i=1; i<5; i++) {
            if (x-i >= 0 && y+i >= 0 && chessNodes[x-i][y+i].getChessType().equals(chessType)){
                bevelLeft++;
            } else {
                break;
            }
        }

        //获胜条件
        if(vertical >= 4 || level >=4 || bevelLeft >= 4 || bevelRight >= 4){
            System.out.println(chessType+"胜利!");
            return true;
        }
        return false;
    }

    //和棋判断
    private boolean peace(){
        if(size == 100){
            return true;
        }
        return false;
    }
    public void run(){
        int choice = 0;
        boolean flag = false;
        do {
            initChessBoard();
            show();
            playChess();
            System.out.println("继续扣1,退出扣0");
            Scanner in = new Scanner(System.in);
            choice = in.nextInt();
            if(choice == 1){
                flag = true;
            }
        }while (flag);
    }
}

 

4.测试

 4.1测试函数

public class Start {
	public static void main(String[] args) {
		Chess chess = new Chess();
		chess.run();
	}
}

测试截图

因为写的很仓促,就测试了几个例子,边界条件啥的都没测试,有可能会有bug,不过主要学习的是类与对象的思想,还有五子棋的判断流程,掌握了就可以了。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值