java井字棋游戏 多人版哦

Posted 玛丽莲茼蒿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java井字棋游戏 多人版哦相关的知识,希望对你有一定的参考价值。

一、两人井字棋游戏

在井字游戏中,两个玩家使用各自的标志(一方用 X 则另一方就用 O ),轮流标记 3 ×3 的网格中的某个空格。当一个玩家在网格的水平方向、垂直方向或者对角线方向上标记了三个相同的 X 或三个相同的 O 时,游戏结束,该玩家获胜。平局(没有赢家)是指当网格中所有的空格都被填满时没有玩家获胜的情况。
 

完整代码来自这篇博客:

Java 井字游戏_Sun Tech的博客-CSDN博客_java 井字游戏创建一个玩井字游戏的程序。程序提示两个玩家交替输入 X 和 O 标记。当输入一个标记时,程序在控制台上重新显示棋盘,然后确定游戏的状态(是获胜、平局还是继续)。https://blog.csdn.net/baidu_34431530/article/details/100133846

import java.util.Scanner;
public class Game 
    private static Scanner input = new Scanner(System.in);
    public static void main(String[] args) 
        char[][] board = new char[3][3];
        displayBoard(board);
        while (true) 
            makeAMove(board, 'X');
            displayBoard(board);
            if (isWon('X', board)) 
                System.out.println("玩家 X 获胜");
                System.exit(1);
            
            else if (isDraw(board)) 
                System.out.println("平局");
                System.exit(2);
            
            makeAMove(board, 'O');
            displayBoard(board);
            if (isWon('O', board)) 
                System.out.println("玩家 O 获胜");
                System.exit(3);
            
            else if (isDraw(board)) 
                System.out.println("平局");
                System.exit(4);
            
        
    
    private static void makeAMove(char[][] board, char player) 
        boolean done = false;
        do 
            System.out.print("玩家 " + player + " :(行,列) = ");
            int row = input.nextInt();
            int column = input.nextInt();
            if (board[row][column] == '\\0') 
                board[row][column] = player;
                done = true;
            
            else
                System.out.println("无效输入");
        
        while (!done);
    
    private static void displayBoard(char[][] board) 
        System.out.println("\\n ——— ——— ———");
        for (int i = 0; i < 3; i++) 
            System.out.print("| ");
            for (int j = 0; j < 3; j++)
                System.out.print(board[i][j] != '\\0' ?  board[i][j] + " | ": "  | ");
            System.out.println("\\n ——— ——— ———");
        
    
    private static boolean isWon(char ch, char[][] board) 
        for (int i = 0; i < 3; i++)
            if (ch == board[i][0] && ch == board[i][1] && ch == board[i][2])
                return true;
        for (int j = 0; j < 3; j++)
            if (ch == board[0][j] && ch == board[1][j] && ch == board[2][j])
                return true;
        if (ch == board[0][0] && ch == board[1][1] && ch == board[2][2])
            return true;
        return ch == board[0][2] && ch == board[1][1] && ch == board[2][0];
    
    private static boolean isDraw(char[][] board) 
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                if (board[i][j] == '\\0')
                    return false;
        return true;
    

二、多人井字棋游戏

今天我们要做的就是对其进行创新。新增规则如下:

(1)支持3~10人同时玩游戏。棋盘大小为玩家人数+1

(2)游戏开始前,设定游戏获胜需要多少个连续的棋子,连续棋子的个数最少为3,最大为玩家人数+1(即棋盘的大小)

代码

设计了3个类

 1. Board 类

package com.tictactoe;

public class Board 
    private char[][] board ;

    //创建棋盘
    //Done!
    public void createBoard(int size)
        board = new char[size][size];  //创建初始棋盘,棋子默认为空
    

    //绘制棋盘
    //Done!
    public void drawBoard(int size)
        for(int i=0; i< size; i++)  //最上面的线
            System.out.print(" ———");
        
        System.out.print("\\n");
        for (int i = 0; i < size; i++)  //每一列
            System.out.print("| ");
            for (int j = 0; j < size; j++)
                System.out.print(board[i][j] != '\\0' ?  board[i][j] + " | ": "  | ");
            System.out.print("\\n");
            for(int k=0; k< size; k++)  //最下面的线
                System.out.print(" ———");
            
            System.out.print("\\n");
        
        System.out.print("\\n");
   

   //玩家下棋后,改变棋盘数组board
   //Done!
    public void changeBoard(int row,int column,char player)
        board[row][column]=player;
    

    //查看棋盘
    //Done!
    public char[][] getBoard() 
        return board;
    

棋盘类中没有什么难点。主要就是创建一个二维char类型的空棋盘、在控制台画出棋盘和已有的棋子、改变棋盘等操作。

