2013-10-25 63 views
4

这是我的代码。我正在努力检查赢家。我只是一个初学者,所以请放轻松。我希望董事会改变尺寸。所以,我希望获胜者的支票可以使用到大小,它不会只检查9块。TicTacToe Java - 检查赢家

import java.util.*; 

public class TicTacToe { 

    private String[][] board; 
    private Scanner console; 

    public TicTacToe(String[][] table, Scanner console) { 
     this.board = table; 
     this.console = console; 
    } 

    public void makeTable() { 
     for (int i = 0; i < board.length; i++) { 
      for (int j = 0; j < board[i].length; j++) { 
       board[i][j] = "_"; 
      } 
     } 
    } 

    public void printTable() { 
     System.out.print(" "); 
     for (int i = 0; i < board.length; i++) { 
      System.out.print(" " + i); 
     } 
     System.out.println(); 
     for (int i = 0; i < board.length; i++) { 
      System.out.print(i + "│"); 
      for (int j = 0; j < board[i].length; j++) { 
       System.out.print(board[i][j] + "│"); 
      } 
      System.out.println(); 
     } 
    } 

    public void play(Scanner console) { 
     int turn = 0; 
     String player = "_"; 
     makeTable(); 
     printTable(); 
     while (turn != 9) { 
      int x = console.nextInt(); 
      int y = console.nextInt(); 

      while (x >= board.length || y >= board[1].length) { 
       System.out.println("Out of bounce, try again!!!"); 
       x = console.nextInt(); 
       y = console.nextInt(); 
      } 

      while (board[y][x] != "_") { 
       System.out.println("Occupied, try again!!!"); 
       x = console.nextInt(); 
       y = console.nextInt(); 
      } 

      if (turn % 2 == 0) { 
       player = "X"; 
      } else { 
       player = "O"; 
      } 
      board[y][x] = player; 
      turn++; 
      printTable(); 
     } 
    } 

    public static void main(String[] args) { 
     Scanner console = new Scanner(System.in); 
     String[][] board = new String[3][3]; 
     TicTacToe ttt = new TicTacToe(board, console); 
     ttt.play(console); 
    } 
} 
+0

对于初学者,您有一个很有希望的编码风格。尼斯。关于检查,你有没有试图做到这一点,如果是的话,你可以包括你的尝试代码? –

+2

