0

ミニマックスでConnect4ゲームを書いていますが、次のステップのチェック機能で予期しない結果が生じることがあります。私のアルゴリズムが正しいかどうか教えてください。

たとえば、私のボードが次のようになっている場合

0000000 
0000000
0000000
0000000
1000000
2002120

プレーヤー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;
    }
4

1 に答える 1

0

フォーラムへようこそ。

投稿したコードにはいくつかの問題があります。

checkNextVertical関数は水平方向にチェックしようとしているcheckNextHorizontalように見え、水平方向と垂直方向の両方をチェックしようとしているように見えます。

arrBoard[column][i]と の両方を使用していることに気付いた場合arrBoard[i][column]。これらのうちの 1 つだけが正しいことに同意していただけると思います。どちらが正しいかを理解することが重要です。そうしないと、コードが配列内の無効な場所にアクセスしようとしてしまい、予期しない動作が発生します。たとえばj、関数内のループcheckNextHorizontalが現在これを実行しています。

array[y / depth / row][x / width / column]- または覚えているものとして使用する必要があります。

個人的には、このコードはややこしいようです:

    int player2;

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

player2=1丸い穴に四角いペグを押し込もうとしているようです。読みやすくするために、またはどちらかint playerに設定して使用できますか?12

私はJoachimに完全に同意します-この種の問題がある場合は、配列にデータを入力してから、デバッガーを使用してコードをステップスルーし、アクセスされているデータが期待どおりのデータであることを確認することをお勧めしますアクセスしました。

あるいは、これは connect4 ゲームなので、ある時点で最後の手が行われた列を知っていると仮定します。その場合、この関数を使用して、それが勝ちの手であったかどうかを確認できます。最後に移動した列と、勝つために必要な「サイズ」を指定するだけです。使用する場合でも、配列アクセスを理解できるように、デバッガーを使用してステップ実行することをお勧めします。注意: あなたのコードは斜めにチェックしていませんでした。あなたがそれをしたい場合は、いくつかの追加のロジックが必要です:

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;
}

古いゲームは最高です - Connect4 は素晴らしいので、頑張ってください。

于 2012-12-04T08:17:22.600 に答える