@@ -130,6 +130,15 @@ public static StateAction withOccupantRemoved(GameState gameState, Occupant occu
130
130
return new StateAction (gameState .withOccupantRemoved (occupant ), Base32 .encodeBits5 (indexToEncode ));
131
131
}
132
132
133
+ private static <T > T getIndexOrThrows (List <T > list , int index ) throws IllegalActionException {
134
+ if (list .size () < index ) throw new IllegalActionException ();
135
+ return list .get (index );
136
+ }
137
+
138
+ private static void validateActionLength (String action , int length ) throws IllegalActionException {
139
+ if (action .length () != length ) throw new IllegalActionException ();
140
+ }
141
+
133
142
/**
134
143
* Decode and apply the given action encoded in Base32 to the given game state,
135
144
* throwing an IllegalActionException if the action is invalid.
@@ -142,52 +151,47 @@ public static StateAction withOccupantRemoved(GameState gameState, Occupant occu
142
151
*/
143
152
private static StateAction decodeAndApplyWithException (GameState gameState , String action )
144
153
throws IllegalActionException {
145
- Preconditions . checkValidAction ( Base32 .isValid (action ));
154
+ if (! Base32 .isValid (action )) throw new IllegalActionException ( );
146
155
// we decode the parameters of the given action differently
147
156
// depending on the next action of the initial game state
148
157
return switch (gameState .nextAction ()) {
149
158
case PLACE_TILE -> { //
150
- Preconditions . checkValidAction (action . length () == WITH_PLACED_TILE_ACTION_LENGTH );
159
+ validateActionLength (action , WITH_PLACED_TILE_ACTION_LENGTH );
151
160
int decoded = Base32 .decode (action );
152
161
int tileInFringeIdx = decoded >> WITH_PLACED_TILE_IDX_SHIFT ;
153
162
int rotationIdx = decoded & WITH_PLACED_TILE_ROTATION_MASK ;
154
- List <Pos > fringeIndexes = fringeIndexes (gameState );
155
- Preconditions .checkValidAction (fringeIndexes .size () > tileInFringeIdx );
156
- Pos pos = fringeIndexes .get (tileInFringeIdx );
163
+ Pos pos = getIndexOrThrows (fringeIndexes (gameState ), tileInFringeIdx );
157
164
Tile tile = gameState .tileToPlace ();
158
165
PlacedTile placedTile = new PlacedTile (
159
- tile , gameState .currentPlayer (), Rotation .ALL .get (rotationIdx ), pos
166
+ tile , gameState .currentPlayer (), Rotation .ALL .get (rotationIdx ), pos
160
167
);
161
- Preconditions . checkValidAction ( gameState .board ().canAddTile (placedTile ));
168
+ if (! gameState .board ().canAddTile (placedTile )) throw new IllegalActionException ( );
162
169
yield new StateAction (gameState .withPlacedTile (placedTile ), action );
163
170
}
164
171
case OCCUPY_TILE -> {
165
- Preconditions . checkValidAction (action . length () == WITH_NEW_OCCUPANT_ACTION_LENGTH );
172
+ validateActionLength (action , WITH_NEW_OCCUPANT_ACTION_LENGTH );
166
173
int decoded = Base32 .decode (action );
167
174
if (decoded == WITH_NO_OCCUPANT ) yield new StateAction (gameState .withNewOccupant (null ), action );
168
175
int kindIdx = decoded >> WITH_NEW_OCCUPANT_KIND_SHIFT ;
169
176
int localId = decoded & WITH_NEW_OCCUPANT_ZONE_MASK ;
170
177
Occupant .Kind kind = Occupant .Kind .ALL .get (kindIdx );
171
178
Occupant occupant = gameState .lastTilePotentialOccupants ().stream ()
172
- .filter (occ -> occ .kind () == kind && Zone .localId (occ .zoneId ()) == localId )
173
- .findFirst ()
174
- .orElseThrow (IllegalActionException ::new );
179
+ .filter (occ -> occ .kind () == kind && Zone .localId (occ .zoneId ()) == localId )
180
+ .findFirst ()
181
+ .orElseThrow (IllegalActionException ::new );
175
182
yield new StateAction (gameState .withNewOccupant (occupant ), action );
176
183
}
177
184
case RETAKE_PAWN -> {
178
- Preconditions . checkValidAction (action . length () == WITH_OCCUPANT_REMOVED_ACTION_LENGTH );
185
+ validateActionLength (action , WITH_OCCUPANT_REMOVED_ACTION_LENGTH );
179
186
int decoded = Base32 .decode (action );
180
187
if (decoded == WITH_NO_OCCUPANT ) yield new StateAction (gameState .withOccupantRemoved (null ), action );
181
- List <Occupant > occupants = gameState .board ().occupants ()
182
- .stream ()
183
- .sorted (Comparator .comparingInt (Occupant ::zoneId ))
184
- .toList ();
185
- Preconditions .checkValidAction (occupants .size () > decoded );
186
- Occupant occupant = occupants .get (decoded );
187
- Preconditions .checkValidAction (occupant .kind () == Occupant .Kind .PAWN );
188
+ List <Occupant > occupants = gameState .board ().occupants ().stream ()
189
+ .sorted (Comparator .comparingInt (Occupant ::zoneId )).toList ();
190
+ Occupant occupant = getIndexOrThrows (occupants , decoded );
191
+ if (occupant .kind () != Occupant .Kind .PAWN ) throw new IllegalActionException ();
188
192
PlayerColor currentPlayer = gameState .currentPlayer ();
189
193
PlayerColor occupantPlacer = gameState .board ().tileWithId (Zone .tileId (occupant .zoneId ())).placer ();
190
- Preconditions . checkValidAction (currentPlayer == occupantPlacer );
194
+ if (currentPlayer != occupantPlacer ) throw new IllegalActionException ( );
191
195
yield new StateAction (gameState .withOccupantRemoved (occupant ), action );
192
196
}
193
197
default -> throw new IllegalActionException ();
0 commit comments