[SO不适用于代码转储](http://meta.stackexchange.com/questions/88842/discourage-code-dumps)。请描述你的问题,你采取的措施来解决它,等等。 –

+0

@DaveNewton我给了他一个非常非常普遍的解决方案。没有代码,只是算法。 –

回答

0

好的,这里是我制作井字时的做法。我用String小号

  1. 创建一个包含所有可能的获胜组合
  2. 创建两个String变量,每个玩家一个二维数组。
  3. 显示板放在桌子上
  4. 数各自为1的块以9开始在左上角
  5. 每当任一的电路板上的用户点击,数附加到播放器String

现在,这里出现了魔法部分,检查赢家:
6.对于棋盘上的每一次点击,开始迭代2d获胜组合。这里是你如何检查是否有人赢了:

String[][] winningCombo = ... initialization ... 
for(int i = 0 ; i < winningCombo.length; i++){ 
    for(j = 0; j < winningCombo[i].length; j ++){ 
     char c1 = winningCombo[i][j].charAt(0); 
     char c2 = winningCombo[i][j].charAt(1); 
     char c3 = winningCombo[i][j].charAt(2); 
     if(currentPlayerString.contains(c1) && currentPlayerString.contains(c2) && currentPlayerString.contains(c3)){ 
      // currentPlayer has won if he has all the 3 positions of a winning combo 
     } 
    } 
} 

所以,如果你可以考虑一种替代方法,你可以使用它。我使用Swing作为用户界面,并使用GridLayout来布局各种JPanel

0

只是检查行的cols和两条对角线:

import java.util.Scanner; 

public class TTT { 

private String[][] board; 
private Scanner console; 
private int size; 

public TTT(String[][] table, Scanner console, int size) { 
    this.board = table; 
    this.console = console; 
    this.size = size; 
} 

public void makeTable() { 
    for (int i = 0; i < board.length; i++) { 
     for (int j = 0; j < board[i].length; j++) { 
      board[i][j] = "_"; 
     } 
    } 
} 

public void printTable() { 
    System.out.print(" "); 
    for (int i = 0; i < board.length; i++) { 
     System.out.print(" " + i); 
    } 
    System.out.println(); 
    for (int i = 0; i < board.length; i++) { 
     System.out.print(i + "│"); 
     for (int j = 0; j < board[i].length; j++) { 
      System.out.print(board[i][j] + "│"); 
     } 
     System.out.println(); 
    } 
} 

public void play(Scanner console) { 
    int turn = 0; 
    String player = "_"; 
    makeTable(); 
    printTable(); 
    while (turn != 9) { 
     int x = console.nextInt(); 
     int y = console.nextInt(); 

     while (x >= board.length || y >= board[1].length) { 
      System.out.println("Out of bounce, try again!!!"); 
      x = console.nextInt(); 
      y = console.nextInt(); 
     } 

     while (board[y][x] != "_") { 
      System.out.println("Occupied, try again!!!"); 
      x = console.nextInt(); 
      y = console.nextInt(); 
     } 

     if (turn % 2 == 0) { 
      player = "X"; 
     } else { 
      player = "O"; 
     } 
     board[y][x] = player; 
     turn++; 
     printTable(); 
     if(check()){ 
      System.out.println("Player "+player+" won!"); 
      break; 
     } 
    } 
} 
public boolean check(){ 
    //check diagonals 
    if(check00ToNN()){ 
     return true; 
    } 
    if(check0NToN0()){ 
     return true; 
    } 
    for(int i = 0 ; i< size ; i++){ 

     if(checkCol(i)){ 
      return true; 
     } 
     if(checkRow(i)){ 
      return true; 
     } 
    } 
    return false; 

} 

public boolean checkRow(int index){ 

    for(int i = 1 ; i< size ; i++){ 
     if(board[i-1][index]!=board[i][index]||board[i][index]=="_"){ 
      return false; 
     } 
    } 
    return true; 


    } 
public boolean checkCol(int index){ 
    for(int i = 1 ; i< size ; i++){ 
     if(board[index][i-1]!=board[index][i]||board[index][i]=="_"){ 
      return false; 
     } 
    } 
    return true; 


    } 
public boolean check00ToNN(){ 
    for(int i = 1 ; i< size ; i++){ 

      if(board[i-1][i-1]!=board[i][i]||board[i][i]=="_"){ 
       return false; 

     } 
    } 
    return true; 
    } 

public boolean check0NToN0(){ //diagonal 
    for(int i = 1 ; i< size ; i++){ 

      if(board[i-1][size-i-1]!=board[i][size-i]||board[i][size-i]=="_"){ 
       return false; 
      } 

    } 
    return true; 
    } 




public static void main(String[] args) { 
    Scanner console = new Scanner(System.in); 
    int size = 3; 
    String[][] board = new String[size][size]; 
    TTT ttt = new TTT(board, console,size); 
    ttt.play(console); 
} 

} 

我只是看看,如果有一个赢家,因为我知道是谁了最后一圈,我知道他是谁。

check()调用真正的checkmethods。

我加了size,因为它是可缩放的。

5

只有当棋子放在棋盘上时才会发生胜利动作,所以你只需要检查包含刚放在棋盘上棋子的胜利组合。

例如,如果董事会的当前状态为:

O X O 
X X 
    O 

而且O放在他们的作品在董事会中:

O X O 
X O X 
    O 

然后你只需要检查获胜涉及这个中间部分的组合,即两个对角线,以及中奖组合(8种组合)总数中的中间栏和中间栏(4种组合)。

因此,跟踪最后的举动对于有效确定董事会是否处于胜利状态至关重要。

1

编辑

前面已经提到一个人,你基本上做的是检查是否上次播放的举动是一个成功的举动。因此,没有必要对系统中的每一行,每列和对角线进行强力检查,以查看是否有胜出的位置或创建某种列表或解决方案来检查当前的电路板。

您真正需要做的就是检查移动的播放行,列和对角线(如果移动在对角线上),看看是否满足获胜条件。

// Takes the row and column coordinates of the last move made 
// and checks to see if that move causes the player to win 
public boolean isWinner(int row, int col){ 
    String Player = board[row][col]; 

    int r = row; 
    int c = col; 

    boolean onDiagonal = (row == col) || (col == -1 * row + (board.length-1)); 
    boolean HorizontalWin = true, VerticalWin = true; 
    boolean DiagonalWinOne = true; DiagonalWinTwo = true; 

    // Check the rows and columns 
    for(int n = 0; n < board.length; n++){ 
     if(!board[r][n].equals(Player)) 
      HorizontalWin = false; 
     if(!board[n][c].equals(Player)) 
      VerticalWin = false; 
    } 

    // Only check diagonals if the move is on a diagonal 
    if(onDiagonal){ 
     // Check the diagonals 
     for(int n = 0; n < board.length; n++){ 
      if(!board[n][n].equals(Player)) 
       DiagonalWinOne = false; 
      if(!board[n][-1*n+(board.length-1)].equals(Player)) 
       DiagonalWinTwo = false; 
     } 
    } 
    else{ 
     DiagonalWinOne = false; 
     DiagonalWinTwo = false; 
    } 

    boolean hasWon = (HorizontalWin || VerticalWin || DiagonalWinOne || DiagonalWinTwo); 

    return hasWon; 

} 

ORIGINAL

有几个人已经回答了这个问题,但这里是我的答案只是它的挫折感。

此外,在您的播放方法中,您有一个while循环来检查以确保用户没有指定超出范围的移动,但之后您再有一个while循环检查以确保该举措是在一个空的空间。您仍然可能需要检查以确保它们的新移动也位于边界内,否则您的循环条件将抛出ArrayOutOfBoundsException。

public boolean isWinner(String player){ 
    // Check for N-in-a-row on the rows and columns 
    for(int i = 0; i < board.length; i++){ 
     boolean verticalWin = true, horizontalWin = true; 
     for(int j = 0; j < board.length; j++){ 
      if(!board[i][j].equals(player))) 
       horizontalWin = false; 
      if(!board[j][i].equals(player)) 
       verticalWin = false; 
      if(!(horizontalWin || verticalWin)) 
       break; 
     } 
     if(horizontalWin || verticalWin) 
      return true; 
    } 

    // If there was a N-in-a-row on the rows or columns 
    // the method would have returned by now, so we're 
    // going to check the diagonals 

    // Check for N-in-a-row on both the diagonals 
    boolean diagonalWinOne = true, diagonalWinTwo = true; 
    for(int n = 0; n < board.length; n++){ 
     diagonalWinOne = true; 
     diagonalWinTwo = true; 
     int row = board.length - 1 - n; 
     if(!board[n][n].equals(player)) 
      diagonalWinOne = false; 
     if(!board[row][n].equals(player)) 
      diagonalWinTwo = false; 
     if(!(diagonalOne || diagonalTwo)) 
      break; 
    } 

    // If either one of the diagonals has N-in-a-row, then there's a winner 
    if(diagonalWinOne || diagonalWinTwo) 
     return true; 
    // Otherwise, no one has won yet 
    else 
     return false; 
} 
0

