是否可以使用jGraphT检查TicTacToe游戏的获胜条件?

2022-09-03 03:01:15

我找到了这个工作解决方案:

private int[] winningPatterns = { 0b111000000, 0b000111000, 0b000000111, // rows
        0b100100100, 0b010010010, 0b001001001, // cols
        0b100010001, 0b001010100 // diagonals
};

/** Returns true if thePlayer wins */
private boolean hasWon(int thePlayer) {
    int pattern = 0b000000000; // 9-bit pattern for the 9 cells
    for (int row = 0; row < 3; ++row) {
        for (int col = 0; col < 3; ++col) {
            if (cells[row][col].content == thePlayer) {
                pattern |= (1 << (row * 3 + col));
            }
        }
    }
    for (int winningPattern : winningPatterns) {
        if ((pattern & winningPattern) == winningPattern)
            return true;
    }
    return false;
}

但我想知道是否有使用图逻辑的更优雅的解决方案。

更新:我也在考虑将我的知识用于3x3板的不同和更大的变体,我相信这种方法在美学上不能很好地扩展。

例如:https://en.wikipedia.org/wiki/Teeko


答案 1

对于25×25的董事会,我认为你拥有的方法可行,但一些改进的方法如下。

  1. 在用户添加棋子时创建模式,因为这样只需花费时间即可完成获胜的Patterns数组。

  2. 为了改进第二部分,您可以尝试更有效地存储它。以一种可以同时检查多个模式的方式存储获胜的模式。例如,如果第一个位置是0,那么它可以从获胜的模式中删除3种可能性,而不仅仅是一种(111 000 000,100 100 100,100 010 001)。

  3. 您可以通过检查最有可能正确的位置来改善平均情况。例如,玩家可以通过4种方式将棋子放在中间来获胜,因此请检查该顺序。

  4. 如果将玩家位置存储在单独的数组中,其中 p1Tiles 和 p2Tiles。然后,这可能会大大增加平均情况,因为大多数时候董事会将相当空旷。在重置棋盘之前,它只会有1个游戏实例的满。

  5. 您实际上不需要检查玩家赢得的所有棋子,您只需要检查当前用户放置的棋子是否获胜即可。因此,使用此方法,您只需要检查最坏情况 12 其他点 ,即使电路板的大小为99..999 x 99..999。(12 因为当前插槽周围的所有插槽加上如果有两个相同颜色的插槽彼此相邻,那么您将不得不查看以下插槽)


答案 2

推荐