DroidFish: Let the human player claim a draw that involves specifying

but not playing a move that would lead to a 50move/3rep draw.
This commit is contained in:
Peter Osterlund 2016-01-06 22:04:11 +01:00
parent ad9c97a3ef
commit 88074f5327
2 changed files with 48 additions and 23 deletions

View File

@ -305,23 +305,37 @@ public class DroidChessController {
/** Make a move for a human player. */ /** Make a move for a human player. */
public final synchronized void makeHumanMove(Move m) { public final synchronized void makeHumanMove(Move m) {
if (humansTurn()) { if (!humansTurn())
Position oldPos = new Position(game.currPos()); return;
if (doMove(m)) { Position oldPos = new Position(game.currPos());
if (m.equals(ponderMove) && !gameMode.analysisMode() && if (game.pendingDrawOffer) {
(computerPlayer.getSearchType() == SearchType.PONDER)) { ArrayList<Move> moves = new MoveGen().legalMoves(oldPos);
computerPlayer.ponderHit(searchId); for (Move m2 : moves) {
ponderMove = null; if (m2.equals(m)) {
} else { if (findValidDrawClaim(TextIO.moveToUCIString(m))) {
abortSearch(); stopPonder();
updateComputeThreads(); updateGUI();
gui.setSelection(-1);
return;
}
break;
} }
setAnimMove(oldPos, m, true);
updateGUI();
} else {
gui.setSelection(-1);
} }
} }
if (doMove(m)) {
if (m.equals(ponderMove) && !gameMode.analysisMode() &&
(computerPlayer.getSearchType() == SearchType.PONDER)) {
computerPlayer.ponderHit(searchId);
ponderMove = null;
} else {
abortSearch();
updateComputeThreads();
}
setAnimMove(oldPos, m, true);
updateGUI();
} else {
gui.setSelection(-1);
}
} }
/** Report promotion choice for incomplete move. /** Report promotion choice for incomplete move.
@ -365,7 +379,7 @@ public class DroidChessController {
/** Help human to claim a draw by trying to find and execute a valid draw claim. */ /** Help human to claim a draw by trying to find and execute a valid draw claim. */
public final synchronized boolean claimDrawIfPossible() { public final synchronized boolean claimDrawIfPossible() {
if (!findValidDrawClaim()) if (!findValidDrawClaim(""))
return false; return false;
updateGUI(); updateGUI();
return true; return true;
@ -1158,13 +1172,15 @@ public class DroidChessController {
gui.setAnimMove(sourcePos, move, forward); gui.setAnimMove(sourcePos, move, forward);
} }
private final boolean findValidDrawClaim() { private final boolean findValidDrawClaim(String ms) {
if (!ms.isEmpty())
ms = " " + ms;
if (game.getGameState() != GameState.ALIVE) return true; if (game.getGameState() != GameState.ALIVE) return true;
game.processString("draw accept"); game.tryClaimDraw("draw accept");
if (game.getGameState() != GameState.ALIVE) return true; if (game.getGameState() != GameState.ALIVE) return true;
game.processString("draw rep"); game.tryClaimDraw("draw rep" + ms);
if (game.getGameState() != GameState.ALIVE) return true; if (game.getGameState() != GameState.ALIVE) return true;
game.processString("draw 50"); game.tryClaimDraw("draw 50" + ms);
if (game.getGameState() != GameState.ALIVE) return true; if (game.getGameState() != GameState.ALIVE) return true;
return false; return false;
} }

View File

@ -39,7 +39,7 @@ public class Game {
/** If true, add new moves as mainline moves. */ /** If true, add new moves as mainline moves. */
private AddMoveBehavior addMoveBehavior; private AddMoveBehavior addMoveBehavior;
PgnToken.PgnTokenReceiver gameTextListener; private PgnToken.PgnTokenReceiver gameTextListener;
public Game(PgnToken.PgnTokenReceiver gameTextListener, TimeControlData tcData) { public Game(PgnToken.PgnTokenReceiver gameTextListener, TimeControlData tcData) {
this.gameTextListener = gameTextListener; this.gameTextListener = gameTextListener;
@ -140,7 +140,7 @@ public class Game {
return false; return false;
if (str.startsWith("draw ")) { if (str.startsWith("draw ")) {
String drawCmd = str.substring(str.indexOf(" ") + 1); String drawCmd = str.substring(str.indexOf(" ") + 1);
handleDrawCmd(drawCmd); handleDrawCmd(drawCmd, true);
return true; return true;
} else if (str.equals("resign")) { } else if (str.equals("resign")) {
addToGameTree(new Move(0, 0, 0), "resign"); addToGameTree(new Move(0, 0, 0), "resign");
@ -160,6 +160,15 @@ public class Game {
return true; return true;
} }
/** Try claim a draw using a command string. Does not play the move involved
* in the draw claim if the draw claim is invalid. */
public final void tryClaimDraw(String str) {
if (str.startsWith("draw ")) {
String drawCmd = str.substring(str.indexOf(" ") + 1);
handleDrawCmd(drawCmd, false);
}
}
private final void addToGameTree(Move m, String playerAction) { private final void addToGameTree(Move m, String playerAction) {
if (m.equals(new Move(0, 0, 0))) { // Don't create more than one game-ending move at a node if (m.equals(new Move(0, 0, 0))) { // Don't create more than one game-ending move at a node
List<Move> varMoves = tree.variations(); List<Move> varMoves = tree.variations();
@ -446,7 +455,7 @@ public class Game {
return new Pair<Position, ArrayList<Move>>(pos, mList); return new Pair<Position, ArrayList<Move>>(pos, mList);
} }
private final void handleDrawCmd(String drawCmd) { private final void handleDrawCmd(String drawCmd, boolean playDrawMove) {
Position pos = tree.currentPos; Position pos = tree.currentPos;
if (drawCmd.startsWith("rep") || drawCmd.startsWith("50")) { if (drawCmd.startsWith("rep") || drawCmd.startsWith("50")) {
boolean rep = drawCmd.startsWith("rep"); boolean rep = drawCmd.startsWith("rep");
@ -499,7 +508,7 @@ public class Game {
addToGameTree(new Move(0, 0, 0), playerAction); addToGameTree(new Move(0, 0, 0), playerAction);
} else { } else {
pendingDrawOffer = true; pendingDrawOffer = true;
if (m != null) { if (m != null && playDrawMove) {
processString(ms); processString(ms);
} }
} }