对Tic Tac Toe的建议

问题描述 投票:4回答:6

我正在为Tic-Tac-Toe游戏设计我的实施策略。由于这是我的第一个游戏实现,我有点困惑,需要一些通用指针。

现在,Tic-Tac-Toe中的获胜组合总数为8.目前,我计划将这些获胜组合存储在一个阵列中。一旦最终用户进行了至少3次移动,我将通过比较Player对阵此阵列的当前位置来开始检查玩家是否赢得了游戏。但是,我确信这不是检查玩家是否有获胜组合的有效方法。

任何人都可以建议我如何设计游戏的逻辑?

java tic-tac-toe
6个回答
11
投票

不要担心效率。我写了一个回溯解决方案,只有549,945个可能的游戏状态。在笔记本电脑上运行这些操作只需不到0.25秒。这是我的逻辑,看看游戏是否结束 - 显然效率不高,但无所谓:

private boolean isWinningMove(int row, int col) {
    int piece = board[row][col];

    // check current row
    boolean w = true;
    for (int x = 0; x < 3; x++) { w = w && (board[row][x] == piece); }
    if (w) { return true; }

    // check current column
    w = true;
    for (int x = 0; x < 3; x++) { w = w && (board[x][col] == piece); }
    if (w) { return true; }

    // check 0,0 diagonal
    w = true;
    for (int x = 0; x < 3; x++) { w = w && (board[x][x] == piece); }
    if (w) { return true; }

    // check 0,2 diagonal
    w = true;
    for (int x = 0; x < 3; x++) { w = w && (board[x][2 - x] == piece); }
    return w;
}

以下是我的结果,它与维基百科页面上的数据匹配:tic-tac-toe:

Moves Simulated: 549945
Draws=46080   Player1-Wins=131184   Player2-Wins=77904
Perfect Strategy Implies: Always a tie.

Games won in 0 moves? 0
Games won in 1 moves? 0
Games won in 2 moves? 0
Games won in 3 moves? 0
Games won in 4 moves? 0
Games won in 5 moves? 1440
Games won in 6 moves? 5328
Games won in 7 moves? 47952
Games won in 8 moves? 72576
Games won in 9 moves? 81792

5
投票

由于井字游戏的状态空间非常小,你可以存储所有可能的最终游戏位置,并使用旋转,但我认为你会稍微过度思考它。

而不是为游戏板存储3x3阵列,使用7x7阵列,游戏板最内部为3x3。你应该至少有三个值,每个方块可以代表 - 像PLAYER_1PLAYER_2NONE。最初,所有值都应设置为NONE。然后,在每个玩家的移动之后,检查所选择的正方形周围的所有3个;上面2个,下面2个,左边2个,右边2个,左上角2个,右下角2个,右上角2个,左下角2个。

为什么7x7阵列?使用7x7阵列,您可以安全地从3x3区域中的任何方向搜索所有方向,而无需if语句来查看您是否从阵列的边缘走出。董事会将如下所示:

  0 1 2 3 4 5 6
0 * * * * * * *

1 * * * * * * *

2 * * * * * * *

3 * * * * * * *

4 * * * * * * *

5 * * * * * * *

6 * * * * * * *

例如,如果第一个玩家移动到tic-tac-toe板上的0,0,则与在7x7板上移动到2,2相同。进行移动时,您将在2,2平方左右进行检查以查看一行中是否有三个具有相同值的正方形

  • 上述:2,0和2,1和2,2
  • 下图:2,2和2,3和2,4
  • 左:0,2和1,2和2,2
  • 右:2,2,2,3和2,4
  • 左上:0,0和1,1和2,2
  • 右上:2,2和3,1和4,0
  • 左下:0,4和1,3和2,2
  • 右下:2,2和3,3和4,4

由于3x3板周围的方块带总是具有值NONE,因此它们永远不会触发获胜条件。

