-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathview.py
More file actions
284 lines (238 loc) · 10.7 KB
/
view.py
File metadata and controls
284 lines (238 loc) · 10.7 KB
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
"""
view.py
A module handling the user interface and input/output operations for the chess tournament
management system. Provides menus, prompts, and display functions for user interaction.
Directory Structure:
data/
players/ - Directory for storing player data (players.json).
tournaments/ - Directory for storing tournament data (e.g., EUChessTour.json).
Usage:
Import and use with the Controller class:
$ python3 main.py
Classes:
View: Handles all user interface and input/output operations.
Author:
Mathieu Patoz
Updated: March 06, 2025
"""
import random
class View:
"""A class handling user interface and input/output operations for the application.
Attributes:
None: All methods are stateless and operate on input parameters.
Methods:
display_menu(): Display the main menu and get user choice.
display_round_management_menu(): Display the round management menu and get user choice.
display_reports_menu(): Display the reports menu and get user choice.
get_tournament_info(): Get tournament details from user input.
get_player_info(): Get player details from user input.
display_players(players): Display a sorted list of players with lifetime scores.
display_tournaments(tournaments): Display a list of all tournaments.
display_unfinished_tournaments(tournaments): Display a list of unfinished tournaments.
display_tournament_details(tournament): Display detailed information about a tournament.
display_message(message): Display a message to the user.
get_choice(prompt): Get a choice from the user with a custom prompt.
get_match_result(player1, player2): Get the result of a match from user input.
confirm_end_tournament(): Confirm with the user to end the tournament.
select_tournament(tournaments): Allow user to select a tournament from a list.
"""
def display_menu(self):
"""Display the main menu and get user choice.
Returns:
str: The user's menu choice (1-6).
"""
print("\n=== Chess Tournament Management ===")
print("1. Add players")
print("2. Create a new tournament")
print("3. Manage existing tournament")
print("4. Manage tournament rounds")
print("5. Generate reports")
print("6. Exit")
return input("Choose an option (1-6): ")
def display_round_management_menu(self):
"""Display the round management menu and get user choice.
Returns:
str: The user's menu choice (1-4).
"""
print("\nRound Management:")
print("1. Start next round")
print("2. Finish current round")
print("3. End tournament")
print("4. Back to main menu")
return input("Choose an option (1-4): ")
def display_reports_menu(self):
"""Display the reports menu and get user choice.
Returns:
str: The user's menu choice (1-4).
"""
print("\nReports:")
print("1. List all players (alphabetical)")
print("2. List all tournaments")
print("3. Show details of a specific tournament")
print("4. Back to main menu")
return input("Choose an option (1-4): ")
def get_tournament_info(self):
"""Get tournament details from user input.
Returns:
tuple: (name, location, start_date, description) as strings.
"""
name = input("Enter tournament name: ")
location = input("Enter tournament location: ")
start_date = input("Enter tournament start date (DD-MM-YYYY): ")
description = input("Enter tournament description (optional): ")
return name, location, start_date, description
def get_player_info(self):
"""Get player details from user input.
Returns:
tuple: (firstname, lastname, birthdate, national_id) as strings.
"""
firstname = input("Enter player firstname: ")
lastname = input("Enter player lastname: ")
birthdate = input("Enter player birthdate (DD-MM-YYYY): ")
national_id = input("Enter player national chess ID (e.g., AB12345): ")
return firstname, lastname, birthdate, national_id
def display_players(self, players):
"""Display a sorted list of players with lifetime scores.
Args:
players (list): List of Player objects to display.
Returns:
None
"""
print("\nPlayers (alphabetical by lastname, firstname) with Lifetime Scores:")
sorted_players = sorted(players, key=lambda p: (p.lastname, p.firstname))
for i, player in enumerate(sorted_players, 1):
print(f"{i}. {player.lastname}, {player.firstname} (ID: {player.national_id}, "
f"Birthdate: {player.birthdate}, Lifetime Score: {player.score})")
def display_tournaments(self, tournaments):
"""Display a list of all tournaments.
Args:
tournaments (list): List of Tournament objects to display.
Returns:
None
"""
if not tournaments or tournaments is None:
print("\nNo tournaments available.")
return
print("\nTournaments:")
for i, t in enumerate(tournaments, 1):
print(f"{i}. {t.name} ({t.location}, {t.start_date} - {t.end_date or 'Ongoing'})")
def display_unfinished_tournaments(self, tournaments):
"""Display a list of unfinished tournaments.
Args:
tournaments (list): List of Tournament objects to filter.
Returns:
list: List of unfinished Tournament objects, or None if none available.
"""
unfinished_tournaments = [t for t in tournaments if t.end_date is None]
if not unfinished_tournaments:
print("\nNo unfinished tournaments available.")
return None
print("\nUnfinished Tournaments:")
for i, t in enumerate(unfinished_tournaments, 1):
print(f"{i}. {t.name} ({t.location}, {t.start_date} - {t.end_date or 'Ongoing'})")
return unfinished_tournaments
def display_tournament_details(self, tournament):
"""Display detailed information about a specific tournament.
Args:
tournament (Tournament): The Tournament object to display.
Returns:
None
"""
if not tournament:
print("\nNo tournament available.")
return
print(f"\nTournament: {tournament.name}")
print(f"Location: {tournament.location}")
print(f"Dates: {tournament.start_date} - {tournament.end_date or 'Ongoing'}")
print(f"Description: {tournament.description}")
print(f"Number of Rounds: {tournament.number_of_rounds}")
print(f"Current Round: {tournament.current_round}")
self.display_players(tournament.players)
print("\nRounds and Matches:")
for round_obj in tournament.rounds:
print(f"{round_obj.name} ({round_obj.start_time} - {round_obj.end_time or 'Ongoing'})")
for match in round_obj.matches:
p1, p2 = match.players
white = "White" if match.white_player == 0 else "Black"
black = "Black" if match.white_player == 0 else "White"
print(f" - {p1[0].lastname}, {p1[0].firstname} ({white}) vs "
f"{p2[0].lastname}, {p2[0].firstname} ({black})")
print(f" Scores: {p1[1]} - {p2[1]}")
def display_message(self, message):
"""Display a message to the user.
Args:
message (str): The message to display.
Returns:
None
"""
print(message)
def get_choice(self, prompt):
"""Get a choice from the user with a custom prompt.
Args:
prompt (str): The prompt message for user input.
Returns:
str: The user's input response.
"""
return input(prompt)
def get_match_result(self, player1, player2):
"""Get the result of a match from user input.
Args:
player1 (Player): The first player in the match.
player2 (Player): The second player in the match.
Returns:
int or None: 0 for player1 win, 1 for player2 win, None for draw.
"""
print(f"\nMatch: {player1.lastname}, {player1.firstname} vs {player2.lastname}, "
f"{player2.firstname}")
print("Default outcome is a win/loss (press 1 for Player 1 win, 2 for Player 2 "
"win).")
print("To specify a draw, type 'draw' and confirm twice (very rare in chess "
"tournaments):")
while True:
choice = input(
"Choice (1/2) or 'draw': ").lower()
if choice in ["1", "2"]:
return 0 if choice == "1" else 1
elif choice == "draw":
confirm = input(
"Are you sure this is a draw? Type 'confirm' to proceed, "
"or press Enter to default to win/loss: ").lower()
if confirm == "confirm":
second_confirm = input(
"Confirm draw again (type 'confirm' or press "
"Enter to default to win/loss): ").lower()
if second_confirm == "confirm":
return None
default_choice = random.choice(["1", "2"])
print(f"Defaulting to {default_choice} (win/loss) due to lack of "
"confirmation for draw.")
return 0 if default_choice == "1" else 1
else:
print("Invalid choice, try again (use 1, 2, or 'draw').")
def confirm_end_tournament(self):
"""Confirm with the user to end the tournament.
Returns:
bool: True if confirmed, False otherwise.
"""
return input("End tournament? (yes/no): ").lower() == "yes"
def select_tournament(self, tournaments):
"""Allow user to select a tournament from a list.
Args:
tournaments (list): List of Tournament objects to choose from.
Returns:
Tournament: The selected Tournament object, or None if cancelled.
"""
if not tournaments or tournaments is None:
print("\nNo tournaments available.")
return None
self.display_tournaments(tournaments)
while True:
try:
choice = int(input("Select a tournament by number (or 0 to cancel): "))
if choice == 0:
return None
if 1 <= choice <= len(tournaments):
return tournaments[choice - 1]
print("Invalid choice, try again.")
except ValueError:
print("Please enter a number.")