-
Notifications
You must be signed in to change notification settings - Fork 1
/
Cluedo.py
183 lines (143 loc) · 6.74 KB
/
Cluedo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
from typing import Union
import constants.defaults as cn
from components.cards import Cards
from components.suspects import Suspects
from components.player import Player
from components.board import Board
from components.accusation import Accusation
from components.players import Players
import components.inputs as inputs
import components.utilities as utilities
class CluedoGame:
def __init__(self, players_number=6):
self.players_number = players_number
self.cards = Cards(cn.CHARACTERS, cn.WEAPONS, cn.ROOMS)
# 3 are the cards to be guessed
self.cards_per_person = (self.cards.number - 3) // self.players_number
self.cards_to_players = self.cards_per_person * self.players_number
self.cards_on_board = self.cards.number - self.cards_to_players - 3
self.suspects = Suspects(cn.CHARACTERS, cn.WEAPONS, cn.ROOMS)
self.board = Board(self.cards_on_board)
self.players: Players = None
# 1) MAIN: Regulating the alternation of the various game phases
def main(self):
self.initiate_game()
self.display_game_info()
while self.suspects.guessing_probability < 1:
action = inputs.get_user_action(self.players.active.name)
if action == "1":
self.accusation_made_event()
self.display_game_info()
if action == "1" or action == "2":
# Go to the next player
self.players.make_next_player_active()
if action == "3":
self.card_revealed_event()
self.display_game_info()
# If probability is 1, the game is solved
self.suspects.display_guessing_probability_message()
# --------------------------------------------------------------------------
# GAME SET UP
# --------------------------------------------------------------------------
def initiate_game(self):
"""Set up a new game getting all the required items ready"""
self.initiate_players()
self.register_users_cards()
return
def initiate_players(self):
"""Create the list of players"""
user_position = inputs.get_user_position(self.players_number)
self.players = Players(
self.players_number, self.cards_per_person, user_position
)
return
def register_users_cards(self) -> None:
"""Register the fact that users owns its initial cards."""
user_owned_cards = inputs.get_users_cards(
self.cards_per_person, self.cards.all_cards
)
self.suspects.remove_multiple_from_suspects(user_owned_cards)
user = self.players.get_player_by_name("You")
for card in user_owned_cards:
self.update_card_owned(card, user)
self.update_card_not_owned(
user_owned_cards, self.players.list, player_excluded=user
)
# --------------------------------------------------------------------------
# ACCUSATION HANDLING
# --------------------------------------------------------------------------
def accusation_made_event(self):
"""Handle the entire event of an accusation being made"""
cs, wp, rm = self.cards.characters, self.cards.weapons, self.cards.rooms
accusation_list = inputs.get_accusation(cs, wp, rm)
accusation = Accusation.from_list(accusation_list)
player_showed_name = inputs.get_player_who_showed(self.players.names)
player_showed = self.players.get_player_by_name(player_showed_name)
players_passing = self.players.range_of_players(player_showed)
self.update_card_not_owned(accusation.items_set, players_passing)
# Distinguishing the actions between "You" and the other players
if self.players.active.name == "You":
self.card_shown_to_user(accusation, player_showed)
else:
self.update_card_owned(accusation.items_list, player_showed)
def card_shown_to_user(self, accusation: Accusation, player_showed: Player) -> None:
"""Handle the event of a card being shown to the user"""
card_showed = inputs.get_card_from_accusation(accusation.items_list)
self.suspects.remove_one_from_suspects(card_showed)
self.update_card_not_owned(card_showed, self.players.list, player_showed)
self.update_card_owned(card_showed, player_showed)
def update_card_not_owned(
self,
card_input: Union[str, list],
players_list: list[Player],
player_excluded=Union[None, Player],
) -> None:
"""Registers that one or more players do not own one or more cards"""
card_input_as_set = utilities.input_to_set(card_input)
for player in players_list:
if player != player_excluded:
player.add_cards_not_owned(card_input_as_set)
def update_card_owned(
self, card_input: Union[str, list], player_to_update: Player
) -> None:
# Not to proceed further if information about the player is complete
if player_to_update.all_cards_known:
return
card_input_as_set = utilities.input_to_set(card_input)
player_to_update.add_cards_owned(card_input_as_set)
# --------------------------------------------------------------------------
# CARD REVEALED HANDLING
# --------------------------------------------------------------------------
def card_revealed_event(self) -> None:
"""Handles the complete event of a card being revealed"""
if self.board.all_cards_revealed:
print(
"It looks like all the cards on the table had already been"
"revealed, please retry.\n"
)
return
revealed_card = inputs.input_in_list(
"Which card was revealed?", self.cards.all_cards
)
self.register_card_revealed(revealed_card)
def register_card_revealed(self, revealed_card: str) -> None:
"""Register that a card has been revealed"""
self.suspects.remove_one_from_suspects(revealed_card)
self.update_card_not_owned(revealed_card, self.players.list)
self.board.add_card(revealed_card)
# --------------------------------------------------------------------------
# INFORMATION DISPLAY
# --------------------------------------------------------------------------
def display_game_info(self):
print("########################### SUSPECTS")
print(self.suspects)
print("########################### PLAYERS INFO")
self.players.display_players_info()
print("########################### BOARD")
print(self.board)
print()
if __name__ == "__main__":
# To test what was done up to now
game = CluedoGame(players_number=6)
game.main()
input("\nPress any key to exit ")