Skip to content

Commit

Permalink
Merge branch 'main' into enhancement/78-implement-main-menu-view
Browse files Browse the repository at this point in the history
  • Loading branch information
tommyah authored May 12, 2026
2 parents 7c4d022 + 238beff commit 7fba2e0
Show file tree
Hide file tree
Showing 45 changed files with 1,082 additions and 266 deletions.
29 changes: 29 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@
<version>6.0.1</version>
<scope>test</scope>
</dependency>

<!-- JavaFX testing -->
<dependency>
<groupId>org.testfx</groupId>
<artifactId>testfx-junit5</artifactId>
<version>4.0.18</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -57,6 +65,27 @@
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.12.0</version>
</plugin>

<!-- Test coverage report creation -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.14</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
22 changes: 17 additions & 5 deletions src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,22 @@
import edu.ntnu.idi.idatt2003.g40.mappe.view.playgame.PlayGameView;
import edu.ntnu.idi.idatt2003.g40.mappe.view.settings.SettingsController;
import edu.ntnu.idi.idatt2003.g40.mappe.view.settings.SettingsView;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
import javafx.stage.Stage;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
* Main class.
*
* <p>Extends {@link Application}</p>
*
* <p>Initializes the application through the javafx framework.</p>
* */
public class Main extends Application {

static void main() {
Expand All @@ -37,11 +44,15 @@ static void main() {
}
}

/**
* {@inheritDoc}
* */
@Override
public void start(final Stage stage) throws Exception {
Scene scene = new Scene(new Pane());
scene.getStylesheets()
.add(Objects.requireNonNull(getClass().getResource("/styles.css")).toExternalForm());
.add(Objects.requireNonNull(getClass().getResource("/styles.css")).toExternalForm());
Font.loadFont(getClass().getResourceAsStream("/Fonts/Aptos.ttf"), 16);
stage.setScene(scene);
stage.setWidth(ConfigValues.VIEWPORT_WIDTH.getValue());
stage.setHeight(ConfigValues.VIEWPORT_HEIGHT.getValue());
Expand All @@ -61,6 +72,7 @@ public void start(final Stage stage) throws Exception {
SaveGameService saveGameService = new SaveGameService();
playGameView.setSaves(saveGameService.loadSaves());


// Settings
SettingsView settingsView = new SettingsView();
new SettingsController(settingsView, eventManager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import edu.ntnu.idi.idatt2003.g40.mappe.model.Player;
import edu.ntnu.idi.idatt2003.g40.mappe.model.PlayerStatus;

import java.math.BigDecimal;

/**
* Controls and calculates the players' status.
*
Expand All @@ -20,38 +18,22 @@ private PlayerStatusController() {
*
* <p>Calculates what status the player should get
* based on players' net worth compared to starting
* money, and current week.</p>
* money.</p>
*
* @param player the player to give a status to.
*
* @return a PlayerStatus
* */
public static PlayerStatus getStatus(final Player player) {
Integer startingMoneyInt = player.getStartingMoney().intValue();

BigDecimal difference =
player.getNetWorth().subtract(player.getStartingMoney());

return switch ((Integer) difference.intValue()) {
case Integer val when val >= percentAmount(startingMoneyInt, 900) -> PlayerStatus.OMNIPOTENT;
case Integer val when val >= percentAmount(startingMoneyInt, 400) -> PlayerStatus.SEER;
case Integer val when val >= percentAmount(startingMoneyInt, 200) -> PlayerStatus.PRO;
case Integer val when val >= percentAmount(startingMoneyInt, 100) -> PlayerStatus.TRYHARD;
case Integer val when val >= percentAmount(startingMoneyInt, 50) -> PlayerStatus.GOOD;
case Integer val when val >= percentAmount(startingMoneyInt, 20) -> PlayerStatus.NOVICE;
default -> PlayerStatus.NOOB;
};
}
float differenceInPercent = ((player.getNetWorth().floatValue()
/ player.getStartingMoney().floatValue()) - 1) * 100;

/**
* Helper method for increasing a value by x percent.
*
* @param value the value to calculate from
* @param x the percent amount
*
* @return the increased value.
* */
private static Integer percentAmount(final Integer value, final Integer x) {
return (value * x) / 100;
for (int i = PlayerStatus.values().length; i > 0; i--) {
PlayerStatus curStatus = PlayerStatus.values()[i - 1];
if (differenceInPercent >= curStatus.getPercentIncreaseNeeded()) {
return curStatus;
}
}
return PlayerStatus.NOOB;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Contains classes that control certain aspects of the application,
* such as the
* {@link edu.ntnu.idi.idatt2003.g40.mappe.controller.PlayerStatusController}.
* */
package edu.ntnu.idi.idatt2003.g40.mappe.controller;
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package edu.ntnu.idi.idatt2003.g40.mappe.engine;

import edu.ntnu.idi.idatt2003.g40.mappe.model.Player;
import edu.ntnu.idi.idatt2003.g40.mappe.model.Purchase;
import edu.ntnu.idi.idatt2003.g40.mappe.model.Sale;
import edu.ntnu.idi.idatt2003.g40.mappe.model.Share;
import edu.ntnu.idi.idatt2003.g40.mappe.model.Player;
import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock;
import edu.ntnu.idi.idatt2003.g40.mappe.model.Transaction;
import edu.ntnu.idi.idatt2003.g40.mappe.service.PurchaseCalculator;
import edu.ntnu.idi.idatt2003.g40.mappe.service.SaleCalculator;
import edu.ntnu.idi.idatt2003.g40.mappe.service.TransactionCalculator;
import edu.ntnu.idi.idatt2003.g40.mappe.utils.Validator;

import java.math.BigDecimal;
import java.util.ArrayList;
Expand Down Expand Up @@ -56,13 +57,17 @@ public final class Exchange {
*
* @param name name of exchange.
* @param stocks list of {@link Stock} objects.
*
* @throws IllegalArgumentException if name or stocks are empty/null.
* */
public Exchange(final String name, final List<Stock> stocks) {
public Exchange(final String name, final List<Stock> stocks) throws IllegalArgumentException {
if (!Validator.NOT_EMPTY.isValid(name) || stocks == null || stocks.isEmpty()) {
throw new IllegalArgumentException("Invalid exchange parameters!");
}
this.name = name;
this.week = 1;
this.stockMap = new HashMap<>();
this.random = new Random();

for (Stock stock : stocks) {
stockMap.put(stock.getSymbol(), stock);
}
Expand Down Expand Up @@ -103,8 +108,14 @@ public boolean hasStock(final String symbol) {
* @param symbol the symbol of the stock to get.
*
* @return {@link Stock} element gotten.
*
* @throws IllegalArgumentException if symbol is invalid.
* */
public Stock getStock(final String symbol) {
public Stock getStock(final String symbol) throws IllegalArgumentException {
if (!Validator.VALID_STOCK_NAME.isValid(symbol)) {
throw new IllegalArgumentException(
Validator.VALID_STOCK_NAME.getErrorMessage());
}
return stockMap.get(symbol);
}

Expand Down Expand Up @@ -136,10 +147,15 @@ public List<Stock> findStocks(final String searchTerm) {
* @param player the player buying stock.
*
* @return Transaction representing the transaction.
*
* @throws IllegalArgumentException if symbol or player is invalid.
* */
public Transaction buy(final String symbol,
final BigDecimal quantity,
final Player player) {
final Player player) throws IllegalArgumentException {
if (!Validator.VALID_STOCK_NAME.isValid(symbol) || player == null) {
throw new IllegalArgumentException("Invalid purchase!");
}
Stock stock = stockMap.get(symbol);
Share share = new Share(stock, quantity, stock.getSalesPrice());
TransactionCalculator calculator = new PurchaseCalculator(share);
Expand All @@ -154,8 +170,14 @@ public Transaction buy(final String symbol,
* @param player the player buying stock.
*
* @return Transaction representing the transaction.
*
* @throws IllegalArgumentException if share or player is null.
* */
public Transaction sell(final Share share, final Player player) {
public Transaction sell(final Share share, final Player player)
throws IllegalArgumentException {
if (share == null || player == null) {
throw new IllegalArgumentException("Invalid sell!");
}
TransactionCalculator calculator = new SaleCalculator(share);
player.addMoney(calculator.calculateTotal());
return new Sale(share, week, calculator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import edu.ntnu.idi.idatt2003.g40.mappe.model.Purchase;
import edu.ntnu.idi.idatt2003.g40.mappe.model.Sale;
import edu.ntnu.idi.idatt2003.g40.mappe.model.Transaction;

import java.util.ArrayList;
import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* Contains classes giving a high level control of the application,
* such as {@link edu.ntnu.idi.idatt2003.g40.mappe.engine.Exchange}.
* */
package edu.ntnu.idi.idatt2003.g40.mappe.engine;
25 changes: 21 additions & 4 deletions src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Player.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package edu.ntnu.idi.idatt2003.g40.mappe.model;

import edu.ntnu.idi.idatt2003.g40.mappe.engine.Exchange;
import edu.ntnu.idi.idatt2003.g40.mappe.controller.PlayerStatusController;
import edu.ntnu.idi.idatt2003.g40.mappe.engine.TransactionArchive;

import edu.ntnu.idi.idatt2003.g40.mappe.utils.Validator;
import java.math.BigDecimal;

/**
Expand All @@ -11,7 +11,8 @@
* <p>Each player:</p>
* <ul>
* <li>Has a portfolio</li>
* <li>Can buy and sell shares on an {@link Exchange}</li>
* <li>Can buy and sell shares on an
* {@link edu.ntnu.idi.idatt2003.g40.mappe.engine.Exchange}.</li>
* <li>Has a set amount of money to use on said exchange.</li>
* <li>Has a {@link TransactionArchive}</li>
* </ul>
Expand Down Expand Up @@ -49,8 +50,13 @@ public final class Player {
*
* @param name the name of the player
* @param startingMoney the starting amount of money
*
* @throws IllegalArgumentException if name is null.
*/
public Player(final String name, final BigDecimal startingMoney) {
public Player(final String name, final BigDecimal startingMoney) throws IllegalArgumentException {
if (!Validator.NOT_EMPTY.isValid(name)) {
throw new IllegalArgumentException("Invalid name!");
}
this.name = name;
this.startingMoney = startingMoney;
this.money = this.startingMoney;
Expand Down Expand Up @@ -132,4 +138,15 @@ public BigDecimal getNetWorth() {
netWorth = netWorth.add(portfolio.getNetWorth()).add(money);
return netWorth;
}

/**
* Getter method for players' current status.
*
* <p>Leaves calculations for the {@link PlayerStatusController}</p>
*
* @return PlayerStatus.
* */
public PlayerStatus getStatus() {
return PlayerStatusController.getStatus(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,56 @@
public enum PlayerStatus {

/** Status representing a beginner. */
NOOB,
NOOB(0),

/**
* Status representing a player who has increased
* their net worth by at least 20 percent. */
NOVICE,
NOVICE(20),

/**
* Status representing a player who has increased
* their net worth by at least 50 percent. */
GOOD,
GOOD(50),

/** Status representing a player who has at least doubled their net worth. */
TRYHARD,
TRYHARD(100),

/** Status representing a player who has at least tripled their net worth. */
PRO,
PRO(200),

/**
* Status representing a player who has at least quintupled their
* net worth. */
SEER,
SEER(400),

/**
* Status representing a player who has at least dectupled their
* net worth. */
OMNIPOTENT;
OMNIPOTENT(900);

/**
* Value representing percent increase
* from starting money needed to get the respective status.
* */
private final int percentIncreaseNeeded;

/**
* Constructor.
*
* @param percentIncreaseNeeded the increase needed to get the status.
* */
PlayerStatus(final int percentIncreaseNeeded) {
this.percentIncreaseNeeded = percentIncreaseNeeded;
}

/**
* Getter method for percentincrease needed.
*
* @return percentIncreaseNeeded.
* */
public int getPercentIncreaseNeeded() {
return percentIncreaseNeeded;
}
}

Loading

0 comments on commit 7fba2e0

Please sign in to comment.