mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-01-30 17:13:50 +01:00
DroidFish: Added support in TimeControl class for multiple time controls and for different time controls for white and black.
This commit is contained in:
parent
671994e004
commit
ba7d8f61eb
|
@ -109,7 +109,8 @@ public class DroidComputerPlayer {
|
|||
boolean isAnalyze; // True if analysis search
|
||||
int wTime; // White remaining time, milliseconds
|
||||
int bTime; // Black remaining time, milliseconds
|
||||
int inc; // Time increment per move, milliseconds
|
||||
int wInc; // White time increment per move, milliseconds
|
||||
int bInc; // Black time increment per move, milliseconds
|
||||
int movesToGo; // Number of moves to next time control
|
||||
|
||||
String engine; // Engine name (identifier)
|
||||
|
@ -157,7 +158,7 @@ public class DroidComputerPlayer {
|
|||
public static SearchRequest searchRequest(int id, long now,
|
||||
Position prevPos, ArrayList<Move> mList,
|
||||
Position currPos, boolean drawOffer,
|
||||
int wTime, int bTime, int inc, int movesToGo,
|
||||
int wTime, int bTime, int wInc, int bInc, int movesToGo,
|
||||
boolean ponderEnabled, Move ponderMove,
|
||||
String engine, int engineThreads,
|
||||
int strength) {
|
||||
|
@ -172,7 +173,8 @@ public class DroidComputerPlayer {
|
|||
sr.isAnalyze = false;
|
||||
sr.wTime = wTime;
|
||||
sr.bTime = bTime;
|
||||
sr.inc = inc;
|
||||
sr.wInc = wInc;
|
||||
sr.bInc = bInc;
|
||||
sr.movesToGo = movesToGo;
|
||||
sr.engine = engine;
|
||||
sr.engineThreads = engineThreads;
|
||||
|
@ -212,7 +214,7 @@ public class DroidComputerPlayer {
|
|||
sr.drawOffer = drawOffer;
|
||||
sr.isSearch = false;
|
||||
sr.isAnalyze = true;
|
||||
sr.wTime = sr.bTime = sr.inc = sr.movesToGo = 0;
|
||||
sr.wTime = sr.bTime = sr.wInc = sr.bInc = sr.movesToGo = 0;
|
||||
sr.engine = engine;
|
||||
sr.engineThreads = engineThreads;
|
||||
sr.strength = 1000;
|
||||
|
@ -554,8 +556,10 @@ public class DroidComputerPlayer {
|
|||
if (sr.bTime < 1) sr.bTime = 1;
|
||||
StringBuilder goStr = new StringBuilder(96);
|
||||
goStr.append(String.format("go wtime %d btime %d", sr.wTime, sr.bTime));
|
||||
if (sr.inc > 0)
|
||||
goStr.append(String.format(" winc %d binc %d", sr.inc, sr.inc));
|
||||
if (sr.wInc > 0)
|
||||
goStr.append(String.format(" winc %d", sr.wInc));
|
||||
if (sr.bInc > 0)
|
||||
goStr.append(String.format(" binc %d", sr.bInc));
|
||||
if (sr.movesToGo > 0)
|
||||
goStr.append(String.format(" movestogo %d", sr.movesToGo));
|
||||
if (sr.ponderMove != null)
|
||||
|
|
|
@ -873,18 +873,15 @@ public class DroidChessController {
|
|||
long now = System.currentTimeMillis();
|
||||
int wTime = game.timeController.getRemainingTime(true, now);
|
||||
int bTime = game.timeController.getRemainingTime(false, now);
|
||||
int inc = game.timeController.getIncrement();
|
||||
int movesToGo = game.timeController.getMovesToTC();
|
||||
if (ponder && !currPos.whiteMove && (movesToGo > 0)) {
|
||||
movesToGo--;
|
||||
if (movesToGo <= 0)
|
||||
movesToGo += game.timeController.getMovesPerSession();
|
||||
}
|
||||
int wInc = game.timeController.getIncrement(true);
|
||||
int bInc = game.timeController.getIncrement(false);
|
||||
boolean wtm = currPos.whiteMove;
|
||||
int movesToGo = game.timeController.getMovesToTC(wtm);
|
||||
final Move fPonderMove = ponder ? ponderMove : null;
|
||||
SearchRequest sr = DroidComputerPlayer.SearchRequest.searchRequest(
|
||||
searchId, now, ph.first, ph.second, currPos,
|
||||
game.haveDrawOffer(),
|
||||
wTime, bTime, inc, movesToGo,
|
||||
wTime, bTime, wInc, bInc, movesToGo,
|
||||
gui.ponderMode(), fPonderMove,
|
||||
engine, gui.engineThreads(),
|
||||
strength);
|
||||
|
|
|
@ -201,9 +201,8 @@ public class Game {
|
|||
int move = currPos.fullMoveCounter;
|
||||
boolean wtm = currPos.whiteMove;
|
||||
if (discardElapsed || (move != timeController.currentMove) || (wtm != timeController.whiteToMove)) {
|
||||
int initialTime = timeController.getInitialTime();
|
||||
int whiteBaseTime = tree.getRemainingTime(true, initialTime);
|
||||
int blackBaseTime = tree.getRemainingTime(false, initialTime);
|
||||
int whiteBaseTime = tree.getRemainingTime(true, timeController.getInitialTime(true));
|
||||
int blackBaseTime = tree.getRemainingTime(false, timeController.getInitialTime(false));
|
||||
timeController.setCurrentMove(move, wtm, whiteBaseTime, blackBaseTime);
|
||||
}
|
||||
long now = System.currentTimeMillis();
|
||||
|
|
|
@ -826,7 +826,7 @@ public class GameTree {
|
|||
}
|
||||
|
||||
final int getRemainingTime(boolean whiteMove, int initialTime) {
|
||||
int undef = Integer.MIN_VALUE;
|
||||
final int undef = Integer.MIN_VALUE;
|
||||
int remainingTime = undef;
|
||||
Node node = currentNode;
|
||||
boolean wtm = currentPos.whiteMove;
|
||||
|
|
|
@ -18,19 +18,33 @@
|
|||
|
||||
package org.petero.droidfish.gamelogic;
|
||||
|
||||
public class TimeControl {
|
||||
private long timeControl;
|
||||
private int movesPerSession;
|
||||
private long increment;
|
||||
import java.util.ArrayList;
|
||||
|
||||
private long whiteBaseTime;
|
||||
private long blackBaseTime;
|
||||
/** 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<TimeControlField> tcW;
|
||||
private ArrayList<TimeControlField> tcB;
|
||||
|
||||
private long whiteBaseTime; // Current remaining time, or remaining time when clock started
|
||||
private long blackBaseTime; // Current remaining time, or remaining time when clock started
|
||||
|
||||
int currentMove;
|
||||
boolean whiteToMove;
|
||||
|
||||
long elapsed; // Accumulated elapsed time for this move.
|
||||
long timerT0; // Time when timer started. 0 if timer is stopped.
|
||||
private long elapsed; // Accumulated elapsed time for this move.
|
||||
private long timerT0; // Time when timer started. 0 if timer is stopped.
|
||||
|
||||
|
||||
/** Constructor. Sets time control to "game in 5min". */
|
||||
|
@ -48,9 +62,17 @@ public class TimeControl {
|
|||
|
||||
/** Set time control to "moves" moves in "time" milliseconds, + inc milliseconds per move. */
|
||||
public final void setTimeControl(long time, int moves, long inc) {
|
||||
timeControl = time;
|
||||
movesPerSession = moves;
|
||||
increment = inc;
|
||||
tcW = new ArrayList<TimeControlField>();
|
||||
tcW.add(new TimeControlField(time, moves, inc));
|
||||
tcB = new ArrayList<TimeControlField>();
|
||||
tcB.add(new TimeControlField(time, moves, inc));
|
||||
}
|
||||
|
||||
/** Set time controls for white and black players. */
|
||||
public final void setTimeControl(ArrayList<TimeControlField> whiteTC,
|
||||
ArrayList<TimeControlField> blackTC) {
|
||||
tcW = whiteTC;
|
||||
tcB = blackTC;
|
||||
}
|
||||
|
||||
public final void setCurrentMove(int move, boolean whiteToMove, long whiteBaseTime, long blackBaseTime) {
|
||||
|
@ -86,11 +108,20 @@ public class TimeControl {
|
|||
/** Compute new remaining time after a move is made. */
|
||||
public final int moveMade(long now, boolean useIncrement) {
|
||||
stopTimer(now);
|
||||
|
||||
ArrayList<TimeControlField> tc = whiteToMove ? tcW : tcB;
|
||||
Pair<Integer,Integer> tcInfo = getCurrentTC(whiteToMove);
|
||||
int tcIdx = tcInfo.first;
|
||||
int movesToTc = tcInfo.second;
|
||||
|
||||
long remaining = getRemainingTime(whiteToMove, now);
|
||||
if (useIncrement) {
|
||||
remaining += increment;
|
||||
if (getMovesToTC() == 1)
|
||||
remaining += timeControl;
|
||||
remaining += tc.get(tcIdx).increment;
|
||||
if (movesToTc == 1) {
|
||||
if (tcIdx+1 < tc.size())
|
||||
tcIdx++;
|
||||
remaining += tc.get(tcIdx).timeControl;
|
||||
}
|
||||
}
|
||||
elapsed = 0;
|
||||
return (int)remaining;
|
||||
|
@ -108,24 +139,42 @@ public class TimeControl {
|
|||
return (int)remaining;
|
||||
}
|
||||
|
||||
public final int getInitialTime() {
|
||||
return (int)timeControl;
|
||||
/** Get initial thinking time in milliseconds. */
|
||||
public final int getInitialTime(boolean whiteMove) {
|
||||
ArrayList<TimeControlField> tc = whiteMove ? tcW : tcB;
|
||||
return (int)tc.get(0).timeControl;
|
||||
}
|
||||
|
||||
public final int getIncrement() {
|
||||
return (int)increment;
|
||||
/** Get time increment in milliseconds after playing next move. */
|
||||
public final int getIncrement(boolean whiteMove) {
|
||||
ArrayList<TimeControlField> tc = whiteMove ? tcW : tcB;
|
||||
int tcIdx = getCurrentTC(whiteMove).first;
|
||||
return (int)tc.get(tcIdx).increment;
|
||||
}
|
||||
|
||||
public final int getMovesToTC() {
|
||||
if (movesPerSession <= 0)
|
||||
return 0;
|
||||
/** Return number of moves to the next time control, or 0 if "sudden death". */
|
||||
public final int getMovesToTC(boolean whiteMove) {
|
||||
return getCurrentTC(whiteMove).second;
|
||||
}
|
||||
|
||||
/** Return the current active time control index and number of moves to next time control. */
|
||||
private Pair<Integer,Integer> getCurrentTC(boolean whiteMove) {
|
||||
ArrayList<TimeControlField> tc = whiteMove ? tcW : tcB;
|
||||
int tcIdx = 0;
|
||||
final int lastTcIdx = tc.size() - 1;
|
||||
int nextTC = 1;
|
||||
while (nextTC <= currentMove)
|
||||
nextTC += movesPerSession;
|
||||
return nextTC - currentMove;
|
||||
}
|
||||
|
||||
public final int getMovesPerSession() {
|
||||
return movesPerSession;
|
||||
int currMove = currentMove;
|
||||
if (!whiteToMove && whiteMove)
|
||||
currMove++;
|
||||
while (true) {
|
||||
if (tc.get(tcIdx).movesPerSession <= 0)
|
||||
return new Pair<Integer,Integer>(tcIdx, 0);
|
||||
nextTC += tc.get(tcIdx).movesPerSession;
|
||||
if (nextTC > currMove)
|
||||
break;
|
||||
if (tcIdx < lastTcIdx)
|
||||
tcIdx++;
|
||||
}
|
||||
return new Pair<Integer,Integer>(tcIdx, nextTC - currMove);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
package org.petero.droidfish.gamelogic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
||||
|
@ -31,20 +33,24 @@ public class TimeControlTest extends TestCase {
|
|||
long t0 = 1000;
|
||||
tc.setTimeControl(totTime, 0, 0);
|
||||
tc.setCurrentMove(1, true, totTime, totTime);
|
||||
assertEquals(0, tc.getMovesToTC());
|
||||
assertEquals(0, tc.getIncrement());
|
||||
assertEquals(0, tc.getMovesToTC(true));
|
||||
assertEquals(0, tc.getMovesToTC(false));
|
||||
assertEquals(0, tc.getIncrement(true));
|
||||
assertEquals(0, tc.getIncrement(false));
|
||||
assertEquals(totTime, tc.getRemainingTime(true, 0));
|
||||
tc.startTimer(t0);
|
||||
int remain = tc.moveMade(t0 + 1000, true);
|
||||
assertEquals(totTime - 1000, remain);
|
||||
|
||||
tc.setCurrentMove(2, true, totTime - 1000, totTime);
|
||||
assertEquals(0, tc.getMovesToTC());
|
||||
assertEquals(0, tc.getMovesToTC(true));
|
||||
assertEquals(0, tc.getMovesToTC(false));
|
||||
assertEquals(totTime - 1000, tc.getRemainingTime(true, t0 + 4711));
|
||||
assertEquals(totTime, tc.getRemainingTime(false, t0 + 4711));
|
||||
|
||||
tc.setCurrentMove(1, false, totTime - 1000, totTime);
|
||||
assertEquals(0, tc.getMovesToTC());
|
||||
assertEquals(0, tc.getMovesToTC(true));
|
||||
assertEquals(0, tc.getMovesToTC(false));
|
||||
assertEquals(totTime - 1000, tc.getRemainingTime(true, t0 + 4711));
|
||||
assertEquals(totTime, tc.getRemainingTime(false, t0 + 4711));
|
||||
|
||||
|
@ -66,24 +72,102 @@ public class TimeControlTest extends TestCase {
|
|||
TimeControl tc = new TimeControl();
|
||||
tc.setTimeControl(2 * 60 * 1000, 40, 0);
|
||||
tc.setCurrentMove(1, true, 0, 0);
|
||||
assertEquals(40, tc.getMovesToTC());
|
||||
assertEquals(40, tc.getMovesToTC(true));
|
||||
assertEquals(40, tc.getMovesToTC(false));
|
||||
tc.setCurrentMove(1, false, 0, 0);
|
||||
assertEquals(40, tc.getMovesToTC());
|
||||
assertEquals(39, tc.getMovesToTC(true));
|
||||
assertEquals(40, tc.getMovesToTC(false));
|
||||
|
||||
tc.setCurrentMove(2, true, 0, 0);
|
||||
assertEquals(39, tc.getMovesToTC());
|
||||
assertEquals(39, tc.getMovesToTC(true));
|
||||
assertEquals(39, tc.getMovesToTC(false));
|
||||
|
||||
tc.setCurrentMove(40, true, 0, 0);
|
||||
assertEquals(1, tc.getMovesToTC());
|
||||
assertEquals(1, tc.getMovesToTC(true));
|
||||
assertEquals(1, tc.getMovesToTC(false));
|
||||
|
||||
tc.setCurrentMove(40, false, 0, 0);
|
||||
assertEquals(40, tc.getMovesToTC(true));
|
||||
assertEquals(1, tc.getMovesToTC(false));
|
||||
|
||||
tc.setCurrentMove(41, true, 0, 0);
|
||||
assertEquals(40, tc.getMovesToTC());
|
||||
assertEquals(40, tc.getMovesToTC(true));
|
||||
assertEquals(40, tc.getMovesToTC(false));
|
||||
|
||||
tc.setCurrentMove(80, true, 0, 0);
|
||||
assertEquals(1, tc.getMovesToTC());
|
||||
assertEquals(1, tc.getMovesToTC(true));
|
||||
assertEquals(1, tc.getMovesToTC(false));
|
||||
|
||||
tc.setCurrentMove(80, false, 0, 0);
|
||||
assertEquals(40, tc.getMovesToTC(true));
|
||||
assertEquals(1, tc.getMovesToTC(false));
|
||||
|
||||
tc.setCurrentMove(81, true, 0, 0);
|
||||
assertEquals(40, tc.getMovesToTC());
|
||||
assertEquals(40, tc.getMovesToTC(true));
|
||||
assertEquals(40, tc.getMovesToTC(false));
|
||||
}
|
||||
|
||||
private TimeControl.TimeControlField tcf(long time, int moves, long inc) {
|
||||
return new TimeControl.TimeControlField(time, moves, inc);
|
||||
}
|
||||
|
||||
/** Test multiple time controls. */
|
||||
public void testMultiTimeControl() {
|
||||
TimeControl tc = new TimeControl();
|
||||
ArrayList<TimeControl.TimeControlField> tcW = new ArrayList<TimeControl.TimeControlField>();
|
||||
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<TimeControl.TimeControlField> tcB = new ArrayList<TimeControl.TimeControlField>();
|
||||
tcB.add(tcf(5*60*1000, 60, 1000));
|
||||
tc.setTimeControl(tcW, tcB);
|
||||
|
||||
assertEquals(40, tc.getMovesToTC(true));
|
||||
assertEquals(60, tc.getMovesToTC(false));
|
||||
assertEquals(0, tc.getIncrement(true));
|
||||
assertEquals(1000, tc.getIncrement(false));
|
||||
|
||||
tc.setCurrentMove(40, true, 0, 0);
|
||||
assertEquals(1, tc.getMovesToTC(true));
|
||||
assertEquals(21, tc.getMovesToTC(false));
|
||||
assertEquals(0, tc.getIncrement(true));
|
||||
assertEquals(1000, tc.getIncrement(false));
|
||||
|
||||
tc.setCurrentMove(40, false, 0, 0);
|
||||
assertEquals(20, tc.getMovesToTC(true));
|
||||
assertEquals(21, tc.getMovesToTC(false));
|
||||
assertEquals(0, tc.getIncrement(true));
|
||||
assertEquals(1000, tc.getIncrement(false));
|
||||
|
||||
tc.setCurrentMove(60, true, 0, 0);
|
||||
assertEquals(1, tc.getMovesToTC(true));
|
||||
assertEquals(1, tc.getMovesToTC(false));
|
||||
assertEquals(0, tc.getIncrement(true));
|
||||
assertEquals(1000, tc.getIncrement(false));
|
||||
|
||||
tc.setCurrentMove(61, true, 0, 0);
|
||||
assertEquals(0, tc.getMovesToTC(true));
|
||||
assertEquals(60, tc.getMovesToTC(false));
|
||||
assertEquals(15000, tc.getIncrement(true));
|
||||
assertEquals(1000, tc.getIncrement(false));
|
||||
|
||||
|
||||
long wBaseTime = 60*1000;
|
||||
long bBaseTime = 50*1000;
|
||||
tc.setCurrentMove(30, true, wBaseTime, bBaseTime);
|
||||
tc.startTimer(1500);
|
||||
wBaseTime = tc.moveMade(1500 + 3000, true);
|
||||
assertEquals(60*1000-3000, wBaseTime);
|
||||
tc.setCurrentMove(30, false, wBaseTime, bBaseTime);
|
||||
assertEquals(60*1000-3000, tc.getRemainingTime(true, 1500 + 3000));
|
||||
assertEquals(50*1000, tc.getRemainingTime(false, 1500 + 3000));
|
||||
|
||||
tc.startTimer(5000);
|
||||
bBaseTime = tc.moveMade(9000, true);
|
||||
assertEquals(50000 - 4000 + 1000, bBaseTime);
|
||||
tc.setCurrentMove(31, true, wBaseTime, bBaseTime);
|
||||
assertEquals(60*1000-3000, tc.getRemainingTime(true, 9000));
|
||||
assertEquals(50000 - 4000 + 1000, tc.getRemainingTime(false, 9000));
|
||||
}
|
||||
|
||||
public void testExtraTime() {
|
||||
|
@ -116,7 +200,7 @@ public class TimeControlTest extends TestCase {
|
|||
assertEquals(timeCont - 1000 + timeCont + inc - 3000 + inc, tc.getRemainingTime(true, t0 + 4711));
|
||||
assertEquals(timeCont - 4000 + timeCont + inc, tc.getRemainingTime(false, t0 + 4711));
|
||||
|
||||
// No increment when move made int paused mode, ie analysis mode
|
||||
// No increment when move made in paused mode, ie analysis mode
|
||||
tc.startTimer(t0 + 9000);
|
||||
bBaseTime = tc.moveMade(t0 + 10000, false);
|
||||
tc.setCurrentMove(7, true, wBaseTime, bBaseTime);
|
||||
|
|
Loading…
Reference in New Issue
Block a user