【问题标题】:Test for possible wins in tictactoe game测试tictactoe游戏中可能的胜利
【发布时间】:2016-03-08 17:00:26
【问题描述】:

我正在创建一个tictactoe游戏,每一步我都需要测试一个玩家是否赢了,这给我带来了很多麻烦。我有一个包含所有可能获胜组合的二维向量:

vector<vector<int>> possibleWins {{1,2,3},{4,5,6},{7,8,9},{1,4,7},{2,5,8},{3,6,9},{1,5,9},{3,5,7}};

每一步我都会遍历 2d 向量,并将 player1 和 player2 向量附加到它们标记的任何单元格:

vector<int> totalX {};
vector<int> totalO {};
int count = 1;
for(int i=0; i<3; i++) {
    for(int j=0; j<3; j++) {
        if(board[i][j] == 'x') {
            if(totalX.size() == 0) {
                totalX.push_back(count);
            }
            for(int k=0; k<totalX.size(); k++) {
                if(count == totalX[k]) {
                    break;
                }
                else {
                    totalX.push_back(count);
                }
            }
        }
        else if(board[i][j] == 'o') {
            if(totalO.size() == 0) {
                totalO.push_back(count);
            }
            for(int k=0; k<totalO.size(); k++) {
                if(count == totalO[k]) {
                    break;
                }
                else {
                    totalO.push_back(count);
                }
            }
        }
        count++;
    }
}

然后我尝试测试每个玩家单元向量中的单元是否是单元的获胜组合,这对我来说很困难:

int xInRow = 0;
for(int x=0; x<totalX.size(); x++) {
    for(int y=0; y<possibleWins.size(); y++) {
        xInRow = 0;
        for(int z=0; z<3; z++) {
            if(totalX[x] == possibleWins[y][z]) {
                xInRow++;
                if(xInRow == 3) {
                    return X_WON;
                }
            }
        }
    }
}

这行不通,我已经尝试以多种不同的方式实现它,但老实说,我不知道如何枚举所有可能的胜利并测试玩家是否拥有这些组合之一。

有没有办法可以更好地构建它以使其工作?我很迷茫。

【问题讨论】:

  • std::vector&lt;std::vector&lt;int&gt;&gt; 用于tictactoe 板是矫枉过正并且带有巨大 的缺点。您应该定义一个TicTacToeBoard 类,其中有九个值代表游戏的九个方格(NW、N、NE、W、C、E、SW、S、SE)的状态(空、x 或 o)。跨度>
  • 顺便说一句,如果您将您的棋盘表示为 3x3 {-1,0,1} 矩阵 A,[ 1 1 1 ]*AA*[1 1 1]^T 会告诉您是否有赢家以及谁赢了:如果乘法结果的复合是3,1胜,如果是-3,1-胜。

标签: c++ tic-tac-toe


【解决方案1】:

有两种方法。你的代码对于一个简单的操作来说有点太复杂了,所以我不会尝试理解它。

我同意 YSC 的观点,即您不需要 std::vector。您知道每次都是 3x3 网格,因此 3x3 枚举数组应该会好得多。类似的东西

enum TTTState {
    EMPTY=0,
    X,
    O
}

TTState board[3][3];

会让您省去很多麻烦。你可以说board[0][0]是左上角,board[2][2]是右下角。

选项 1

我喜欢你对 possibleWins 的想法,所以使用新的 board[3][3] 数据结构,你可以用 int solutions[8][3][2] 存储一对数字,但这已经有点乱了。

for each solution in solutions
    for each triplet in solution
        for each pair in triplet
            if board[pair[0]][pair[1]] matches all other pair in triplet
                then whoever has pieces in the row has won

选项 2

这可能更干净。有 3 种可能的获胜方式。水平、垂直和对角线。您可以分别检查这三种方式。

for i = 0 ; i != 3; i++
    type = board[i][0]
    won = true
    for ii = 1; ii != 3; ii++
        if board[i][ii] is not type
            won = false
    if won then you can return the function with who won

for i = 0 ; i != 3; i++
    type = board[0][i]
    won = true
    for ii = 1; ii != 3; ii++
        if board[ii][i] is not type
            won = false
    if won then you can return the function with who won

对角线可以硬编码,因为只有两个可能的胜利位置..

【讨论】:

    【解决方案2】:

    你让事情有点复杂了。
    您无需先收集玩家使用过的位置,然后查看其中有多少处于获胜位置。
    由于您已经知道获胜位置,您只需要检查是否有任何玩家占据了所有位置。

    假设' ' 标记了一个空方格,

    for(const auto& win: possibleWins)
    {
        if (board[win[0]] == board[win[1]] 
         && board[win[1]] == board[win[2]]
         && board[win[0]] != ' ')
        {
            // if board[win[0]] == 'X' , then X won
            // if board[win[0]] == 'O' , then O won
        }
    }
    

    应该这样做。

    【讨论】:

      【解决方案3】:
         |   |
      ---+---+---
         |   |   
      ---+---+---
         |   |   
      

      是一个 int myArray[9];然后你把玩家移动到它上面myArray[played_position] = playerValue;,然后你可以使用你的vector&lt;vector&lt;int&gt;&gt; possibleWins {{1,2,3},{4,5,6},{7,8,9},{1,4,7},{2,5,8},{3,6,9},{1,5,9},{3,5,7}};在3移动之后检查位置是否对应相同的值(玩家!)......

      for(int idx=0; idx<possibleWins.size(); idx++)
      {
         if(myArray[possibleWins[idx][0]] == myArray[possibleWins[idx][1]] == myArray[possibleWins[idx][2]])
            {
                return myArray[possibleWins[idx][0];
            }
       }
      

      只是一个想法,希望对你有所帮助....

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-27
        • 1970-01-01
        相关资源
        最近更新 更多