diff options
-rw-r--r-- | src/ch/epfl/xblast/Cell.java | 12 | ||||
-rw-r--r-- | src/ch/epfl/xblast/SubCell.java | 21 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/Board.java | 8 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/GameState.java | 382 | ||||
-rw-r--r-- | test/ch/epfl/xblast/namecheck/NameCheck05.java | 31 |
5 files changed, 428 insertions, 26 deletions
diff --git a/src/ch/epfl/xblast/Cell.java b/src/ch/epfl/xblast/Cell.java index d31a889..06dfdbb 100644 --- a/src/ch/epfl/xblast/Cell.java +++ b/src/ch/epfl/xblast/Cell.java | |||
@@ -171,7 +171,17 @@ public final class Cell { | |||
171 | if (that == null) return false; | 171 | if (that == null) return false; |
172 | if (that == this) return true; | 172 | if (that == this) return true; |
173 | if (!(that instanceof Cell)) return false; | 173 | if (!(that instanceof Cell)) return false; |
174 | return (((Cell) that).x == this.x && ((Cell) that).y == this.y); | 174 | return (((Cell) that).rowMajorIndex() == this.rowMajorIndex()); |
175 | } | ||
176 | |||
177 | /** | ||
178 | * Returns the hash code for this Cell, given by its row-major index. | ||
179 | * | ||
180 | * @return the hash code | ||
181 | */ | ||
182 | @Override | ||
183 | public int hashCode() { | ||
184 | return this.rowMajorIndex(); | ||
175 | } | 185 | } |
176 | 186 | ||
177 | /** | 187 | /** |
diff --git a/src/ch/epfl/xblast/SubCell.java b/src/ch/epfl/xblast/SubCell.java index a95e65e..27d5bcc 100644 --- a/src/ch/epfl/xblast/SubCell.java +++ b/src/ch/epfl/xblast/SubCell.java | |||
@@ -133,7 +133,17 @@ public final class SubCell { | |||
133 | if (that == null) return false; | 133 | if (that == null) return false; |
134 | if (that == this) return true; | 134 | if (that == this) return true; |
135 | if (!(that instanceof SubCell)) return false; | 135 | if (!(that instanceof SubCell)) return false; |
136 | return (((SubCell) that).x == this.x && ((SubCell) that).y == this.y); | 136 | return (((SubCell) that).rowMajorIndex() == this.rowMajorIndex()); |
137 | } | ||
138 | |||
139 | /** | ||
140 | * Returns the hash code of this SubCell, given by its row-major index. | ||
141 | * | ||
142 | * @return the hash code | ||
143 | */ | ||
144 | @Override | ||
145 | public int hashCode() { | ||
146 | return this.rowMajorIndex(); | ||
137 | } | 147 | } |
138 | 148 | ||
139 | /** | 149 | /** |
@@ -146,4 +156,13 @@ public final class SubCell { | |||
146 | return String.format("(%d,%d)", this.x, this.y); | 156 | return String.format("(%d,%d)", this.x, this.y); |
147 | } | 157 | } |
148 | 158 | ||
159 | /** | ||
160 | * Returns the index of the SubCell (major ordered). | ||
161 | * | ||
162 | * @return the index of the SubCell | ||
163 | */ | ||
164 | private int rowMajorIndex() { | ||
165 | return this.y * SUB_COLUMNS + this.x; | ||
166 | } | ||
167 | |||
149 | } | 168 | } |
diff --git a/src/ch/epfl/xblast/server/Board.java b/src/ch/epfl/xblast/server/Board.java index 18ee532..f2a3c89 100644 --- a/src/ch/epfl/xblast/server/Board.java +++ b/src/ch/epfl/xblast/server/Board.java | |||
@@ -142,4 +142,12 @@ public final class Board { | |||
142 | return this.blocksAt(c).head(); | 142 | return this.blocksAt(c).head(); |
143 | } | 143 | } |
144 | 144 | ||
145 | /** | ||
146 | * Return the blocks of the Board. | ||
147 | * | ||
148 | * @return a list of the Sequences of blocks of the board. | ||
149 | */ | ||
150 | public List<Sq<Block>> getBlocks() { | ||
151 | return blocks; | ||
152 | } | ||
145 | } | 153 | } |
diff --git a/src/ch/epfl/xblast/server/GameState.java b/src/ch/epfl/xblast/server/GameState.java index ef792b6..1abe17a 100644 --- a/src/ch/epfl/xblast/server/GameState.java +++ b/src/ch/epfl/xblast/server/GameState.java | |||
@@ -1,14 +1,10 @@ | |||
1 | package ch.epfl.xblast.server; | 1 | package ch.epfl.xblast.server; |
2 | 2 | ||
3 | import ch.epfl.cs108.Sq; | 3 | import ch.epfl.cs108.Sq; |
4 | import ch.epfl.xblast.ArgumentChecker; | 4 | import ch.epfl.xblast.*; |
5 | import ch.epfl.xblast.Cell; | 5 | |
6 | import ch.epfl.xblast.PlayerID; | 6 | import java.util.*; |
7 | 7 | import java.util.function.Function; | |
8 | import java.util.ArrayList; | ||
9 | import java.util.List; | ||
10 | import java.util.Objects; | ||
11 | import java.util.Optional; | ||
12 | import java.util.stream.Collectors; | 8 | import java.util.stream.Collectors; |
13 | import java.util.stream.Stream; | 9 | import java.util.stream.Stream; |
14 | 10 | ||
@@ -20,33 +16,209 @@ import java.util.stream.Stream; | |||
20 | */ | 16 | */ |
21 | public final class GameState { | 17 | public final class GameState { |
22 | 18 | ||
23 | private final int ticks; | 19 | /** |
24 | private final Board board; | 20 | * The list of player priority order permutations. |
25 | private final List<Player> players; | 21 | */ |
26 | private final List<Bomb> bombs; | 22 | private static final List<List<PlayerID>> PLAYER_PRIORITY_ORDERS = GameState.buildPlayerPriorityOrderList(); |
27 | private final List<Sq<Sq<Cell>>> explosions; | 23 | |
28 | private final List<Sq<Cell>> blasts; | 24 | /** |
25 | * The list of bonuses to choose randomly from. | ||
26 | */ | ||
27 | private static final Block[] RANDOM_BONUSES = new Block[]{Block.BONUS_BOMB, Block.BONUS_RANGE, Block.FREE}; | ||
28 | |||
29 | /** | ||
30 | * The seed used for random value generation. | ||
31 | * Constant between executions to make tests reproducible. | ||
32 | */ | ||
33 | private static final int RANDOM_SEED = 2016; | ||
34 | |||
35 | /** | ||
36 | * Pseudo-random source for randomized behaviours. | ||
37 | */ | ||
38 | private static final Random RANDOM_SOURCE = new Random(GameState.RANDOM_SEED); | ||
29 | 39 | ||
30 | /** | 40 | /** |
31 | * Compute the next state of a blast. | 41 | * Builds and returns the player priority order permutations. |
32 | * | 42 | * |
33 | * @param blasts existing particles | 43 | * @return the list of player priority orders |
34 | * @param board the game's board | 44 | */ |
35 | * @param explosions active explosions | 45 | private static List<List<PlayerID>> buildPlayerPriorityOrderList() { |
46 | return Lists.permutations(Arrays.asList(PlayerID.values())); | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * Returns a randomly chosen bonus Block with an equal probability distribution. | ||
51 | * | ||
52 | * @return a random bonus block | ||
53 | */ | ||
54 | private static Block randomBonus() { | ||
55 | int randomIndex = RANDOM_SOURCE.nextInt(GameState.RANDOM_BONUSES.length); | ||
56 | return GameState.RANDOM_BONUSES[randomIndex]; | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Filters the given list of players and returns the lively ones. | ||
61 | * | ||
62 | * @param players a list of players | ||
63 | * @return the list of alive players | ||
64 | */ | ||
65 | private static List<Player> alivePlayers(List<Player> players) { | ||
66 | return players.stream() | ||
67 | .filter(Player::isAlive) | ||
68 | .collect(Collectors.toList()); | ||
69 | } | ||
70 | |||
71 | /** | ||
72 | * Maps the given bombs to their position. | ||
73 | * | ||
74 | * @param bombs a list of bombs | ||
75 | * @return a map of positions and their bombs | ||
76 | */ | ||
77 | private static Map<Cell, Bomb> bombedCells(List<Bomb> bombs) { | ||
78 | return bombs.stream() | ||
79 | .collect(Collectors.toMap(Bomb::position, Function.identity())); | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * Returns a set of cells that contains at least one blast in the given blasts sequences. | ||
84 | * | ||
85 | * @param blasts the list of blast sequences | ||
86 | * @return the set of blasted cells | ||
87 | */ | ||
88 | private static Set<Cell> blastedCells(List<Sq<Cell>> blasts) { | ||
89 | return blasts.stream() | ||
90 | .map(Sq::head) | ||
91 | .collect(Collectors.toSet()); | ||
92 | } | ||
93 | |||
94 | /** | ||
95 | * Computes the next state of a blast. | ||
96 | * | ||
97 | * @param blasts0 existing particles | ||
98 | * @param board0 the game's board | ||
99 | * @param explosions0 active explosions | ||
36 | * @return the position of the explosion's particles for the next state. | 100 | * @return the position of the explosion's particles for the next state. |
37 | */ | 101 | */ |
38 | private static List<Sq<Cell>> nextBlasts(List<Sq<Cell>> blasts, Board board, List<Sq<Sq<Cell>>> explosions) { | 102 | private static List<Sq<Cell>> nextBlasts(List<Sq<Cell>> blasts0, Board board0, List<Sq<Sq<Cell>>> explosions0) { |
39 | return Stream.concat( | 103 | return Stream.concat( |
40 | blasts.stream() | 104 | blasts0.stream() |
41 | .filter(blastSeq -> !blastSeq.tail().isEmpty()) | 105 | .filter(blastSeq -> !blastSeq.tail().isEmpty()) |
42 | .filter(blastSeq -> board.blockAt(blastSeq.head()).isFree()) | 106 | .filter(blastSeq -> board0.blockAt(blastSeq.head()).isFree()) |
43 | .map(Sq::tail), | 107 | .map(Sq::tail), |
44 | explosions.stream() | 108 | explosions0.stream() |
45 | .map(Sq::head) | 109 | .map(Sq::head) |
46 | ).collect(Collectors.toList()); | 110 | ).collect(Collectors.toList()); |
47 | } | 111 | } |
48 | 112 | ||
49 | /** | 113 | /** |
114 | * Computes and returns the next board state of the given board according to the given events. | ||
115 | * | ||
116 | * @param board0 the previous board | ||
117 | * @param consumedBonuses the set of consumed bonuses | ||
118 | * @param blastedCells1 the set of newly blasted cells | ||
119 | * @return the next board | ||
120 | */ | ||
121 | private static Board nextBoard(Board board0, Set<Cell> consumedBonuses, Set<Cell> blastedCells1) { | ||
122 | List<Sq<Block>> blocks0 = board0.getBlocks(); | ||
123 | List<Sq<Block>> blocks1 = new ArrayList<>(); | ||
124 | |||
125 | int i = 0; | ||
126 | for (Sq<Block> blockSq : blocks0) { | ||