一种不同的方法(只是为另一种方法的缘故)。将创造一切可能的获胜板组合的查找表,因为只有8

这看起来在第一,但只听到复杂我出去了。你让一个多维数组,其中每个维度持有你的2D网格中的三个坐标

static final class WinCombos { 

    /* 3 combos shown are 
    * 
    * X X X 
    * 
    * X 
    * X 
    *  X 
    * 
    * and 
    * 
    * X 
    * X 
    * X 
    * 
    */ 

    int[][][] positions = { 
     { {0, 0}, {0, 1}, {0, 2} }, 
     { {0, 0}, {1, 1}, {2, 2} }, 
     { {0, 0}, {1, 0}, {2, 0} }, 
     { {....}, {....}, {....} } 
    }; 
} 

别担心,您可以创建程序,如果你想要的阵列。主要我只想说明数组是如何工作的。

然后当玩家走棋是什么,你要做的就是通过赢得连击迭代和检查,看看是否在游戏网格坐标匹配起来:如果你想在板来调整你所需要的

boolean xWon = false; 
boolean oWon = false; 

for (int[][] combo : WinCombos.positions) { 
    xWon = oWon = true; 

    for (int[] coord : combo) { 

     if (!"X".equals(board[coord[0]][coord[1]])) { 
      xWon = false; 
     } 

     if (!"O".equals(board[coord[0]][coord[1]])) { 
      oWon = false; 
     } 
    } 

    // if all three coordinates were either X or O 
    // otherwise xWon/oWon would have been set to false 

    if (oWon || xWon) break; 
} 

if (xWon) { 
    System.out.println("X won!"); 
} else if (oWon) { 
    System.out.println("O won!"); 
} 

现在要做的是每次重新调整板子的尺寸时重新设置获胜坐标。井字游戏将相对简单,因为获胜的组合应始终为board.length。

所以,你需要一些循环:

public final class WinCombos { 

    public int[][][] positions; 

    static { 
     findCombos(3); 
    } 

    public static final void findCombos(int blen) { 

     int combos = blen * 2 + 2; 
     positions = new int[combos][blen][]; 

     for (int i = 0; i < blen; i++) { 
      for (int k = 0; k < blen; k++) { 

       positions[i][k] = new int[] { i, k }; 
       positions[i + blen][k] = new int[] { k, i }; 

      } 
     } 

     // now diagonals 

     for (int i = blen - 2; i < blen; i++) { 
      for (int k = 0; k < blen; k++) { 

       positions[i][k] = new int[] { k, k }; 

      } 
     } 
    } 
} 

而且你去那里。我没有测试过这个。