Skip to content

Commit

Permalink
Game logic WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Mw3y committed May 6, 2024
1 parent 0f84249 commit 2200222
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/ch/epfl/chacun/gui/BoardUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public static Node create(int reach, ObservableValue<GameState> gameStateO,
if (event.getButton() == MouseButton.SECONDARY) {
// Allow for clockwise and counter-clockwise rotation using the ALT key
Rotation rotationToAdd = event.isAltDown() ? Rotation.RIGHT : Rotation.LEFT;
rotationToApply.accept(rotationO.getValue().add(rotationToAdd));
rotationToApply.accept(rotationToAdd);
}
// Place the tile
if (event.getButton() == MouseButton.PRIMARY) {
Expand Down
127 changes: 116 additions & 11 deletions src/ch/epfl/chacun/gui/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import ch.epfl.chacun.*;
import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.Consumer;
import java.util.random.RandomGenerator;
import java.util.random.RandomGeneratorFactory;
import java.util.stream.Collectors;
Expand All @@ -19,6 +23,9 @@
*/
public class Main extends Application {

private static final int INITIAL_WIDTH = 1440;
private static final int INITIAL_HEIGHT = 1080;

public static void main(String[] args) {
launch(args);
}
Expand All @@ -27,22 +34,120 @@ public static void main(String[] args) {
public void start(Stage primaryStage) throws Exception {
Parameters params = getParameters();
List<String> playerNames = params.getUnnamed();
String rawSeed = params.getNamed().get("seed");

// Check if the number of players is valid
Preconditions.checkArgument(playerNames.size() >= 2 && playerNames.size() <= 5);
// Create the player map
List<PlayerColor> playerColors = PlayerColor.ALL.subList(0, playerNames.size());
Map<PlayerColor, String> players = new HashMap<>();
for (int i = 0; i < playerNames.size(); ++i) {
players.put(playerColors.get(i), playerNames.get(i));
}

// Apply the seed to ALL tiles
long seed = Long.parseUnsignedLong(rawSeed);
RandomGenerator shuffler = RandomGeneratorFactory.getDefault().create(seed);
String rawSeed = params.getNamed().get("seed");
RandomGeneratorFactory<RandomGenerator> defaultRandomFactory = RandomGeneratorFactory.getDefault();

RandomGenerator shuffler;
if (rawSeed != null) {
long seed = Long.parseUnsignedLong(rawSeed);
shuffler = defaultRandomFactory.create(seed);
} else {
shuffler = defaultRandomFactory.create();
}

List<Tile> tiles = new ArrayList<>(Tiles.TILES);
Collections.shuffle(tiles, shuffler);
// Group tiles by kind to create the decks
Map<Tile.Kind, List<Tile>> decks = tiles.stream().collect(Collectors.groupingBy(Tile::kind));
TileDecks tileDecks = new TileDecks(decks);

TextMaker textMaker = new TextMakerFr(Map.of());
MessageBoard messageBoard = new MessageBoard(textMaker, List.of());
GameState gameState = new GameState(PlayerColor.ALL.subList(0, playerNames.size()), tileDecks,
null, Board.EMPTY, GameState.Action.START_GAME, messageBoard);
TextMaker textMaker = new TextMakerFr(players);
GameState gameState = GameState.initial(players.keySet().stream().toList(), tileDecks, textMaker);

SimpleObjectProperty<Rotation> tileToPlaceRotationP = new SimpleObjectProperty<>(Rotation.NONE);
SimpleObjectProperty<Set<Occupant>> visibleOccupantsP = new SimpleObjectProperty<>(Set.of());
SimpleObjectProperty<Set<Integer>> highlightedTilesP = new SimpleObjectProperty<>(Set.of());
SimpleObjectProperty<String> textToDisplayP = new SimpleObjectProperty<>("");
SimpleObjectProperty<List<String>> actionsP = new SimpleObjectProperty<>(List.of());

SimpleObjectProperty<GameState> gameStateO = new SimpleObjectProperty<>(gameState);
ObservableValue<MessageBoard> messageBoardO = gameStateO.map(GameState::messageBoard);

gameStateO.set(gameState);
gameStateO.set(gameStateO.get().withStartingTilePlaced());

Consumer<Rotation> applyRotation = rotation -> {
tileToPlaceRotationP.set(tileToPlaceRotationP.get().add(rotation));
};

Consumer<Pos> placeTileAtPos = pos -> {
GameState state = gameStateO.get();
PlacedTile placedTile = new PlacedTile(
state.tileToPlace(), state.currentPlayer(), tileToPlaceRotationP.get(), pos);

if (state.board().canAddTile(placedTile)) {
ActionEncoder.StateAction stateAction = ActionEncoder.withPLacedTile(gameState, placedTile);
// Add action
List<String> actions = new ArrayList<>(actionsP.get());
actions.add(stateAction.action());
actionsP.set(actions);
// Register action
gameStateO.set(stateAction.gameState());
tileToPlaceRotationP.set(Rotation.NONE);
// Display potential occupants
Set<Occupant> occupantsToDisplay = new HashSet<>(visibleOccupantsP.get());
occupantsToDisplay.addAll(gameStateO.get().lastTilePotentialOccupants());
visibleOccupantsP.set(Set.copyOf(occupantsToDisplay));
textToDisplayP.set(textMaker.clickToOccupy());
}
};

Consumer<Occupant> selectOccupant = occupant -> {
ActionEncoder.StateAction stateAction = ActionEncoder.withNewOccupant(gameState, occupant);
// Add action
List<String> actions = new ArrayList<>(actionsP.get());
actions.add(stateAction.action());
actionsP.set(actions);
// Register action
gameStateO.set(stateAction.gameState());
// Reset properties
visibleOccupantsP.set(gameStateO.get().board().occupants());
textToDisplayP.set("");
};

Consumer<String> applyAction = action -> {
ActionEncoder.StateAction stateAction = ActionEncoder.decodeAndApply(gameStateO.get(), action);
if (stateAction != null) {
List<String> previousActions = actionsP.get();
List<String> newActions = new ArrayList<>(previousActions);
newActions.add(action);
actionsP.set(newActions);
}
};


Node boardUI = BoardUI.create(Board.REACH, gameStateO, tileToPlaceRotationP, visibleOccupantsP, highlightedTilesP, applyRotation, placeTileAtPos, selectOccupant);

Node playersUI = PlayersUI.create(gameStateO, textMaker);
Node messageBoardUI = MessageBoardUI.create(messageBoardO.map(MessageBoard::messages), highlightedTilesP);

ObservableValue<Tile> tileToPlaceO = gameStateO.map(GameState::tileToPlace);
ObservableValue<TileDecks> decksO = gameStateO.map(GameState::tileDecks);
ObservableValue<Integer> normalTilesSizeO = decksO.map(gameDecks -> gameDecks.normalTiles().size());
ObservableValue<Integer> menhirTilesSizeO = decksO.map(gameDecks -> gameDecks.menhirTiles().size());
Node decksUI = DecksUI.create(tileToPlaceO, normalTilesSizeO, menhirTilesSizeO, textToDisplayP, selectOccupant);

Node actionsUI = ActionsUI.create(actionsP, applyAction);

BorderPane sidePanel = new BorderPane(
messageBoardUI, playersUI, null, new VBox(actionsUI, decksUI), null);
Scene scene = new Scene(new BorderPane(boardUI, null, sidePanel, null, null));

primaryStage.setScene(scene);
primaryStage.setWidth(INITIAL_WIDTH);
primaryStage.setHeight(INITIAL_HEIGHT);
primaryStage.setTitle("ChaCuN");
primaryStage.show();
}
}

0 comments on commit 2200222

Please sign in to comment.