@startuml
'https://plantuml.com/class-diagram
skinparam classAttributeIconSize 0

package services {

class FileImporter {

}

}

package controllers {

class MatadorMain {

}

class GameController {
    -players: Player[]
    -board: Board
    -diceCup: DiceCup
}

'class GameSetupController {
'
'}

class ViewController {

}

}

package models {

class GameSettings {
    {static}+MINNUMOFPLAYERS: int
    {static}+MAXNUMOFPLAYERS: int
    {static}+STARTINGBALANCE: int
    {static}+STARTBONUS: int
    {static}+JAILFEE: int
    {static}+STATETAXAMOUNT: int
    {static}+INCOMETAXAMOUNT: int
}

class Player {
    -name: String
    -isBankrupt: Boolean
    -onField: int
    -account: Account
    -isInJail: Boolean
    -jailCard1: ChanceCard
    -jailCard2: ChanceCard

    +moveToField(fieldNum : int) : int
    +moveSteps(steps : int) : void
    +hasAJailCard() : Boolean
    +giveJailCard(jailCard : ChanceCard) : void
    +returnJailCard() : ChanceCard
    +collectStartBonus() : void
}

class Board {
    -fields: Field[]

    +ownsAllOfSameType(fieldNum : int) : boolean
    +updateRentForAllOfSameType(fieldNum : int) : void
    +numOfShippingFieldsOwned(playerNum : int) : int
    +getTotalNumOfFields() : int
    +buildHouse() : void
    +buildHotel() : void
    +sellHouse() : void
}

class Field {
    #fieldName: String

    +landOnField(currentPlayerObject : Player)
    +isOwnableField() : boolean
}

class Account {
    -balance: int

    +deposit(amount : int) : void
    +withdraw(amount : int) : void
    +transfer(amount : int, recipientPlayerNum : int) : void
}

class DiceCup {
    -die1: Die
    -die2: Die

    +roll() : void
    +isSameFaceValue() : boolean
}

class Die {
    -facevalue: int
    -NUMOFSIDES: int

    +roll() : void
}

class ChanceCardType {
    -DESCRIPTION: String
}

abstract class ChanceCard {
    {abstract}returnChanceCardText() : String
    {abstract}+effect(currentPlayerObject : Player) : void
}

abstract class OwnableField {
        #ownerNum: int
        #PRICE: int
        #currentRent: int
        #RENTARRAY: int[]
        #isMortgaged: boolean
        #MORTGAGEVALUE: int

        +buyField(currentPlayerObject : Player) : void
        +updateRent() : void
        +mortgageField() : void
        +auctionField() : void
        +tradeField() : void
}

class StreetField {
    -numOfHouses: int
    -hasHotel: boolean
    -HOUSEPRICE: int
    -STREETCOLOR: String

}

class BreweryField {

}

class ShippingField {

}

class ChanceField {
    {static}-chanceCards: ChanceCard[]
    {static}-currentCard: ChanceCard

    {static}+drawChanceCard() : ChanceCard
    {static}+shuffleChanceCards() : void
    {static}+putBackChanceCard(jailCard : ChanceCard) : void
    {static}-putAllNullCardsInBottom() : void
}

class JailField {

}

abstract class TaxField {
    #FIXEDTAX: int

    {abstract}+calculateTax(currentPlayerObject : Player) : int
}

class StateTaxField {

}

class IncomeTaxField {

}

}

MatadorMain *-- GameController
ViewController --> FileImporter
ViewController --* GameController
GameController --> GameSettings
GameController *--- Board
GameController *--- DiceCup
GameController *--- Player
Player *-- Account
Board *-- "40" Field
OwnableField <|-- StreetField
Field <|-- ChanceField
Field <|-- JailField
ChanceField o- ChanceCard
ChanceCard <|-- ChanceCardType
DiceCup *-- "2" Die
Field <|-- OwnableField
OwnableField <|-- BreweryField
OwnableField <|-- ShippingField
Field <|-- TaxField
TaxField <|-- StateTaxField
TaxField <|-- IncomeTaxField


@enduml