C++ - 井字游戏的最短获胜检查功能?

C++ - Shortest win-checking function for tic-tac-toe?

这是我在 C++ 控制台井字游戏中的 "getWin" 函数。它在这个简单程序的范围内工作得很好,但出于好奇,什么是 shorter/more 编写一个函数的有效方法 returns 赢家(如果有的话)到一个 tic战术游戏?

注意 - winArg 是 'X' 或 'O',具体取决于您要测试的播放器。 top_left、middle_center等都是枚举类型。最后的 return 声明,return 'n';,适用于还没有获胜者的情况。

char getWin(char winArg)
{
    if (board[top_left] == winArg)
    {
        if (board[top_center] == winArg)
        {
            if (board[top_right] == winArg)
                return winArg;
        }
        if (board[middle_center] == winArg)
        {
            if (board[bottom_right] == winArg)
                return winArg;
        }
        if (board[middle_left] == winArg)
        {
            if (board[bottom_left] == winArg)
                return winArg;
        }
    }
    if (board[top_right] == winArg)
    {
        if (board[middle_center] == winArg)
        {
            if (board[bottom_left] == winArg)
                return winArg;
        }
        if (board[middle_right] == winArg)
        {
            if (board[bottom_right] == winArg)
                return winArg;
        }
    }
    if (board[bottom_right] == winArg)
    {
        if (board[bottom_center] == winArg)
        {
            if (board[bottom_left] == winArg)
                return winArg;
        }
    }
    //middle vertical and horizontal lines
    if (board[top_center] == winArg && board[middle_center] == winArg && board[bottom_center] == winArg)
    {
        return winArg;
    }
    else if (board[middle_right] == winArg && board[middle_center] == winArg && board[middle_left] == winArg)
    {
        return winArg;
    }

    return 'n';
}

在我看来,您可以通过排除行检查的检测来使其更具可读性,例如:

char lineWin(int a, int b, int c) {
    if (board[a] == ' ')      return 'n';
    if (board[a] != board[b]) return 'n';
    if (board[b] != board[c]) return 'n';
    return board[a];
}

然后您可以整理完整的检查代码,例如:

char getWinner(void) {
    char wnr;

    // Horizontal lines.

    if ((wnr = lineWin(top_left,    top_center,    top_right   )) != 'n') return wnr;
    if ((wnr = lineWin(middle_left, middle_center, middle_right)) != 'n') return wnr;
    if ((wnr = lineWin(bottom_left, bottom_center, bottom_right)) != 'n') return wnr;

    // Vertical lines.

    if ((wnr = lineWin(top_left,   middle_left,   bottom_left  )) != 'n') return wnr;
    if ((wnr = lineWin(top_center, middle_center, bottom_center)) != 'n') return wnr;
    if ((wnr = lineWin(top_right,  middle_right,  bottom_right )) != 'n') return wnr;

    // Diagonal lines.

    if ((wnr = lineWin(top_left,  middle_center, bottom_right  )) != 'n') return wnr;
    if ((wnr = lineWin(top_right, middle_center, bottom_left   )) != 'n') return wnr;

    return 'n';
}

请记住,此解决方案适用于 3x3 井字游戏。如果这就是您所做的一切,那么它是理想的,并且比算法解决方案更合适,算法解决方案对于每个单元格,检查八个不同的方向以获得胜利,同时限制检查棋盘的边缘。

如果您要为 Connect-Four/Four-in-a-row 或任何其他具有大量获胜方式的游戏设计内容,那么您的方法必须有所不同。虽然,即便如此,您 仍然 不必过分检查每个单元格的每个方向,您仍然可以使用 a relatively simple algorithm.