2012-02-28 220 views
0

我在我的國際象棋程序中實現一個簡單的NegaMax時遇到問題。NegaMax無法正常工作

據一些網站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 

這不可能是正確的,如果我negaMax從ply3起始位置。

如果我在遞歸函數調用前刪除減號,我會得到更好的結果。但在我看來,這是不對的,因爲如果沒有上述代碼中的減號,我只會最大限度地提高一名球員的得分,但對兩者都不會。

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.我會非常感謝任何提示。

回答

0

negamax的實際框架似乎正確實施。 (但是,我更習慣於看到傳遞給遞歸函數的單個深度變量,每個層都會減去 - 並在等於0時返回評估分數)。但由於對其他代碼的依賴性很大,因此很難將您的問題診斷爲局外人。

與其爲您釣魚,我覺得教您如何釣魚會更好。我建議花一些時間來構建一個例程,以某種方式在視覺上輸出樹結構和累積分數。看起來好像你已經擁有這樣的構件。最初這樣做可能會花費很長時間,但從長遠來看,這對調試有很大幫助 - 並且相信我,通過使用國際象棋引擎,通過這棵樹進行拖網將是一個不幸的事情,尤其是當您執行更加模糊的動作時,比如en - 通行證 - 這些可能會導致樹內的各種麻煩(我去過那裏)。

嘗試輸出是這樣的:

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

...其中表示舉動。

很明顯,這將會變得更大更深,但至少你可以看到發生了什麼,以更人性化的方式。希望從長遠來看,它也能幫助你解決其他問題。使用國際象棋引擎建立一個良好的調試系統是非常重要的,你可能會發現。

+0

非常感謝您的建議。我用這種方法向我展示了最深層板的當前板面情況,並帶有一些評估函數的分數,並認識到存在一個小錯誤。無法弄清楚爲什麼它對一名沒有減號的球員有效,但現在最大化似乎對兩名球員都有效。 – Peter 2012-02-28 15:29:31

+0

不用擔心,很高興這有幫助。有時候最微妙的錯誤可能會導致看似無關的問題,特別是像國際象棋引擎這樣的問題! – 2012-03-01 06:36:30