Compare commits

...

4 Commits

Author SHA1 Message Date
22a7798ed5 Correcty wide typo on O'Connell 2024-05-24 15:39:19 +02:00
2ba1340ce8 Split main code file 2024-05-24 15:36:37 +02:00
2570974192 Remove deprecated code 2024-05-24 15:20:00 +02:00
83b9f4f9d4 Add stickers counters 2024-05-24 15:19:43 +02:00
5 changed files with 158 additions and 125 deletions

169
main.py
View File

@ -2,117 +2,12 @@
# Imports # Imports
import os import os
import random
import jsonpickle import jsonpickle
from src.MamaOConnel import MamaOConnel
class Circus: from src.Circus import Circus
# There are: from src.TreasureCard import TreasureCard
# 4 wagons of each colors (until 2 players' stop) from src.Player import Player, ConcessionCard
# 2 wagons of each colors (until 3 players' stop) from src.MamaOConnell import MamaOConnell
# 2 wagons of each colors (until 4 players' stop)
# 2 wagons of each colors (until 5 players' stop)
# NOTE: In the original distribution, the same color never appears twice in a row
# We chose to remove this constraint, for the sake of simplicity
def __init__(self, playersNb):
wagonsPerColors = 2 * playersNb
colors = "blue", "green", "black", "red", "yellow"
remaining = {"blue": wagonsPerColors, "green": wagonsPerColors, "black": wagonsPerColors, "red": wagonsPerColors,\
"yellow": wagonsPerColors}
self.wagons = []
for n in range(0, 5 * wagonsPerColors):
color = colors[random.randint(0, 4)]
while remaining[color] == 0:
color = colors[random.randint(0, 4)]
self.wagons.append(color)
remaining[color] = remaining[color] - 1
self.state = 0 # 0 means Circus is not used in game yet, 1 means next wagon in list is #1, and so on
def enable(self):
if self.state > 0:
print("Circus is already in game.")
return False
self.state = 1
def getNextColor(self):
return self.wagons[self.state - 1]
def takeWagon(self):
if self.state == 0:
print("Circus is not or no longer in game.")
return False
print("Player obtained a " + self.wagons[self.state - 1] + " circus sticker!")
self.state = self.state + 1
if self.state > len(self.wagons):
print("Circus stickers are now depleted.")
self.state = 0 # effectively disable circus
class TreasureCard:
def __init__(self):
self.treasures = [36, 33, 29, 27, 24]
self.state = -1 # disabled
def enable(self):
self.state = 0 # 0 means 0 treasures have been found
def getFoundNumber(self):
if self.state == -1:
print("Treasure hunt has not started yet or is completed.")
return False
return self.state
def takeTreasure(self):
if self.state == -1:
print("Treasure hunt has not started yet or is completed.")
return False
print("Congrats! You obtained $" + str(self.treasures[self.state]))
self.state = self.state + 1
if self.state == 5:
print("All treasures have been found.")
self.state = -1 # effectively disable treasure card
class ConcessionCard:
# Each card contains:
# 6 cities to connect to the player's concession. There is no need to implement those.
# 7 gold nuggets, as rewards when the player succefully connects a city to their concession. The player can choose
# which nugget to earn, and then discovers the associated reward (between 11 and 17 coins).
# A ConcessionCard is then composed of 7 nuggets, with the rewards randomly distributed.
def __init__(self):
availableValues = [11, 12, 13, 14, 15, 16, 17]
nuggetsNb = len(availableValues) - 1
self.nuggets = []
for n in range(0, 7):
choice = random.randint(0, nuggetsNb - n)
self.nuggets.append(availableValues[choice])
availableValues.pop(choice)
self.taken = set()
def getRemainingPepites(self):
return {1, 2, 3, 4, 5, 6, 7} - self.taken
def takeReward(self, choice):
if not choice.isdigit():
print("Please choose a number.")
return False
choice = int(choice)
if choice not in range(1, 8):
print("This is not a valid number")
return False
if choice in self.taken:
print(str(choice) + " has already been obtained.")
return False
self.taken.add(choice)
print("Congrats! You obtained $" + str(self.nuggets[choice - 1]))
class Player:
def __init__(self, color):
self.color = color
self.concession = ConcessionCard()
class Game: class Game:
@ -132,9 +27,9 @@ class Game:
# General data to generate # General data to generate
self.circus = Circus(playersNb) self.circus = Circus(playersNb)
self.treasure = TreasureCard() self.treasure = TreasureCard()
self.mamaoc = MamaOConnel() self.mamaoc = MamaOConnell()
while not self.mamaoc.solver(): while not self.mamaoc.solver():
self.mamaoc = MamaOConnel() self.mamaoc = MamaOConnell()
# Players # Players
self.players = [] self.players = []
@ -142,6 +37,9 @@ class Game:
color = input("Enter player " + str(n + 1) + "'s color: ") color = input("Enter player " + str(n + 1) + "'s color: ")
self.players.append(Player(color)) self.players.append(Player(color))
# Stickers pools
self.stickers = {'White': 0, 'Red': 0, 'Blue': 0, 'Yellow': 0, 'Green': 0, 'Black': 0}
def getPlayerByColor(self, color): def getPlayerByColor(self, color):
for player in self.players: for player in self.players:
if player.color.lower() == color.lower(): if player.color.lower() == color.lower():
@ -155,7 +53,7 @@ class Game:
def disableConcession(self): def disableConcession(self):
self.concession = False self.concession = False
# if number = 0 print Mama O'Connel's location, else print hint #number # if number = 0 print Mama O'Connell's location, else print hint #number
def printMamaHint(self, number): def printMamaHint(self, number):
if number not in range(0, 4): if number not in range(0, 4):
return False return False
@ -164,17 +62,36 @@ class Game:
print("") print("")
match number: match number:
case 0: case 0:
print("Mama O'Connel is at: " + self.mamaoc.location.name) print("Mama O'Connell is at: " + self.mamaoc.location.name)
case 1: case 1:
print("Mama O'Connel is " + str(self.mamaoc.hint1[1]) + " cities from " + self.mamaoc.hint1[0].name) print("Mama O'Connell is " + str(self.mamaoc.hint1[1]) + " cities from " + self.mamaoc.hint1[0].name)
case 2: case 2:
print("Mama O'Connel is " + str(self.mamaoc.hint2[1]) + " cities from " + self.mamaoc.hint2[0].name) print("Mama O'Connell is " + str(self.mamaoc.hint2[1]) + " cities from " + self.mamaoc.hint2[0].name)
case 3: case 3:
print("Mama O'Connel is " + str(self.mamaoc.hint3[1]) + " cities from " + self.mamaoc.hint3[0].name) print("Mama O'Connell is " + str(self.mamaoc.hint3[1]) + " cities from " + self.mamaoc.hint3[0].name)
print("") print("")
input("When you are done, press Enter.") input("When you are done, press Enter.")
os.system('clear') os.system('clear')
def takeSticker(self, color, nb):
if not nb.isdigit() or int(nb) < 1:
print("ERROR: Not a positive number")
return False
nb = int(nb)
for c, n in self.stickers.items():
if c.lower() == color.lower():
if nb > n:
print("ERROR: not enough stickers remaining.")
return False
else:
self.stickers[c] = n - nb
return True
print("ERROR: color not found.")
return False
def newStickersBatch(self):
self.stickers = {x: self.stickers[x] + 7 for x in self.stickers}
def printStatus(self): def printStatus(self):
print("") print("")
print("---------------------------------------------------------------------") print("---------------------------------------------------------------------")
@ -191,8 +108,13 @@ class Game:
print("") print("")
if self.circus.state > 0: if self.circus.state > 0:
print("Circus next sticker color: " + self.circus.getNextColor()) print("Circus next sticker color: " + self.circus.getNextColor())
print("")
if self.treasure.state > -1: if self.treasure.state > -1:
print(f"Treasures found: {self.treasure.getFoundNumber()}") print(f"Treasures found: {self.treasure.getFoundNumber()}")
print("")
print("Road stickers:")
for color, nb in self.stickers.items():
print(" " + color + ": " + str(nb))
def saveData(self, path): def saveData(self, path):
savefile = open('./' + path, 'w+') savefile = open('./' + path, 'w+')
@ -224,16 +146,17 @@ elif choice == "load":
while True: while True:
myGame.printStatus() myGame.printStatus()
command = input("==> ") command = input("==> ")
while command not in ('load', 'save', 'next year', 'exit', 'enable circus', 'take circus', 'enable concession',\ while command not in ('load', 'save', 'next year', 'exit', 'take sticker', 'batch sticker', 'enable circus',\
'take concession', 'disable concession', 'enable treasure', 'take treasure', 'mama hint 1', 'mama hint 2',\ 'take circus', 'enable concession', 'take concession', 'disable concession', 'enable treasure', 'take treasure',\
'mama hint 3', 'mama location'): 'mama hint 1', 'mama hint 2', 'mama hint 3', 'mama location'):
print("") print("")
print("Available commands:") print("Available commands:")
print(" Main: 'load', 'save', 'next year', 'exit'") print(" Main: 'load', 'save', 'next year', 'exit'")
print(" Stickers: 'take sticker', 'batch sticker'")
print(" Circus: 'enable circus', 'take circus'") print(" Circus: 'enable circus', 'take circus'")
print(" Treasure: 'enable treasure', 'take treasure'") print(" Treasure: 'enable treasure', 'take treasure'")
print(" Concessions: 'enable concession', 'take concession', 'disable concession'") print(" Concessions: 'enable concession', 'take concession', 'disable concession'")
print(" Mama O'Connel tracking: 'mama hint 1', 'mama hint 2', 'mama hint 3', 'mama location'") print(" Mama O'Connell tracking: 'mama hint 1', 'mama hint 2', 'mama hint 3', 'mama location'")
command = input("==> ") command = input("==> ")
print("") print("")
match command: match command:
@ -254,6 +177,12 @@ while True:
myGame.yearId = myGame.yearId + 1 myGame.yearId = myGame.yearId + 1
case 'exit': case 'exit':
exit() exit()
case 'take sticker':
choice = input("Color ? ==> ")
number = input("Nb ? ==> ")
myGame.takeSticker(choice, number)
case 'batch sticker':
myGame.newStickersBatch()
case 'enable circus': case 'enable circus':
myGame.circus.enable() myGame.circus.enable()
case 'take circus': case 'take circus':

