Skip to content

Commit

Permalink
Merge pull request #146 from einaskoi/per/merge
Browse files Browse the repository at this point in the history
Per/merge
  • Loading branch information
peretr authored May 25, 2026
2 parents 5655ee7 + 8bae994 commit 1a14ad5
Show file tree
Hide file tree
Showing 25 changed files with 879 additions and 638 deletions.
8 changes: 8 additions & 0 deletions src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Launcher.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
package edu.ntnu.idi.idatt2003.gruppe42;

/**
* Main class for launching the application.
*/
public class Launcher {
/**
* Launches the application.
*
* @param args command-line arguments
*/
public static void main(String[] args) {
Millions.launch(Millions.class, args);
}
Expand Down
6 changes: 2 additions & 4 deletions src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Millions.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import edu.ntnu.idi.idatt2003.gruppe42.model.Player;
import edu.ntnu.idi.idatt2003.gruppe42.view.views.DesktopView;
import edu.ntnu.idi.idatt2003.gruppe42.view.views.StartView;

import java.io.InputStream;
import javafx.application.Application;
import javafx.scene.Scene;
Expand Down Expand Up @@ -68,7 +67,8 @@ public void start(final Stage stage) {
* @param popupsController controller managing popups
*/
public void initGame(final String username, final Difficulty difficulty,
InputStream stocksStream, PopupsController popupsController) {
InputStream stocksStream, PopupsController popupsController)
throws Exception {
player = GameFactory.createPlayer(username, difficulty);
gameController = new GameController();

Expand All @@ -77,8 +77,6 @@ public void initGame(final String username, final Difficulty difficulty,
desktopViewController.setOnGameOver(this::resetGame);
desktopView = desktopViewController.getDesktopView();
scene.setRoot(desktopView.getRoot());

gameController.startGame();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void setGameState(final GameState gameState) {
public void startGame() {
timer = new Timer(true);
final int delay = 0;
final int period = 100;
final int period = 1000;

timer.scheduleAtFixedRate(new TimerTask() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import edu.ntnu.idi.idatt2003.gruppe42.model.exceptions.StockFileParseException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -78,11 +79,16 @@ public void nextTick() {
public void startMarket() {
for (Stock stock : exchange.getAllStocks()) {
StockController controller = stockControllers.get(stock.getSymbol());
if (controller != null) {
for (int i = 0; i < STOCK_RESOLUTION; i++) {
stock.addNewSalesPrice(controller.updatePrice());
}
if (controller == null) {
continue;
}

for (int i = 0; i < STOCK_RESOLUTION; i++) {
stock.addNewSalesPrice(controller.updatePrice());
}

stock.reverseHistory();
controller.syncPrice();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,11 @@ public BigDecimal getPrice() {
return price;
}

/**
* Resets the internal price to match the stock's current sales price after history manipulation.
*/
public void syncPrice() {
this.price = stock.getSalesPrice();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
* Controller responsible for managing in-game time, days, weeks, and weather.
*/
public class TimeAndWeatherController implements AppController {
private final IntegerProperty hour = new SimpleIntegerProperty(HOURS_PER_DAY - 1);
private final IntegerProperty dayIndex = new SimpleIntegerProperty(SATURDAY_INDEX);
private final IntegerProperty hour = new SimpleIntegerProperty(0);
private final IntegerProperty dayIndex = new SimpleIntegerProperty(0);
private final IntegerProperty weekNumber = new SimpleIntegerProperty(0);
private final IntegerProperty temperature = new SimpleIntegerProperty(15);
private final StringProperty weather = new SimpleStringProperty("Sunny");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package edu.ntnu.idi.idatt2003.gruppe42.controller.appcontrollers;

import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;

/**
* Renders formatted tutorial chapter text into a VBox content area.
*/
public record HustlersContentRenderer(VBox contentBody) {

private static final String ACCENT = "#a0720a";
private static final String ACCENT_DIM = "#c9a84c";
private static final String TEXT_PRIMARY = "#1a1a1a";

/**
* Creates a renderer targeting the given content body.
*
* @param contentBody the VBox to render content into
*/
public HustlersContentRenderer {
}

/**
* Clears the content body and renders the given raw text.
*
* @param rawText the chapter body text to render
*/
public void render(final String rawText) {
contentBody.getChildren().clear();
for (String para : rawText.split("\n\n")) {
para = para.trim();
if (para.isEmpty()) {
continue;
}

if (isSectionHeader(para)) {
renderSectionHeader(para);
} else {
renderParagraph(para);
}
}
}

private void renderSectionHeader(final String text) {
Region divider = new Region();
divider.setPrefHeight(1);
divider.setMaxWidth(32);
divider.setStyle("-fx-background-color: " + ACCENT_DIM + ";");
VBox.setMargin(divider, new Insets(4, 0, 5, 0));

Label header = new Label(text);
header.setStyle(
"-fx-text-fill: " + ACCENT + ";"
+ "-fx-font-size: 10px;"
+ "-fx-font-weight: bold;"
+ "-fx-font-family: 'Georgia';"
);
contentBody.getChildren().addAll(divider, header);
}

private void renderParagraph(final String para) {
TextFlow flow = new TextFlow();
flow.setLineSpacing(3);
String[] lines = para.split("\n");
for (int i = 0; i < lines.length; i++) {
Text t = new Text((i > 0 ? "\n" : "") + lines[i]);
t.setStyle("-fx-fill: " + TEXT_PRIMARY + ";");
t.setFont(Font.font("Georgia", 12.5));
flow.getChildren().add(t);
}
contentBody.getChildren().add(flow);
}

private boolean isSectionHeader(final String text) {
String stripped = text.replaceAll("[^a-zA-Z]", "");
return !stripped.isEmpty() && stripped.equals(stripped.toUpperCase()) && text.length() < 60;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import edu.ntnu.idi.idatt2003.gruppe42.model.StockFileHandler;
import edu.ntnu.idi.idatt2003.gruppe42.view.apps.SettingsApp;
import edu.ntnu.idi.idatt2003.gruppe42.view.apps.SettingsApp.GradientConfig;

import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -30,6 +29,11 @@ public class SettingsAppController implements AppController {

private final SettingsApp settingsApp;

/**
* Constructor for the SettingsAppController.
*
* @param settingsApp the SettingsApp instance to control
*/
public SettingsAppController(
final SettingsApp settingsApp) {

Expand Down Expand Up @@ -144,6 +148,11 @@ private void wireLoggedInControls() {
});
}

/**
* Sets the logged-in status of the SettingsApp.
*
* @param status the new logged-in status
*/
public void setLoggedIn(boolean status) {
settingsApp.setLoggedIn(status);
wireControls();
Expand All @@ -159,6 +168,11 @@ private boolean isValidStockFile(Path path) {
}
}

/**
* Returns stock file.
*
* @return the selected stock file as an InputStream, or null if no file is selected
*/
public InputStream getSelectedStockStream() {
if (userSelectedPath == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,9 @@ private void handleSell(final Stock stock, final BigDecimal quantity) {
transaction.commit(player);
player.updateStatus();
} catch (Exception e) {
LOGGER.log(System.Logger.Level.WARNING, "Unexpected error during sell transaction", e);
LOGGER.log(
System.Logger.Level.WARNING,
"Unexpected error during sell transaction", e);
}
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package edu.ntnu.idi.idatt2003.gruppe42.controller.viewcontrollers;

import edu.ntnu.idi.idatt2003.gruppe42.controller.PopupsController;
import edu.ntnu.idi.idatt2003.gruppe42.controller.TimeAndWeatherController;
import edu.ntnu.idi.idatt2003.gruppe42.controller.appcontrollers.StockAppController;
import edu.ntnu.idi.idatt2003.gruppe42.model.App;
import edu.ntnu.idi.idatt2003.gruppe42.model.Player;
import edu.ntnu.idi.idatt2003.gruppe42.view.views.DesktopView;
import javafx.application.Platform;

/**
* Responsible for binding UI components and listeners to game state in the desktop view.
*/
public record DesktopBindings(DesktopView desktopView, Player player,
TimeAndWeatherController timeAndWeatherController,
StockAppController stockAppController,
PopupsController popupsController,
DesktopDialogController dialogController,
Runnable onAdvanceWeek) {

private static final int SATURDAY_INDEX = 6;
private static final int SUNDAY_INDEX = 0;

/**
* Creates a new DesktopBindings instance.
*
* @param desktopView the desktop view
* @param player the player model
* @param timeAndWeatherController the time and weather controller
* @param stockAppController the stock app controller
* @param popupsController the popups controller
* @param dialogController the dialog controller
* @param onAdvanceWeek callback to advance the week
*/
public DesktopBindings {

}

/**
* Binds all UI components and listeners.
*/
public void setup() {
setupDesktopUi();
setupListeners();
syncInitialState();
}

private void setupDesktopUi() {
desktopView.getNextWeekButton().setOnAction(event -> handleAdvanceWeek());
desktopView.getSettingsButton().setOnAction(event -> popupsController.show(App.SETTINGS));

timeAndWeatherController.dayIndexProperty().addListener((obs, oldDay, newDay) -> {
int day = newDay.intValue();
boolean isWeekend = day == SATURDAY_INDEX || day == SUNDAY_INDEX;
Platform.runLater(() -> stockAppController.setWeekend(isWeekend));
if (day == SATURDAY_INDEX) {
Platform.runLater(dialogController::showWeekendRapport);
}
});
}

private void setupListeners() {
timeAndWeatherController.hourProperty().addListener((obs, ov, nv) -> {
desktopView.updateClock(timeAndWeatherController.getTimeString());
player.updateStatus();
});

timeAndWeatherController.dayIndexProperty().addListener((obs, ov, nv) -> {
String dayName = timeAndWeatherController.getDayOfWeekString();
desktopView.updateDay(dayName, dayName.equals("SUN"));
});

timeAndWeatherController.weekIndexProperty().addListener((obs, ov, nv) ->
desktopView.updateWeek(timeAndWeatherController.getWeekString()));

timeAndWeatherController.weatherProperty().addListener((obs, ov, nv) ->
desktopView.updateWeather(nv));

timeAndWeatherController.temperatureProperty().addListener((obs, ov, nv) ->
desktopView.updateTemperature(String.valueOf(nv)));

player.addNameListener(name ->
Platform.runLater(() -> desktopView.updatePlayerName(name)));

player.updateStatus();
player.addStatusListener(s ->
Platform.runLater(() -> desktopView.updatePlayerStatus(s.name())));
}

private void syncInitialState() {
desktopView.updateClock(timeAndWeatherController.getTimeString());
String startDay = timeAndWeatherController.getDayOfWeekString();
desktopView.updateDay(startDay, startDay.equals("SUN"));
desktopView.updateWeek(timeAndWeatherController.getWeekString());
desktopView.updateWeather(timeAndWeatherController.weatherProperty().get());
desktopView.updateTemperature(
String.valueOf(timeAndWeatherController.temperatureProperty().get()));
desktopView.updatePlayerName(player.getName());
}

private void handleAdvanceWeek() {
if (player.isInDebt()) {
dialogController.showDebtWarning();
} else {
onAdvanceWeek.run();
}
}
}
Loading

0 comments on commit 1a14ad5

Please sign in to comment.