X-Git-Url: https://troll.desast.re/troll.git/blobdiff_plain/424174766971a11af0e953a6d5a328d466b8f68b..ee0b3a350bf74952ace849ec105866675c91db5c:/src/main/java/com/codingame/game/Model.java diff --git a/src/main/java/com/codingame/game/Model.java b/src/main/java/com/codingame/game/Model.java index 4cd1280..beff100 100644 --- a/src/main/java/com/codingame/game/Model.java +++ b/src/main/java/com/codingame/game/Model.java @@ -1,12 +1,16 @@ 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 gameManager; + @Inject private LeagueManager league; + long seed; Random random; int roadLength; int initialStones; @@ -16,8 +20,17 @@ class Model { class Player { com.codingame.game.Player gp; int index; + boolean hit; - Player(int i) { index = i; } + Player(int i) { + index = i; + hit = false; + } + + void loseRound() { + hit = true; + winner = 1 - index; + } private int castlePosition; public int getCastlePosition() { return castlePosition; } @@ -25,16 +38,37 @@ class Model { private int multiplier; public int getMultiplier() { return multiplier; } - public void setMultiplier(int m){ multiplier = m; } + 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 InvalidAction { + public void consumeStones(int n) + throws ThrewMoreStonesThanHad, + FailedToThrowStonesAndShouldHave + { if (n > stones) { - throw new InvalidAction("attempted to throw more stones than they had."); + 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; } @@ -43,7 +77,9 @@ class Model { } public void adjustScore(int trollPosition) { - gp.setScore(Math.abs(castlePosition - trollPosition)); + if (gp.isActive()) { + gp.setScore(Math.abs(castlePosition - trollPosition)); + } } public int getTrollDistance() { @@ -51,27 +87,79 @@ class Model { } } - void init(long seed) { + void init() { + seed = gameManager.getSeed(); random = new Random(seed); - switch (random.nextInt(4)) { - case 0: + + switch(league.mapLevel) { + case SINGLE: roadLength = 6; initialStones = 15; break; - case 1: - roadLength = 6; - initialStones = 30; - break; - case 2: - roadLength = 14; - initialStones = 30; + 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 3: - roadLength = 14; - initialStones = 50; + 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); @@ -89,23 +177,38 @@ class Model { p1.setStones(initialStones); } - private int winner; - boolean haveWinner() { - if (trollPosition == 0) { + void moveTroll(int delta) { + trollPosition += delta; + if (trollPosition <= 0) { + trollPosition = 0; winner = 1; - return true; } - else if (trollPosition == roadLength) { + if (trollPosition >= roadLength) { + trollPosition = roadLength; winner = 0; - return true; } - else { - return false; + + p0.adjustScore(trollPosition); + p1.adjustScore(trollPosition); + } + + boolean FIX_IT() { + switch (league.fixLevel) { + case SOMETIMES: return random.nextInt(10) > 0; + case NEVER: return false; + default: throw new JavaLimitationError(); } } + + 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; + return p0.getStones() <= 0 || p1.getStones() <= 0; } }