DroidFish: A mating move could be added more than once to the game tree.

This commit is contained in:
Peter Osterlund 2016-12-25 21:38:25 +01:00
parent 1808bbb10c
commit b73f1d477b
3 changed files with 96 additions and 4 deletions

View File

@ -88,6 +88,7 @@ public class Game {
updateTimeControl(false);
}
/** Set game state from a PGN string. */
final public boolean readPGN(String pgn, PGNOptions options) throws ChessParseError {
boolean ret = tree.readPGN(pgn, options);
if (ret) {
@ -192,13 +193,18 @@ public class Game {
nVars = varMoves.size();
}
}
Boolean gameEndingMove = null;
for (varNo = 0; varNo < nVars; varNo++) {
if (varMoves.get(varNo).equals(m)) {
boolean match = true;
if (playerAction.isEmpty()) {
tree.goForward(varNo, false);
match = tree.getGameState() == GameState.ALIVE;
tree.goBack();
if (gameEndingMove == null)
gameEndingMove = gameEndingMove(m);
if (!gameEndingMove) {
tree.goForward(varNo, false);
match = tree.getGameState() == GameState.ALIVE;
tree.goBack();
}
}
if (match) {
movePresent = true;
@ -222,6 +228,16 @@ public class Game {
pendingDrawOffer = false;
}
/** Return true if move "m" in the current position ends the game (mate or stalemate). */
private boolean gameEndingMove(Move m) {
Position pos = currPos();
UndoInfo ui = new UndoInfo();
pos.makeMove(m, ui);
boolean gameEnd = MoveGen.instance.legalMoves(pos).isEmpty();
pos.unMakeMove(m, ui);
return gameEnd;
}
private final void updateTimeControl(boolean discardElapsed) {
Position currPos = currPos();
int move = currPos.fullMoveCounter;

View File

@ -20,6 +20,8 @@ package org.petero.droidfish.gamelogic;
import java.util.ArrayList;
import org.petero.droidfish.PGNOptions;
import junit.framework.TestCase;
@ -485,4 +487,78 @@ public class GameTest extends TestCase {
expectedPos = TextIO.readFEN(TextIO.startPosFEN);
assertEquals(expectedPos, hist.first);
}
public final void testDuplicateMoves() throws ChessParseError {
PGNOptions options = new PGNOptions();
options.imp.variations = true;
options.imp.comments = true;
options.imp.nag = true;
{
Game game = new Game(null, new TimeControlData());
boolean res = game.readPGN("[Event \"\"]\n[Result \"0-1\"]\n\ne4 0-1", options);
assertEquals(true, res);
assertEquals("e4", GameTreeTest.getVariationsAsString(game.tree));
Pair<Boolean,Move> p = game.processString("e4");
assertEquals(true, (boolean)p.first);
assertEquals(TextIO.UCIstringToMove("e2e4"), p.second);
game.undoMove();
assertEquals("e4 e4", GameTreeTest.getVariationsAsString(game.tree));
p = game.processString("e4");
assertEquals(true, (boolean)p.first);
assertEquals(TextIO.UCIstringToMove("e2e4"), p.second);
game.undoMove();
assertEquals("e4 e4", GameTreeTest.getVariationsAsString(game.tree));
p = game.processString("d4");
assertEquals(true, (boolean)p.first);
assertEquals(TextIO.UCIstringToMove("d2d4"), p.second);
game.undoMove();
assertEquals("d4 e4 e4", GameTreeTest.getVariationsAsString(game.tree));
}
{
Game game = new Game(null, new TimeControlData());
game.setPos(TextIO.readFEN("k7/5R2/6R1/2K5/8/8/8/8 w - - 0 1"));
Pair<Boolean,Move> p = game.processString("Rg8");
assertEquals(true, (boolean)p.first);
assertEquals(TextIO.UCIstringToMove("g6g8"), p.second);
game.undoMove();
assertEquals("Rg8#", GameTreeTest.getVariationsAsString(game.tree));
p = game.processString("Rg8");
assertEquals(true, (boolean)p.first);
assertEquals(TextIO.UCIstringToMove("g6g8"), p.second);
game.undoMove();
assertEquals("Rg8#", GameTreeTest.getVariationsAsString(game.tree));
p = game.processString("Rgg7");
assertEquals(true, (boolean)p.first);
assertEquals(TextIO.UCIstringToMove("g6g7"), p.second);
game.undoMove();
assertEquals("Rgg7 Rg8#", GameTreeTest.getVariationsAsString(game.tree));
}
{
Game game = new Game(null, new TimeControlData());
game.setPos(TextIO.readFEN("k7/8/1K6/8/8/8/2Q5/8 w - - 0 1"));
Pair<Boolean,Move> p = game.processString("Qc7");
assertEquals(true, (boolean)p.first);
assertEquals(TextIO.UCIstringToMove("c2c7"), p.second);
game.undoMove();
assertEquals("Qc7", GameTreeTest.getVariationsAsString(game.tree));
p = game.processString("Qc7");
assertEquals(true, (boolean)p.first);
assertEquals(TextIO.UCIstringToMove("c2c7"), p.second);
game.undoMove();
assertEquals("Qc7", GameTreeTest.getVariationsAsString(game.tree));
p = game.processString("Qc8");
assertEquals(true, (boolean)p.first);
assertEquals(TextIO.UCIstringToMove("c2c8"), p.second);
game.undoMove();
assertEquals("Qc8# Qc7", GameTreeTest.getVariationsAsString(game.tree));
}
}
}

View File

@ -242,7 +242,7 @@ public class GameTreeTest extends TestCase {
assertEquals(0, gt.currentNode.defaultChild);
}
private final String getVariationsAsString(GameTree gt) {
final static String getVariationsAsString(GameTree gt) {
StringBuilder ret = new StringBuilder();
List<Move> vars = gt.variations();
for (int i = 0; i < vars.size(); i++) {