java实现简单三子棋-面向对象思想编写程序(4000字中短文)

笔者作为一个初学者,在此分享java实现三子棋.

代码虽然是本人自己敲的,但,因为原理是笔者通过学习他人的代码了解的,所以笔者不可避免地和他人代码存在雷同.

.笔者旨在记录和分享知识,并无依次获利的目的.

对象

java是一种面向对象的语言,在三子棋当中,我们的对象,很简单,笼统说就俩

1.棋盘

2.游戏内容

接下来,笔者将分享代码,并解释一些写法

棋盘类

package board;

import java.util.Arrays;

public class Board {
    private char[][] board; // 棋盘状态

    // 构造函数,初始化棋盘
    public Board() {
        board = new char[3][3];
        for (char[] row : board) {
            Arrays.fill(row, ' '); // 将棋盘初始化为空格
        }
    }

    // 打印棋盘
    public void printBoard() {
        for (char[] row : board) {
            for (char cell : row) {
                System.out.print(cell + " | "); // 打印每个单元格
            }
            System.out.println();
            System.out.println("---------"); // 打印分隔线
        }
    }

    // 在指定位置放置棋子
    public boolean placePiece(int row, int col, char piece) {
        if (row < 0 || row >= 3 || col < 0 || col >= 3 || board[row][col] != ' ') {
            return false;  // 如果位置无效或已经有棋子,返回 false
        }

        board[row][col] = piece; // 在指定位置放置棋子
        return true;
    }

    // 检查游戏状态,返回获胜者或游戏尚未结束
    public char checkWinner() {
        // 检查行
        for (int i = 0; i < 3; ++i) {
            if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][1] == board[i][2]) {
                return board[i][0];  // 如果一行的棋子都相同,返回获胜者
            }
        }
        // 检查列
        for (int j = 0; j < 3; ++j) {
            if (board[0][j] != ' ' && board[0][j] == board[1][j] && board[1][j] == board[2][j]) {
                return board[0][j];  // 如果一列的棋子都相同,返回获胜者
            }
        }
        // 检查对角线
        if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
            return board[0][0];  // 如果左上到右下对角线的棋子都相同,返回获胜者
        }
        if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
            return board[0][2];  // 如果左下到右上对角线的棋子都相同,返回获胜者
        }

        return ' ';  // 游戏尚未结束,返回空格
    }
}

我们都知道,这是一个二维数组,所以我们先定义一个二维数组,并且构造它.

然后,是放置棋子,我们写一个placePiece函数,来判断下, 我们这里是否可以合法放置我们的棋子

最后是检查你赢没赢,三子棋就三种赢法,有没有同一行,同一列,或者左上右上.(让我想起了之前用dfs写N皇后问题,以后有空也想分享一下)

 public char checkWinner() {
        // 检查行
        for (int i = 0; i < 3; ++i)
        {
            if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][1] == board[i][2])
            {
                return board[i][0];  // 该行有相同的棋子,返回获胜方
            }
        }
        // 检查列
        for (int j = 0; j < 3; ++j)
        {
            if (board[0][j] != ' ' && board[0][j] == board[1][j] && board[1][j] == board[2][j]) {
                return board[0][j];  // 该列有相同的棋子,返回获胜方
            }
        }
        // 检查对角线
        if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
            return board[0][0];  // 左上到右下对角线有相同的棋子,返回获胜方
        }
        if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
            return board[0][2];  // 左下到右上对角线有相同的棋子,返回获胜方
        }
        return ' ';  // 游戏尚未结束
    }

我这里因为图方便,棋子和选手公用了一个名字,所以return棋子也就是return棋手.

比赛类

package game;

import board.Board;
import java.util.Scanner;
public class Game {
    private Board board;
    private char currentPlayer;

    public Game() {
        board = new Board();
        currentPlayer = 'X';
    }
    // 开始游戏
    public void startGame() {
        Scanner scanner = new Scanner(System.in);
        while (true)
        {
            board.printBoard();
            System.out.print("Player " + currentPlayer + ", enter your move (row and column): ");
            int row = scanner.nextInt();
            int col = scanner.nextInt();
            if (board.placePiece(row, col, currentPlayer))
            {
                char winner = board.checkWinner();
                if (winner != ' ')
                {
                    board.printBoard();
                    System.out.println("Player " + winner + " wins!");
                    break;
                }
                togglePlayer();
            } else {
                System.out.println("Invalid move. Try again.");
            }
        }
        scanner.close();
    }
    // 切换当前玩家
    private void togglePlayer() {
        currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
    }
}

首先,先创建新的棋盘,以及选手,并且进行构造

注意 ,此时的Board类,也是一种数据了.

当我们创建Board对象时,使用  new Board() 语句会在堆内存中分配一块新的内存空间来存储棋盘对象,并返回对该对象的引用。

    private Board board;
    private char currentPlayer;

    public Game() {
        board = new Board();
        currentPlayer = 'X';
    }

