Skip to content

Commit 4a4b8f4

Browse files
committed
add actions
1 parent 864da13 commit 4a4b8f4

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

src/ch/epfl/chacun/Main.java

+25-10
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ public static void main(String[] args) {
3232
launch(args);
3333
}
3434

35+
private void saveState(
36+
ActionEncoder.StateAction stateAction,
37+
SimpleObjectProperty<GameState> gameStateO,
38+
SimpleObjectProperty<List<String>> actionsO
39+
) {
40+
gameStateO.setValue(stateAction.gameState());
41+
List<String> newActions = new ArrayList<>(actionsO.getValue());
42+
newActions.add(stateAction.action());
43+
actionsO.setValue(newActions);
44+
}
45+
3546
private TileDecks getShuffledTileDecks(Long seed) {
3647
List<Tile> tiles = new ArrayList<>(Tiles.TILES);
3748
if (seed != null) {
@@ -73,7 +84,6 @@ public void start(Stage primaryStage) {
7384
tileDecks,
7485
textMaker
7586
);
76-
gameState = gameState.withStartingTilePlaced();
7787

7888
SimpleObjectProperty<GameState> gameStateO = new SimpleObjectProperty<>(gameState);
7989
ObservableValue<List<MessageBoard.Message>> observableMessagesO = gameStateO.map(
@@ -85,42 +95,44 @@ public void start(Stage primaryStage) {
8595
ObservableValue<TileDecks> tileDecksO = gameStateO.map(GameState::tileDecks);
8696
ObservableValue<Integer> leftNormalTilesO = tileDecksO.map(tDecks -> tDecks.normalTiles().size());
8797
ObservableValue<Integer> leftMenhirTilesO = tileDecksO.map(tDecks -> tDecks.menhirTiles().size());
88-
ObservableValue<String> textToDisplayO = gameStateO.map(gameState1 ->
89-
switch (gameState1.nextAction()){
98+
ObservableValue<String> textToDisplayO = gameStateO.map(gState ->
99+
switch (gState.nextAction()){
90100
case GameState.Action.OCCUPY_TILE -> textMaker.clickToOccupy();
91101
case GameState.Action.RETAKE_PAWN -> textMaker.clickToUnoccupy();
92102
default -> "";
93103
}
94104
);
95105

106+
SimpleObjectProperty<List<String>> actionsO = new SimpleObjectProperty<>(List.of());
107+
96108
Consumer<Occupant> onOccupantClick = occupant -> {
97109
// todo handle things
98110
GameState currentGameState = gameStateO.getValue();
99111
if (currentGameState.nextAction() == GameState.Action.OCCUPY_TILE) {
100112
assert currentGameState.board().lastPlacedTile() != null;
101113
int lastPlacedTileId = currentGameState.board().lastPlacedTile().id();
102114
if (occupant != null && Zone.tileId(occupant.zoneId()) != lastPlacedTileId) return;
103-
gameStateO.setValue(currentGameState.withNewOccupant(occupant));
115+
ActionEncoder.StateAction stateAction = ActionEncoder.withNewOccupant(currentGameState, occupant);
116+
saveState(stateAction, gameStateO, actionsO);
104117
}
105118
else if (currentGameState.nextAction() == GameState.Action.RETAKE_PAWN) {
106119
// todo check owner stuff etc
107-
gameStateO.setValue(currentGameState.withOccupantRemoved(occupant));
120+
ActionEncoder.StateAction stateAction = ActionEncoder.withOccupantRemoved(currentGameState, occupant);
121+
saveState(stateAction, gameStateO, actionsO);
108122
}
109123
};
110124

111-
SimpleObjectProperty<List<String>> actions = new SimpleObjectProperty<>(List.of());
112-
113125
Consumer<String> onEnteredAction = action -> {
114126
ActionEncoder.StateAction newSt = ActionEncoder.decodeAndApply(gameStateO.getValue(), action);
115127
if (newSt != null) {
116-
gameStateO.setValue(newSt.gameState());
128+
saveState(newSt, gameStateO, actionsO);
117129
}
118130
};
119131

120132
Node playersNode = PlayersUI.create(gameStateO, new TextMakerFr(playersNames));
121133
Node messagesNode = MessageBoardUI.create(observableMessagesO, highlightedTilesO);
122134
Node decksNode = DecksUI.create(tileToPlaceO, leftNormalTilesO, leftMenhirTilesO, textToDisplayO, onOccupantClick);
123-
Node actionsNode = ActionsUI.create(actions, onEnteredAction);
135+
Node actionsNode = ActionsUI.create(actionsO, onEnteredAction);
124136

125137
SimpleObjectProperty<Rotation> nextRotationO = new SimpleObjectProperty<>(Rotation.NONE);
126138
Consumer<Rotation> onRotationClick = r -> {
@@ -139,7 +151,8 @@ else if (currentGameState.nextAction() == GameState.Action.RETAKE_PAWN) {
139151
nextRotationO.getValue(),
140152
pos
141153
);
142-
gameStateO.setValue(currentGameState.withPlacedTile(placedTile));
154+
ActionEncoder.StateAction stateAction = ActionEncoder.withPlacedTile(currentGameState, placedTile);
155+
saveState(stateAction, gameStateO, actionsO);
143156
};
144157

145158
ObservableValue<Set<Occupant>> visibleOccupants = gameStateO.map(gState -> {
@@ -179,5 +192,7 @@ else if (currentGameState.nextAction() == GameState.Action.RETAKE_PAWN) {
179192
primaryStage.setTitle("ChaCuN");
180193
primaryStage.show();
181194

195+
gameStateO.setValue(gameStateO.getValue().withStartingTilePlaced());
196+
182197
}
183198
}

src/ch/epfl/chacun/gui/BoardUI.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,11 @@ public static Node create(
8787
// the fringe only exists when the next action is to place a tile
8888
ObservableValue<Set<Pos>> fringeTilesO = gameStateO.map(
8989
state -> state.nextAction() == GameState.Action.PLACE_TILE
90-
? boardO.getValue().insertionPositions()
90+
// important to understand
91+
// we can not use boardO.getValue() here!
92+
// because this map may be triggered before boardO gets updated!
93+
// therefore we would be using the old board
94+
? state.board().insertionPositions()
9195
: Set.of()
9296
);
9397

@@ -168,7 +172,7 @@ public static Node create(
168172
placedTileO.addListener((_, oldPlacedTile, placedTile) -> {
169173
if (oldPlacedTile != null || placedTile == null) return;
170174

171-
double negatedTileRotation = placedTile.rotation().negated().quarterTurnsCW();
175+
double negatedTileRotation = placedTile.rotation().negated().degreesCW();
172176

173177
// handle "jeton d'annulation", a marker that signals that an animal is cancelled
174178
placedTile.meadowZones().stream()

src/ch/epfl/chacun/gui/DecksUI.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ public static Node create(
5151

5252
// ImageView of the next tile to place, which has to be shown in large size
5353
ImageView view = new ImageView();
54-
view.setImage(ImageLoader.largeImageForTile(tileO.getValue().id()));
54+
view.imageProperty().bind(tileO.map(t ->
55+
t == null
56+
? ImageLoader.EMPTY_IMAGE
57+
: ImageLoader.largeImageForTile(t.id())));
5558
view.setFitHeight(ImageLoader.LARGE_TILE_FIT_SIZE);
5659
view.setFitWidth(ImageLoader.LARGE_TILE_FIT_SIZE);
5760
// Text, occupy tile (only visible if textToDisplay is not empty,

0 commit comments

Comments
 (0)