Extract more referee to the view
[troll.git] / src / main / java / com / codingame / game / Model.java
1 package com.codingame.game;
2
3 import java.util.Random;
4
5 import com.codingame.gameengine.core.MultiplayerGameManager;
6 import com.google.inject.Inject;
7
8 class Model {
9     @Inject private MultiplayerGameManager<com.codingame.game.Player> gameManager;
10     Random random;
11     int roadLength;
12     int initialStones;
13     int trollPosition;
14     Player p0, p1;
15
16     class Player {
17         com.codingame.game.Player gp;
18         int index;
19
20         Player(int i) { index = i; }
21
22         private int castlePosition;
23         public int getCastlePosition() { return castlePosition; }
24         public void setCastlePosition(int pos) { castlePosition = pos; }
25
26         private int multiplier;
27         public int getMultiplier() { return multiplier; }
28         public void setMultiplier(int m) { multiplier = m; }
29
30         class FailedToThrowStonesAndShouldHave extends Exception {}
31         class ThrewMoreStonesThanHad extends Exception {}
32
33         private int stones;
34         public int getStones() { return stones; }
35         public void consumeStones(int n)
36             throws ThrewMoreStonesThanHad,
37                    FailedToThrowStonesAndShouldHave
38         {
39             if (n > stones) {
40                 throw new ThrewMoreStonesThanHad();
41             }
42             if (n == 0 && stones > 0) {
43                 throw new FailedToThrowStonesAndShouldHave();
44             }
45             setStones(stones - n);
46         }
47         public int consumeMaxStones() {
48             int r = stones;
49             stones = 0;
50             return r;
51         }
52         public int consumeMinStones() {
53             if (stones < 1) {
54                 throw new Error("Internal error: tried to consume min stones on an empty heap.");
55             }
56             stones--;
57             return 1;
58         }
59         public void setStones(int n) {
60             stones = n;
61         }
62         public int getOppStones() {
63             return p0.stones + p1.stones - stones;
64         }
65
66         public void adjustScore(int trollPosition) {
67             gp.setScore(Math.abs(castlePosition - trollPosition));
68         }
69
70         public int getTrollDistance() {
71             return Math.abs(castlePosition - trollPosition);
72         }
73     }
74
75     void init(long seed) {
76         random = new Random(seed);
77         switch (random.nextInt(4)) {
78         case 0:
79             roadLength = 6;
80             initialStones = 15;
81             break;
82         case 1:
83             roadLength = 6;
84             initialStones = 30;
85             break;
86         case 2:
87             roadLength = 14;
88             initialStones = 30;
89             break;
90         case 3:
91             roadLength = 14;
92             initialStones = 50;
93             break;
94         }
95
96         trollPosition = roadLength / 2;
97
98         p0 = new Player(0);
99         p0.gp = gameManager.getPlayer(0);
100         p0.setCastlePosition(0);
101         p0.setMultiplier(1);
102         p0.adjustScore(trollPosition);
103         p0.setStones(initialStones);
104
105         p1 = new Player(1);
106         p1.gp = gameManager.getPlayer(1);
107         p1.setCastlePosition(roadLength);
108         p1.setMultiplier(-1);
109         p1.adjustScore(trollPosition);
110         p1.setStones(initialStones);
111     }
112
113     private int winner;
114     boolean haveWinner() {
115         if (trollPosition == 0) {
116             winner = 1;
117             return true;
118         }
119         else if (trollPosition == roadLength) {
120             winner = 0;
121             return true;
122         }
123         else {
124             return false;
125         }
126     }
127     int getWinner() { return winner; }
128     int getLoser() { return 1 - winner; }
129
130     boolean exhausted() {
131         return p0.getStones() <= 0 && p1.getStones() <= 0;
132     }
133 }