Skip to content

Commit

Permalink
Merge pull request #73 from Team-40-IDATT2003/51-update-various-classes
Browse files Browse the repository at this point in the history
51 update various classes
  • Loading branch information
etsorens authored Apr 8, 2026
2 parents cb771f0 + 86b4ec2 commit 3aae11d
Show file tree
Hide file tree
Showing 22 changed files with 1,515 additions and 947 deletions.
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

0 comments on commit 3aae11d

Please sign in to comment.