Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into 85-update-pubsub-model
Browse files Browse the repository at this point in the history
  • Loading branch information
tommyah committed May 11, 2026
2 parents 8335216 + ff3c59f commit 355d75f
Show file tree
Hide file tree
Showing 25 changed files with 515 additions and 204 deletions.
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
@@ -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;
}
}

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package edu.ntnu.idi.idatt2003.g40.mappe.model;

import edu.ntnu.idi.idatt2003.g40.mappe.service.SaleCalculator;
import edu.ntnu.idi.idatt2003.g40.mappe.utils.Validator;

import java.math.BigDecimal;
import java.util.ArrayList;
Expand Down Expand Up @@ -31,22 +32,33 @@ public Portfolio() {
* Adds a share to the portfolio.
*
* @param share the share to add
*
* @return {@code true} if the share was added, {@code false} otherwise
*
* @throws IllegalArgumentException if share is null.
*/
public boolean addShare(final Share share) {
Objects.requireNonNull(share, "share cannot be null");
public boolean addShare(final Share share) throws IllegalArgumentException {
if (share == null) {
throw new IllegalArgumentException("Invalid share!");
}
return shares.add(share);
}

/**
* Removes a share from the portfolio.
*
* @param share the share to remove
*
* @return {@code true} if the share was removed,
* {@code false} if it was not present.
*
* @throws IllegalArgumentException if share is null.
*
*/
public boolean removeShare(final Share share) {
Objects.requireNonNull(share, "share cannot be null");
public boolean removeShare(final Share share) throws IllegalArgumentException {
if (share == null) {
throw new IllegalArgumentException("Invalid share!");
}
return shares.remove(share);
}

Expand All @@ -65,9 +77,14 @@ public List<Share> getShares() {
*
* @param symbol the stock symbol to match
* @return a list of shares matching the symbol
*
* @throws IllegalArgumentException if symbol is invalid.
*/
public List<Share> getShares(final String symbol) {
Objects.requireNonNull(symbol, "symbol cannot be null");
public List<Share> getShares(final String symbol) throws IllegalArgumentException {
if (!Validator.VALID_STOCK_NAME.isValid(symbol)) {
throw new IllegalArgumentException(
Validator.VALID_STOCK_NAME.getErrorMessage());
}
return shares.stream()
.filter(s -> symbol.equalsIgnoreCase(s.getStock().getSymbol()))
.toList();
Expand All @@ -77,11 +94,16 @@ public List<Share> getShares(final String symbol) {
* Checks whether the given share exists in the portfolio.
*
* @param share the share to check
*
* @return {@code true} if the portfolio
* contains the share, otherwise {@code false}
*
* @throws IllegalArgumentException if share is null.
*/
public boolean contains(final Share share) {
Objects.requireNonNull(share, "share cannot be null");
public boolean contains(final Share share) throws IllegalArgumentException {
if (share == null) {
throw new IllegalArgumentException("Invalid share!");
}
return shares.contains(share);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,15 @@ public final class Share {
* @param stock the stock that was purchased
* @param quantity the quantity purchased
* @param purchasePrice the price per unit at purchase time
*
* @throws IllegalArgumentException if stock is null.
*/
public Share(final Stock stock,
final BigDecimal quantity,
final BigDecimal purchasePrice) {
final BigDecimal purchasePrice) throws IllegalArgumentException {
if (stock == null) {
throw new IllegalArgumentException("Invalid stock!");
}
this.stock = stock;
this.quantity = quantity;
this.purchasePrice = purchasePrice;
Expand Down
Loading

0 comments on commit 355d75f

Please sign in to comment.