--- /dev/null
+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)
+ }
+ }
+}
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++
}
}
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 {
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
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
case TypeTax:
SpaceToTaxSpace[spaceID] = taxIndex
taxIndex++
+ case TypeGo:
+ GoSpaceID = spaceID
}
ownableIndex++
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?
} 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?
} 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?
} else {
UnownedPropertyVisitors = append(UnownedPropertyVisitors, UnownedPropertyVisitor{visitorID: playerID, propertyID: propIndex})
}
- case TypeParking:
- ParkingVisitors = append(ParkingVisitors, playerID)
- case TypePolice:
- PoliceVisitors = append(PoliceVisitors, playerID)
}
}
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++
}
}
AdjustPlayerMoney(visitorID, -rent)
AdjustPlayerMoney(ownerID, rent)
+ // reset railroad rent mod after payment
+ ModifierRailroadRentMultiplier = 1
}
}
package game
type User struct {
- UUID string
- Money int32
+ UUID string
+ Money int32
+ CurrentSpaceID int32
}
type PropertyType int
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++
}
}
// 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
}
}