package com.codingame.game;
import java.util.Random;
+import java.util.Properties;
+
+import com.codingame.gameengine.core.GameManager;
+import com.codingame.gameengine.core.MultiplayerGameManager;
+import com.google.inject.Inject;
class Model {
+ @Inject private MultiplayerGameManager<com.codingame.game.Player> gameManager;
+ @Inject private LeagueManager league;
+ long seed;
Random random;
int roadLength;
int initialStones;
int trollPosition;
+ Player p0, p1;
+
+ class Player {
+ com.codingame.game.Player gp;
+ int index;
+ boolean hit;
+
+ Player(int i) {
+ index = i;
+ hit = false;
+ }
+
+ void loseRound() {
+ hit = true;
+ winner = 1 - index;
+ }
+
+ private int castlePosition;
+ public int getCastlePosition() { return castlePosition; }
+ public void setCastlePosition(int pos) { castlePosition = pos; }
+
+ private int multiplier;
+ public int getMultiplier() { return multiplier; }
+ public void setMultiplier(int m) { multiplier = m; }
+
+ class FailedToThrowStonesAndShouldHave extends Exception {}
+ class ThrewMoreStonesThanHad extends Exception {}
+
+ private int stones;
+ public int getStones() { return stones; }
+ public void consumeStones(int n)
+ throws ThrewMoreStonesThanHad,
+ FailedToThrowStonesAndShouldHave
+ {
+ if (n > stones) {
+ throw new ThrewMoreStonesThanHad();
+ }
+ if (n == 0 && stones > 0) {
+ throw new FailedToThrowStonesAndShouldHave();
+ }
+ setStones(stones - n);
+ }
+ public int consumeMaxStones() {
+ int r = stones;
+ stones = 0;
+ return r;
+ }
+ public int consumeMinStones() {
+ if (stones < 1) {
+ throw new Error("Internal error: tried to consume min stones on an empty heap.");
+ }
+ stones--;
+ return 1;
+ }
+ public void setStones(int n) {
+ stones = n;
+ }
+ public int getOppStones() {
+ return p0.stones + p1.stones - stones;
+ }
+
+ public void adjustScore(int trollPosition) {
+ if (gp.isActive()) {
+ gp.setScore(Math.abs(castlePosition - trollPosition));
+ }
+ }
+
+ public int getTrollDistance() {
+ return Math.abs(castlePosition - trollPosition);
+ }
+ }
+
+ void init() {
+ seed = gameManager.getSeed();
+ random = new Random(seed);
+
+ switch(league.mapLevel) {
+ case SINGLE:
+ roadLength = 6;
+ initialStones = 15;
+ break;
+ case DISCRETE:
+ int i = random.nextInt(4);
+ switch (i) {
+ case 0:
+ roadLength = 6;
+ initialStones = 15;
+ break;
+ case 1:
+ roadLength = 6;
+ initialStones = 30;
+ break;
+ case 2:
+ roadLength = 14;
+ initialStones = 30;
+ break;
+ case 3:
+ roadLength = 14;
+ initialStones = 50;
+ break;
+ }
+ break;
+ case CONTINUOUS:
+ roadLength = 2 * (3 + random.nextInt(7-3+1));
+ initialStones = 15 + random.nextInt(50-15+1);
+ break;
+ }
+
+ Properties ps = gameManager.getGameParameters();
+ String buf = ps.getProperty("roadLength");
+ if (buf != null) {
+ try {
+ int i = Integer.parseInt(buf);
+ if (i < 0 || i > 20 || (i & 1) != 0) {
+ gameManager.addToGameSummary(GameManager.formatErrorMessage("Ignoring invalid road length: " + buf));
+ }
+ else {
+ roadLength = i;
+ gameManager.addToGameSummary("Road length overridden to " + i);
+ }
+ }
+ catch(NumberFormatException e) {
+ gameManager.addToGameSummary(GameManager.formatErrorMessage("Ill-formed road length: " + buf));
+ }
+ }
+ ps.setProperty("roadLength", new Integer(roadLength).toString());
+
+ buf = ps.getProperty("initialStones");
+ if (buf != null) {
+ try {
+ int i = Integer.parseInt(buf);
+ if (i > 50) {
+ gameManager.addToGameSummary(GameManager.formatErrorMessage("Ignoring invalid initial stone count: " + buf));
+ }
+ else {
+ initialStones = i;
+ gameManager.addToGameSummary("Initial stone count overridden to " + buf);
+ }
+ }
+ catch (NumberFormatException e) {
+ gameManager.addToGameSummary(GameManager.formatErrorMessage("Ill-formed initial stone count: " + buf));
+ }
+ }
+ ps.setProperty("initialStones", new Integer(initialStones).toString());
+
+ trollPosition = roadLength / 2;
+
+ p0 = new Player(0);
+ p0.gp = gameManager.getPlayer(0);
+ p0.setCastlePosition(0);
+ p0.setMultiplier(1);
+ p0.adjustScore(trollPosition);
+ p0.setStones(initialStones);
+
+ p1 = new Player(1);
+ p1.gp = gameManager.getPlayer(1);
+ p1.setCastlePosition(roadLength);
+ p1.setMultiplier(-1);
+ p1.adjustScore(trollPosition);
+ p1.setStones(initialStones);
+ }
+
+ void moveTroll(int delta) {
+ trollPosition += delta;
+ if (trollPosition <= 0) {
+ trollPosition = 0;
+ winner = 1;
+ }
+ if (trollPosition >= roadLength) {
+ trollPosition = roadLength;
+ winner = 0;
+ }
+
+ p0.adjustScore(trollPosition);
+ p1.adjustScore(trollPosition);
+ }
+
+ private Integer winner;
+ boolean haveWinner() {
+ return winner != null;
+ }
+
+ int getWinner() { return winner; }
+ int getLoser() { return 1 - winner; }
+
+ boolean exhausted() {
+ return p0.getStones() <= 0 || p1.getStones() <= 0;
+ }
}