2

我正在完成我的任务,即创建一个井字棋检查器,但由于某种原因,我想不出一种方法来完成创建游戏的第一步。我们从一个包含代表一个游戏的行的文本文件中读取;例如:

x,x,o, , ,x, ,o,o

在传统板上看起来像这样:

x|x|o
-----
 | |x
-----
 |o|o

这是我到目前为止所拥有的:

class TicTacToe{
    static String[][] game;

    public TicTacToe(int size){
        this.game = new String[size][size];
    }

    public static TicTacToe create(String input){
        String tokens = input.split(",");
        int size = (int)Math.sqrt(tokens.length); //For setting a size
                                                  // of the board

        return null;
    }
}

我不明白的是如何返回一个新的井字游戏对象:当我编写检查行、列等的方法时,我将如何让棋盘进行检查?我会以正确的方式解决这个问题吗?

4

3 回答 3

2

[W]当我编写检查行、列等的方法时,我将如何让董事会检查?

您的对象的实例应该包含有关板的所有信息。您已经(大部分)完成了 -game是包含有关董事会信息的字段。唯一的问题是每个板将包含相同的板信息,如果它被更新,它将包含更新的信息。

如果您想像对待工厂一样对待它,那么您需要做四件事:

  • 从 中删除static修饰符game。这是不必要的,并且会导致跨多个对象的状态不一致。
  • 将您的构造函数设为私有 - 除非我遗漏了什么,否则没有理由在工厂之外对其进行初始化。

     private TicTacToe(int size) {
         game = new String[size][size];
     }
    

    或者,更好的是:

     private TicTacToe(String[][] hydratedBoard) {
          game = hydratedBoard;
     }
    

    我稍后会告诉你为什么。

  • 实施TicTacToe.create(String),并返回完全水合的对象。一个建议是String[][]隐式创建,使用作为参数传入构造函数的对象创建对象,然后返回您的TicTacToe对象。

    public static TicTacToe create(String input) {
        String[][] board = new String[3][3];
        int i = 0; // count the row we're on
        String[] tokens = input.split(",");
        for(int j = 0; j < board.length; j++) {
            if (j % 3 == 0) { // advanced to the end of the column set (SO)
                i++;
            }
            board[i][j] =  tokens[i*3 + j];
        }
        return new TicTacToe(board);
     }
    
  • 为板对象提供某种吸气剂。您可能不必根据作业执行此操作,但这是一种很好的做法。它可以是 的直接吸气剂,也可以是String[][]某种漂亮的打印表示;我不知道。我将把这个实现留给读者。
于 2013-04-03T00:37:15.123 回答
1

你想多了。不要使用“return null;”,而是使用“return new TicTacToe(size);”。

虽然,通常当我创建一个静态工厂方法(如您的“创建”方法)时,我将构造函数设为私有,因此只能从静态创建方法调用它。

...然后,如果您想真正记住您传入的 x/o 位置,则需要更新板子...

于 2013-04-03T00:22:05.123 回答
0

在这里,我为这个游戏添加了一个集成测试,它可能会给你一些关于如何创建/思考游戏的想法。

    public void testWinnerPlayerIWithVerticalLine() {

    this.displayUnitTestDescription("Integration Test for having player 'X' as winner on a vertical line use case");
    final IBoardGame<TicTacToeMove, TicTacToePlayer> ticTacTocGame = new TicTacToeGame();
    final String playerIDisplayName = "X";
    final String playerIIDisplayName = "O";
    final TicTacToePlayer playerI = new TicTacToePlayer(playerIDisplayName);
    final TicTacToePlayer playerII = new TicTacToePlayer(playerIIDisplayName);
    ticTacTocGame.setGamePlayers(new TicTacToePlayer[]{playerI, playerII});
    TicTacToePlayer[][] expectedBoardInteractionSnapshot = new TicTacToePlayer[][]{
        new TicTacToePlayer[]{playerI,      null,       playerII},
        new TicTacToePlayer[]{playerI,      playerII,   null},
        new TicTacToePlayer[]{playerI,      playerII,   playerI}            
    };

    ticTacTocGame.start();
    ticTacTocGame.makeMove(new TicTacToeMove(0, 0));
    ticTacTocGame.makeMove(new TicTacToeMove(1, 1));
    ticTacTocGame.makeMove(new TicTacToeMove(2, 2));
    ticTacTocGame.makeMove(new TicTacToeMove(0, 2));
    ticTacTocGame.makeMove(new TicTacToeMove(2, 0));
    ticTacTocGame.makeMove(new TicTacToeMove(2, 1));
    ticTacTocGame.makeMove(new TicTacToeMove(1, 0));

    this.displayBoardPlayerInteractionSnapshot(ticTacTocGame);
    final TicTacToePlayer[][] actualBoardInteractionSnapshot = ticTacTocGame.getPlayerInteractionSnapshotBoard();

    Assert.assertFalse(ticTacTocGame.isGameDraw());
    Assert.assertTrue(ticTacTocGame.existWinner());
    Assert.assertEquals(ticTacTocGame.getWinner().getDisplayName(), playerIDisplayName);
    Assert.assertArrayEquals(actualBoardInteractionSnapshot, expectedBoardInteractionSnapshot);     
}

如果您有兴趣了解更多信息,可以找到井字游戏的整个 java 实现: https ://github.com/ncaralicea/tictactoe

于 2015-09-03T16:17:57.360 回答