检查谁赢得了Tic Tac Toe更高效的C ++

时间:2011-03-08 09:32:52

标签: c++ if-statement

我正在写一个Tic Tac Toe游戏,我想知道如何能够有效地检查谁赢了。包含X,O或空格的二维数组代表电路板。

  char CheckWin(const char board[][NUM_COLS], int& sum) // tic tac toe board - IN
{
    char tmp;
    int lcv;
    tmp = ' ';

    if (sum == 9)
    {
        return 'T';
    }
    else if (sum != 9)
    {
        if (((tmp = board[1][1]) != ' ' && board[0][0] == tmp && board[2][2] == tmp) || (board[2][0] == tmp && board[0][2] == tmp))
        {
            return tmp;
        }

        for (lcv = 0; lcv < 3; lcv++)
        {
            if ((tmp = board[lcv][0]) != ' ' && board[lcv][1] == tmp && board[lcv][2] == tmp)
            {
                return tmp;
            }
            else if ((tmp = board[lcv][0]) != ' ' && board[lcv][1] == tmp && board[lcv][2] == tmp)
            {
                return tmp;
            }
        }
    }

    return 'N';
}

除了一遍又一遍地做类似的事情之外,我怎么能检查谁赢了并且如果X赢了则返回X,如果O有一个则是O,如果是平局则是T,如果没有则是N然而。提前致谢。我一直在努力熟悉C ++和编程。

编辑:我刚用简单的方法,但是我搞砸了,有人知道怎么办?看起来它没有返回任何东西,因为当我在玩家选择一行和一列(这工作正常)后在主要部分调用它时,它不输出任何东西

3 个答案:

答案 0 :(得分:13)

您可以将数组转换为两个九位值,一个用于O位置,一个用于X位置,以及一个空格数:

x_mask = 0
y_mask = 0
empty_count = 0
mask = 1
for each square
  if x then x_mask |= mask
  if y then y_mask |= mask
  if empty then empty_count++
  mask <<= 1

然后将x_mask和y_mask与八种可能的获胜组合进行比较:

for each player
  for each winning combination
    if player_mask & winning_mask == winning_mask then player has won

然后处理双方都没赢过的案件:

if neither player won
  if empty_count == 0
    its a tie
  else
    moves still available

答案 1 :(得分:2)

一种简单的“结构化”方法

如果您将董事会视为:

A  B  C
D  E  F
G  H  I

然后,任何获胜布局必须触及的最小选择框将是:

A B C
D
G

您可以在X和Y方向的每个位置移动0,1或-1位置,从获胜线中的任何位置设想运动。我们可以列出您需要检查的动作:

A: (++x) (++x, ++y) (++y)
B: (++y)
C: (++y) (--x, ++y)
D: (++x)
E: (++x)

在C ++中,您可以创建起始点的x / y坐标和上面显示的+ / - / 0 x / y移动增量的列表/向量,然后使用三个嵌套循环来评估整个板上的每条线

这比仅仅在x和y坐标以及两个对角线(下方)上对两个循环进行硬编码要多得多,但它是一种更具算法性的方法,可能在理智上具有吸引力:更像是在处理时可能需要做的事情一个更大的董事会。


明显的蛮力方法

为了记录,这个更简单的方法看起来像这样:

int x;
for (row = 0; row < 3; ++row)
    if ((x = board[row][0]) != Empty &&
        board[row][1] == x && board[row][2] == x)
        return x;
// similar loop for columns...
...
// hardcode diagonals...
if ((x = board[1][1]) != Empty &&
    (board[0][0] == x && board[2][2] == x ||
     board[2][0] == x && board[0][2] == x))
    return x

答案 2 :(得分:2)

我认为您可以为每个获胜板可能分配一个数字(基本上是一个哈希值),然后通过生成其哈希值来检查当前板是否与表中的任何值匹配。另一方面,我不建议花太多时间试图使CheckWin功能超级高效。除非它被称为数百万次或者某种东西并且需要非常快,否则将时间花在其他事情上 - 它可能不会成为瓶颈。