forked from samia-boubaya/project_01-escape-room-2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
536 lines (416 loc) · 20 KB
/
utils.py
File metadata and controls
536 lines (416 loc) · 20 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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
##############################################################################################
#################### HOW TO USE UTILS ########################################################
def function_name
##############################################################################################
################## DATA LISTs ###############################################################
##############################################################################################
# LIST : actions available to a player
actions = ['explore', 'examine', 'unlock door', 'navigate', 'restart', 'quit','play']
# LIST : spaces
spaces = ['game room', 'bedroom 1', 'bedroom 2', 'living room','outside']
# LIST : items
items = ['couch', 'piano', 'queen bed', 'double bed', 'dresser', "dining table"]
# LIST : doors
doors = ['door A', 'door B', 'door C', 'door D']
# LIST : keys
keys = ['key door A', 'key door B', 'key door C', 'key door D']
##############################################################################################
################## DATA DICTs ###############################################################
##############################################################################################
# Each key in this dictionary represents a room; each value is a list of objects, doors and keys
# Dictionary : GAME AREAS
game_areas = {
"game room" : ['couch', 'piano', 'door A', 'key door A'],
"bedroom 1": ['queen bed', 'door A', 'door B', 'door C', 'key door B'],
"bedroom 2": ['double bed', 'door B', 'dresser', 'key door D', 'key door C'],
"living room": ["dining table", 'door C', 'door D'],
"outside": ["freedom"]
}
#############################################################################################
# Keep track of the player : current space; current item to examine; and inventory of keys
# Dict : GAME STATE
game_state = {
'space_path' : [], # player current space to navigate and make a space path
'item_path' : [], # to select an item to examine for key; and make an item path
'inventory': [], # to store found keys
'time': ["display_clock_countdown"] , #library time for live timer and countdown
}
##############################################################################################
################## FUNCTIONS = ACTIONS ######################################################
##############################################################################################
#### the order of the main functions :
# 0) player_action
### // can still input another action or repeat same one ####
# 1) explore
# // update_item_path(item)
# // return list of items in space
# 2) examine
# // return true if key found
# // return false if key not found and not in inventory
# // return false if key in inventory
# // return
# 3) unlock_door
# // quiz
# // update_door_path(door)
# 4) navigate
# //
# // update_space_path(space)
###################################################################################################################
actions = ['explore', 'examine', 'unlock door', 'navigate', 'restart', 'quit', 'play']
def player_action(player_input: str):
while True:
action = player_input.strip().lower()
# Invalid input → show available actions and ask again
if action not in actions:
print("\nInvalid action! Please choose one of the following:")
print(", ".join(actions))
player_input = input("Enter an action: ")
continue
# Quit the game
if action == 'quit':
print(f"\nPlayer inputs the action: {action}")
print("Quitting the game. Goodbye!")
break
# Restart the game
elif action == 'restart':
print(f"\nPlayer inputs the action: {action}")
print("Game restarting!")
player_input = 'play'
continue # Restart goes back to play automatically
# Play the game
elif action == 'play':
print(f"\nPlayer inputs the action: {action}")
print("Starting the game...")
# You can add your game logic here
player_input = input("Enter next action: ")
continue
# Other valid actions
else:
print(f"\nPlayer inputs the action: {action}")
print(f"Performing action: {action}")
player_input = input("Enter next action: ")
continue
################## PLAYER_ACTION(PLAYER_INPUT) MAIN FUNCTION ######################################################
def player_action(player_input: str):
action = player_input
while player_input in actions:
# Quit the game
if player_input=='quit':
print(f"Player inputs the action: {action}")
print("Quitting the game. Goodbye!")
break
# Restart the game
elif player_input == 'restart':
print(f"Player inputs the action: {action}")
print("Game restarting!")
player_action('play')
# Play the game
elif player_input == 'play':
while player_input=='play' and player_input != 'quit' and player_input != 'restart': # While player_input is not 'quit' and 'restart'
print(f"Player inputs the action: {action}")
return action
# Value Erorr
else:
print("Value Error, choose again!")
################## start_game('play') MAIN FUNCTION ######################################################
def game_start():
return player_action('play')
################## PLAYER_INPUT = EXPLORE ######################################################
# define Function : explore(space)
def explore(space: str):
space_items = []
print(f"You are exploring {space}. You see these items:")
for item in items:
print("-", item)
space_items.append(item)
return space_items
################## PLAYER_INPUT = EXAMINE ######################################################
# define Function : examine
def examine(space:str):
print(f'Here is a list of items in {space}:', explore(space))
select_item= input(f'Select an item to examine:') #select item
print((f'You are examining :{select_item}'))
print(f'Examining the {select_item} carefully...')
#### ITEMS in SPACE ############################################
for select_item in space:
#### GAME ROOM ITEMS ################
# ITEM = PIANO
if select_item == 'couch':
key= ''
check(space, select_item, key)
# ITEM = COUCH
elif select_item == 'piano':
key= 'key door A'
check(space, select_item, key)
#### BEDROOM 1 ITEM ################
# ITEM = QUEEN BED
elif select_item == 'queen bed':
key= 'key door B'
check(space, select_item, key)
#### BEDROOM 2 ITEMS ################
# ITEM = DOUBLE BED
elif select_item == 'double bed':
key= 'key door C'
check(space, select_item, key)
# ITEM = DRESSER
elif select_item == 'dresser':
key= 'key door D'
check(space, select_item, key)
#### LIVING ROOM ITEMS ########
# ITEM = DINNING TABLE
elif select_item == 'dinning table':
key= ''
check(space, select_item, key)
# Re-INPUT
else:
print("Value ERROR !", examine(space))
result=check(space, select_item, key)
return result
################## FUNCTION CHECK ######################################################
#check for key in selected item in current space
# use this function inside examine()
def check(space, select_item, key):
#if found key and not in inventory then update inventory
if ( key!='' and key not in game_state['inventory'] ):
print(f'You found {key} in {select_item}')
update_inventory(key)
result = True
#elif key=='' no key found
elif key=='':
print(f'No key found in {select_item}')
result=False
#else key in inventory
else:
print(f'You already have the key in your inventory {game_state["inventory"]}')
result=False
return result
#####################################################################################################
################## PLAYER_INPUT = UNLOCK DOOR ######################################################
#####################################################################################################
#player_input = 'unlock door'
# action = player_input
# action = 'unlock door'
inventory = game_state['inventory']
action = 'unlock door'
space = 'game room'
door = 'door A'
# define Function : unlock_door(action, door, inventory, space)
action = 'unlock door'
def unlock_door(inventory:list, action, space, door):
while action=='unlock door' and action!='quit' and action!='restart': # While action is not 'quit' and 'restart'
# we check every key and door cuz we have to compare two string 'door A' in 'key door A'
for key in game_state['inventory']:
if door in game_state['inventory'][key]:
print("You have the key in your inventory to unlock it ... POP QUIZ! Answer correctly to unlock it! ")
quiz(door)
if quiz(door)==True:
update_door_path(door)
# unlocked door
while door in doors:
print(f'You chose to unlock {door} in {space}')
if door in space:
door = input("Enter the door you want to try unlock : ").lower() # Player inputs space of choice
print(f'Player chose to try unlock: {door}')
for i in game_state[inventory]:
if key in inventory[i]:
print(f"This key is already in your inventory !")
return True
quiz(door)
update_door_path(door)
return result # if true unlocked if false still locked
############################## QUIZ FUNCTION ###########################################################################################
inventory = game_state['inventory']
key = 'key door A'
def quiz(inventory:list, door:str, key:str):
# Quiz function to unlock doors
for key in inventory:
if door in inventory:
print("You have the key to this door in your inventory ~ you can proceed to unlock!")
#######################################################################################
if door == 'door A': # quiz('door A')
print("Question: What is the primary function of Door A, as suggested by its location in the floor plan?")
print("A) To access the outdoors.")
print("B) To provide entry or exit to a specific room.")
print("C) To serve as a decorative element.")
answer = input("Enter your choice (A, B, or C): ").upper()
if answer == "B":
print("Correct! Door A is most likely for entering or exiting a room.")
quiz_answer=True
else:
print("Incorrect. Try another time!")
quiz_answer=False
return player_action('play')
#######################################################################################
elif door == 'door B': # quiz('door B')
print("Question: Considering the layout, which room is Door B most likely connected to?")
print("A) The Game Room")
print("B) Bedroom 1")
print("C) The Outdoors")
answer = input("Enter your choice (A, B, or C): ").upper()
if answer == "B":
print("Correct! Based on the plan, Door B likely leads to Bedroom 1.")
quiz_answer=True
else:
print("Incorrect. Try another time!")
quiz_answer=False
return player_action('play')
#######################################################################################
elif door == 'door C': # quiz('door C')
print("Question: If you wake up on the couch, and the key to Door C is found nearby, what is the most logical room Door C leads to, considering the floor plan?")
print("A) The Game Room")
print("B) Bedroom 2")
print("C) The Outdoors")
answer = input("Enter your choice (A, B, or C): ").upper()
if answer == "C":
print("Correct! It makes sense that Door C might lead outside.")
quiz_answer=True
else:
print("Incorrect. Consider the layout again!")
quiz_answer=False
return player_action('play')
#######################################################################################
elif door == 'door D': # quiz('door D')
print("Question: Considering the floor plan, and the fact you woke up on the couch, where is Door D most likely located?")
print("A) In the Game Room")
print("B) In Bedroom 1")
print("C) Not visible on the plan")
answer = input("Enter your choice (A, B, or C): ").upper()
if answer == "C":
print("Correct! Since Door D isn't shown, it's not visible on the plan.")
quiz_answer=True
else:
print("Incorrect. Maybe Door D is a secret door?")
quiz_answer=False
return player_action('play')
#######################################################################################
return quiz_answer
######################################################################################################
################## GAME PATHS ######################################################
# DICTIONARY : to track paths taken by player spaces, items, doors
game_paths = {
'space_path': [],
'item_path': [],
'door_path': [],
}
# update space path [game room, bedroom 1, bedroom 2...]
def update_space_path(current_space:str):
game_paths['space path'].append(current_space)
return game_paths['space path']
# update item path [couch, piano, queen bed...]
def update_item_path(item:str):
game_paths['item path'].append(item)
return game_paths['item path']
# update door path [door A, door B, door C, ...]
def update_door_path(door:str):
game_paths['door path'].append(door)
return game_paths['door path']
# update inventory [key door A, key door B, key door C...]
def update_inventory(key:str):
game_paths['inventory'].append(key)
return game_paths['inventory']
# display_clock_countdown
################## UPDATE GAME STATE ######################################################
game_state = {
'space_path': [],
'item_path': [],
'door_path': [],
'inventory': [],
'time':["display_clock_countdown"]
}
def update_inventory(key: str, space: str):
game_state["inventory"].append(key)
return game_state["inventory"]
def update_game_state(door: str, key: str, item: str, space: str):
update_space_path(space) #update space
update_item_path(item) #update item
update_door_path(door) #update door
update_inventory(key) #update key
display_clock_countdown() #run clock countdown
################## PLAYER_INPUT = NAVIGATE ######################################################
print('Player is navigating to a new space!')
def navigate(action, space, door, inventory):
print(f'Navigating through the {door}')
if door in game_paths['door_path'] and space in spaces:
# space is new_space
while (action == 'unlock door' and action != 'quit' and action != 'restart'): # While loop
if ('door A' in space) and ('door B' not in space) and ('door C' not in space) and ('door D' not in space):
update_space_path('game room')
elif ('door A' in space) and ('door B' in space) and ('door C' in space) and ('door D' not in space):
update_space_path('bedroom 1')
elif ('door A' not in space) and ('door B' in space) and ('door C' not in space) and ('door D' not in space):
update_space_path('bedroom 2')
elif ('door A' not in space) and ('door B' not in space) and ('door C' in space) and ('door D' in space):
update_space_path('living room')
elif ('door A' not in space) and ('door B' not in space) and ('door C' not in space) and ('door D' in space):
update_space_path('outside')
print("FREEDOM | YOU WIN !")
print(game_state)
break
else:
("UNKNOWN SPACE in the system?")
print(f'You are now in{space}')
update_space_path(space)
################## RESTART FUNCTION ######################################################
def restart(answer: bool):
reset_game_state()
################## PLAYER_INPUT = RESTART ######################################################
def reset_game_state():
answer = input("Do you want to restart the game? Enter: YES or NO")
while answer !='YES' and answer!='NO':
answer = input("To restart Enter only : YES or NO")
if answer.low() == 'yes':
print("Restarting the game...")
game_state["space_path"].append('game room')
game_state["item_path"].clear()
game_state["inventory"].clear()
game_state["door_path"].clear()
elif answer.low() == 'no':
print("Continue to play...")
player_action('play')
else:
print("Value Error: Enter YES or NO")
return game_state
################## PLAYER_INPUT = QUIT ######################################################
def quit():
print("Quitting the game...")
return game_state
##########################################################################################################
################## EXTRA FEATURES CAN BE ADDED HERE ######################################################
##########################################################################################################
# define a function that starts the clock, countdown, and display
''' def display_clock_countdown(t): '''
# Starts the live clock and countdown display for t minutes.
# Example: Start 5-minute countdown
''' display_clock_countdown(5) '''
# define Function to display live clock and countdown timer
import time
import sys
from datetime import datetime, timedelta
def display_clock_countdown(minutes):
try:
while True: # Repeat indefinitely (change True to play=true)
end_time = datetime.now() + timedelta(minutes=minutes)
while True:
# Current time
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
# Remaining time
remaining_time = end_time - now
if remaining_time.total_seconds() <= 0:
print(f"\rClock: {current_time} | Countdown: 00:00:00 ⌛", end="")
break
hours, remainder = divmod(int(remaining_time.total_seconds()), 3600)
mins, secs = divmod(remainder, 60)
countdown_str = f"{hours:02}:{mins:02}:{secs:02}"
# Print live clock and countdown on one line
print(f"\r🕰️ Clock: {current_time} | ⏳ Countdown: {countdown_str}", end="")
sys.stdout.flush()
time.sleep(1)
# Big "Time's Up" banner
print("\n" + "*"*50)
print("***** TIME'S UP! *****")
print("***** Restarting countdown... *****")
print("*"*50 + "\n")
time.sleep(1) # Optional pause before restarting
except KeyboardInterrupt:
print("\nCountdown stopped manually.")