2. GameLogic 类(难点!

package com.tictactoe;
import java.util.Scanner;


public class GameLogic 
    private static Scanner input = new Scanner(System.in);

    //玩家下一个棋子,改变棋盘布局
    //Done!
    public void makeAMove(Board board, char player) 
        char[][] board2 = board.getBoard();     //获取棋盘目前状态
        boolean done = false;  //用来判断循环,用户第一次输入的是正确位置就一次循环;否则进入下一次
        do 
            System.out.print("玩家 " + player + " :(行,列) = ");
            int row = input.nextInt();  //玩家输入棋子的行数
            int column = input.nextInt();  //玩家输入棋子的列数
            if (board2[row][column] == '\\0') 
                board.changeBoard(row,column,player);  //玩家成功下了一棋!
                done = true;  //有位置就放下,跳出这个循环
            
            else
                System.out.println("无效输入");  //玩家选择的位置已经有棋子了,重新下
        
        while (!done);
    

    //判断player是否赢了,返回true为赢
    //思路:仿照卷积核进行卷积的过程
    public boolean isWon(char player, Board board,int piece,int size) 
        char[][] board2 = board.getBoard();     //获取棋盘目前状态

        for(int row=0; row<=size-piece;row++)
            for(int col=0;col<=size-piece;col++)
                /*-----------------以piece×piece为大小的内部检查-------------*/
                //行相同
                for(int i=row;i<row+piece;i++)
                    for(int j=col;j<col+piece;j++)
                        if(player==board2[i][j])
                            if(j==col+piece-1) return true; //找到满足条件的行
                        else break;  //这一行不满足,跳出内循环,检查下一行
                    
                
                //列相同
                for(int j=col;j<col+piece;j++)
                    for(int i=row;i<row+piece;i++)
                        if(player==board2[i][j])
                            if(i==row+piece-1) return true; //找到满足条件的列
                        else break; //这一列不满足,检查下一列
                    
                
                //正对角线相同
                for(int k=0;k<piece;k++)
                    if(player==board2[row+k][col+k])
                        if(row+k==row+piece-1) return true; //找到满足条件的正对角线
                    else break; //正对角线不满足
                
                //负对角线
                int row2=row+piece-1;
                int col2=col;
                for(int k=0;k<piece;k++)
                    if(player==board2[row2-k][col2+k])
                        if(row2-k==row) return true; //找到满足条件的副对角线
                    else break; //负对角线不满足
                
            
        
        return false;
    

    //判断是否平局:返回false为否,返回true为平局
    //Done!
    public boolean isDraw(Board board,int size) 
        char [][]board2 = board.getBoard();
        for (int i = 0; i < size; i++)
            for (int j = 0; j < size; j++)
                if (board2[i][j] == '\\0')
                    return false; //棋盘存在空白,未平局
        return true;
    

makeAMove()方法较容易理解,一行一行看下来基本上就知道逻辑了,注释也都写得很清晰。

难点在于isWon()方法,即对player是否获胜的判断。这里利用的是卷积核的思想(不懂可以去搜“卷积神经网络”)。我们假设玩家人数为n(那么棋盘大小就是n+1),玩家规定连续m个棋子赢得游戏。那么我们就可以把棋盘看成一张(n+1)×(n+1)大小的图像,卷积核大小是m×m。在m×m大小的区域内,检查行、列、主对角线、副对角线是否有连续相同的,一旦有一种情况满足条件,立刻返回true。

isDraw()方法:判断是否平局。棋盘都下满了就是平局,所以关键在于判断棋盘满了没有。

3. tictactoe2 类

package com.tictactoe;

import java.util.Scanner;

public class tictactoe2 
    private static Scanner input = new Scanner(System.in);
    public static void main(String[] args) 
        /*--------输入玩家人数、输入连续棋子的个数------*/
        System.out.println("请输入玩家的个数(3~10人):");
        int player_num = input.nextInt();
        System.out.println("请输入赢家连续棋子的个数(最少为3,最大为玩家人数+1):");
        int piece_num = input.nextInt();

        /*-------------初始化棋盘---------------*/
        int size = player_num + 1; //棋盘的大小
        Board board = new Board();
        board.createBoard(size); //创建棋盘
        board.drawBoard(size); //绘制初始棋盘

        /*-------------初始化玩家------------*/
        char player[] = new char[player_num];
        for(int i=0; i<player_num;i++)
            int temp = 97+i;  //准备由int向char进行转换
            player[i]= (char) temp;  //用字母a~j表示0号~9号玩家(根据题目要求,最多10人,第10人为j)
        
        /*--------------开始下棋-------------*/
        GameLogic logic = new GameLogic();
        int play_i=0; //从0号玩家开始
        while (true) 

            logic.makeAMove(board,player[play_i]);  //下棋,更新棋盘
            board.drawBoard(size); //绘制新棋盘
            if (logic.isWon(player[play_i], board,piece_num,size))   //判断第i号玩家是否获胜
                System.out.println("玩家"+player[play_i]+"获胜");
                System.exit(1);
            
            else if (logic.isDraw(board,size))   //判断是否平局
                System.out.println("平局");
                System.exit(2);
            

            if(play_i<player_num-1)
                play_i++; //下一个玩家
            else 
                play_i=0;  //又轮到0号玩家
            
        
    




这里稍微难一点的地方有两点。

1)利用int类型向char类型的转换,把1~10号玩家分别用字母a~j去表示。

2)另一个难点在于如何实现玩家轮着下棋。重点看play_i这个变量就明白了

4. 玩法示例

(1)示例1

(2)平局示例

 

5. 总结

(1)对类的封装还不是太好,如果再写一个player类,程序的封装性就更好了

(2)学习了Sanner的使用。主要就是四个函数。

        

以上是关于java井字棋游戏 多人版哦的主要内容,如果未能解决你的问题,请参考以下文章

井字游戏循环在平局时停止 - Java

童年回忆《三子棋》

在平局的情况下井字游戏不会终止

C语言实战小游戏:井字棋(三子棋)大战!文内含有源码

用React写井字棋游戏

react入门学习:井字棋游戏(官方文档教程)