diff --git a/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java b/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java index 6ec7898..0202ff4 100644 --- a/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java +++ b/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java @@ -34,6 +34,7 @@ import org.petero.droidfish.engine.DroidComputerPlayer.SearchRequest; import org.petero.droidfish.engine.DroidComputerPlayer.SearchType; import org.petero.droidfish.gamelogic.Game.GameState; import org.petero.droidfish.gamelogic.GameTree.Node; +import org.petero.droidfish.gamelogic.TimeControlData.TimeControlField; /** * The glue between the chess engine and the GUI. @@ -54,9 +55,7 @@ public class DroidChessController { private int strength = 1000; private int numPV = 1; - private int timeControl; - private int movesPerSession; - private int timeIncrement; + private TimeControlData tcData; private SearchListener listener; private boolean guiPaused = false; @@ -72,6 +71,7 @@ public class DroidChessController { this.gameTextListener = gameTextListener; gameMode = new GameMode(GameMode.TWO_PLAYERS); pgnOptions = options; + tcData = new TimeControlData(); listener = new SearchListener(); searchId = 0; } @@ -89,7 +89,7 @@ public class DroidChessController { } computerPlayer.queueStartEngine(searchId, engine); searchId++; - game = new Game(gameTextListener, timeControl, movesPerSession, timeIncrement); + game = new Game(gameTextListener, tcData); computerPlayer.clearTT(); setPlayerNames(game); updateGameMode(); @@ -105,11 +105,9 @@ public class DroidChessController { /** Set time control parameters. */ public final synchronized void setTimeLimit(int time, int moves, int inc) { - timeControl = time; - movesPerSession = moves; - timeIncrement = inc; + tcData.setTimeControl(time, moves, inc); if (game != null) - game.timeController.setTimeControl(timeControl, movesPerSession, timeIncrement); + game.timeController.setTimeControl(tcData); } /** @return Array containing time control, moves per session and time increment. */ @@ -117,9 +115,10 @@ public class DroidChessController { if (game != null) return game.timeController.getTimeLimit(game.currPos().whiteMove); int[] ret = new int[3]; - ret[0] = timeControl; - ret[1] = movesPerSession; - ret[2] = timeIncrement; + TimeControlField tc = tcData.getTC(true).get(0); + ret[0] = (int)tc.timeControl; + ret[1] = tc.movesPerSession; + ret[2] = (int)tc.increment; return ret; } @@ -237,7 +236,7 @@ public class DroidChessController { /** Parse a string as FEN or PGN data. */ public final synchronized void setFENOrPGN(String fenPgn) throws ChessParseError { - Game newGame = new Game(gameTextListener, timeControl, movesPerSession, timeIncrement); + Game newGame = new Game(gameTextListener, tcData); try { Position pos = TextIO.readFEN(fenPgn); newGame.setPos(pos); diff --git a/DroidFish/src/org/petero/droidfish/gamelogic/Game.java b/DroidFish/src/org/petero/droidfish/gamelogic/Game.java index 4be0be2..e115fdd 100644 --- a/DroidFish/src/org/petero/droidfish/gamelogic/Game.java +++ b/DroidFish/src/org/petero/droidfish/gamelogic/Game.java @@ -38,12 +38,11 @@ public class Game { PgnToken.PgnTokenReceiver gameTextListener; - public Game(PgnToken.PgnTokenReceiver gameTextListener, - int timeControl, int movesPerSession, int timeIncrement) { + public Game(PgnToken.PgnTokenReceiver gameTextListener, TimeControlData tcData) { this.gameTextListener = gameTextListener; tree = new GameTree(gameTextListener); timeController = new TimeControl(); - timeController.setTimeControl(timeControl, movesPerSession, timeIncrement); + timeController.setTimeControl(tcData); gamePaused = false; newGame(); } diff --git a/DroidFish/src/org/petero/droidfish/gamelogic/TimeControl.java b/DroidFish/src/org/petero/droidfish/gamelogic/TimeControl.java index 8266833..1204b28 100644 --- a/DroidFish/src/org/petero/droidfish/gamelogic/TimeControl.java +++ b/DroidFish/src/org/petero/droidfish/gamelogic/TimeControl.java @@ -20,22 +20,11 @@ package org.petero.droidfish.gamelogic; import java.util.ArrayList; +import org.petero.droidfish.gamelogic.TimeControlData.TimeControlField; + /** Keep track of time control information for both players. */ public class TimeControl { - public static final class TimeControlField { - long timeControl; - int movesPerSession; - long increment; - - public TimeControlField(long time, int moves, long inc) { - timeControl = time; - movesPerSession = moves; - increment = inc; - } - } - - private ArrayList tcW; - private ArrayList tcB; + private TimeControlData tcData; private long whiteBaseTime; // Current remaining time, or remaining time when clock started private long blackBaseTime; // Current remaining time, or remaining time when clock started @@ -49,7 +38,7 @@ public class TimeControl { /** Constructor. Sets time control to "game in 5min". */ public TimeControl() { - setTimeControl(5 * 60 * 1000, 0, 0); + tcData = new TimeControlData(); reset(); } @@ -60,19 +49,9 @@ public class TimeControl { timerT0 = 0; } - /** Set time control to "moves" moves in "time" milliseconds, + inc milliseconds per move. */ - public final void setTimeControl(long time, int moves, long inc) { - tcW = new ArrayList(); - tcW.add(new TimeControlField(time, moves, inc)); - tcB = new ArrayList(); - tcB.add(new TimeControlField(time, moves, inc)); - } - /** Set time controls for white and black players. */ - public final void setTimeControl(ArrayList whiteTC, - ArrayList blackTC) { - tcW = whiteTC; - tcB = blackTC; + public final void setTimeControl(TimeControlData tcData) { + this.tcData = tcData; } public final void setCurrentMove(int move, boolean whiteToMove, long whiteBaseTime, long blackBaseTime) { @@ -109,7 +88,7 @@ public class TimeControl { public final int moveMade(long now, boolean useIncrement) { stopTimer(now); - ArrayList tc = whiteToMove ? tcW : tcB; + ArrayList tc = tcData.getTC(whiteToMove); Pair tcInfo = getCurrentTC(whiteToMove); int tcIdx = tcInfo.first; int movesToTc = tcInfo.second; @@ -141,13 +120,13 @@ public class TimeControl { /** Get initial thinking time in milliseconds. */ public final int getInitialTime(boolean whiteMove) { - ArrayList tc = whiteMove ? tcW : tcB; + ArrayList tc = tcData.getTC(whiteMove); return (int)tc.get(0).timeControl; } /** Get time increment in milliseconds after playing next move. */ public final int getIncrement(boolean whiteMove) { - ArrayList tc = whiteMove ? tcW : tcB; + ArrayList tc = tcData.getTC(whiteMove); int tcIdx = getCurrentTC(whiteMove).first; return (int)tc.get(tcIdx).increment; } @@ -159,7 +138,7 @@ public class TimeControl { /** @return Array containing time control, moves per session and time increment. */ public int[] getTimeLimit(boolean whiteMove) { - ArrayList tc = whiteMove ? tcW : tcB; + ArrayList tc = tcData.getTC(whiteMove); int tcIdx = getCurrentTC(whiteMove).first; TimeControlField t = tc.get(tcIdx); return new int[]{(int)t.timeControl, t.movesPerSession, (int)t.increment}; @@ -167,7 +146,7 @@ public class TimeControl { /** Return the current active time control index and number of moves to next time control. */ private Pair getCurrentTC(boolean whiteMove) { - ArrayList tc = whiteMove ? tcW : tcB; + ArrayList tc = tcData.getTC(whiteMove); int tcIdx = 0; final int lastTcIdx = tc.size() - 1; int nextTC = 1; diff --git a/DroidFish/src/org/petero/droidfish/gamelogic/TimeControlData.java b/DroidFish/src/org/petero/droidfish/gamelogic/TimeControlData.java new file mode 100644 index 0000000..f579dea --- /dev/null +++ b/DroidFish/src/org/petero/droidfish/gamelogic/TimeControlData.java @@ -0,0 +1,38 @@ +package org.petero.droidfish.gamelogic; + +import java.util.ArrayList; + +public final class TimeControlData { + public static final class TimeControlField { + long timeControl; + int movesPerSession; + long increment; + + public TimeControlField(long time, int moves, long inc) { + timeControl = time; + movesPerSession = moves; + increment = inc; + } + } + + ArrayList tcW, tcB; + + TimeControlData() { + tcW = new ArrayList(); + tcW.add(new TimeControlField(5*60*1000, 60, 0)); + tcB = new ArrayList(); + tcB.add(new TimeControlField(5*60*1000, 60, 0)); + } + + public final void setTimeControl(long time, int moves, long inc) { + tcW = new ArrayList(); + tcW.add(new TimeControlField(time, moves, inc)); + tcB = new ArrayList(); + tcB.add(new TimeControlField(time, moves, inc)); + } + + /** Get time control data array for white or black player. */ + public ArrayList getTC(boolean whiteMove) { + return whiteMove ? tcW : tcB; + } +} diff --git a/DroidFishTest/src/org/petero/droidfish/gamelogic/GameTest.java b/DroidFishTest/src/org/petero/droidfish/gamelogic/GameTest.java index dfe5fcb..44edb26 100644 --- a/DroidFishTest/src/org/petero/droidfish/gamelogic/GameTest.java +++ b/DroidFishTest/src/org/petero/droidfish/gamelogic/GameTest.java @@ -36,7 +36,7 @@ public class GameTest extends TestCase { * Test of haveDrawOffer method, of class Game. */ public void testHaveDrawOffer() { - Game game = new Game(null, 0, 0, 0); + Game game = new Game(null, new TimeControlData()); assertEquals(false, game.haveDrawOffer()); boolean res = game.processString("e4"); @@ -124,7 +124,7 @@ public class GameTest extends TestCase { * Test of draw by 50 move rule, of class Game. */ public void testDraw50() throws ChessParseError { - Game game = new Game(null, 0, 0, 0); + Game game = new Game(null, new TimeControlData()); assertEquals(false, game.haveDrawOffer()); boolean res = game.processString("draw 50"); assertEquals(true, res); @@ -179,7 +179,7 @@ public class GameTest extends TestCase { * Test of draw by repetition, of class Game. */ public void testDrawRep() throws ChessParseError { - Game game = new Game(null, 0, 0, 0); + Game game = new Game(null, new TimeControlData()); assertEquals(false, game.haveDrawOffer()); game.processString("Nc3"); game.processString("Nc6"); @@ -251,7 +251,7 @@ public class GameTest extends TestCase { * Test of draw offer/accept/request command. */ public void testDrawBug() throws ChessParseError { - Game game = new Game(null, 0, 0, 0); + Game game = new Game(null, new TimeControlData()); assertEquals(false, game.haveDrawOffer()); game.processString("e4"); game.processString("c5"); @@ -269,7 +269,7 @@ public class GameTest extends TestCase { * Test of resign command, of class Game. */ public void testResign() throws ChessParseError { - Game game = new Game(null, 0, 0, 0); + Game game = new Game(null, new TimeControlData()); assertEquals(Game.GameState.ALIVE, game.getGameState()); game.processString("f3"); assertEquals(Game.GameState.ALIVE, game.getGameState()); @@ -299,7 +299,7 @@ public class GameTest extends TestCase { * Test of processString method, of class Game. */ public void testProcessString() throws ChessParseError { - Game game = new Game(null, 0, 0, 0); + Game game = new Game(null, new TimeControlData()); assertEquals(TextIO.startPosFEN, TextIO.toFEN(game.currPos())); boolean res = game.processString("Nf3"); assertEquals(true, res); @@ -348,7 +348,7 @@ public class GameTest extends TestCase { * Test of getGameState method, of class Game. */ public void testGetGameState() throws ChessParseError { - Game game = new Game(null, 0, 0, 0); + Game game = new Game(null, new TimeControlData()); assertEquals(Game.GameState.ALIVE, game.getGameState()); game.processString("f3"); game.processString("e5"); @@ -364,7 +364,7 @@ public class GameTest extends TestCase { * Test of insufficientMaterial method, of class Game. */ public void testInsufficientMaterial() throws ChessParseError { - Game game = new Game(null, 0, 0, 0); + Game game = new Game(null, new TimeControlData()); assertEquals(Game.GameState.ALIVE, game.getGameState()); game.setPos(TextIO.readFEN("4k3/8/8/8/8/8/8/4K3 w - - 0 1")); assertEquals(Game.GameState.DRAW_NO_MATE, game.getGameState()); @@ -407,7 +407,7 @@ public class GameTest extends TestCase { /** Test that UCI history is not longer than necessary. * We can't expect engines to handle null moves, for example. */ public void testUCIHistory() throws ChessParseError { - Game game = new Game(null, 0, 0, 0); + Game game = new Game(null, new TimeControlData()); Pair> hist = game.getUCIHistory(); assertEquals(0, hist.second.size()); diff --git a/DroidFishTest/src/org/petero/droidfish/gamelogic/TimeControlTest.java b/DroidFishTest/src/org/petero/droidfish/gamelogic/TimeControlTest.java index a0651c4..c237819 100644 --- a/DroidFishTest/src/org/petero/droidfish/gamelogic/TimeControlTest.java +++ b/DroidFishTest/src/org/petero/droidfish/gamelogic/TimeControlTest.java @@ -20,6 +20,8 @@ package org.petero.droidfish.gamelogic; import java.util.ArrayList; +import org.petero.droidfish.gamelogic.TimeControlData.TimeControlField; + import junit.framework.TestCase; @@ -31,7 +33,9 @@ public class TimeControlTest extends TestCase { TimeControl tc = new TimeControl(); long totTime = 5 * 60 * 1000; long t0 = 1000; - tc.setTimeControl(totTime, 0, 0); + TimeControlData tcData = new TimeControlData(); + tcData.setTimeControl(totTime, 0, 0); + tc.setTimeControl(tcData); tc.setCurrentMove(1, true, totTime, totTime); assertEquals(0, tc.getMovesToTC(true)); assertEquals(0, tc.getMovesToTC(false)); @@ -70,7 +74,9 @@ public class TimeControlTest extends TestCase { /** Test getMovesToTC */ public void testTimeControl() { TimeControl tc = new TimeControl(); - tc.setTimeControl(2 * 60 * 1000, 40, 0); + TimeControlData tcData = new TimeControlData(); + tcData.setTimeControl(2 * 60 * 1000, 40, 0); + tc.setTimeControl(tcData); tc.setCurrentMove(1, true, 0, 0); assertEquals(40, tc.getMovesToTC(true)); assertEquals(40, tc.getMovesToTC(false)); @@ -107,20 +113,21 @@ public class TimeControlTest extends TestCase { assertEquals(40, tc.getMovesToTC(false)); } - private TimeControl.TimeControlField tcf(long time, int moves, long inc) { - return new TimeControl.TimeControlField(time, moves, inc); + private TimeControlField tcf(long time, int moves, long inc) { + return new TimeControlField(time, moves, inc); } /** Test multiple time controls. */ public void testMultiTimeControl() { TimeControl tc = new TimeControl(); - ArrayList tcW = new ArrayList(); - tcW.add(tcf(120*60*1000, 40, 0)); - tcW.add(tcf(60*60*1000, 20, 0)); - tcW.add(tcf(30*60*1000, 0, 15*1000)); - ArrayList tcB = new ArrayList(); - tcB.add(tcf(5*60*1000, 60, 1000)); - tc.setTimeControl(tcW, tcB); + TimeControlData tcData = new TimeControlData(); + tcData.tcW = new ArrayList(); + tcData.tcW.add(tcf(120*60*1000, 40, 0)); + tcData.tcW.add(tcf(60*60*1000, 20, 0)); + tcData.tcW.add(tcf(30*60*1000, 0, 15*1000)); + tcData.tcB = new ArrayList(); + tcData.tcB.add(tcf(5*60*1000, 60, 1000)); + tc.setTimeControl(tcData); assertEquals(40, tc.getMovesToTC(true)); assertEquals(60, tc.getMovesToTC(false)); @@ -176,7 +183,9 @@ public class TimeControlTest extends TestCase { int wBaseTime = (int)timeCont; int bBaseTime = (int)timeCont; final long inc = 700; - tc.setTimeControl(timeCont, 5, inc); + TimeControlData tcData = new TimeControlData(); + tcData.setTimeControl(timeCont, 5, inc); + tc.setTimeControl(tcData); tc.setCurrentMove(5, true, wBaseTime, bBaseTime); long t0 = 1342134; assertEquals(timeCont, tc.getRemainingTime(true, t0 + 4711)); @@ -208,7 +217,8 @@ public class TimeControlTest extends TestCase { assertEquals(timeCont - 4000 + timeCont + inc - 1000, tc.getRemainingTime(false, t0 + 4711)); // No extra time when passing time control in analysis mode - tc.setTimeControl(timeCont, 1, inc); + tcData.setTimeControl(timeCont, 1, inc); + tc.setTimeControl(tcData); wBaseTime = bBaseTime = (int)timeCont; tc.setCurrentMove(1, true, wBaseTime, bBaseTime); tc.startTimer(t0 + 1000);