Skip to content

Commit

Permalink
Merge pull request #51 from solvena/50-add-diagrams
Browse files Browse the repository at this point in the history
Added diagrams
  • Loading branch information
solvena authored May 26, 2026
2 parents d7ae460 + 03ae3b7 commit b9f4692
Show file tree
Hide file tree
Showing 4 changed files with 376 additions and 1 deletion.
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,35 @@
Wireframes: https://www.figma.com/proto/hij5HpFYSpCNvGAZTeBcZo/Stock-Trading-Game?node-id=0-1&t=FXjhcz0tGCcKHnMm-1
# Mappevurdering project IDATT2003

FIRST STUDENT NAME = "Solveig Natvig"
FIRST STUDENT ID = "10125"
SECOND STUDENT NAME = "Elisabeth Berg"
SECOND STUDENT ID = "10089"

## Project description
This project is a GUI-based game program written in Java, "Stock Trading Game". As the name implies, the game is about stock trading, and the goal is to gain the highest net worth through stocks. The player writes their name, starting money and chooses a CSV-file with different stocks to start the game. Throughout the game the player can see their own status, the best and worst stocks, and their portfolio. The player can then buy and sell shares that change value every week randomly.

## Project structure
This project uses standard Maven-structure.
The main project is located in src\main\java.
Tests are located in src\test\java.

## Link to repository
https://git.ntnu.no/solvena/Programmering2_mappe_v26

## How to run the project
Open the project in VSCode or other IDE.
You run the project via Maven by typing "mvn javafx:run" in the terminal.
A starting game scene will pop up, there you will type chosen name, starting amount and choose a CSV-file for stocks with the format "ticker,company,price".

You can exit the program by clicking "exit" then "exit game".

## How to run the tests
To run the tests, you can either:
- Use Maven: run mvn test in the project directory.
- Run tests directly from your IDE (e.g., right-click the test class and select "Run").

The test results will be displayed in the console, showing whether tests passed or failed.

## References
Wireframes:
https://www.figma.com/proto/hij5HpFYSpCNvGAZTeBcZo/Stock-Trading-Game?node-id=0-1&t=FXjhcz0tGCcKHnMm-1
38 changes: 38 additions & 0 deletions activity_diagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@startuml ActivityDiagram
!define START #90EE90
!define END #FFB6C6
!define DECISION #FFFFE6
!define ACTION #E6F2FF

title Stock Trading Game - Purchase Transaction Activity Diagram

start
:Player initiates purchase request;
:Exchange.buy() called with symbol and quantity;

if (Symbol valid and stock exists?) then (No)
:Throw IllegalArgumentException;
end
else (Yes)
:Get Stock from exchange;
:Create Share with current market price;
endif

:Create Purchase transaction;

if (Player has sufficient funds?) then (No)
:Throw IllegalStateException;
end
else (Yes)
:Deduct purchase cost from player money;
:Add share to portfolio;
:Record transaction in archive;
:Mark transaction as committed;
endif

:Exchange notifies all observers;
:UI updates with new portfolio state;

stop

@enduml
202 changes: 202 additions & 0 deletions class_diagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
@startuml ClassDiagram
!define ABSTRACT_COLOR #FFE6E6
!define INTERFACE_COLOR #E6F2FF
!define ENUM_COLOR #FFFFE6

skinparam backgroundColor #FFFFFF
skinparam classBackgroundColor #FFFFFF
skinparam classBorderColor #333333

package Model {

' Enums
enum PlayerStatus #FFFFE6 {
NOVICE
INVESTOR
SPECULATOR
--
getDisplayName(): String
}

' Interfaces
interface ExchangeObserver #E6F2FF {
onExchangeUpdated(exchange: Exchange): void
}

' Core Model Classes
class Player {
- name: String
- startingMoney: BigDecimal
- money: BigDecimal
- portfolio: Portfolio
- transactionArchive: TransactionArchive
--
+ Player(name: String, startingMoney: BigDecimal)
+ getName(): String
+ getMoney(): BigDecimal
+ addMoney(amount: BigDecimal): void
+ withdrawMoney(amount: BigDecimal): void
+ getPortfolio(): Portfolio
+ getTransactionArchive(): TransactionArchive
+ getStatus(): PlayerStatus
}

class Stock {
- symbol: String
- company: String
- prices: List<BigDecimal>
--
+ Stock(symbol: String, company: String, salesPrice: BigDecimal)
+ getSymbol(): String
+ getCompany(): String
+ getSalesPrice(): BigDecimal
+ addNewSalesPrice(price: BigDecimal): void
+ getHistoricalPrices(): List<BigDecimal>
+ getHighestPrice(): BigDecimal
+ getLowestPrice(): BigDecimal
+ getLatestPriceChange(): BigDecimal
}

class Share {
- stock: Stock
- quantity: BigDecimal
- purchasePrice: BigDecimal
--
+ Share(stock: Stock, quantity: BigDecimal, purchasePrice: BigDecimal)
+ getStock(): Stock
+ getQuantity(): BigDecimal
+ getPurchasePrice(): BigDecimal
}

class Portfolio {
- shares: List<Share>
--
+ Portfolio()
+ addShare(share: Share): boolean
+ removeShare(share: Share): boolean
+ getShares(): List<Share>
+ getShares(symbol: String): List<Share>
+ contains(share: Share): boolean
+ getNetWorth(): BigDecimal
}

