Java实现三子棋小游戏

作者:庸人冲 时间:2022-09-12 01:27:20 

# 前言

之前在学习C语言的时候,做过一个三子棋的小游戏,最近开始学习Java,就想着能不能用Java再把之前的练习重新实现一边,既然有这个想法了,那就开始行动啦~。

再写的过程中,能感觉到面向过程语言和面向对象语言的一些差异。最让我头疼的是类的设计,感觉不仅得考虑功能得实现,还需要考虑类之间得逻辑关系,函数的功能是单一的,但函数与函数之间谈不上什么关系,你要用的上我,你就用,不用就拉倒。类在设计的时候需要考虑将哪些方法封装在哪个类当中,封装位置不合适,尽管也可能实现功能,但总感觉怪怪的。自己最后的代码其实还是按照之前C的设计思路写的,只不过把其中一些内容抽象成了类,然后在其中封装了对应的方法。

三子棋介绍

三子期是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。

三子棋规则

玩家和电脑交替在棋盘中落下一个棋子,直到一方胜利或者平局,则结束游戏。

当棋盘上同一行或者同一列或者对角线的三个棋子都相同时,棋子所属方胜利。

当棋盘已满还未分出胜负,则平局。

具体实现

测试类

用来测试程序的各项功能,其中也包括了程序的运行逻辑


public class BoardTest {
   public static void main(String[] args) {

while(true){
           showMenu();  // 显示棋盘
           boolean isPlay = Utility.readMenuSelection();   // 读取玩家输入
           if(isPlay){  // isPlay == true 进入游戏
               System.out.println("欢迎来到三子棋小游戏!");
               Board board = new Board();      // 创建棋盘对象
               Player player = new Player();   // 创建玩家对象
               Computer computer = new Computer(); // 创建电脑对象
               board.initBoard();  // 初始化棋盘
               char flag = ' ';    // 接收棋局判断的返回值
               // 博弈过程
               while(true){
                   board.showBoard();  // 显示棋盘
                   System.out.print("请输入落棋点(x,y):>");
                   player.moveChess(board);   // 玩家走
                   flag = board.isWin();
                   if(flag != 'c'){  // 将玩家和电脑的棋子传入,判断当前棋局的形式
                       break;   // != 'c' 则跳出循环
                   }
                   computer.moveChess(board); // 电脑走
                   flag = board.isWin();
                   if(flag != 'c'){  // 将玩家和电脑的棋子传入,判断当前棋局的形式
                       break;   // != 'c' 则跳出循环
                   }
               }
               if(flag == player.getChess()){
                   System.out.println("玩家赢!");
               } else if (flag == computer.getChess()){
                   System.out.println("电脑赢!");
               } else {
                   System.out.println("平局!");
               }
           } else {    // 否则 再次确认玩家是否要离开
               System.out.println("真的要离开嘛?(Y/N):");
               boolean isExit = Utility.readConfirmSelection();  // 读取玩家输入
               if(isExit){  // isExit == true 退出游戏
                   System.out.println("退出成功!");
                   break;
               }
           }
       }

}

// 游戏菜单
   public static void showMenu(){
       System.out.println("============================================");
       System.out.println("==========        1. play        ===========");
       System.out.println("==========        2. exit        ===========");
       System.out.println("============================================");
       System.out.print("请输入选择:>");
   }
}

棋盘类

属性方法概述


// 属性:
private int row; // 行
private int col; // 列
private char[][] board; // 棋盘数组

// 方法:
public void initBoard() {...} // 用来初始化棋盘,讲棋盘二维数组中的每个元素赋值为' '
public void showBoard() {...} // 用来显示棋盘
public char isWin() {...}     // 判断当前棋局的形势
private boolean isFull(){...} // 判断棋盘是否已满
// getter方法,因为不允许设置棋盘属性,没有setter方法
public int getRow() {...}    // 返回行
public int getCol() {...}    // 返回列
public char[][] getBoard() {...}  // 返回棋盘数组
// 构造器
public Board() {...} // 空参构造器,在其中默认设置了行列,并new了棋盘数组对象

完整代码


