井字游戏java只使用方法和二维数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22004426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 11:59:29  来源:igfitidea点击:

Tic Tac Toe Game java using only methods and 2d arrays

java

提问by zeesh91

Still cannot figure out what im doing wrong. I have no idea how to get the CPU choice into the board. I did get the board to re display the updated board with the row and column the player selected. I need to have 4 methods and id like them to do exactly only this: 1) displayBoard (takes single passed parameter of 2d array representing current tic tac toe board. 2.) makeAMove (takes 2 passed parameters: Two dimensional array representing tictactoe board and player character value ('X' or 'O'). Updates array with valid row and column selected by player character. This method does NOT return anything, it simply updates the board array. 3.) hasWon (Takes 2 passed parameters, 2 dimensional array representing TicTacToe board and player character ('X' or 'O'). Return TRUE if player character has won, FALSE otherwise. 4.) boardFull (Takes single passed parameter of two dimensional array representing TicTacToe board and return TRUE if all cells are occupied, false otherewise. These area ll the methods, some of which i have done in an ineffiecient way (i know) but im trying to teach myself just the logic of it first without using any classes. Anyone that can either comment here it would greatly help as i feel stuck at this point.

仍然无法弄清楚我做错了什么。我不知道如何在板上选择 CPU。我确实让电路板重新显示更新后的电路板,其中包含玩家选择的行和列。我需要有 4 种方法和 id 喜欢他们来做这件事:1)displayBoard(采用代表当前井字棋板的二维数组的单个传递参数。2.)makeAMove(需要 2 个传递参数:代表 tictactoe 棋盘的二维数组和玩家角色值('X' 或 'O')。使用玩家角色选择的有效行和列更新数组。此方法不返回任何内容,它只是更新棋盘数组。3.)hasWon(接受 2 个传递的参数,代表井字棋盘和玩家角色('X' 或 'O')的二维数组。如果玩家角色获胜,则返回 TRUE,否则返回 FALSE。4.

import java.util.Scanner;

public class TicTacToe {

    public static void main(String[] args) {

        char[][] board = {{'1','2','3'}, {'4','5','6'}, {'7', '8', '9'}};
        // assign player to char value of X's only

        int play;

        char player = 'X';

        char cpu = 'O';

        int rowNumber;

        int columnNumber;

        int playerORow;
        int playerOcolumn;

        System.out.println("Welcome to tic, tac, toe!\n");

        System.out.println("Do you wish to play? 1 for yes, 2 for no ");

        Scanner input = new Scanner(System.in);

        play = input.nextInt();

        if(play != 1) {
            System.out.print("Invalid input, game will now EXIT thanks for playing!");
            System.exit(0);
        } // end if

            displayBoard(board);
            System.out.println("You are limited to X's only, good luck!");
            System.out.println("Please enter row (0-3) of your move: ");
            rowNumber = input.nextInt();
            System.out.println("Please enter column (1-3); of your move: ");
            columnNumber = input.nextInt();

            System.out.println("Please enter row (0-3) for player O: ");
            playerORow = input.nextInt();
            System.out.println("Please enter column (1-3); of your move: ");
            playerOcolumn = input.nextInt();


            if(board[rowNumber][columnNumber] != 'X' && board[rowNumber][columnNumber] != 'O')  {
                board[rowNumber][columnNumber] = player;
            } // end if

            else {

            }


            makeAMove(board, player);
            hasWon(board, player);
            boardFull(board);

} // end main method

// displays only the tic tac toe board
public static void displayBoard(char[][] board) {
    // loop for each row
    System.out.println(board[0][0] + " | " + board[0][1] + " | " + board[0][2] + "\n---------");
    System.out.println(board[1][0] + " | " + board[1][1] + " | " + board[1][2] + "\n---------");
    System.out.println(board[2][0] + " | " + board[2][1] + " | " + board[2][2] + "\n");

} // end display board method

// takes board array of values and updates it with valid row and column selected by player..does not return anything
public static void makeAMove(char[][] board, char player) {
    displayBoard(board);


} // end makeAMove method


// compare each element in board to see if the char value of 'X' exists
    // if exists then then return true, else return false
public static boolean hasWon(char[][] board, char player) {

        // Check if the player has won by checking winning conditions.
        if (board[0][0] == player && board[0][1] == player && board[0][2] == player || // 1st row
            board[1][0] == player && board[1][1] == player && board[1][2] == player || // 2nd row
            board[2][0] == player && board[2][1] == player && board[2][2] == player || // 3rd row
            board[0][0] == player && board[1][0] == player && board[2][0] == player || // 1st col.
            board[0][1] == player && board[1][1] == player && board[2][1] == player || // 2nd col.
            board[0][2] == player && board[1][2] == player && board[2][2] == player || // 3rd col.
            board[0][0] == player && board[1][1] == player && board[2][2] == player || // Diagonal          \ 
            board[2][0] == player && board[1][1] == player && board[0][2] == player) //   Diagonal      /

            return true;

        else {

            return false;
        }

} // end hasWon method

public static boolean boardFull(char [][] board) {

    if (board[0][0] != '1' && board[0][1] != '2' && board[0][2] != '3' &&
        board[1][0] != '4' && board[1][1] != '5' && board[1][2] != '6' &&
        board[2][0] != '7' && board[2][1] != '8' && board[2][2] != '9')

        return true;

    else {

        return false;
    } // end else

} // end boardFull method

} // end class

} // 结束类

