【问题标题】:Tic Tac Toe determine winner algorithm井字游戏确定获胜者算法
【发布时间】:2019-05-22 03:18:20
【问题描述】:

我最初打算将其发布在 Codereview SE 上,但由于我真的不知道下面的代码是否可以被认为是完整的,所以我认为它更适合这里。如果您觉得将其发布在其他地方会更好,请随时关闭它。

考虑到一个“有效”的井字游戏规则 3x3 数组作为输入,称为 game,该算法如何寻找获胜者?

我是 C 和一般编程方面的菜鸟,我想知道这段代码的性能/复杂性有多好,因为它与我在 SO 中的其他帖子上发现的有所不同。 for 循环是否使这变得不必要地复杂?

if (game[1][3] == game[2][2] && game[2][2] == game[3][1]) /*antidiagonal check */
    {
        w = game[1][3]; /* w is player X or O */
    }

    t1 = 0;

    for (i=0; i<=2; ++i)
    {
        if (game[i][i] == game[i+1][i+1]) /* main diagonal check */
        {
            t1 += 1;
        }
            if (t1 == 2)
            {
                w = game[i][i];
            }
    }

    for (i=0; i<=2; ++i)
    {
        t2 = 0;
        for (j=0; j<=1; ++j)
        {
            if (game[i][j] == game[i][j+1]) /* row check */
            {
                t2 += 1;
                if (t2 == 2)
                {
                    w = game[i][j];
                }
            }
        }
    }

    for (i=0; i<=1; ++i)
    {
        t3=0;
        for (j=0; j<=2; ++j)
        {
            if (game[i][j] == game[i+1][j]) /* column check */
            {
                t3 += 1;
                if (t3 == 2)
                {
                    w = game[i][j];
                }
            }
        }
    }

    if (t1<2 && t2<2 && t3<3)
    {
        printf("No winner\n");
    }
    else
    {
        printf("%c wins\n", w);
    }

【问题讨论】:

  • 作为经常光顾这里和 CR 的人,我只想指出:正如您所写的那样,它并不适合任何一个站点;虽然这更适合 CR。将其更多地用于要求改进您的代码,显示一个完整的可运行示例,它将适合那里。不过,这可能会被认为过于宽泛且基于意见。
  • 创建一个包含 8 个条目的数组可能会更简单,每个条目由一个包含 3 个 x、y 索引对的数组组成(3 个水平、3 个垂直和 2 个对角线总共 8 个) )。然后,您所需要的只是一个迭代 8 个顶级条目的外循环,以及一个迭代该获胜条件的 3 个条目的内循环。代码很少。
  • 如果电路板尺寸较大或用户可选择,则使用循环会很有意义。但是 3x3 板使 if 语句(如反对角检查)比循环(如主对角检查)简单得多。在检查行和列时,我会妥协:遍历每一行并使用简单的if 来检查行。

标签: c tic-tac-toe


【解决方案1】:

井字游戏有 9 个棋子。

每个图块中要么有一个X,要么没有。这意味着您可以使用 9 位无符号整数来表示每个图块是否有/没有X;然后在(512 条目)查找表中使用此数字来确定X 是否获胜。

以同样的方式;每个图块要么有一个O,要么没有;因此您可以将其编码为不同的 9 位无符号整数,并在同一个(512 项)查找表中使用它来确定 O 获胜。

如果板子处处都表示为一对9位整数(避免了板子状态的转换),那么代码就变成了:

if( table[XboardState] == WIN) {
    printf("X wins\n");
} else if( table[OboardState] == WIN) {
    printf("O wins\n");
} else {
    printf("No winner\n");
}

注意:查找表每个条目只需要一位;因此,通过使用位域(以及一些移位/屏蔽来选择正确的位),它可以小到 64 个字节。当然,您可以编写一个原始/临时实用程序来为您生成表格,然后将表格“剪切并粘贴”到您的游戏代码中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多