0

私はチェスゲームをプログラムしようとしていますが、コードを修正するのに何日も費やしました. 最小最大も試しましたが、同じ結果で終了しました。AI は常にコーナーから開始し、ポーンを邪魔にならないように移動し、ルークはターンごとに前後に移動します。食べられてしまうと、AI はすべてのピースを片っ端から片っ端から全部食べてしまうまで動かします。次のコードのどこが間違っているか知っていますか?

public Move MakeMove(int depth)
{
    bestmove.reset();
    bestscore = 0;
    score = 0;
    int maxDepth = depth;
    negaMax(depth, maxDepth);
    return bestmove;
}


public int EvalGame() //calculates the score from all the pieces on the board
{
    int score = 0;
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            if (AIboard[i, j].getPiece() != GRID.BLANK)
            {
                score += EvalPiece(AIboard[i, j].getPiece());
            }
        }
    }

    return score;
}

private int negaMax(int depth, int maxDepth)
{
    if (depth <= 0)
    {
        return EvalGame();
    }

    int max = -200000000;

    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            for (int k = 0; k < 8; k++)
            {
                for (int l = 0; l < 8; l++)
                {
                    if(GenerateMove(i, j, k, l)) //generates all possible moves
                    {
                        //code to move the piece on the board
                        board.makemove(nextmove);
                        score = -negaMax(depth - 1, maxDepth);

                        if( score > max )
                        {
                            max = score;

                            if (depth == maxDepth)
                            {
                                bestmove = nextmove;
                            }
                        }

                        //code to undo the move
                        board.undomove;
                    }
                }
            }
        }
    }

    return max;
}

public bool GenerateMove(int i, int j, int k, int l)
{
    Move move;
    move.moveFrom.X = i;
    move.moveFrom.Y = j;
    move.moveTo.X = k;
    move.moveTo.Y = l;

    if (checkLegalMoves(move.moveTo, move.moveFrom)) //if a legal move
    {
        nextMove = move;
        return true;
    }

    return false;
}
4

2 に答える 2

0

次の 2 つの問題が考えられます。

  1. 変数宣言が表示されていないため、ややあいまいですが、グローバル変数を使用しすぎていると思います。Negamax は、各ノードで最良の動きを計算することによって機能するため、値と動きを検索している間はローカルである必要があります。いずれにせよ、変数のスコープをできる限り狭く保つことをお勧めします。ゲーム ツリーをトラバースすると、非常に多くの変数が変更されるため、コードについて推論するのが難しくなります。ただし、検索では正しい値が返されるはずです。

  2. あなたの評価は、どちらのチームがプレーしているかを区別するものではないようです。これを処理するかどうかはわかりませんEvalPieceが、いずれにせよ評価は、現在移動する権利がある側の観点から行う必要があります。

また、問題に直接関係のない他の問題もあります。

  1. あなたのムーブジェネレーションは怖いです。ボード上の from/to 正方形のすべての可能なペアをペアごとにトラバースしています。これは非常に非効率的であり、そのような方法がどのように機能するかさえわかりません。ボード上のすべてのピースをループするか、より遅い方法でボード上のすべての正方形 (4096 の正方形ではなく) をループするだけで済みます。

  2. MakeMoveルートノードの場所のようです。現在、検索が終了する最後のノードがルートになるという点で、スキームは機能します。ただし、反復深化などのルートで特別なルーチンを使用するのが一般的であるため、ルートで別のループを使用するとよい場合があります。

于 2013-06-28T03:44:58.743 に答える