采纳答案by Rohit Jain

You just have to do this:

你只需要这样做:

board[rowNumber][columnNumber] = player;

Of course you would have to check beforehand that cell is not already occupied. If yes, then ask again for user input. I guess that wouldn't be that tough.

当然,您必须事先检查单元格是否已被占用。如果是,则再次询问用户输入。我想那不会那么难。

Apart from that, I would suggest you some improvements to your code:

除此之外,我建议您对代码进行一些改进:

  • Rather than having two players as chartypes, use an enum Player, with two constants - Xand O. And use a Player[]instead.

    enum Player {
        X, O;
    }
    
  • No need to initialize your array with '1', '2', .... Now that they will be nullby default.

  • Rather than having boardas local variable, and passing it in all the methods, make it a field in your class.

  • Currently your code is making just one move. Why? Also, you're not even using the return value of hasWon()and boardFull()method.

  • You can divide the hasWonmethod into 3 methods - hasWonHorizontal(), hasWonVertical(), hasWonDiagonal(). This will avoid that long ifcondition in the same method. And then call these 3 methods in sequence from hasWon()method.

  • 与其将两个玩家作为char类型,不如使用enum Player, 和两个常量 -XO。并使用 aPlayer[]代替。

    enum Player {
        X, O;
    }
    
  • 无需使用'1', '2', .... 现在他们将是null默认的。

  • 与其将其board作为局部变量并将其传递到所有方法中,不如将其作为类中的一个字段。

  • 目前,您的代码只进行了一项操作。为什么?此外,您甚至没有使用hasWon()andboardFull()方法的返回值。

  • 您可以将该hasWon方法分为 3 种方法 - hasWonHorizontal()hasWonVertical()hasWonDiagonal()。这将if在相同的方法中避免这种长时间的情况。然后从hasWon()method依次调用这3个方法。

回答by SchwartzCode

Seems all you need to do is check to see if player/cpu has already taken that space. If not, you should just assign 'X' or 'O' to that element in the array.

似乎您需要做的就是检查播放器/cpu 是否已经占用了该空间。如果没有,您应该只将 'X' 或 'O' 分配给数组中的该元素。

if(board[rowNumber][columnNumber] != 'X' && board[rowNumber][columnNumber] != 'O')
    {
        board[rowNumber][columnNumber] = player;
    }
if(board[rowNumber][columnNumber] != 'X' && board[rowNumber][columnNumber] != 'O')
    {
        board[rowNumber][columnNumber] = player;
    }

You will probably want to have some kind of loop within your main() function to continuously allow players to move as well. The current implementation appears to only allow a player to make one move.

您可能希望在 main() 函数中包含某种循环,以持续允许玩家移动。当前的实现似乎只允许玩家做一个动作。

回答by Sebastian H?ffner

First a direct answer to your question:

首先直接回答你的问题:

// update board array with player row number and player column number
board[rowNumber][columnNumber] = player;

To show the new board you can just call your displayBoard()method again.

要显示新板,您只需displayBoard()再次调用您的方法即可。

You should be careful with your scanner as it doesn't validate the input. If you get a number not in [0..2] you will get an ArrayIndexOutOfBounds here, so you might want to do something like

您应该小心使用您的扫描仪,因为它不会验证输入。如果你得到一个不在 [0..2] 中的数字,你会在这里得到一个 ArrayIndexOutOfBounds,所以你可能想要做类似的事情

do {
    System.out.println("Please enter row (0-3) of your move: ");
} while((rowNumber = input.nextInt()) < 0 || rowNumber > 2);

and the same for the column to prevent this. Also you can add checks for strings and so on.

和列相同以防止这种情况。您还可以添加对字符串等的检查。

Some other aspects for the game:

游戏的其他一些方面:

  • Do you want to ask to continue before every move? If not, better move it to a new method and ask it once in the beginning.
  • Make board, player and cpu class variables. (or see below)
  • Use a loop around your game state, you already have a very nice "state"-machine by providing your functions:
  • 你想在每一步之前要求继续吗?如果没有,最好将其移至新方法并在开始时询问一次。
  • 制作 board、player 和 cpu 类变量。(或见下文)
  • 使用围绕您的游戏状态的循环,通过提供您的功能,您已经拥有了一个非常好的“状态”机:

.

.

