0

チェス プログラムに単純な NegaMax を実装する際に問題があります。

いくつかの Web サイトによると、私のコードでは negamax は次のようになります。

int Position::negaMax(int curr_depth, int depth) {
    cd = curr_depth-1;
    if (curr_depth==depth) return evaluate();

    int max = -500000;

    calc_moves(true);
    doBackup(cd);
    for (int i=0;i<mvSize[cd];i++) {
        move_figure(mvD[cd][i][0],mvD[cd][i][1],mvD[cd][i][2],mvI[cd][i][0],mvI[cd][i][1]);    
        int score = -negaMax(curr_depth+1,depth);
        cd--; undoMove(cd);

        if (curr_depth==1)
            cout << "Move: " << getMoveString(i) << ", Score: " << score << endl;        

        if (score>max)
            max=score;
   }
   return max;
}

しかし、このコードを使用すると、次の出力が得られます。

Move: a2a3, Score: 0
Move: a2a4, Score: 0
Move: b2b3, Score: 0
Move: b2b4, Score: 0
Move: c2c3, Score: 0
Move: c2c4, Score: 0
Move: d2d3, Score: 0
Move: d2d4, Score: 0
Move: e2e3, Score: 0
Move: e2e4, Score: 0
Move: f2f3, Score: 0
Move: f2f4, Score: 0
Move: g2g3, Score: 0
Move: g2g4, Score: 0
Move: h2h3, Score: 0
Move: h2h4, Score: 0
Move: b1a3, Score: 0
Move: b1c3, Score: 0
Move: g1h3, Score: 0
Move: g1f3, Score: 0
score: 0

開始位置から ply3 の max をネガすると、それは正しくありません。

再帰関数呼び出しの前にあるマイナス記号を削除すると、より良い結果が得られます。しかし、私の意見では、上記のコードにマイナス記号がないと、一方のプレーヤーのスコアのみを最大化し、両方のプレーヤーのスコアを最大化しないため、それは正しくありません。

Move: a2a3, Score: 0
Move: a2a4, Score: 30
Move: b2b3, Score: 0
Move: b2b4, Score: 30
Move: c2c3, Score: 0
Move: c2c4, Score: 30
Move: d2d3, Score: 295
Move: d2d4, Score: 295
Move: e2e3, Score: 295
Move: e2e4, Score: 295
Move: f2f3, Score: 0
Move: f2f4, Score: 30
Move: g2g3, Score: 0
Move: g2g4, Score: 30
Move: h2h3, Score: 0
Move: h2h4, Score: 30
Move: b1a3, Score: 30
Move: b1c3, Score: 30
Move: g1h3, Score: 30
Move: g1f3, Score: 30
score: 295

MinMax、NegaMax、および AlphaBeta のさまざまなバージョンを実装しようとしました。しかし、私は常に 0 のスコアを取得します。ヒントがあれば非常にありがたいです。

4

1 に答える 1

0

negamax の実際のスケルトンは正しく実装されているようです。(しかし、私は、各層が減算される再帰関数に渡される単一の深さ変数を見ることに慣れており、0 に等しいときに評価されたスコアを返します)。しかし、他のコードに大きく依存しているため、あなたの問題を部外者として診断することは困難です。

あなたのために釣りをするより、あなたに釣り方を教えたほうがいいと思います。ツリー構造と累積スコアを何らかの方法で視覚的に出力するルーチンを構築するために、時間を費やすことをお勧めします。あなたもすでにそのようなものの構成要素を持っているようです. 最初にこれを行うのは時間がかかるかもしれませんが、長い目で見ればデバッグに大いに役立ちます - そして私を信じてください、チェスエンジンでは、このツリーをトロールすることは残念ながら頻繁に現実になるでしょう。 -passant - これらはツリー内であらゆる種類の問題を引き起こす可能性があります (私はそこにいました)。

次のようなものを出力してみてください。

<move-white ---->
    <move-black ----><eval score>
    <move-black ----><eval score>
    <move-black ----><eval score>
    <best black score>
<move-white ---->
    <move-black ----><eval score>
    <move-black ----><eval score>
    <move-black ----><eval score>
    <move-black ----><eval score>
    <move-black ----><eval score>
    <move-black ----><eval score>
    <best black score>
<move-white ---->
    <move-black ----><eval score>
    <move-black ----><eval score>
    <best black score>
<best white score>

...ここで----移動を示します。

明らかに、これははるかに大きく、より深くなるでしょうが、少なくとも、より人間に優しい方法で何が起こっているかを見ることができます. 長期的には他の問題にも役立つことを願っています。おそらくわかるように、チェスエンジンを備えた優れたデバッグシステムをセットアップすることが不可欠です。

于 2012-02-28T09:33:14.907 に答える