From 88074f53274be62db16bad9666150ecdfdb4553d Mon Sep 17 00:00:00 2001 From: Peter Osterlund Date: Wed, 6 Jan 2016 22:04:11 +0100 Subject: [PATCH] DroidFish: Let the human player claim a draw that involves specifying but not playing a move that would lead to a 50move/3rep draw. --- .../gamelogic/DroidChessController.java | 54 ++++++++++++------- .../org/petero/droidfish/gamelogic/Game.java | 17 ++++-- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java b/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java index 1a3231d..3e7a475 100644 --- a/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java +++ b/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java @@ -305,23 +305,37 @@ public class DroidChessController { /** Make a move for a human player. */ public final synchronized void makeHumanMove(Move m) { - if (humansTurn()) { - Position oldPos = new Position(game.currPos()); - if (doMove(m)) { - if (m.equals(ponderMove) && !gameMode.analysisMode() && - (computerPlayer.getSearchType() == SearchType.PONDER)) { - computerPlayer.ponderHit(searchId); - ponderMove = null; - } else { - abortSearch(); - updateComputeThreads(); + if (!humansTurn()) + return; + Position oldPos = new Position(game.currPos()); + if (game.pendingDrawOffer) { + ArrayList moves = new MoveGen().legalMoves(oldPos); + for (Move m2 : moves) { + if (m2.equals(m)) { + if (findValidDrawClaim(TextIO.moveToUCIString(m))) { + stopPonder(); + 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. @@ -365,7 +379,7 @@ public class DroidChessController { /** Help human to claim a draw by trying to find and execute a valid draw claim. */ public final synchronized boolean claimDrawIfPossible() { - if (!findValidDrawClaim()) + if (!findValidDrawClaim("")) return false; updateGUI(); return true; @@ -1158,13 +1172,15 @@ public class DroidChessController { 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; - game.processString("draw accept"); + game.tryClaimDraw("draw accept"); if (game.getGameState() != GameState.ALIVE) return true; - game.processString("draw rep"); + game.tryClaimDraw("draw rep" + ms); if (game.getGameState() != GameState.ALIVE) return true; - game.processString("draw 50"); + game.tryClaimDraw("draw 50" + ms); if (game.getGameState() != GameState.ALIVE) return true; return false; } diff --git a/DroidFish/src/org/petero/droidfish/gamelogic/Game.java b/DroidFish/src/org/petero/droidfish/gamelogic/Game.java index 30572cc..d4d7fbf 100644 --- a/DroidFish/src/org/petero/droidfish/gamelogic/Game.java +++ b/DroidFish/src/org/petero/droidfish/gamelogic/Game.java @@ -39,7 +39,7 @@ public class Game { /** If true, add new moves as mainline moves. */ private AddMoveBehavior addMoveBehavior; - PgnToken.PgnTokenReceiver gameTextListener; + private PgnToken.PgnTokenReceiver gameTextListener; public Game(PgnToken.PgnTokenReceiver gameTextListener, TimeControlData tcData) { this.gameTextListener = gameTextListener; @@ -140,7 +140,7 @@ public class Game { return false; if (str.startsWith("draw ")) { String drawCmd = str.substring(str.indexOf(" ") + 1); - handleDrawCmd(drawCmd); + handleDrawCmd(drawCmd, true); return true; } else if (str.equals("resign")) { addToGameTree(new Move(0, 0, 0), "resign"); @@ -160,6 +160,15 @@ public class Game { 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) { if (m.equals(new Move(0, 0, 0))) { // Don't create more than one game-ending move at a node List varMoves = tree.variations(); @@ -446,7 +455,7 @@ public class Game { return new Pair>(pos, mList); } - private final void handleDrawCmd(String drawCmd) { + private final void handleDrawCmd(String drawCmd, boolean playDrawMove) { Position pos = tree.currentPos; if (drawCmd.startsWith("rep") || drawCmd.startsWith("50")) { boolean rep = drawCmd.startsWith("rep"); @@ -499,7 +508,7 @@ public class Game { addToGameTree(new Move(0, 0, 0), playerAction); } else { pendingDrawOffer = true; - if (m != null) { + if (m != null && playDrawMove) { processString(ms); } }