public class Board {
   private int row; // 行
   private int col; // 列
   private char[][] board; // 棋盘数组

/**
    * @description: 构造器,用来设置棋盘大小
    * @parameter row, 表示行数;  col, 表示列数
    */
   public Board() {
       row = 3;
       col = 3;
       board = new char[row][col];
   }

/**
    * @description: 用来初始化棋盘,讲棋盘二维数组中的每个元素赋值为' '
    */
   public void initBoard() {
       for (int i = 0; i < row; i++) {
           for (int j = 0; j < col; j++) {
               board[i][j] = ' ';
           }
       }
   }

/**
    * @description: 用来显示棋盘
    */
   public void showBoard() {
       for (int i = 0; i < row; i++) {
           for (int j = 0; j < col; j++) {
               if (j < col - 1) {
                   System.out.print(" " + board[i][j] + " |");
               } else {
                   System.out.print(" " + board[i][j] + " ");
               }
           }
           System.out.println();
           if (i < row - 1) {
               for (int k = 0; k < col; k++) {
                   if (k < col - 1) {
                       System.out.print("---|");
                   } else {
                       System.out.print("---");
                   }
               }
               System.out.println();
           }
       }
   }

/**
    * @description 判断当前棋局的形势
    * @return 返回  玩家的棋子 玩家赢, 返回 电脑的棋子 电脑赢
    * 返回 'q' 平局           , 返回 'c' 继续
    */
   public char isWin() {
       // 判断同一行是否相同
       for (int i = 0; i < row; i++) {
           if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ') {
               return board[i][0];  // 返回该行的一个棋子
           }
       }
       // 判断同一列是否相同
       for(int i = 0; i < col; i++){
           if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ') {
               return board[i][0];  // 返回该列的一个棋子
           }
       }
       // 判断对角线是否相同
       if(board[0][0] == board[1][1] && board[1][1]  == board[2][2] && board[0][0] != ' ' || board[0][2] == board[1][1] && board[1][1] ==  board[2][0] && board[0][2] != ' '){
           return board[1][1];        // 返回对角线中间的棋子
       }

// 判断棋盘是否已满
       if(isFull()){
           return 'q';  // 已满返回'q'
       } else {
           return 'c';  // 未满返回'c'
       }
   }

/**
    * @description 判断棋盘是否已满
    * @return true 表示已满  false 表示未满
    */
   private boolean isFull(){
       for (int i = 0; i < row; i++) {
           for (int j = 0; j < col; j++) {
               if(board[i][j] == ' '){
                   return false;  // 未满返回false
               }
           }
       }
       return true; // 已满返回true
   }

public int getRow() {
       return row;
   }

public int getCol() {
       return col;
   }

public char[][] getBoard() {
       return board;
   }
}

用户类

属性方法概述


// 属性:
private char chess;  // 玩家的棋子
// 方法:
public void moveChess(Board board){...} // 玩家下棋,讲棋子放到指定位置
// getter方法
public char getChess() {...} // 用来返回玩家的棋子
// 构造器:
public Player() {...} // 空参构造器,默认设置了代表玩家棋子的字符

完整代码


public class Player {
   private char chess;  // 棋子

/**
    * @description 空参构造器,用来设置用户的棋子
    */
   public Player() {
       chess = '*';
   }

/**
    * @description 玩家下棋,讲棋子放到指定位置
    * @param board 接收使用的棋盘数组
    */
   public void moveChess(Board board){
       Scanner sc = new Scanner(System.in);
       while(true){
           int x = sc.nextInt(); // 接收x坐标
           int y = sc.nextInt(); // 接收y坐标
           boolean isFlag = Utility.readPosition(x,y,board); // 判断位置是否合适
           if(isFlag){ // 合适则将玩家棋子存入棋盘的对应位置中
               board.getBoard()[x-1][y-1] = chess;
               return;
           }
           System.out.print("输入有误,请重新输入:>");
       }
   }

/**
    * @return 返回玩家的棋子
    */
   public char getChess() {
       return chess;
   }
}

电脑类

属性方法概述


// 属性:
private char chess;  // 电脑的棋子
// 方法:
public void moveChess(Board board){...} // 电脑下棋,在棋盘中随机位置放入一个棋子
// getter方法:
public char getChess() {...}  // 返回电脑的棋子
// 构造器:
public Computer() {...}   // 空参构造,默认设置了代表电脑棋子的字符

完整代码


import java.util.Scanner;

