笔者作为一个初学者,在此分享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; // 棋盘已满
}
棋盘代码如上