From 411c0b36ec2ab7f9a447cede24d3236d2b7b5b1c Mon Sep 17 00:00:00 2001
From: EspenTinius
Date: Wed, 27 May 2026 00:11:40 +0200
Subject: [PATCH 1/2] 10 desimaler
---
.../edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java
index bfeaad4..16da1ea 100644
--- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java
+++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java
@@ -331,8 +331,11 @@ public void advance() {
stock.setFortune(0);
BigDecimal factor = BigDecimal.ONE.add(change);
+ // Keep full simulation precision at 10 decimals. The UI is free
+ // to round for display, but the underlying numbers stay accurate
+ // so the chart and net-worth do not drift over many weeks.
BigDecimal newPrice = currentPrice.multiply(factor)
- .setScale(2, java.math.RoundingMode.HALF_UP);
+ .setScale(10, java.math.RoundingMode.HALF_UP);
stock.addNewSalesPrice(newPrice);
}
week.set(week.get() + 1);
From a52a8519f51c506eb2635d3c988c8880b12d56c2 Mon Sep 17 00:00:00 2001
From: EspenTinius
Date: Wed, 27 May 2026 00:16:56 +0200
Subject: [PATCH 2/2] s
---
.../idatt2003/g40/mappe/engine/Exchange.java | 199 +++++++++---------
1 file changed, 101 insertions(+), 98 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java
index 16da1ea..c4d5dcd 100644
--- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java
+++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java
@@ -19,51 +19,57 @@
/**
* Represents a stock exchange where stocks can be traded.
*
- * Holds a map of {@link Stock} objects where stock symbol is key and
- * stock is value.
+ *
+ * Holds a map of {@link Stock} objects where stock symbol is key and
+ * stock is value.
+ *
*
- * Delegates buying and selling to player elements using calculators
+ *
+ * Delegates buying and selling to player elements using calculators
+ *
*
- * Additionally controls the time in weeks, and therefore has the main
- * responsibility for advancing weeks.
+ *
+ * Additionally controls the time in weeks, and therefore has the main
+ * responsibility for advancing weeks.
+ *
*
* @see Player
* @see edu.ntnu.idi.idatt2003.g40.mappe.service.TransactionCalculator
*
* @version 1.1.0
- * */
+ */
public final class Exchange {
/**
* Exchange name.
- * */
+ */
private final String name;
/**
* Current week (set to 1 in constructor).
- * */
+ */
private final ReadOnlyIntegerWrapper week = new ReadOnlyIntegerWrapper(1);
/**
* Map of {@link Stock} objects. Key is stock symbol. Value is stock.
- * */
+ */
private final Map stockMap;
/**
* Random value determining week changes.
- * */
+ */
private final Random random;
/**
* Constructor.
*
- * @param name name of exchange.
- * @param stocks list of {@link Stock} objects.
+ * @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 stocks)
- throws IllegalArgumentException {
+ throws IllegalArgumentException {
if (!Validator.NOT_EMPTY.isValid(name)
|| stocks == null
|| stocks.isEmpty()) {
@@ -81,7 +87,7 @@ public Exchange(final String name, final List stocks)
* Getter method for name.
*
* @return name of exchange.
- * */
+ */
public String getName() {
return name;
}
@@ -90,7 +96,7 @@ public String getName() {
* Getter method for current week.
*
* @return week.
- * */
+ */
public int getWeek() {
return week.get();
}
@@ -99,7 +105,7 @@ public int getWeek() {
* Getter method for the {@link ReadOnlyIntegerProperty} object of week.
*
* @return week.
- * */
+ */
public ReadOnlyIntegerProperty weekProperty() {
return week.getReadOnlyProperty();
}
@@ -117,7 +123,7 @@ public ReadOnlyIntegerProperty weekProperty() {
* @param newWeek the value to set the week to.
*
* @throws IllegalArgumentException if newWeek is below 1.
- * */
+ */
public void setWeek(final int newWeek) throws IllegalArgumentException {
if (newWeek < 1) {
throw new IllegalArgumentException("Week must be at least 1!");
@@ -140,7 +146,7 @@ public void setWeek(final int newWeek) throws IllegalArgumentException {
* @param baselinePrices map of symbol to the price to seed with.
* Symbols that aren't on this exchange are
* skipped.
- * */
+ */
public void resetStocksTo(final Map baselinePrices) {
if (baselinePrices == null) {
return;
@@ -158,8 +164,8 @@ public void resetStocksTo(final Map baselinePrices) {
*
* @param symbol the stock symbol.
*
- * @return true or false.
- * */
+ * @return true or false.
+ */
public boolean hasStock(final String symbol) {
return stockMap.containsKey(symbol);
}
@@ -168,7 +174,7 @@ public boolean hasStock(final String symbol) {
* Getter method for all stocks in exchange.
*
* @return List of stocks.
- * */
+ */
public List getStocks() {
return List.copyOf(this.stockMap.values());
}
@@ -176,18 +182,18 @@ public List getStocks() {
/**
* Getter method for stock element.
*
- * @param symbol the symbol of the stock to get.
+ * @param symbol the symbol of the stock to get.
*
- * @return {@link Stock} element gotten.
+ * @return {@link Stock} element gotten.
*
* @throws IllegalArgumentException if symbol is invalid or not in exchange.
- * */
+ */
public Stock getStock(final String symbol)
- throws IllegalArgumentException {
+ throws IllegalArgumentException {
if (!Validator.VALID_STOCK_SYMBOL.isValid(symbol)
|| !stockMap.containsKey(symbol)) {
throw new IllegalArgumentException(
- Validator.VALID_STOCK_SYMBOL.getErrorMessage());
+ Validator.VALID_STOCK_SYMBOL.getErrorMessage());
}
return stockMap.get(symbol);
}
@@ -197,14 +203,14 @@ public Stock getStock(final String symbol)
*
* @param searchTerm the term to search for.
*
- * @return a list of {@link Stock} objects.
- * */
+ * @return a list of {@link Stock} objects.
+ */
public List findStocks(final String searchTerm) {
List result = new ArrayList<>();
for (Stock stock : stockMap.values()) {
if (stock.getSymbol().toLowerCase()
- .contains(searchTerm.toLowerCase())
- || stock.getCompany().toLowerCase()
+ .contains(searchTerm.toLowerCase())
+ || stock.getCompany().toLowerCase()
.contains(searchTerm.toLowerCase())) {
result.add(stock);
}
@@ -215,17 +221,17 @@ public List findStocks(final String searchTerm) {
/**
* Method called when a player buys a stock.
*
- * @param symbol the stock this player buys.
- * @param quantity the amount of stock to buy.
- * @param player the player buying stock.
+ * @param symbol the stock this player buys.
+ * @param quantity the amount of stock to buy.
+ * @param player the player buying stock.
*
- * @return Transaction representing the transaction.
+ * @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) throws IllegalArgumentException {
+ final BigDecimal quantity,
+ final Player player) throws IllegalArgumentException {
if (!Validator.VALID_STOCK_SYMBOL.isValid(symbol)
|| quantity == null
|| player == null) {
@@ -234,8 +240,7 @@ public Transaction buy(final String symbol,
Stock stock = getStock(symbol);
Share share = new Share(stock, quantity, stock.getSalesPrice());
Transaction purchase = TransactionFactory.createTransaction(
- TransactionType.PURCHASE, share, getWeek()
- );
+ TransactionType.PURCHASE, share, getWeek());
player.handleTransaction(purchase);
return purchase;
}
@@ -243,21 +248,20 @@ TransactionType.PURCHASE, share, getWeek()
/**
* Method called when a player sells share.
*
- * @param share the share to sell.
- * @param player the player buying stock.
+ * @param share the share to sell.
+ * @param player the player buying stock.
*
- * @return Transaction representing the transaction.
+ * @return Transaction representing the transaction.
*
* @throws IllegalArgumentException if share or player is null.
- * */
+ */
public Transaction sell(final Share share, final Player player)
- throws IllegalArgumentException {
+ throws IllegalArgumentException {
if (share == null || player == null) {
throw new IllegalArgumentException("Invalid sell!");
}
Transaction sale = TransactionFactory.createTransaction(
- TransactionType.SALE, share, getWeek()
- );
+ TransactionType.SALE, share, getWeek());
player.handleTransaction(sale);
return sale;
}
@@ -266,26 +270,28 @@ TransactionType.SALE, share, getWeek()
* Method called when a player sells share,
* defined by an amount instead of specific {@link Share} object.
*
- * {@link edu.ntnu.idi.idatt2003.g40.mappe.model.Portfolio}
+ *
+ * {@link edu.ntnu.idi.idatt2003.g40.mappe.model.Portfolio}
+ *
*
* @param amount the amount of "shares" to sell.
* @param stockSymbol the stock to sell shares in.
* @param player the player buying stock.
*
- * @return List of transactions commited to sell the shares.
+ * @return List of transactions commited to sell the shares.
*
* @throws IllegalArgumentException if any parameter is null,
* or if player does not have enough shares,
* or if player does not own any shares
* of the given stock.
- * */
+ */
public Transaction sell(BigDecimal amount,
- final String stockSymbol,
- final Player player)
- throws IllegalArgumentException {
+ final String stockSymbol,
+ final Player player)
+ throws IllegalArgumentException {
if (amount == null
- || player == null
- || !Validator.VALID_STOCK_SYMBOL.isValid(stockSymbol)) {
+ || player == null
+ || !Validator.VALID_STOCK_SYMBOL.isValid(stockSymbol)) {
throw new IllegalArgumentException("Invalid sell parameters!");
}
@@ -306,8 +312,7 @@ public Transaction sell(BigDecimal amount,
Share shareToSell = new Share(stock, amount, stock.getSalesPrice());
Transaction sale = TransactionFactory.createTransaction(
- TransactionType.SALE, shareToSell, getWeek()
- );
+ TransactionType.SALE, shareToSell, getWeek());
player.handleTransaction(sale);
return sale;
@@ -316,26 +321,26 @@ TransactionType.SALE, shareToSell, getWeek()
/**
* Method for advancing time, increasing the amount of weeks.
*
- * Applies a random price change from -5% to 5% to every stock,
+ *
+ * Applies a random price change from -5% to 5% to every stock,
* plus a flat percent determined by their fortune, that can range from
- * -10% to +10%.
+ * -10% to +10%.
+ *
*
* @see edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.minigames.GameEngineView
- * */
+ */
public void advance() {
for (Stock stock : stockMap.values()) {
BigDecimal currentPrice = stock.getSalesPrice();
BigDecimal change = BigDecimal.valueOf(random.nextDouble() * 0.10 - 0.05)
- .add(BigDecimal.valueOf(stock.getFortune()));
+ .add(BigDecimal.valueOf(stock.getFortune()));
stock.setFortune(0);
BigDecimal factor = BigDecimal.ONE.add(change);
- // Keep full simulation precision at 10 decimals. The UI is free
- // to round for display, but the underlying numbers stay accurate
- // so the chart and net-worth do not drift over many weeks.
+ // Keep full simulation precision at 10 decimals.
BigDecimal newPrice = currentPrice.multiply(factor)
- .setScale(10, java.math.RoundingMode.HALF_UP);
+ .setScale(10, java.math.RoundingMode.HALF_UP);
stock.addNewSalesPrice(newPrice);
}
week.set(week.get() + 1);
@@ -345,31 +350,29 @@ public void advance() {
* Method for getting the stocks with the most
* amount of increase since last week.
*
- * @param limit the maximum amount of stocks returned
+ * @param limit the maximum amount of stocks returned
*
* @return list of {@link Stock} objects.
*
* @throws IllegalArgumentException if limit is invalid (negative or zero).
- * */
+ */
public List getGainers(final int limit)
- throws IllegalArgumentException {
+ throws IllegalArgumentException {
if (limit < 1) {
throw new IllegalArgumentException("Invalid limit for getting gainers!");
}
return stockMap.entrySet().stream()
- // We only want the stocks with a positive price change.
- .filter(e ->
- e.getValue().getLatestPriceChange()
- .compareTo(BigDecimal.ZERO) > 0)
- // We sort the stocks based on the price change.
- .sorted((e1, e2) ->
- e2.getValue().getLatestPriceChange()
- .compareTo(e1.getValue().getLatestPriceChange()))
- // Sets a limit to the stream.
- .limit(limit)
- .map(Map.Entry::getValue)
- // Converts to a list
- .toList();
+ // We only want the stocks with a positive price change.
+ .filter(e -> e.getValue().getLatestPriceChange()
+ .compareTo(BigDecimal.ZERO) > 0)
+ // We sort the stocks based on the price change.
+ .sorted((e1, e2) -> e2.getValue().getLatestPriceChange()
+ .compareTo(e1.getValue().getLatestPriceChange()))
+ // Sets a limit to the stream.
+ .limit(limit)
+ .map(Map.Entry::getValue)
+ // Converts to a list
+ .toList();
}
/**
@@ -381,34 +384,34 @@ public List getGainers(final int limit)
* @return list of {@link Stock} objects.
*
* @throws IllegalArgumentException if limit is invalid (negative or zero).
- * */
+ */
public List getLosers(final int limit)
- throws IllegalArgumentException {
+ throws IllegalArgumentException {
if (limit < 1) {
throw new IllegalArgumentException("Invalid limit for getting losers!");
}
return stockMap.entrySet().stream()
- // Only get entries with negative price change.
- .filter(e ->
- e.getValue().getLatestPriceChange()
- .compareTo(BigDecimal.ZERO) < 0)
- // Sort (lowest first)
- .sorted((e1, e2) ->
- e1.getValue().getLatestPriceChange()
- .compareTo(e2.getValue().getLatestPriceChange()))
- .limit(limit)
- .map(Map.Entry::getValue)
- .toList();
+ // Only get entries with negative price change.
+ .filter(e -> e.getValue().getLatestPriceChange()
+ .compareTo(BigDecimal.ZERO) < 0)
+ // Sort (lowest first)
+ .sorted((e1, e2) -> e1.getValue().getLatestPriceChange()
+ .compareTo(e2.getValue().getLatestPriceChange()))
+ .limit(limit)
+ .map(Map.Entry::getValue)
+ .toList();
}
/**
* Replaces list of stocks with a new list.
*
- * Used when loading a save game that uses a completely different set of
- * stocks than the currently active simulation context.
+ *
+ * Used when loading a save game that uses a completely different set of
+ * stocks than the currently active simulation context.
+ *
*
- * @param newStocks the new list of {@link Stock}
- * objects to list on the exchange.
+ * @param newStocks the new list of {@link Stock}
+ * objects to list on the exchange.
* @throws IllegalArgumentException if the provided list is null or empty.
*/
public void updateStockPool(final List newStocks) throws IllegalArgumentException {