]> Skullheadx's Git Forge - monopoly-web.git/commitdiff
chance cards
authorSkullheadx <admonty1@protonmail.com>
Sun, 17 May 2026 05:56:41 +0000 (01:56 -0400)
committerSkullheadx <admonty1@protonmail.com>
Sun, 17 May 2026 05:56:41 +0000 (01:56 -0400)
game/chance.go [new file with mode: 0644]
game/color.go
game/game.go
game/movement.go
game/railroad.go
game/types.go
game/utility.go

diff --git a/game/chance.go b/game/chance.go
new file mode 100644 (file)
index 0000000..08e6e67
--- /dev/null
@@ -0,0 +1,111 @@
+package game
+
+var ChanceCards = [...]string{
+       0:  "Advance to St. Charles Place. If you pass Go, collect $200.",
+       1:  "Advance to the nearest Railroad. If unowned, you may buy it from the Bank. If owned, pay owner twice the rental to which they are otherwise entitled.",
+       2:  "Advance to the nearest Railroad. If unowned, you may buy it from the Bank. If owned, pay owner twice the rental to which they are otherwise entitled.",
+       3:  "Advance token to nearest Utility. If unowned, you may buy it from the Bank. If owned, throw dice and pay owner a total ten times amount thrown.",
+       4:  "Go to Jail. Go directly to Jail, do not pass Go, do not collect $200.",
+       5:  "Take a trip to Reading Railroad. If you pass Go, collect $200.",
+       6:  "Advance to Go (Collect $200)",
+       7:  "Get Out of Jail Free.",
+       8:  "Advance to Boardwalk.",
+       9:  "Your building loan matures. Collect $150.",
+       10: "Go Back 3 Spaces.",
+       11: "Speeding fine $15.",
+       12: "Advance to Illinois Avenue. If you pass Go, collect $200.",
+       13: "Make general repairs on all your property. For each house pay $25. For each hotel pay $100.",
+       14: "You have been elected Chairman of the Board. Pay each player $50.",
+       15: "Bank pays you dividend of $50.",
+}
+
+func getPlayerMoveDistance(start int32, dest int32) int32 {
+       distance := dest - start
+       if distance < 0 {
+               distance += int32(len(BoardSpaces))
+       }
+       return distance
+}
+
+func processChance() {
+       for _, visitorID := range ChanceVisitors {
+               card := RandSrc.IntN(len(ChanceCards))
+
+               currentPos := Users[visitorID].CurrentSpaceID
+
+               switch card {
+               case 0:
+                       MoveQueue = append(MoveQueue, getPlayerMoveDistance(currentPos, StCharlesPlaceSpaceID))
+               case 1, 2:
+                       for i := range BoardSpaces {
+                               offset := int32(i)
+                               next_pos := currentPos + offset
+                               propertyType := BoardSpaces[next_pos]
+                               if propertyType == TypeRailroad {
+                                       distance := getPlayerMoveDistance(currentPos, next_pos)
+                                       if PropertyOwners[SpaceToOwnableProperty[CalculateNextPos(currentPos, distance)]] != visitorID {
+                                               ModifierRailroadRentMultiplier = 2
+                                       }
+                                       MoveQueue = append(MoveQueue, distance)
+                               }
+                       }
+               case 3:
+                       for i := range BoardSpaces {
+                               offset := int32(i)
+                               next_pos := currentPos + offset
+                               propertyType := BoardSpaces[next_pos]
+                               if propertyType == TypeUtility {
+                                       distance := getPlayerMoveDistance(currentPos, next_pos)
+                                       if PropertyOwners[SpaceToOwnableProperty[CalculateNextPos(currentPos, distance)]] != visitorID {
+                                               ModifierUtilityForceRentMultiplier = true
+                                       }
+                                       MoveQueue = append(MoveQueue, distance)
+                               }
+                       }
+
+               case 4:
+                       // TODO
+               case 5:
+                       MoveQueue = append(MoveQueue, getPlayerMoveDistance(currentPos, ReadingRailroadSpaceID))
+               case 6:
+                       MoveQueue = append(MoveQueue, getPlayerMoveDistance(currentPos, GoSpaceID))
+               case 7:
+                       // TODO
+               case 8:
+                       MoveQueue = append(MoveQueue, getPlayerMoveDistance(currentPos, BoardwalkSpaceID))
+               case 9:
+                       AdjustPlayerMoney(visitorID, 150)
+               case 10:
+                       MoveQueue = append(MoveQueue, -3)
+               case 11:
+                       AdjustPlayerMoney(visitorID, -15)
+               case 12:
+                       var repairCost int32 = 0
+                       for propID, ownerID := range PropertyOwners {
+                               if ownerID == visitorID && OwnablePropertyType[propID] == TypeColor {
+                                       colorID := OwnableToRespProperty[int32(propID)]
+                                       colorProp := ColorProperties[colorID]
+                                       if colorProp.Houses > MAX_PROP_HOUSES { // its a hotel
+                                               repairCost += 100
+                                       } else {
+                                               repairCost += colorProp.Houses * 25
+                                       }
+                               }
+                       }
+
+                       AdjustPlayerMoney(visitorID, -repairCost)
+               case 14:
+                       for i := range Users {
+                               pID := int32(i)
+                               if pID == visitorID {
+                                       AdjustPlayerMoney(pID, -50*int32(len(Users)-1))
+                               } else {
+                                       AdjustPlayerMoney(pID, 50)
+                               }
+
+                       }
+               case 15:
+                       AdjustPlayerMoney(visitorID, 50)
+               }
+       }
+}
index 937cfb2a8cf790261a0c3a705f50d4701c698833..9cad60ba7b13157bcfcf186a34bf7f3abde30139 100644 (file)
@@ -1,9 +1,11 @@
 package game
 
