package org.drooms.impl.util;
import org.drooms.api.Player;
import org.drooms.util.CommonProperties;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Properties;
/**
* Prepares the game properties by reading them from a property file.
*
* <p>
* Mandatory properties are:
* </p>
*
* <dl>
* <dt>collectibles</dt>
* <dd>Which {@link CollectibleType}s exist, as a comma-separated list. Each name in this list will then subsequently
* require properties 'collectible.expiration.$NAME', 'collectible.price.$NAME' and 'collectible.probability.$NAME'.</dd>
* </dl>
*
* <p>
* Optional properties are:
* </p>
*
* <dl>
* <dt>worm.length.start (defaults to 3)</dt>
* <dd>Length of the worm at the start of the game. Actually, initially each worm will only have a length of 1. But as
* it first moves its head, the tail of the worm will stay where the head was, until the worm reaches the specified
* starting length. From then on, the length will be kept constant and only changed upon collecting an item.</dd>
* <dt>worm.max.turns (defaults to 1000)</dt>
* <dd>Maximum length of the game, in case more than 1 worm keeps on surviving.</dd>
* <dt>worm.max.inactive.turns (defaults to 3)</dt>
* <dd>Maximum number of turns of inactivity after which a player may be terminated, if the game decides so.</dd>
* <dt>worm.timeout.seconds (defaults to 1)</dt>
* <dd>The maximum amount of time that the {@link Player}'s Strategy has to make a decision on the next movement
* of the worm. If it doesn't make it in time, STAY is enforced, potentially leading to the worm being terminated for
* inactivity.</dd>
* <dt>worm.survival.bonus (defaults to 5)</dt>
* <dd>The amount of points that the worm will be awarded upon surviving another worm.</dd>
* </dl>
*/
public class GameProperties extends CommonProperties {
public static final int FIRST_TURN_NUMBER = 1;
public static class CollectibleType {
private final int expiration;
private final String name;
private final int points;
private final BigDecimal probabilityOfAppearance;
private CollectibleType(final String name, final int expiration, final int points,
final BigDecimal probabilityOfAppearance) {
this.name = name;
this.expiration = expiration;
this.points = points;
this.probabilityOfAppearance = probabilityOfAppearance;
}
public int getExpiration() {
return this.expiration;
}
public String getName() {
return this.name;
}
public int getPoints() {
return this.points;
}
public BigDecimal getProbabilityOfAppearance() {
return this.probabilityOfAppearance;
}
}
public static GameProperties read(final InputStream is) throws IOException {
return new GameProperties(CommonProperties.loadPropertiesFromInputStream(is));
}
private final Collection<CollectibleType> collectibleTypes;
private final int deadWormBonus;
private final int maximumInactiveTurns;
private final int maximumTurns;
private final int startingWormLength;
private final int strategyTimeoutInSeconds;
private GameProperties(final Properties p) {
super(p);
this.startingWormLength = Integer.valueOf(this.getOptionalProperty("worm.length.start", "3"));
this.maximumInactiveTurns = Integer.valueOf(this.getOptionalProperty("worm.max.inactive.turns", "3"));
this.maximumTurns = Integer.valueOf(this.getOptionalProperty("worm.max.turns", "1000"));
this.deadWormBonus = Integer.valueOf(this.getOptionalProperty("worm.survival.bonus", "5"));
this.strategyTimeoutInSeconds = Integer.valueOf(this.getOptionalProperty("worm.timeout.seconds", "1"));
final Collection<CollectibleType> collectibleTypes = new ArrayList<CollectibleType>();
for (final String collectibleName : this.getMandatoryProperty("collectibles").split("\\Q,\\E")) {
final int expiration = Integer.valueOf(this.getMandatoryProperty("collectible.expiration."
+ collectibleName));
final int points = Integer.valueOf(this.getMandatoryProperty("collectible.price." + collectibleName));
final BigDecimal prob = new BigDecimal(this.getMandatoryProperty("collectible.probability."
+ collectibleName));
collectibleTypes.add(new CollectibleType(collectibleName, expiration, points, prob));
}
this.collectibleTypes = Collections.unmodifiableCollection(collectibleTypes);
}
public Collection<CollectibleType> getCollectibleTypes() {
return this.collectibleTypes;
}
public int getDeadWormBonus() {
return this.deadWormBonus;
}
public int getMaximumInactiveTurns() {
return this.maximumInactiveTurns;
}
public int getMaximumTurns() {
return this.maximumTurns;
}
public int getStartingWormLength() {
return this.startingWormLength;
}
public int getStrategyTimeoutInSeconds() {
return this.strategyTimeoutInSeconds;
}
}