如果其中任何一个都匹配相同的玩家价值(例如第一个玩家的PLAYER_1),则游戏结束并获胜。否则,如果所有方格都被拍摄,那么游戏就是平局。

我过去曾将它用于其他类似游戏,效果很好。


3
投票

考虑用整数表示板。

-1 = X
 0 = empty
 1 = O

现在,将8种可能性中的每一种加上正方形的值(3个上下,3个左右,2个区域)。

如果总和为3,如果总和为-3,则O获胜,X获胜

如果总和是2,那么如果总和i -2,那么O在其中一个位置有一个获胜的移动,那么X在这些位置之一中有一个获胜的移动。

AI可以将其作为决策的基础。向前看一步就足以永远不会失败。

如果AI开始游戏,那么最好的动作就是一个角落。如果对手未能占据中锋,则AI获胜。如果他确实占据了中心,那么AI赢了,或者抽签。


3
投票

而不是迭代的东西,我只写了8个组合。

我的评估函数执行以下操作:如果A是移动的一侧,如果在所有组合之一中有两个A元素和一个0(空),那么它就是赢:

boolean player_can_win(int value) { //value is side's element*2
    return board[0] + board[1] + board[2] == value
            || board[3] + board[4] + board[5] == value
            || board[6] + board[7] + board[8] == value
            || board[0] + board[3] + board[6] == value
            || board[1] + board[4] + board[7] == value
            || board[2] + board[5] + board[8] == value
            || board[0] + board[4] + board[8] == value
            || board[2] + board[4] + board[6] == value;
}

2
投票

如果你正在播放广义的N X N tic-tac-toe,那么明确地存储和比较解决方案并不是最有效的,但是因为它就像小板,只有8个这样的组合,所以显式存储这样的解决方案没有任何问题。

更大的问题是,根据存储风格,与解决方案无关的空间可能是个问题。

O - -        - O -
X X X   vs.  X X X
O - O        O - O

比较3x3状态数组这些是不同的,因此这种方法需要超过8个结束状态

我认为你保留像gameState 3x3数组的东西,空白= 0,X = 1,O = 2?

除了那些明确的比较,你可以做类似的事情

win = false   
// rows/columns
for i in 0,1,2
   if (state[i][0] != BLANK && state[i][0] == state[i][1] == state[i][2]) win = true
          #extensible to NxN - all(j == state[i][0] for j in state[i])
   if (state[0][i] != BLANK && state[0][i] == state[1][i] == state[2][i]) win = true
          #extensible to NxN - all(j == state[0][i] for j in zip(*state)[i])
//diagonals
if (state[0][0] != BLANK && state[0][0] == state[1][1] == state[2][2]) win = true
          #extensible to NxN - all(state[j][j] == state[0][0] for j in range(len(state))
if (state [2][0] != BLANK && state[2][0] == state[1][1] == state[0][2]) win = true

如果你想赢得存储而不是标记,那么将win = BLANK置于顶部,并设置为任何相关正方形的值。不应该是必要的,胜利者显然是最近的举动!

我认为,你可能会发现最具挑战性,但不是太难的井井有条的部分。编写一个不会丢失的AI(总是至少可以强制打平)并不是很困难,但并非完全无足轻重。如果你想要一个能够偶尔丢失的相对优秀的AI,你需要添加一些随机性或其他东西。


0
投票

实现Tic Tac Toe游戏可能是人工智能和搜索空间最难解决的问题。

关键是用MinimaxIterative deepening Depth-first searchAlpha-beta pruning算法解决问题。

这是我在Python中的游戏implementation,它只有大约200行代码,并且有能力像Human vs. HumanHuman vs. ComputerComputer vs. Computer一样玩游戏。它还可以保持达到/修剪的深度和节点数量的统计数据,从而实现最佳移动。

我强烈推荐edX.org人工智能course,它提供了当前AI主题和解决方案的基础知识。

© www.soinside.com 2019 - 2024. All rights reserved.