Skip to content

Commit

Permalink
Add time controls for games
Browse files Browse the repository at this point in the history
Sothatsit committed Jun 17, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 9312006 commit 9a729c4
Showing 3 changed files with 117 additions and 4 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@

<groupId>net.royalur</groupId>
<artifactId>royalur</artifactId>
<version>4.2.0-SNAPSHOT</version>
<version>4.3.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>RoyalUr</name>
39 changes: 36 additions & 3 deletions src/main/java/net/royalur/model/GameMetadata.java
Original file line number Diff line number Diff line change
@@ -30,6 +30,20 @@ public class GameMetadata {
*/
public static final String END_DATETIME_KEY = "EndTime";

/**
* The key for storing the time control of a game.
*/
public static final String TIME_CONTROL_KEY = "TimeControl";

/**
* The standard known keys that are used for game metadata.
*/
public static final String[] STANDARD_KEYS = {
START_DATETIME_KEY,
END_DATETIME_KEY,
TIME_CONTROL_KEY
};

/**
* Arbitrary metadata about a game.
*/
@@ -146,6 +160,27 @@ public void setEndTime(TemporalAccessor datetime) {
return DATETIME_FORMATTER.parse(formatted);
}

/**
* Sets the time control used for this game.
* @param timeControl The time control used for this game.
*/
public void setTimeControl(TimeControl timeControl) {
put(TIME_CONTROL_KEY, timeControl.toString());
}

/**
* Gets the time control used for this game, or {@code null} if no
* time control was included in this game's metadata.
* @return The time control used for this game, or else {@code null}.
*/
public @Nullable TimeControl getTimeControl() {
String text = get(TIME_CONTROL_KEY);
if (text == null)
return null;

return TimeControl.fromString(text);
}

@Override
public boolean equals(@Nullable Object obj) {
if (obj == null || !getClass().equals(obj.getClass()))
@@ -173,9 +208,7 @@ public void initialiseForNewGame(GameSettings settings) {
* @param settings The settings used for the game.
* @return Metadata for a new game.
*/
public static GameMetadata createForNewGame(
GameSettings settings
) {
public static GameMetadata createForNewGame(GameSettings settings) {
GameMetadata metadata = new GameMetadata();
metadata.initialiseForNewGame(settings);
return metadata;
80 changes: 80 additions & 0 deletions src/main/java/net/royalur/model/TimeControl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package net.royalur.model;

import javax.annotation.Nullable;

public class TimeControl {
public static final TimeControl NONE = new TimeControl(0);

/**
* It is important that these are ordered from longest to shortest suffix.
*/
private static final String[] SECONDS_SUFFIXES = {
" seconds", " second", "seconds", "second", " secs", " sec", "secs", "sec", " s", "s"
};

private final int perMoveSeconds;

public TimeControl(int perMoveSeconds) {
if (perMoveSeconds < 0)
throw new IllegalArgumentException("perMoveSeconds must be >= 0");

this.perMoveSeconds = perMoveSeconds;
}

public static TimeControl perMoveSeconds(int perMoveSeconds) {
return new TimeControl(perMoveSeconds);
}

public boolean hasPerMoveSeconds() {
return perMoveSeconds > 0;
}

public int getPerMoveSeconds() {
if (perMoveSeconds == 0)
throw new IllegalStateException("Time control does not have a per move time");
return perMoveSeconds;
}

@Override
public boolean equals(@Nullable Object obj) {
if (obj == this)
return true;
if (obj == null || !getClass().equals(obj.getClass()))
return false;

TimeControl other = (TimeControl) obj;
return perMoveSeconds == other.perMoveSeconds;
}

@Override
public String toString() {
if (perMoveSeconds == 0)
return "no time control";
if (perMoveSeconds == 1)
return "1 second per move";

return perMoveSeconds + " seconds per move";
}

public static int parseSeconds(String text) {
for (String suffix : SECONDS_SUFFIXES) {
if (text.endsWith(suffix)) {
String numberText = text.substring(0, text.length() - suffix.length());
return Integer.parseInt(numberText);
}
}
throw new IllegalArgumentException("Unable to recognise time duration: " + text);
}

public static TimeControl fromString(String text) {
if (text.equals("no time control"))
return NONE;

if (text.endsWith(" per move")) {
String perMoveText = text.substring(0, text.length() - " per move".length());
int perMoveSeconds = parseSeconds(perMoveText);
return new TimeControl(perMoveSeconds);
}
throw new IllegalArgumentException("Unable to recognise time control: " + text);
}
}

0 comments on commit 9a729c4

Please sign in to comment.