43
src/Circus.py Normal file
View File

@ -0,0 +1,43 @@
import random
class Circus:
# There are:
# 4 wagons of each colors (until 2 players' stop)
# 2 wagons of each colors (until 3 players' stop)
# 2 wagons of each colors (until 4 players' stop)
# 2 wagons of each colors (until 5 players' stop)
# NOTE: In the original distribution, the same color never appears twice in a row
# We chose to remove this constraint, for the sake of simplicity
def __init__(self, playersNb):
wagonsPerColors = 2 * playersNb
colors = "blue", "green", "black", "red", "yellow"
remaining = {"blue": wagonsPerColors, "green": wagonsPerColors, "black": wagonsPerColors, "red": wagonsPerColors,\
"yellow": wagonsPerColors}
self.wagons = []
for n in range(0, 5 * wagonsPerColors):
color = colors[random.randint(0, 4)]
while remaining[color] == 0:
color = colors[random.randint(0, 4)]
self.wagons.append(color)
remaining[color] = remaining[color] - 1
self.state = 0 # 0 means Circus is not used in game yet, 1 means next wagon in list is #1, and so on
def enable(self):
if self.state > 0:
print("Circus is already in game.")
return False
self.state = 1
def getNextColor(self):
return self.wagons[self.state - 1]
def takeWagon(self):
if self.state == 0:
print("Circus is not or no longer in game.")
return False
print("Player obtained a " + self.wagons[self.state - 1] + " circus sticker!")
self.state = self.state + 1
if self.state > len(self.wagons):
print("Circus stickers are now depleted.")
self.state = 0 # effectively disable circus