+const MAX_PROP_HOUSES = 4
+
 func HasColorMonopoly(playerID int32, targetGroup ColorGroup) bool {
        var ownedCount int32
-       for colorID, ownerID := range PropertyOwners {
-               if ownerID == playerID && OwnablePropertyType[RespPropertyToOwnable[int32(colorID)]] == TypeColor && ColorProperties[colorID].GroupID == targetGroup {
+       for propID, ownerID := range PropertyOwners {
+               if ownerID == playerID && OwnablePropertyType[int32(propID)] == TypeColor && ColorProperties[OwnableToRespProperty[int32(propID)]].GroupID == targetGroup {
                        ownedCount++
                }
        }
index 29467db44820865e93369f9ffbc79c78cd4c4b94..ff03d7a650e7fd37e9a4071ddad098e292054d84 100644 (file)
@@ -1,7 +1,18 @@
 package game
 
+import (
+       "math/rand/v2"
+)
+
+var RandSeed = rand.NewPCG(20, 26)
+var RandSrc = rand.New(RandSeed)
+
 var Users []User
 var DebtEvents []int32
+var MoveQueue []int32
+
+var ModifierRailroadRentMultiplier int32 = 1
+var ModifierUtilityForceRentMultiplier bool = false
 
 func IsInDebt(playerID int32) (bool, int32) {
        for i, pID := range DebtEvents {
index e74bb6f3f310db02ab95694fa5a66b7da40355cd..c60d8712bdb76d1a518604fb1f2ad2b0f74bf2e7 100644 (file)
@@ -183,6 +183,11 @@ var SpaceToTaxSpace = make(map[int32]int32)
 var OwnableToRespProperty = make(map[int32]int32)
 var RespPropertyToOwnable = make(map[int32]int32)
 
+var StCharlesPlaceSpaceID int32 = 0
+var GoSpaceID int32 = 0
+var ReadingRailroadSpaceID int32 = 0
+var BoardwalkSpaceID int32 = 0
+
 func init() {
        var (
                colorIndex    int32 = 0
@@ -207,11 +212,21 @@ func init() {
                        OwnableToRespProperty[ownableIndex] = colorIndex
                        RespPropertyToOwnable[colorIndex] = ownableIndex
                        colorIndex++
+
+                       if ColorProperties[colorIndex].Name == "St. Charles Place" {
+                               StCharlesPlaceSpaceID = spaceID
+                       } else if ColorProperties[colorIndex].Name == "Boardwalk" {
+                               BoardwalkSpaceID = spaceID
+                       }
+
                case TypeRailroad:
                        SpaceToRespProperty[spaceID] = railroadIndex
                        OwnableToRespProperty[ownableIndex] = railroadIndex
                        RespPropertyToOwnable[railroadIndex] = ownableIndex
                        railroadIndex++
+                       if ColorProperties[colorIndex].Name == "Reading Railroad" {
+                               ReadingRailroadSpaceID = spaceID
+                       }
                case TypeUtility:
                        SpaceToRespProperty[spaceID] = utilityIndex
                        OwnableToRespProperty[ownableIndex] = utilityIndex
@@ -220,6 +235,8 @@ func init() {
                case TypeTax:
                        SpaceToTaxSpace[spaceID] = taxIndex
                        taxIndex++
+               case TypeGo:
+                       GoSpaceID = spaceID
                }
 
                ownableIndex++
@@ -266,18 +283,40 @@ var (
        PoliceVisitors          []int32
 )
 
+func CalculateNextPos(currentPosition int32, distance int32) int32 {
+       nextPos := (currentPosition + distance)
+       nextPos %= int32(len(BoardSpaces))
+
+       return nextPos
+}
+
 func AdvancePlayer(playerID int32, currentPosition int32, diceRoll int32) {
-       nextPos := (currentPosition + diceRoll)
-       if nextPos > int32(len(BoardSpaces))-1 { // Passed Go, but did not land on Go
-               GoVisitors = append(GoVisitors, playerID)
+       nextPos := CalculateNextPos(currentPosition, diceRoll)
+
+       numGoPasses := (currentPosition + diceRoll) / (int32(len(BoardSpaces)) - 1)
+       if numGoPasses > 0 {
+               for _ = range numGoPasses {
+                       GoVisitors = append(GoVisitors, playerID)
+               }
        }
-       nextPos %= int32(len(BoardSpaces))
 
        propType := BoardSpaces[nextPos]
 
        switch propType {
        case TypeGo:
                GoVisitors = append(GoVisitors, playerID)
+       case TypeChest:
+               ChestVisitors = append(ChestVisitors, playerID)
+       case TypeChance:
+               ChanceVisitors = append(ChanceVisitors, playerID)
+       case TypeTax:
+               TaxVisitors = append(TaxVisitors, playerID)
+       // case TypeParking: // nothing ever happens
+       //      ParkingVisitors = append(ParkingVisitors, playerID)
+       case TypePolice:
+               PoliceVisitors = append(PoliceVisitors, playerID)
+       case TypeJail:
+               JailVisitors = append(JailVisitors, playerID)
        case TypeColor:
                propIndex := SpaceToOwnableProperty[nextPos]
                if PropertyOwners[propIndex] != -1 { // property owned?
@@ -288,10 +327,6 @@ func AdvancePlayer(playerID int32, currentPosition int32, diceRoll int32) {
                } else {
                        UnownedPropertyVisitors = append(UnownedPropertyVisitors, UnownedPropertyVisitor{visitorID: playerID, propertyID: propIndex})
                }
-       case TypeChest:
-               ChestVisitors = append(ChestVisitors, playerID)
-       case TypeTax:
-               TaxVisitors = append(TaxVisitors, playerID)
        case TypeRailroad:
                propIndex := SpaceToOwnableProperty[nextPos]
                if PropertyOwners[propIndex] != -1 { // property owned?
@@ -302,10 +337,6 @@ func AdvancePlayer(playerID int32, currentPosition int32, diceRoll int32) {
                } else {
                        UnownedPropertyVisitors = append(UnownedPropertyVisitors, UnownedPropertyVisitor{visitorID: playerID, propertyID: propIndex})
                }
-       case TypeChance:
-               ChanceVisitors = append(ChanceVisitors, playerID)
-       case TypeJail:
-               JailVisitors = append(JailVisitors, playerID)
        case TypeUtility:
                propIndex := SpaceToOwnableProperty[nextPos]
                if PropertyOwners[propIndex] != -1 { // property owned?
@@ -316,9 +347,5 @@ func AdvancePlayer(playerID int32, currentPosition int32, diceRoll int32) {
                } else {
                        UnownedPropertyVisitors = append(UnownedPropertyVisitors, UnownedPropertyVisitor{visitorID: playerID, propertyID: propIndex})
                }
-       case TypeParking:
-               ParkingVisitors = append(ParkingVisitors, playerID)
-       case TypePolice:
-               PoliceVisitors = append(PoliceVisitors, playerID)
        }
 }
index 44e6bfa4137aec6952aefd0169b0eb5af68c463b..ad7b13a7ff1f6033eb26a6b68bb7088341306cac 100644 (file)
@@ -2,8 +2,8 @@ package game
 
 func numRailroadOwned(playerID int32) int32 {
        var ownedCount int32 = 0
-       for railroadID, ownerID := range PropertyOwners {
-               if ownerID == playerID && OwnablePropertyType[RespPropertyToOwnable[int32(railroadID)]] == TypeRailroad {
+       for propID, ownerID := range PropertyOwners {
+               if ownerID == playerID && OwnablePropertyType[int32(propID)] == TypeRailroad {
                        ownedCount++
                }
        }
@@ -21,5 +21,7 @@ func processOwnedRailroad() {
 
                AdjustPlayerMoney(visitorID, -rent)
                AdjustPlayerMoney(ownerID, rent)
+               // reset railroad rent mod after payment
+               ModifierRailroadRentMultiplier = 1
        }
 }
index 7e756392cbd1e6f2b65f9ec91c81cc507359e9f6..8d104e6907236d1d6a9e7955f858e54e0f32704f 100644 (file)
@@ -1,8 +1,9 @@
 package game
 
 type User struct {
-       UUID  string
-       Money int32
+       UUID           string
+       Money          int32
+       CurrentSpaceID int32
 }
 
 type PropertyType int
index 897e3c921b156e8f776e604df630a26335a97c30..4a7a3a5ef3adb35afd9ed457012cdb7eed861abf 100644 (file)
@@ -2,8 +2,8 @@ package game
 
 func numUtilities(playerID int32) int32 {
        var ownedCount int32 = 0
-       for utilityID, ownerID := range PropertyOwners {
-               if ownerID == playerID && OwnablePropertyType[RespPropertyToOwnable[int32(utilityID)]] == TypeUtility {
+       for propID, ownerID := range PropertyOwners {
+               if ownerID == playerID && OwnablePropertyType[int32(propID)] == TypeUtility {
                        ownedCount++
                }
        }
@@ -18,9 +18,17 @@ func processOwnedUtility() {
                // utilityID := oUV.utilityID
                diceRoll := oUV.diceRoll
 
-               var rent int32 = UtilityRentMult[numUtilities(ownerID)] * diceRoll
+               var rent int32 = 0
+
+               if !ModifierUtilityForceRentMultiplier {
+                       rent = UtilityRentMult[numUtilities(ownerID)] * diceRoll
+               } else {
+                       rent = 10 * diceRoll
+               }
 
                AdjustPlayerMoney(visitorID, -rent)
                AdjustPlayerMoney(ownerID, rent)
+
+               ModifierUtilityForceRentMultiplier = false
        }
 }