e6c941f0f5f65eee16a6fd0911202888dbce5a6e
[troll.git] / src / main / java / com / codingame / game / Referee.java
1 package com.codingame.game;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.List;
6 import java.util.Random;
7
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;
19
20 public class Referee extends AbstractReferee {
21     @Inject private MultiplayerGameManager<Player> gameManager;
22     @Inject private GraphicEntityModule graphicEntityModule;
23
24     @Inject private View view;
25     @Inject private Model model;
26
27     @Override
28     public void init() {
29         model.init(gameManager.getSeed());
30         gameManager.getPlayer(0).model = model.p0;
31         gameManager.getPlayer(1).model = model.p1;
32
33         for (Player p : gameManager.getPlayers()) {
34             p.sendInputLine(String.format("%d %d", model.roadLength, model.initialStones));
35         }
36
37         view.init(model);
38
39         gameManager.getPlayer(0).view = view.p0;
40         gameManager.getPlayer(1).view = view.p1;
41
42         gameManager.setFrameDuration(2000); // XXX
43     }
44
45     @Override
46     public void gameTurn(int turn) {
47         // System.err.println("Starting turn " + turn);
48
49         boolean disqual = false;
50         boolean victory = false;
51         boolean exhausted = false;
52
53         int delta = 0;
54         for (Player player : gameManager.getActivePlayers()) {
55             Model.Player p = player.model;
56             {
57                 int trollDistance = p.getTrollDistance();
58                 int stones = p.getStones();
59                 int oppStones = p.getOppStones();
60                 player.sendInputLine(String.format("%d %d %d", trollDistance, stones, oppStones));
61             }
62             player.execute();
63         }
64
65         // SDK @#%^&! arbitrary sequence point: last input < first output
66
67         for (Player player : gameManager.getActivePlayers()) {
68             Model.Player p = player.model;
69
70             try {
71                 int stones = player.getAction();
72                 if (stones == 0 && p.getStones() > 0) {
73                     if (model.random.nextInt(10) > 0) {
74                         gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " tried not throwing stones.  Fixing that for them because I'm in a good mood today."));
75                         stones = 1;
76                     }
77                     else {
78                         throw new InvalidAction("tried not throwing any stone.  They were then eaten by a grue.");
79                     }
80                 }
81                 p.consumeStones(stones);
82                 gameManager.addToGameSummary(String.format("%s throws %d stone%s at the troll.", player.getNicknameToken(), stones, stones == 1 ? "" : "s"));
83                 delta += player.model.getMultiplier() * stones;
84
85                 if (stones < 0) {
86                     player.deactivate(player.getNicknameToken() + " CHEAT");
87                     gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " cheated.  Banning account."));
88                     player.setScore(-1);
89                     disqual = true;
90                 }
91                 else if (stones > 0) {
92                     player.view.animateStones(stones);
93                     player.view.updateStoneCounter();
94                 }
95             }
96             catch (InvalidAction e) {
97                 player.deactivate(player.getNicknameToken() + " INVALID");
98                 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " " + e.getMessage()));
99                 player.setScore(-1);
100                 disqual = true;
101             }
102             catch (NumberFormatException e) {
103                 player.deactivate(player.getNicknameToken() + " ERROR");
104                 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " provided malformed input!"));
105                 player.setScore(-1);
106                 disqual = true;
107             }
108             catch (TimeoutException e) {
109                 gameManager.addToGameSummary(player.getNicknameToken() + " timed out!");
110                 player.deactivate(player.getNicknameToken() + " T/O");
111                 player.setScore(-1);
112                 disqual = true;
113             }
114
115             player.view.displayMessage(player.getMessageString());
116         }
117
118         if (! disqual) {
119             if (delta > 0) {
120                 gameManager.addToGameSummary("Troll walks right.");
121                 model.trollPosition++;
122             }
123             else if (delta < 0) {
124                 gameManager.addToGameSummary("Troll walks left.");
125                 model.trollPosition--;
126             }
127             else {
128                 gameManager.addToGameSummary("Troll stands still.");
129                 // XXX animate
130             }
131             view.moveTroll();
132
133             for (Player player : gameManager.getActivePlayers()) {
134                 player.model.adjustScore(model.trollPosition);
135             }
136
137             if (model.haveWinner()) {
138                 int winner = model.getWinner();
139                 gameManager.addToGameSummary(GameManager.formatErrorMessage("Troll destroys " + gameManager.getPlayer(winner).getNicknameToken()));
140                 victory = true;
141             }
142             else if (model.exhausted()) exhausted = true;
143         }
144
145         if (disqual || victory || exhausted) endGame();
146     }
147
148     private void endGame() {
149         gameManager.endGame();
150
151         Player p0 = gameManager.getPlayer(0);
152         Player p1 = gameManager.getPlayer(1);
153
154         int s0 = p0.getScore();
155         int s1 = p1.getScore();
156
157         if (s0 > s1) {
158             gameManager.addToGameSummary(GameManager.formatSuccessMessage(p0.getNicknameToken() + " wins"));
159             p1.view.destroy();
160         }
161         else if (s0 < s1) {
162             gameManager.addToGameSummary(GameManager.formatSuccessMessage(p1.getNicknameToken() + " wins"));
163             p0.view.destroy();
164         }
165         else if (s0 < 0) {
166             gameManager.addToGameSummary(GameManager.formatErrorMessage("Everybody loses!"));
167             p0.view.destroy();
168             p1.view.destroy();
169         }
170         else {
171             gameManager.addToGameSummary("Draw.");
172         }
173     }
174 }