-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #51 from solvena/50-add-diagrams
Added diagrams
- Loading branch information
Showing
4 changed files
with
376 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |