简体   繁体   English

C ++ Connect 4检查下一步错误

[英]C++ Connect 4 Checking Next Step Error

I am writing a Connect 4 game with minimax, but my next-step checking function is sometimes giving me unexpected results. 我正在用minimax编写Connect 4游戏,但是我的下一步检查功能有时会给我带来意想不到的结果。 Can you please tell me if my algorithm is correct? 您能告诉我我的算法是否正确吗?

For example if my board looks like this 例如,如果我的董事会看起来像这样

0000000 
0000000
0000000
0000000
1000000
2002120

it will return column 0 as true for player 2. 对于玩家2,它将返回第0列为true。

bool Board::check2(int player, int& bestMove)
{
    for (int i=0; i<WIDTH; i++)
    {
        if(addToColumn(i, player))
        {



            if (checkNext(2, i, player))
            {
                bestMove=i;
                removeFromColumn(i, player);
                return true;
            }
            removeFromColumn(i, player);
        }

    }
    return false;
}


    bool Board::checkNextVertical(int size, int column, int player1)
    {
        int counter=0;
        int player2;

        if (player1==1)
        {
            player2=2;
        }
        else
            player2=1;

        for (int i=0 ; i<DEPTH; i++)
        {
            if (arrBoard[column][i]==player1)
            {
                counter++;
            }

            if (arrBoard[column][i]==player2)
            {
                return false;
            }
            if (counter==size)
            {
                return true;
            }



        }
        return false;
    }

    bool Board::checkNextHorizontal(int size, int column, int player1)
    {
        int counter=0;
        int player2;

        if (player1==1)
        {
            player2=2;
        }
        else
            player2=1;

        for (int i=0 ; i<DEPTH; i++)
        {
            if (arrBoard[i][column]==player1)
            {

                for (int j = 0; j<WIDTH; j++)
                {
                    if (arrBoard[i][j]==player1)
                    {
                        counter++;
                    }

                    if (arrBoard[i][j]!=player1)
                    {
                        counter=0;
                    }
                    if (counter==size)
                    {
                        return true;
                    }


                }
            }
    }
        return false;

    }

    bool Board::checkNext(int size, int column, int player)
    {
        if (checkNextVertical(size, column, player))
        {
            //  printBoard();
            return true;
        }


        if (checkNextHorizontal(size, column, player))
        {
          //  printBoard();
            return true;
        }



        return false;
    }

Welcome to the forum. 欢迎来到论坛。

There are a few problems with the code you posted: 您发布的代码存在一些问题:

Your checkNextVertical function appears to be attempting to check horizontally, and your checkNextHorizontal function appears to attempting to check both horizontally and vertically. 您的checkNextVertical函数似乎试图进行水平检查,而您的checkNextHorizontal函数似乎试图进行水平和垂直检查。

If you notice you use both arrBoard[column][i] and arrBoard[i][column] . 如果您注意到您同时使用了arrBoard[column][i]arrBoard[i][column] I'm sure you'll agree only one of these can be correct. 我相信您会同意其中只有一种是正确的。 It's important to understand which is correct, or else your code will end up attempting to access locations in the array which are not valid, and you will get unexpected behaviour, for example your j loop in the checkNextHorizontal function is currently doing this. 重要的是要了解哪个是正确的,否则您的代码将最终试图访问数组中无效的位置,并且您将得到意外的行为,例如, checkNextHorizontal函数中的j循环当前正在执行此操作。

It should be used as array[y / depth / row][x / width / column] - or whatever you will remember. 它应该用作array[y / depth / row][x / width / column] -或您会记住的任何东西。

Personally, this code seems confusing: 就个人而言,此代码似乎令人困惑:

    int player2;

    if (player1==1)
    {
        player2=2;
    }
    else
        player2=1;

player2=1 seems like trying to push a square peg in a round hole. player2=1似乎试图在圆孔中推一个方形钉。 Could you use int player and set it to either 1 or 2 to make it easier to read? 您可以使用int player并将其设置为12以便于阅读吗?

I totally agree with Joachim - if you have these sorts of problems, it's always a great idea to fill the array with some data, then use the debugger to step through your code and check that the data being accessed is the data you expect to be accessed. 我完全同意Joachim的观点-如果您遇到此类问题,将一些数据填充到数组中总是一个好主意,然后使用调试器单步执行代码并检查所访问的数据是否是您期望的数据访问。

Alternatively, since it's a connect4 game, I assume at some point you know the column which the last move was made, in which case you can use this function to check if it was a winning move. 或者,由于它是一个connect4游戏,所以我认为在某个时候您知道最后一步的出局,在这种情况下,您可以使用此功能来检查这是否是获胜的一步。 You just need to tell it which column the last move was, and the required 'size' to win. 您只需要告诉它最后一步是哪一列,以及获胜所需的“大小”即可。 If you do use it, I would still recommend stepping through it with the debugger so you can understand the array access. 如果您确实使用它,我仍然建议您通过调试器逐步完成它,以便您了解阵列访问。 NB: your code wasn't checking diagonally - so neither does this. 注意:您的代码不是按对角线检查的-所以也没有。 Some extra logic required if you want to do that: 如果要这样做,则需要一些额外的逻辑:

bool winningMove(int column, int size)
{
  bool winnerWinnerChickenDinner = false;

  int player = 0;
  int row    = 0;

  // Who was the last player to go in this column
  // i.e. find the top non-zero entry
  for (int i = 0; i < DEPTH; i++)
  {
    if (arrBoard[i][column] != 0)
    {
      player = arrBoard[i][column];
      row = i;
      break;
    }
  }

  // If we found a player, check if it was a winning move
  if (player != 0)
  {
    int count = 0;

    // Loop twice, first horizontally, then vertically
    for (int i = 0; i < 2 && !winnerWinnerChickenDinner; i++)
    {
      bool horizontal = (i == 0);

      for (int j = 0; j < (horizontal ? WIDTH : DEPTH); j++)
      {
        // Check if we have 'size' consecutive entries by the same player
        // (When we check horizontally, use arrBoard[row][j]    to check the row)
        // (When we check vertically,   use arrBoard[j][column] to check the column)
        if (arrBoard[(horizontal ? row : j)][(horizontal ? j : column)] == player)
        {
          if (++count == size)
          {
            winnerWinnerChickenDinner = true;
            break;
          }
        }
        else
        {
          count = 0;
        }
      }
    }
  }

  return winnerWinnerChickenDinner;
}

The old games are the best - Connect4 is awesome, so good luck. 旧游戏是最好的-Connect4很棒,祝您好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM