diff --git a/engine/core/src/main/java/com/codingame/gameengine/core/AbstractPlayer.java b/engine/core/src/main/java/com/codingame/gameengine/core/AbstractPlayer.java index 81a1d70f..2dffdc8b 100644 --- a/engine/core/src/main/java/com/codingame/gameengine/core/AbstractPlayer.java +++ b/engine/core/src/main/java/com/codingame/gameengine/core/AbstractPlayer.java @@ -28,10 +28,14 @@ public static class TimeoutException extends Exception { private List inputs = new ArrayList<>(); private List outputs; private boolean timeout; + private int timelimit; private int score; private boolean hasBeenExecuted; private boolean hasNeverBeenExecuted = true; private long lastExecutionTimeMs = -1; + private int timelimitsExceeded = 0; + private boolean timelimitExceededLastTurn = false; + private final int MAX_SOFT_TIMELIMIT_EXCEEDS = 2; /** * Returns a string that will be converted into the real nickname by the viewer. @@ -79,6 +83,10 @@ void setScore(int score) { this.score = score; } + void setTimelimit(int timelimit) { + this.timelimit = timelimit; + } + /** * Adds a new line to the input to send to the player on execute. * @@ -102,6 +110,9 @@ public final void execute() { gameManagerProvider.get().execute(this); this.hasBeenExecuted = true; this.hasNeverBeenExecuted = false; + this.timelimitExceededLastTurn = getLastExectionTimeMs() > this.timelimit; + if (this.timelimitExceededLastTurn) this.timelimitsExceeded++; + if (this.timelimitsExceeded > MAX_SOFT_TIMELIMIT_EXCEEDS) this.timeout = true; } /** @@ -183,4 +194,12 @@ final public void setLastExecutionTimeMs(long ms) { public long getLastExectionTimeMs() { return lastExecutionTimeMs; } + + public int getTimelimitsExceeded() { + return timelimitsExceeded; + } + + public boolean hasTimelimitExceededLastTurn() { + return timelimitExceededLastTurn; + } } diff --git a/engine/core/src/main/java/com/codingame/gameengine/core/GameManager.java b/engine/core/src/main/java/com/codingame/gameengine/core/GameManager.java index 619da988..7a8fc067 100644 --- a/engine/core/src/main/java/com/codingame/gameengine/core/GameManager.java +++ b/engine/core/src/main/java/com/codingame/gameengine/core/GameManager.java @@ -39,6 +39,7 @@ abstract public class GameManager { private static final int GAME_DURATION_SOFT_QUOTA = 25_000; private static final int MAX_TURN_TIME = GAME_DURATION_SOFT_QUOTA; private static final int MIN_TURN_TIME = 50; + private static final int SOFT_TIMELIMIT_EXTRA = 50; protected List players; private int maxTurns = 200; @@ -196,7 +197,9 @@ protected void execute(T player, int nbrOutputLines) { if (nbrOutputLines > 0) { addTurnTime(); } - dumpNextPlayerInfos(player.getIndex(), nbrOutputLines, player.hasNeverBeenExecuted() ? firstTurnMaxTime : turnMaxTime); + int timelimit = player.hasNeverBeenExecuted() ? firstTurnMaxTime : turnMaxTime; + player.setTimelimit(timelimit); + dumpNextPlayerInfos(player.getIndex(), nbrOutputLines, timelimit + SOFT_TIMELIMIT_EXTRA); // READ PLAYER OUTPUTS iCmd = InputCommand.parse(s.nextLine());