如何避免用户输入重复的单元格



如何防止用户输入相同的tic tac toe坐标?

用户输入在Game类的main方法中获取。

坐标为[x, y]的单元格可以是(0-2):

0(_), 1 (X)或2 (O)

带有alpha - beta搜索树修剪算法的网格类

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Grid {
  List<Cell> availableCells;
  int[][] board = new int[3][3];
  Scanner scan = new Scanner(System.in);
  // Set limit to search tree depth
  int treeDepth = 9;
  List<CellsAndScores> rootsChildrenScore = new ArrayList<>();
  public int score() {
    int score = 0;
    // Check all columns
    for (int j = 0; j < 3; ++j) {
      int X = 0;
      int O = 0;
      for (int i = 0; i < 3; ++i) {
        if (board[i][j] == 0) {
        } else if (board[i][j] == 1) {
          X++;
        } else {
          O++;
        }
      }
      score += changeInScore(X, O);
    }
    // Check all rows
    for (int i = 0; i < 3; ++i) {
      int X = 0;
      int O = 0;
      for (int j = 0; j < 3; ++j) {
        if (board[i][j] == 0) {
        } else if (board[i][j] == 1) {
          X++;
        } else {
          O++;
        }
      }
      score += changeInScore(X, O);
    }
    int X = 0;
    int O = 0;
    // Check diagonal (first)
    for (int i = 0, j = 0; i < 3; ++i, ++j) {
      if (board[i][j] == 1) {
        X++;
      } else if (board[i][j] == 2) {
        O++;
      } else {
      }
    }
    score += changeInScore(X, O);
    X = 0;
    O = 0;
    // Check Diagonal (Second)
    for (int i = 2, j = 0; i > -1; --i, ++j) {
      if (board[i][j] == 1) {
        X++;
      } else if (board[i][j] == 2) {
        O++;
      } else {
      }
    }
    score += changeInScore(X, O);
    return score;
  }
  private int changeInScore(int X, int O) {
    int change;
    if (X == 3) {
      change = 100;
    } else if (X == 2 && O == 0) {
      change = 10;
    } else if (X == 1 && O == 0) {
      change = 1;
    } else if (O == 3) {
      change = -100;
    } else if (O == 2 && X == 0) {
      change = -10;
    } else if (O == 1 && X == 0) {
      change = -1;
    } else {
      change = 0;
    }
    return change;
  }
  public int alphaBetaMinimax(int alpha, int beta, int depth, int turn) {
    if (beta <= alpha) {
      System.out.println("Pruning at tree depth = " + depth + " alpha: " + alpha + " beta: " + beta);
      if (turn == 1)
        return Integer.MAX_VALUE;
      else
        return Integer.MIN_VALUE;
    }
    if (depth == treeDepth || gameOver()) {
      return score();
    }
    List<Cell> cellsAvailable = getAvailableStates();
    if (cellsAvailable.isEmpty()) {
      return 0;
    }
    if (depth == 0) {
      rootsChildrenScore.clear();
    }
    int maxValue = Integer.MIN_VALUE, minValue = Integer.MAX_VALUE;
    for (int i = 0; i < cellsAvailable.size(); ++i) {
      Cell cell = cellsAvailable.get(i);
      int currentScore = 0;
      if (turn == 1) {
        placeAMove(cell, 1);
        currentScore = alphaBetaMinimax(alpha, beta, depth + 1, 2);
        maxValue = Math.max(maxValue, currentScore);
        // Set alpha
        alpha = Math.max(currentScore, alpha);
        if (depth == 0) {
          rootsChildrenScore.add(new CellsAndScores(currentScore, cell));
        }
      } else if (turn == 2) {
        placeAMove(cell, 2);
        currentScore = alphaBetaMinimax(alpha, beta, depth + 1, 1);
        minValue = Math.min(minValue, currentScore);
        // Set beta
        beta = Math.min(currentScore, beta);
      }
      // reset board
      board[cell.x][cell.y] = 0;
      // Do not evaluate the rest of the branches after search tree is pruned
      if (currentScore == Integer.MAX_VALUE || currentScore == Integer.MIN_VALUE)
        break;
    }
    return turn == 1 ? maxValue : minValue;
  }
  public boolean gameOver() {
    // Game is over is someone has won, or board is full (draw)
    return (hasXWon() || hasOWon() || getAvailableStates().isEmpty());
  }
  public boolean hasXWon() {
    if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == 1)
        || (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == 1)) {
      // System.out.println("X Diagonal Win");
      return true;
    }
    for (int i = 0; i < 3; ++i) {
      if (((board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == 1)
          || (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] == 1))) {
        // System.out.println("X Row or Column win");
        return true;
      }
    }
    return false;
  }
  public boolean hasOWon() {
    if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == 2)
        || (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == 2)) {
      // System.out.println("O Diagonal Win");
      return true;
    }
    for (int i = 0; i < 3; ++i) {
      if ((board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == 2)
          || (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] == 2)) {
        // System.out.println("O Row or Column win");
        return true;
      }
    }
    return false;
  }
  public List<Cell> getAvailableStates() {
    availableCells = new ArrayList<>();
    for (int i = 0; i < 3; ++i) {
      for (int j = 0; j < 3; ++j) {
        if (board[i][j] == 0) {
          availableCells.add(new Cell(i, j));
        }
      }
    }
    return availableCells;
  }
  public void placeAMove(Cell Cell, int player) {
    board[Cell.x][Cell.y] = player; // player = 1 for X, 2 for O
  }
  public Cell returnBestMove() {
    int MAX = -100000;
    int best = -1;
    for (int i = 0; i < rootsChildrenScore.size(); ++i) {
      if (MAX < rootsChildrenScore.get(i).score) {
        MAX = rootsChildrenScore.get(i).score;
        best = i;
      }
    }
    return rootsChildrenScore.get(best).cell;
  }
  public void displayBoard() {
    System.out.println();
    for (int i = 0; i < 3; ++i) {
      for (int j = 0; j < 3; ++j) {
        if (board[i][j] == 0)
          System.out.print("_" + " ");
        if (board[i][j] == 1)
          System.out.print("X" + " ");
        if (board[i][j] == 2)
          System.out.print("O" + " ");
      }
      System.out.println("");
    }
    System.out.println();
  }
  public void resetGrid() {
    for (int i = 0; i < 3; ++i) {
      for (int j = 0; j < 3; ++j) {
        board[i][j] = 0;
      }
    }
  }
}