class Exchange {
- name: String
- week: int
- stockMap: Map<String, Stock>
- observers: List<ExchangeObserver>
- random: Random
--
+ Exchange(name: String, stocks: List<Stock>)
+ addObserver(observer: ExchangeObserver): void
+ removeObserver(observer: ExchangeObserver): void
- notifyObservers(): void
+ getName(): String
+ getWeek(): int
+ hasStock(symbol: String): boolean
+ getStock(symbol: String): Stock
+ findStocks(searchTerm: String): List<Stock>
+ buy(symbol: String, quantity: BigDecimal, player: Player): Transaction
+ sell(share: Share, player: Player): Transaction
+ sell(originalShare: Share, sellQuantity: BigDecimal, player: Player): Transaction
+ advance(): void
+ getGainers(limit: int): List<Stock>
+ getLosers(limit: int): List<Stock>
}

' Transaction Hierarchy
abstract class Transaction #FFE6E6 {
# share: Share
# week: int
# calculator: TransactionCalculator
# committed: boolean
--
# Transaction(share: Share, week: int, calculator: TransactionCalculator)
+ getShare(): Share
+ getWeek(): int
+ getCalculator(): TransactionCalculator
+ isCommitted(): boolean
+ commit(player: Player): void {abstract}
}

class Purchase {
--
+ Purchase(share: Share, week: int)
+ commit(player: Player): void
}

class Sale {
--
+ Sale(share: Share, week: int)
+ commit(player: Player): void
}

class TransactionArchive {
- transactions: List<Transaction>
--
+ TransactionArchive()
+ add(transaction: Transaction): boolean
+ isEmpty(): boolean
+ getTransactions(week: int): List<Transaction>
+ getPurchase(week: int): List<Purchase>
+ getSale(week: int): List<Sale>
+ getAllTransactions(): List<Transaction>
+ countDistinctWeeks(): int
}

' Calculator Classes
interface TransactionCalculator #E6F2FF {
calculateTotal(): BigDecimal
}

class PurchaseCalculator {
- share: Share
--
+ PurchaseCalculator(share: Share)
+ calculateTotal(): BigDecimal
}

class SaleCalculator {
- share: Share
--
+ SaleCalculator(share: Share)
+ calculateTotal(): BigDecimal
}

class TransactionFactory {
--
+ {static} createPurchase(share: Share, week: int): Purchase
+ {static} createSale(share: Share, week: int): Sale
}

' Relationships
Player --> Portfolio : "has"
Player --> TransactionArchive : "has"
Player --> PlayerStatus : "has"

Portfolio --> Share : "contains *"

Share --> Stock : "references"

Exchange --> Stock : "manages *"
Exchange --> ExchangeObserver : "notifies *"
Exchange --> Transaction : "creates"

Transaction --> Share : "trades"
Transaction --> TransactionCalculator : "uses"

Purchase --|> Transaction : "extends"
Sale --|> Transaction : "extends"

PurchaseCalculator ..|> TransactionCalculator : "implements"
SaleCalculator ..|> TransactionCalculator : "implements"

TransactionFactory --> Purchase : "creates"
TransactionFactory --> Sale : "creates"

TransactionArchive --> Transaction : "stores *"
TransactionArchive --> Purchase : "retrieves"
TransactionArchive --> Sale : "retrieves"
}

@enduml
101 changes: 101 additions & 0 deletions sequence_diagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
@startuml SequenceDiagram
title Stock Trading Game - Buy Stock Transaction Sequence

actor User as user
participant "View" as view
participant "Exchange" as exchange
participant "Stock" as stock
participant "Share" as share
participant "Purchase" as purchase
participant "Player" as player
participant "Portfolio" as portfolio
participant "PurchaseCalculator" as calc
participant "TransactionArchive" as archive
participant "Observer" as observer

user -> view: Click Buy Button
activate view
view -> exchange: buy(symbol, quantity, player)
activate exchange

exchange -> exchange: Validate inputs
exchange -> stock: getStock(symbol)
activate stock
stock --> exchange: Stock object
deactivate stock

exchange -> exchange: Check if stock exists

exchange -> stock: getSalesPrice()
activate stock
stock --> exchange: BigDecimal price
deactivate stock

exchange -> share: new Share(stock, quantity, price)
activate share
share --> exchange: Share instance
deactivate share

exchange -> purchase: new Purchase(share, week)
activate purchase
purchase -> calc: new PurchaseCalculator(share)
activate calc
calc --> purchase: Calculator instance
deactivate calc
purchase --> exchange: Purchase instance
deactivate purchase

exchange -> purchase: commit(player)
activate purchase

purchase -> calc: calculateTotal()
activate calc
calc --> purchase: BigDecimal total cost
deactivate calc

purchase -> player: getMoney()
activate player
player --> purchase: BigDecimal current money
deactivate player

alt Sufficient Funds
purchase -> player: withdrawMoney(cost)
activate player
player -> player: Subtract from balance
deactivate player

purchase -> portfolio: addShare(share)
activate portfolio
portfolio -> portfolio: Add share to list
portfolio --> purchase: true
deactivate portfolio

purchase -> archive: add(this)
activate archive
archive -> archive: Add transaction to list
archive --> purchase: true
deactivate archive

purchase -> purchase: committed = true
purchase --> exchange: void

else Insufficient Funds
purchase --> exchange: throw IllegalStateException
end

deactivate purchase

exchange -> observer: notifyObservers()
activate observer
observer -> observer: Update UI state
observer --> exchange: void
deactivate observer

exchange --> view: Transaction completed
deactivate exchange

view -> view: Refresh display
view --> user: Show updated portfolio
deactivate view

@enduml

0 comments on commit b9f4692

Please sign in to comment.