public class Computer {
   private char chess;  // 电脑的棋子

/**
    * @description 用来设置电脑的棋子
    */
   public Computer() {
       chess = '#';
   }

/**
    * @description   在棋盘中随机位置放入一个棋子
    * @param board   接收使用的棋盘数组
    */
   public void moveChess(Board board){
       Scanner sc = new Scanner(System.in);
       while(true){
           int x = (int)(Math.random() * 3);
           int y = (int)(Math.random() * 3);
           boolean isFlag = Utility.readPosition(x+1,y+1,board);
           if(isFlag){
               board.getBoard()[x][y] = chess;
               return;
           }
       }

}

/**
    *
    * @return 返回电脑的棋子
    */
   public char getChess() {
       return chess;
   }
}

工具类

提供了static方法,主要用来接收玩家的输入,判断输入是否合适。

属性方法概述


// 方法
public static boolean readMenuSelection() {...} // 读取玩家进入菜单界面的输入选项,并进行判断。
public static boolean readConfirmSelection() {...} // 读取玩家确认选项的输入,'Y'表示确认 'N'表示否认
public static boolean readPosition(int x, int y, Board board){...} // 判断玩家输入的x y 坐标是否合理,合理位置返回true, 不合理位置返回false

完整代码


import java.util.Scanner;

public class Utility {
   /**
    * @description: 读取用户输入的数字,并进行判断
    * @return 输入1则返回true, 输入2 则返回false
    */
   public static boolean readMenuSelection() {
       int num = new Scanner(System.in).nextInt();
       while (true) {
           if (num == 1) {
               return true;
           } else if (num == 2) {
               return false;
           } else {
               System.out.print("输入有误,请重新输入:>");
           }
       }
   }

/**
    * @description: 读取用户输入的字符,并做出判断
    * @return 输入'Y' 返回true, 输入'N' 返回false
    */
   public static boolean readConfirmSelection() {
       String str = new Scanner(System.in).next();
       while(true){
           if(str.length() == 1){
               char ch = str.toUpperCase().charAt(0);  // 获取该字符
               System.out.println(ch);
               if(ch == 'Y'){
                   return true;
               } else if( ch == 'N'){
                   return false;
               }
           }
           System.out.print("输入有误,请重新输入:>");
       }
   }

/**
    * @description 判断用户输入的落棋点是否在合理位置
    * @param x x坐标
    * @param y y坐标
    * @param board 使用的棋盘对象
    * @return 合理位置返回true, 不合理位置返回false
    */
   public static boolean readPosition(int x, int y, Board board){
       if(1 <= x && x <= board.getRow() && 1 <= y && y <= board.getCol() && board.getBoard()[x - 1][y - 1] == ' '){
           return true;
       }
       return false;
   }
}

来源:https://blog.csdn.net/weixin_48084293/article/details/119150792

标签:java,三子棋
0
投稿

猜你喜欢

  • java图形界面编程之模拟血压计

    2023-10-01 07:16:05
  • Java实现Web应用中的定时任务(实例讲解)

    2022-08-12 23:40:02
  • 安卓逆向半次元app逆向分析源码

    2023-07-28 14:36:05
  • Java中静态代码块、构造代码块、构造函数和普通代码块的区别

    2023-11-25 10:09:06
  • Kotlin开发Android应用实例详解

    2023-09-11 00:22:50
  • MyBatis 如何配置多个别名 typeAliasesPackage

    2021-11-16 06:35:54
  • 腾讯云部署javaWeb项目的实现步骤

    2023-11-05 18:03:29
  • Java设计模式之享元模式实例详解

    2021-12-19 17:54:00
  • Android 显示GIF图片实例详解

    2023-08-06 09:11:52
  • Java常用类String的面试题汇总(java面试题)

    2023-11-23 20:40:45
  • Java非侵入式API接口文档工具apigcc用法详解

    2023-11-24 10:01:00
  • Android Studio多渠道打包的配置方法

    2023-06-15 23:19:48
  • Kotlin 接口与 Java8 新特性接口详解

    2023-09-10 01:10:45
  • 详解Spring Bean的集合注入和自动装配

    2023-02-18 15:02:58
  • java环境变量path和classpath的配置

    2023-08-31 01:09:04
  • Java实现拖拽列表项的排序功能

    2023-11-28 23:39:00
  • java中单例模式讲解

    2022-05-22 14:24:07
  • MyBatis-Plus不使用数据库默认值的问题及解决

    2023-11-13 17:37:20
  • javaWeb使用servlet搭建服务器入门

    2023-11-21 04:47:45
  • 手把手带你了解Java-Stream流方法学习及总结

    2023-11-25 19:30:15
  • asp之家 软件编程 m.aspxhome.com