细胞类

class Cell {
  int x, y;
  public Cell(int x, int y) {
    this.x = x;
    this.y = y;
  }
  public String toString() {
    return "[" + x + ", " + y + "]";
  }
}
class CellsAndScores {
  int score;
  Cell cell;
  CellsAndScores(int score, Cell cell) {
    this.score = score;
    this.cell = cell;
  }
}

带有main方法的游戏类-接受用户输入

import java.util.Random;
public class Game {
  public static void main(String[] args) {
    Grid grid = new Grid();
    Random random = new Random();
    grid.displayBoard();
    System.out.print("Who moves first? [1]Computer(X) [2]User(O): ");
    int turn = grid.scan.nextInt();
    if (turn == 1) {
      Cell p = new Cell(random.nextInt(3), random.nextInt(3));
      grid.placeAMove(p, 1);
      grid.displayBoard();
    }
    while (!grid.gameOver()) {
      int x = 0, y = 0;
      System.out.print("Please enter an x coordinate [0-2]: ");
      x = grid.scan.nextInt();
      System.out.print("Please enter an y coordinate [0-2]: ");
      y = grid.scan.nextInt();
      Cell userMove = new Cell(y, x);
      grid.placeAMove(userMove, 2); // 2 for O and O is the user
      grid.displayBoard();
      if (grid.gameOver())
        break;
      grid.alphaBetaMinimax(Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 1);
      for (CellsAndScores pas : grid.rootsChildrenScore)
        System.out.println("Cell: " + pas.cell + " Score: " + pas.score);
      grid.placeAMove(grid.returnBestMove(), 1);
      grid.displayBoard();
    }
    if (grid.hasXWon()) {
      System.out.println("Unfortunately, you lost!");
      grid.resetGrid();
    } else if (grid.hasOWon()) {
      System.out.println("You win!");
      grid.resetGrid();
    } else {
      System.out.println("It's a draw!");
      grid.resetGrid();
    }
  }
}

我的答案是在Grid.java类中添加一个布尔检查方法,然后在主方法中调用这个布尔检查方法,然后在placemove()方法之前调用这个布尔检查方法。

例如,在Grid.java类中,添加以下方法:
/*
 * Return true if space is ok to use.
 */
public boolean isMoveOK(Cell cell) {
    return board[cell.x][cell.y] == 0;
}

这样,使用您已经存在的0/1/2值来跟踪空/X/O空间值,您可以提供检查,看看空间值是否为零。

这将是在你的主方法中使用它的一种方式,来回答你的问题,"我如何防止用户输入相同的井字坐标?"'

Cell userMove = new Cell(y, x);
if (grid.isMoveOK(userMove)) {
    grid.placeAMove(userMove, 2); // 2 for O and O is the user
} else {
    System.out.println("Please try a different space/cell");
    continue;
}
grid.displayBoard();
if (grid.gameOver())
    break;
通过这种方式,我跳过主方法循环中剩余的循环代码,直到有一个有效的开放空间。(如果存在,则程序应继续检查获胜值或是否继续播放)

希望这能回答你的问题!:)

欢呼

相关内容

  • 没有找到相关文章

最新更新