Skip to content

51 update various classes #73

Merged
merged 6 commits into from
Apr 8, 2026
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
281 changes: 209 additions & 72 deletions src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Exchange.java
Original file line number Diff line number Diff line change
@@ -1,81 +1,218 @@
package edu.ntnu.idi.idatt2003.g40.mappe;

import java.math.BigDecimal;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
* Represents a stock exchange where stocks can be traded.
*/
public class Exchange {

private final String name;
private int week;
private final Map<String, Stock> stockMap;
private final Random random;

public Exchange(String name, List<Stock> stocks) {
this.name = name;
this.week = 1;
this.stockMap = new HashMap<>();
this.random = new Random();

for (Stock stock : stocks) {
stockMap.put(stock.getSymbol(), stock);
}
*
* <p>Holds a map of stocks where stock symbol is key and stock is value.</p>
*
* <p>Delegates buying and selling to player elements using calculators</p>
*
* <p>Advances week.</p>
*
* @see Player
* @see TransactionCalculator
* */
public final class Exchange {

/**
* Exchange name.
* */
private final String name;

/**
* Current week (set to 1 in constructor).
* */
private int week;

/**
* Map of {@link Stock} objects. Key is stock symbol. Value is stock.
* */
private final Map<String, Stock> stockMap;

/**
* Random value determining week changes.
* */
private final Random random;

/**
* Constructor.
*
* @param name name of exchange.
* @param stocks list of {@link Stock} objects.
* */
public Exchange(final String name, final List<Stock> stocks) {
this.name = name;
this.week = 1;
this.stockMap = new HashMap<>();
this.random = new Random();

for (Stock stock : stocks) {
stockMap.put(stock.getSymbol(), stock);
}

public String getName() {
return name;
}

public int getWeek() {
return week;
}

public boolean hasStock(String symbol) {
return stockMap.containsKey(symbol);
}

public Stock getStock(String symbol) {
return stockMap.get(symbol);
}

public List<Stock> findStocks(String searchTerm) {
List<Stock> result = new ArrayList<>();
for (Stock stock : stockMap.values()) {
if (stock.getSymbol().toLowerCase().contains(searchTerm.toLowerCase())
|| stock.getCompany().toLowerCase().contains(searchTerm.toLowerCase())) {
result.add(stock);
}
}
return result;
}

/**
* Getter method for name.
*
* @return name of exchange.
* */
public String getName() {
return name;
}

/**
* Getter method for current week.
*
* @return week.
* */
public int getWeek() {
return week;
}

/**
* Method for checking whether exchange has a stock.
*
* @param symbol the stock symbol.
*
* @return true or false.
* */
public boolean hasStock(final String symbol) {
return stockMap.containsKey(symbol);
}

/**
* Getter method for stock element.
*
* @param symbol the symbol of the stock to get.
*
* @return {@link Stock} element gotten.
* */
public Stock getStock(final String symbol) {
return stockMap.get(symbol);
}

/**
* Returns a list of stocks matching a given search term.
*
* @param searchTerm the term to search for.
*
* @return a list of {@link Stock} objects.
* */
public List<Stock> findStocks(final String searchTerm) {
List<Stock> result = new ArrayList<>();
for (Stock stock : stockMap.values()) {
if (stock.getSymbol().toLowerCase()
.contains(searchTerm.toLowerCase())
|| stock.getCompany().toLowerCase()
.contains(searchTerm.toLowerCase())) {
result.add(stock);
}
}

public Transaction buy(String symbol, BigDecimal quantity, Player player) {
Stock stock = stockMap.get(symbol);
Share share = new Share(stock, quantity, stock.getSalesPrice());
TransactionCalculator calculator = new PurchaseCalculator(share);
player.withdrawMoney(calculator.calculateTotal());
return new Purchase(share, week, calculator);
}

public Transaction sell(Share share, Player player) {
TransactionCalculator calculator = new SaleCalculator(share);
player.addMoney(calculator.calculateTotal());
return new Sale(share, week, calculator);
}

public void advance() {
week++;

for (Stock stock : stockMap.values()) {
BigDecimal currentPrice = stock.getSalesPrice();

double change = (random.nextDouble() * 0.10) - 0.05;
BigDecimal factor = BigDecimal.valueOf(1 + change);

BigDecimal newPrice = currentPrice.multiply(factor);
stock.addNewSalesPrice(newPrice);
}
return result;
}

/**
* 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.
*
* @return Transaction representing the transaction.
* */
public Transaction buy(final String symbol,
final BigDecimal quantity,
final Player player) {
Stock stock = stockMap.get(symbol);
Share share = new Share(stock, quantity, stock.getSalesPrice());
TransactionCalculator calculator = new PurchaseCalculator(share);
player.withdrawMoney(calculator.calculateTotal());
return new Purchase(share, week, calculator);
}

/**
* Method called when a player sells share.
*
* @param share the share to sell.
* @param player the player buying stock.
*
* @return Transaction representing the transaction.
* */
public Transaction sell(final Share share, final Player player) {
TransactionCalculator calculator = new SaleCalculator(share);
player.addMoney(calculator.calculateTotal());
return new Sale(share, week, calculator);
}

/**
* Method for advancing time, increasing the amount of weeks.
* */
public void advance() {
week++;

for (Stock stock : stockMap.values()) {
BigDecimal currentPrice = stock.getSalesPrice();

double change = (random.nextDouble() * 0.10) - 0.05;
BigDecimal factor = BigDecimal.valueOf(1 + change);

BigDecimal newPrice = currentPrice.multiply(factor);
stock.addNewSalesPrice(newPrice);
}
}
}

/**
* Method for getting the stocks with the most
* amount of increase since last week.
*
* @param limit the maximum amount of stocks returned
*
* @return list of {@link Stock} objects.
* */
public List<Stock> getGainers(final int limit) {
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();
}

/**
* Method for getting the stocks with the highest
* loss of price since last week.
*
* @param limit the maximum amount of stocks returned
*
* @return list of {@link Stock} objects.
* */
public List<Stock> getLosers(final int limit) {
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();
}
}
Loading