然后是正式开始游戏了

函数如下

  public void startGame() {
        Scanner scanner = new Scanner(System.in);
        while (true)
        {
            board.printBoard();
            System.out.print("Player " + currentPlayer + ", enter your move (row and column): ");
            int row = scanner.nextInt();
            int col = scanner.nextInt();
            if (board.placePiece(row, col, currentPlayer))
            {
                char winner = board.checkWinner();
                if (winner != ' ')
                {
                    board.printBoard();
                    System.out.println("Player " + winner + " wins!");
                    break;
                }
                togglePlayer();
            } else {
                System.out.println("Invalid move. Try again.");
            }
        }
        scanner.close();
    }
    // 切换当前玩家
    private void togglePlayer()
    {
        currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
    }

我们先打印棋盘,然后输入坐标,然后切换选手,周而复始,知道有人赢了或者平局

在这里我们就可以看出,棋子和棋手 共用一个字符的好处了,直接就可以切换

主函数

import game.Game;
import board.Board;
public class Main {
    public static void main(String[] args) {
        Game game = new Game();
        game.startGame();
    }
}

这样就可以初步实现一个简单的三子棋游戏了

  

缺陷

这个代码也不是没有缺陷,假如平局了,哪怕没地方放棋子了,这个代码也不会停下来,但是因为结构在这里,要增加这个功能也不是难事,就留给读者你们去思考这么增加了,笔者写的时候没考虑到,写博客以后才想起来没加这个功能.

缺陷二,这是直接输入坐标来进行的游戏,并且,我们都知道数组下标是从0开始的,但是没有接触过编程的人就不到,笔者这里还是沿用了从0开始,没有特意去设置从1开始,在使用体验上就会差一点,因为我自己都搞错过.

总结

这是笔者花费一个小时(你没看错,一个小时,我也觉得长了)写的,先前学习c语言的时候写过,笔者只是把它移到了java中,加上一些面向对象思想.

大体结构如图

这样写好处是,结构很清晰,也便于我们后续增加功能,大家伙可以试试把笔者的缺陷补上.

平局情况的增加(该博客发布一小时后增加的)

加一个函数遍历一下,看看是否平局即可,代码如下

   public void startGame() {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            board.printBoard(); // 打印当前棋盘状态
            System.out.print("Player " + currentPlayer + ", enter your move (row and column): ");
            int row = scanner.nextInt(); // 获取玩家输入的行数
            int col = scanner.nextInt(); // 获取玩家输入的列数

            if (board.placePiece(row, col, currentPlayer))
            {
                char winner = board.checkWinner(); // 检查是否有玩家获胜
                if (winner != ' ') {
                    board.printBoard(); // 打印最终的棋盘状态
                    System.out.println("Player " + winner + " wins!"); // 输出获胜者
                    break; // 游戏结束
                } else if(board.isBoardFull())
                {
                    board.printBoard(); // 打印最终的棋盘状态
                    System.out.println("It's a draw!"); // 输出平局
                    break; // 游戏结束
                }
                togglePlayer(); // 切换玩家
            } else {
                System.out.println("Invalid move. Try again."); // 如果玩家输入无效,提示重新输入
            }
        }
        scanner.close();
    }    // 切换当前玩家
    private void togglePlayer() {
        currentPlayer = (currentPlayer == 'X') ? 'O' : 'X'; // 如果当前玩家是 X,则切换为 O;如果当前玩家是 O,则切换为 X
    }

游戏代码如上

public boolean placePiece(int row, int col, char piece) {
        if (row < 0 || row >= 3 || col < 0 || col >= 3 || board[row][col] != ' ') {
            return false;  // 如果位置无效或已经有棋子,返回 false
        }

        board[row][col] = piece; // 在指定位置放置棋子
        return true;
    }

    // 检查游戏状态,返回获胜者或游戏尚未结束
    public char checkWinner() {
        // 检查行
        for (int i = 0; i < 3; ++i) {
            if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][1] == board[i][2]) {
                return board[i][0];  // 如果一行的棋子都相同,返回获胜者
            }
        }
        // 检查列
        for (int j = 0; j < 3; ++j) {
            if (board[0][j] != ' ' && board[0][j] == board[1][j] && board[1][j] == board[2][j]) {
                return board[0][j];  // 如果一列的棋子都相同,返回获胜者
            }
        }
        // 检查对角线
        if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
            return board[0][0];  // 如果左上到右下对角线的棋子都相同,返回获胜者
        }
        if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
            return board[0][2];  // 如果左下到右上对角线的棋子都相同,返回获胜者
        }

        return ' ';  // 游戏尚未结束,返回空格
    }

    // 检查是否棋盘已满
    public boolean isBoardFull() {
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                if (board[i][j] == ' ') {
                    return false; // 如果有空格,表示棋盘尚未满
                }
            }
        }
        return true; // 棋盘已满
    }

棋盘代码如上

  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值