View File

@ -208,7 +208,7 @@ class Board:
i = i + 1 i = i + 1
return result return result
class MamaOConnel: class MamaOConnell:
def __init__(self): def __init__(self):
board = Board() # TODO Board should be a "static" or "constant" class, see what we can do board = Board() # TODO Board should be a "static" or "constant" class, see what we can do
@ -273,7 +273,3 @@ class MamaOConnel:
if len(cross) > 1: # multiple cities remaining after 3 hints if len(cross) > 1: # multiple cities remaining after 3 hints
return False return False
return True return True
# myMama = MamaOConnel()
# while not myMama.solver():
# myMama = MamaOConnel()

41
src/Player.py Normal file
View File

@ -0,0 +1,41 @@
import random
class ConcessionCard:
# Each card contains:
# 6 cities to connect to the player's concession. There is no need to implement those.
# 7 gold nuggets, as rewards when the player succefully connects a city to their concession. The player can choose
# which nugget to earn, and then discovers the associated reward (between 11 and 17 coins).
# A ConcessionCard is then composed of 7 nuggets, with the rewards randomly distributed.
def __init__(self):
availableValues = [11, 12, 13, 14, 15, 16, 17]
nuggetsNb = len(availableValues) - 1
self.nuggets = []
for n in range(0, 7):
choice = random.randint(0, nuggetsNb - n)
self.nuggets.append(availableValues[choice])
availableValues.pop(choice)
self.taken = set()
def getRemainingPepites(self):
return {1, 2, 3, 4, 5, 6, 7} - self.taken
def takeReward(self, choice):
if not choice.isdigit():
print("Please choose a number.")
return False
choice = int(choice)
if choice not in range(1, 8):
print("This is not a valid number")
return False
if choice in self.taken:
print(str(choice) + " has already been obtained.")
return False
self.taken.add(choice)
print("Congrats! You obtained $" + str(self.nuggets[choice - 1]))
class Player:
def __init__(self, color):
self.color = color
self.concession = ConcessionCard()

24
src/TreasureCard.py Normal file
View File

@ -0,0 +1,24 @@
class TreasureCard:
def __init__(self):
self.treasures = [36, 33, 29, 27, 24]
self.state = -1 # disabled
def enable(self):
self.state = 0 # 0 means 0 treasures have been found
def getFoundNumber(self):
if self.state == -1:
print("Treasure hunt has not started yet or is completed.")
return False
return self.state
def takeTreasure(self):
if self.state == -1:
print("Treasure hunt has not started yet or is completed.")
return False
print("Congrats! You obtained $" + str(self.treasures[self.state]))
self.state = self.state + 1
if self.state == 5:
print("All treasures have been found.")
self.state = -1 # effectively disable treasure card