1

Irgendwelche Idee oder Pseudocode für einen nicht-rekursiven, iterativ basierten Negamax-Algorithmus?Benötigen Sie einen nicht-rekursiven, iterativ basierten Negamax-Algorithmus für eine Schach-AI

Ich benutze Negamax als Suchkern meiner Schach-KI.

Meine Engine ist in JavaScript geschrieben und kann laut Literatur 4fach nutzen, wenn Iteration über Rekursion verwendet wurde.

Die JavaScript zu C Strafe ist etwa 3x langsamer in Bezug auf die Knotentiefe. Dieser eine Tweak könnte das Spielfeld nivellieren, aber beide Faktoren mit einem Körnchen Salz nehmen :)

Anstelle des längeren Negamax-Codes. Ähnlicher rekursiven Code ist mein "Static Exchange-Eval" (SEE)

function _see(sq, fen, depth, maxDepth, color, chess) { 
 
    "use strict"; 
 
    if (chess.fen() !== fen) { 
 
     console.error("s fen/chess sync error"); 
 
     chess.load(fen); 
 
    } 
 

 
    if (chess.in_checkmate() || chess.game_over()) { 
 
     return MATE; 
 
    } else if (chess.in_check()) { 
 
     return 0; // ???? 
 
    } 
 

 
    var value = 0, moves, index, move_score, tfen, foo, bar; 
 

 
    if (depth < maxDepth) { 
 
     moves = chess.moves({ 
 
      square: sq, 
 
      verbose: true 
 
     }); 
 
     if (moves.length > 0) { 
 
      counter.seeNodes = counter.seeNodes + 1; 
 
      moves = _.chain(moves) 
 
       //only captures 
 
       .reject(function (e) { 
 
        return !e.hasOwnProperty('captured'); 
 
       }) 
 
       //material MVV 
 
       .sortBy(function (s) { 
 
        return evalPiece(s.piece); 
 
       }) 
 
       //captures LVA 
 
       .sortBy(function (s) { 
 
        return -evalPiece(s.captured); 
 
       }) 
 
       .value(); 
 
      //counter.sDepth = Math.max(depth, counter.sDepth); 
 
      //counter.maxSDepth = Math.max(maxDepth, counter.maxSDepth);  console.error(JSON.stringify(moves)); 
 

 
      for (index = 0; index < moves.length; index += 1) { 
 
       foo = chess.move(moves[index]); 
 
       if (foo === null) { 
 
        console.error("see move generated error, aborting loop"); 
 
        break; 
 
       } 
 
       tfen = chess.fen(); 
 
       value = Math.max(0, evalPiece(foo.captured) - _see(sq, tfen, depth + 1, maxDepth, -color, chess)); 
 
       bar = chess.undo(); 
 
       if (bar === null) { 
 
        console.error("see: bar=null"); 
 
       } 
 
      } 
 

 
     } 
 

 
    } 
 
    return value; 
 
}

+1

Die Veröffentlichung Ihres aktuellen Codes würde Ihnen helfen, eine bessere Lösung zu finden. – Chris

+0

Ich habe kürzlich eine generische nicht-rekursive Negamax-Routine geschrieben, die ein einfaches Array von Objekten verwendet. Die Bibliothek [easyAI] (http://zulko.github.io/easyAI/) wird eher in Python als in Javascript geschrieben. aber Sie könnten den Code sicherlich mit wenig Problem konvertieren. Die spezifische Quelldatei ist unter: https://github.com/Zulko/easyAI/blob/master/easyAI/AI/NonRecursiveNegamax.py – JohnAD

Antwort

2

Sie können mit einem Stapel einen rekursiven Algorithmus zu einem iterativen einem übersetzen. Im Allgemeinen entspricht das Objekt, das Sie auf dem Stapel schieben, den Parametern, mit denen Sie den rekursiven Aufruf durchführen.

+0

Schöne Idee und ich sehe Ihre Logik. Mein Bauchgefühl ist, dass der Stack-Ansatz nur marginal besser funktioniert als Rekursion, aber die gleichen Grenzen und ähnlichen Speicherbedarf hat. Nicht die 3fache Erhöhung der Taktrate, die ich brauche. Haben Sie JavaScript-Pseudocode? –

0

Ich schrieb eine nicht-rekursive Negamax-Routine als eine Option in der EasyAI Python-Bibliothek. Die spezifische Quellcode ist unter:

https://github.com/Zulko/easyAI/blob/master/easyAI/AI/NonRecursiveNegamax.py

Es verwendet eine einfache Schleife mit einer festen Anordnung von Objekten (Größe von Zieltiefe bestimmt wird) nach oben und nach unten in dem Baum eine geordneten Weise. Für das spezielle Projekt, in dem ich es verwendete, war es sechs Mal schneller als die rekursive Version. Aber ich bin mir sicher, dass jedes Spiel anders reagieren würde.

Es gibt keine Möglichkeit zu leugnen, dass dies ein dichter und komplexer Code ist und die Konvertierung in Javascript ... schwierig wird. Es ist so ziemlich nichts als Grenzfälle. :)

Wenn Sie es in Javascript konvertieren, würde ich gerne die Ergebnisse sehen. Einen Link in den Kommentar einfügen?

Verwandte Themen