1 package com.codingame.game;
3 import java.util.ArrayList;
4 import java.util.Collections;
6 import java.util.Random;
8 import com.codingame.gameengine.core.AbstractPlayer.TimeoutException;
9 import com.codingame.gameengine.core.AbstractReferee;
10 import com.codingame.gameengine.core.GameManager;
11 import com.codingame.gameengine.core.MultiplayerGameManager;
12 import com.codingame.gameengine.module.entities.GraphicEntityModule;
13 import com.codingame.gameengine.module.entities.Rectangle;
14 import com.codingame.gameengine.module.entities.Sprite;
15 import com.codingame.gameengine.module.entities.Text;
16 import com.codingame.gameengine.module.entities.Curve;
17 import com.google.inject.Inject;
18 import com.google.inject.Provider;
20 public class Referee extends AbstractReferee {
21 @Inject private MultiplayerGameManager<Player> gameManager;
22 @Inject private GraphicEntityModule graphicEntityModule;
24 @Inject private View view;
25 @Inject private Model model;
29 model.init(gameManager.getSeed());
30 gameManager.getPlayer(0).model = model.p0;
31 gameManager.getPlayer(1).model = model.p1;
33 for (Player p: gameManager.getPlayers()) {
34 p.gameInit(model.roadLength, model.initialStones);
38 gameManager.getPlayer(0).view = view.p0;
39 gameManager.getPlayer(1).view = view.p1;
40 gameManager.setFrameDuration(2000);
44 public void gameTurn(int turn) {
45 // System.err.println("Starting turn " + turn);
49 for (Player player : gameManager.getActivePlayers()) {
50 player.sendGameTurn();
52 // SDK @#%^&! arbitrary sequence point: last input < first output
54 /* Parse player actions and decide basic disqualifications.
55 * Display their optional message right now: if their action
56 * is ill-formed it could help them debug. Or shame them, at
59 boolean disqual = false;
60 for (Player player : gameManager.getActivePlayers()) {
61 player.receiveGameTurn();
62 switch (player.type) {
64 gameManager.addToGameSummary(player.getNicknameToken() + " timed out!");
65 player.deactivate(player.getNicknameToken() + " T/O");
70 player.deactivate(player.getNicknameToken() + " INVALID");
71 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " provided an ill-formed action"));
76 try { player.model.consumeStones(player.stoneThrow); }
77 catch (Model.Player.ThrewMoreStonesThanHad e) {
78 if (model.random.nextInt(10) > 0) {
79 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " tried to throw more stones than they had. I'll let it slide for this time. (But not let them throw that much!)"));
80 player.stoneThrow = player.model.consumeMaxStones();
83 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " tried to throw more stones than they had. They went into debt trying to provide. The economy tanked, recession and famine ensued; even the troll wouldn't have wanted to bash them anymore. But that's no victory."));
84 player.deactivate(player.getNicknameToken() + " ILLEGAL");
89 catch (Model.Player.FailedToThrowStonesAndShouldHave e) {
90 if (model.random.nextInt(10) > 0) {
91 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " tried not throwing any stones. Fixing that for them because I'm in a good mood today."));
92 player.stoneThrow = player.model.consumeMinStones();
95 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + "tried not throwing any stones. They were then eaten by a grue."));
96 player.deactivate(player.getNicknameToken() + " ILLEGAL");
103 player.view.displayMessage(player.messageString);
106 /* Update game model and view.
108 * As a special case, the "cheater" (sending out negative
109 * stones) handling is deferred here because we need to update
110 * its view for it to be funny. In the end, they're still
113 * Gather other game end scenarios (actual victory or stone
117 boolean victory = false;
118 boolean exhausted = false;
120 for (Player player : gameManager.getActivePlayers()) {
121 gameManager.addToGameSummary(String.format("%s throws %d stone%s at the troll.", player.getNicknameToken(), player.stoneThrow, player.stoneThrow == 1 ? "" : "s"));
122 delta += player.model.getMultiplier() * player.stoneThrow;
124 if (player.stoneThrow < 0) {
125 player.deactivate(player.getNicknameToken() + " CHEAT");
126 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " cheated. Banning account."));
130 else if (player.stoneThrow > 0) {
131 player.view.animateStones(player.stoneThrow);
132 player.view.updateStoneCounter();
136 /* If a player cheated, delta is unusable as is.
137 * (Consider the case the player on the right sent
138 * INT_MIN. INT_MIN * (-1) = INT_MIN, so that player
139 * would both glean the stones *and* push the troll away.
140 * It would be unfair to have a cheating player "win"
141 * (earn the opponent castle destruction animation) this
144 boolean cheat0 = gameManager.getPlayer(0).stoneThrow < 0;
145 boolean cheat1 = gameManager.getPlayer(1).stoneThrow < 0;
146 if (cheat0 && cheat1); // here we can actually keep delta's value
147 else if (cheat0) delta = -1;
148 else if (cheat1) delta = 1;
151 gameManager.addToGameSummary("Troll walks right.");
152 model.trollPosition++;
154 else if (delta < 0) {
155 gameManager.addToGameSummary("Troll walks left.");
156 model.trollPosition--;
159 gameManager.addToGameSummary("Troll stands still.");
164 for (Player player : gameManager.getActivePlayers()) {
165 player.model.adjustScore(model.trollPosition);
168 if (model.haveWinner()) {
169 int loser = model.getLoser();
170 gameManager.addToGameSummary(GameManager.formatErrorMessage("Troll destroys " + gameManager.getPlayer(loser).getNicknameToken()) + ".");
173 else if (model.exhausted()) exhausted = true;
176 if (disqual || victory || exhausted) endGame();
179 private void endGame() {
180 gameManager.endGame();
182 Player p0 = gameManager.getPlayer(0);
183 Player p1 = gameManager.getPlayer(1);
185 int s0 = p0.getScore();
186 int s1 = p1.getScore();
189 gameManager.addToGameSummary(GameManager.formatSuccessMessage(p0.getNicknameToken() + " wins."));
193 gameManager.addToGameSummary(GameManager.formatSuccessMessage(p1.getNicknameToken() + " wins."));
197 gameManager.addToGameSummary(GameManager.formatErrorMessage("Everybody loses!"));
202 gameManager.addToGameSummary("Draw.");