// a possible loop/game might look like this:
if(askForPlaying()) {
    char currentPlayer = player;
    while(!(boardFull(board) || hasWon(board, player) || hasWon(board, cpu)) {
        displayBoard(board);
        if(currentPlayer == player) {
            makeAMove(board, currentPlayer);
        } else {
            cpuMove(board, currentPlayer);
        }
        currentPlayer==player?cpu:player;
    }
    if(hasWon(board, player)) System.out.println("You won!");
    if(hasWon(board, player)) System.out.println("You lost!");
}

The best way to improve your game would be to make a TicTacToe class and a Main class. The TicTacToe class would hold the board, the player, the cpu and some methods to display the board and modify it, and maybe also to switch the player and so on.

改进游戏的最佳方法是创建 TicTacToe 类和 Main 类。TicTacToe 类将保存棋盘、播放器、cpu 和一些显示棋盘和修改它的方法,也可能还可以切换播放器等。

The Main class would then just create the TicTacToe instance and run a main loop (the while-loop I posted above) which modifies it accordingly. But for now just go with your approach and maybe later you might want to improve it further. Then you can come back and think about it.

然后 Main 类将只创建 TicTacToe 实例并运行一个主循环(我在上面发布的 while 循环),它会相应地修改它。但是现在就采用你的方法,也许以后你可能想要进一步改进它。然后你可以回来考虑一下。

回答by Anuj Dhiman

  There is fully code for tic tac toe game. I have refer this article 

tic tac toe Example

井字游戏示例

  public class TicTacTOe {
      int _row=3;
    char _board[][]=new char[_row][_row]; 
    public void makeBoard(){
     for (int i = 0; i <_row; i++) {
      for (int j = 0; j < _row; j++) {
       _board[i][j]='o';
      }

     }
    }
    boolean isValid(int r,int c){
     return((r>=0&&r<_row)&&(c>=0&&c<_row));
    }
    boolean isFill(int r,int c){
     return(_board[r][c]!='o');
    }
    public boolean gamePlay(int r ,int c,int playerNo){
     if (!(isValid(r,c))) {
      System.out.println("Enter Correct index");
      return true ;
     }
     if (isFill(r,c)) {
      System.out.println("This index already fill");
      return true;
     }
     if (playerNo==1) {
      _board[r][c]='*';
     } else {
            _board[r][c]='+';
     }
     return false;
    }

    boolean horizontalAndVerticalMatch(char ch,int n){
     // for row and col math
          boolean flag=true;
      for (int i = 0; i < _row; i++) {
           flag=true;
         for (int j = 0; j < _row; j++) {
          System.out.println("i="+i+"j="+j);
          char ch1=(n==1)?_board[i][j]:_board[j][i];
               if (ch1!=ch) {
                System.out.println("y");
        flag=false;
        break;
       }
        } 
         if (flag) {
          return flag;
      }
      }
     return flag; 
    }
    boolean majorDiagonal(char ch){
     return((_board[0][0]==ch)&&(_board[1][1]==ch)&&(_board[2][2]==ch));
    }
    boolean minorDiagonal(char ch){
     return((_board[2][0]==ch)&&(_board[1][1]==ch)&&(_board[0][2]==ch));
    }
    public boolean isGameOver(int PlayerNo){
     char ch;
     if (PlayerNo==1) {
       ch='*';
     } else {
       ch='+';
     }
     return(horizontalAndVerticalMatch(ch,1)||horizontalAndVerticalMatch(ch,2)||majorDiagonal(ch)||minorDiagonal(ch));
    }
    public void display(){
     for (int i = 0; i <_row; i++) {
      for (int j = 0; j < _row; j++) {
       System.out.print("     "+_board[i][j]);
      }
      System.out.println("");
     }
    } 

    }

    MainTicTacToe.java
    import java.util.Scanner;

    public class MainTicTacToe extends TicTacTOe {
     public static void main(String[] args) {
     TicTacTOe obj=new TicTacTOe();
     obj.makeBoard();
     obj.display();
     int r,c;
     Scanner input=new Scanner(System.in);
     while(true){
      boolean flag=true;
      while(flag){
       System.out.println("Player 1");
       System.out.println("enter row");
       r=input.nextInt();
       System.out.println("enter col");
       c=input.nextInt();
       flag=obj.gamePlay(r,c,1);
      }
      if (obj.isGameOver(1)) {
       obj.display();
       System.out.println("Player 1 Win Game");   
       break;
      }
      System.out.println("============");
      obj.display();
      flag=true;
      while(flag){
      System.out.println("Player 2");
      System.out.println("enter row");
      r=input.nextInt();
      System.out.println("enter col");
      c=input.nextInt();
      flag=obj.gamePlay(r,c,2);
      }
      if (obj.isGameOver(2)) {
       obj.display();
       System.out.println("Player 2 Win Game");   
       break;
      }
      System.out.println("============");
      obj.display();
     }
    }
    }

Source : Click Here

来源:点击这里