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
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
|
from tkinter import *
from tkinter import ttk
from tkinter import simpledialog
import GameObject
from PIL import Image, ImageTk
PORTRAIT_LAYOUT = False
# Define all 22 locations
ROOM_001 = 1
ROOM_002 = 2
ROOM_003 = 3
ROOM_004 = 4
ROOM_005 = 5
ROOM_006 = 6
ROOM_007 = 7
ROOM_008 = 8
ROOM_009 = 9
ROOM_010 = 10
ROOM_011 = 11
ROOM_012 = 12
ROOM_013 = 13
ROOM_014 = 14
ROOM_015 = 15
ROOM_016 = 16
ROOM_017 = 17
ROOM_018 = 18
ROOM_019 = 19
ROOM_020 = 20
ROOM_021 = 21
ROOM_022 = 22
# Map connections - each room maps to [north, south, east, west]
ROOM_CONNECTIONS = {
ROOM_001: [0, ROOM_006, ROOM_002, 0],
ROOM_002: [0, ROOM_006, ROOM_003, ROOM_001],
ROOM_003: [0, 0, ROOM_004, ROOM_002],
ROOM_004: [0, 0, ROOM_005, ROOM_003],
ROOM_005: [0, 0, 0, ROOM_004],
ROOM_006: [ROOM_002, 0, ROOM_007, 0],
ROOM_007: [0, 0, ROOM_008, ROOM_006],
ROOM_008: [0, ROOM_011, 0, ROOM_007],
ROOM_009: [0, ROOM_012, 0, 0],
ROOM_010: [0, 0, ROOM_011, 0],
ROOM_011: [ROOM_008, ROOM_015, 0, ROOM_010],
ROOM_012: [ROOM_009, 0, ROOM_013, 0],
ROOM_013: [0, ROOM_017, ROOM_014, ROOM_012],
ROOM_014: [0, 0, 0, ROOM_013],
ROOM_015: [ROOM_011, ROOM_019, ROOM_016, 0],
ROOM_016: [0, 0, 0, ROOM_015],
ROOM_017: [ROOM_013, ROOM_020, ROOM_018, 0],
ROOM_018: [0, ROOM_021, ROOM_019, ROOM_017],
ROOM_019: [ROOM_015, 0, 0, ROOM_018],
ROOM_020: [ROOM_017, 0, 0, 0],
ROOM_021: [ROOM_018, 0, ROOM_022, 0],
ROOM_022: [0, 0, 0, ROOM_021]
}
command_widget = None
image_label = None
description_widget = None
inventory_widget = None
map_widget = None
north_button = None
south_button = None
east_button = None
west_button = None
root = None
refresh_location = True
refresh_objects_visible = True
current_location = ROOM_021 # Starting room as per README
end_of_game = False
player_health = 100
player_gold = 0
# Track visited rooms for map display
visited_rooms = {ROOM_021} # Start with room 021 as visited
discovered_rooms = set() # Rooms we know exist but haven't entered (locked doors, etc.)
# Create all game objects based on README specifications
tripwire = GameObject.GameObject("tripwire", ROOM_001, False, True, False, "A dangerous tripwire blocks your path")
snake_002 = GameObject.GameObject("snake", ROOM_002, False, True, False, "A deadly snake coiled and ready to strike")
guard = GameObject.GameObject("guard", ROOM_004, False, True, False, "A stern guard blocks the way")
spider_007 = GameObject.GameObject("spider", ROOM_007, False, True, False, "A large spider with venomous fangs")
spider_killer_sword = GameObject.GameObject("spider killer sword", ROOM_008, True, True, False, "A gleaming sword effective against all creatures")
big_spider = GameObject.GameObject("big spider", ROOM_009, False, True, False, "An enormous spider, bigger than the others")
giant_bat = GameObject.GameObject("giant bat", ROOM_010, False, True, False, "A massive bat with razor-sharp claws")
pink_key = GameObject.GameObject("pink key", ROOM_011, True, True, False, "A bright pink key")
rats = GameObject.GameObject("rats", ROOM_012, False, True, False, "Four rats scurrying about - count them!")
snake_013 = GameObject.GameObject("snake 2", ROOM_013, False, True, False, "Another deadly snake")
green_key = GameObject.GameObject("green key", ROOM_014, True, True, False, "A vibrant green key")
spider_015 = GameObject.GameObject("spider", ROOM_015, False, True, False, "A spider waiting in the shadows")
merchant = GameObject.GameObject("merchant", ROOM_016, False, True, False, "A merchant selling weapons")
bow = GameObject.GameObject("bow", ROOM_016, True, False, False, "A powerful bow and arrows")
rusty_sword = GameObject.GameObject("rusty sword", ROOM_020, True, True, False, "An old but still sharp rusty sword")
blue_key = GameObject.GameObject("blue key", ROOM_010, True, False, False, "A deep blue key (obtained from giant bat)")
yellow_key = GameObject.GameObject("yellow key", ROOM_022, True, True, False, "A bright yellow key")
game_objects = [tripwire, snake_002, guard, spider_007, spider_killer_sword, big_spider,
giant_bat, pink_key, rats, snake_013, green_key, spider_015, merchant,
bow, rusty_sword, blue_key, yellow_key]
def perform_command(verb, noun):
if (verb == "GO"):
perform_go_command(noun)
elif ((verb == "N") or (verb == "S") or (verb == "E") or (verb == "W")):
perform_go_command(verb)
elif ((verb == "NORTH") or (verb == "SOUTH") or (verb == "EAST") or (verb == "WEST")):
perform_go_command(verb)
elif (verb == "GET"):
perform_get_command(noun)
elif (verb == "PUT"):
perform_put_command(noun)
elif (verb == "LOOK"):
perform_look_command(noun)
elif (verb == "X"):
perform_x_command(noun)
elif (verb == "ATTACK" or verb == "KILL" or verb == "FIGHT"):
perform_attack_command(noun)
elif (verb == "USE"):
perform_use_command(noun)
elif (verb == "BUY" or verb == "PURCHASE"):
perform_buy_command(noun)
elif (verb == "GIVE" or verb == "PAY"):
perform_give_command(noun)
elif (verb == "ENTER" or verb == "UNLOCK"):
perform_enter_command(noun)
elif (verb == "INVENTORY" or verb == "I"):
perform_inventory_command()
elif (verb == "HEALTH" or verb == "HP"):
perform_health_command()
elif (verb == "HELP"):
perform_help_command()
else:
print_to_description("š¤ I don't understand that command. Type HELP for available commands.")
def perform_go_command(direction):
global current_location
global refresh_location
if (direction == "N" or direction == "NORTH"):
new_location = get_location_to_north()
elif (direction == "S" or direction == "SOUTH"):
new_location = get_location_to_south()
elif (direction == "E" or direction == "EAST"):
new_location = get_location_to_east()
elif (direction == "W" or direction == "WEST"):
new_location = get_location_to_west()
else:
new_location = 0
if (new_location == 0):
print_to_description("š« You can't go that way!")
else:
# Check special movement restrictions
movement_blocked = check_movement_restrictions(current_location, new_location)
if movement_blocked:
return # Don't move if blocked
# Check for dangerous rooms
if check_dangerous_entry(new_location):
return # Don't move if player dies
current_location = new_location
visited_rooms.add(current_location) # Mark room as visited
refresh_location = True
def check_movement_restrictions(from_room, to_room):
"""Check if movement is blocked by locks, guards, etc."""
global player_gold, discovered_rooms
# Room 007 requires pink key
if to_room == ROOM_007 and not has_item_carried("PINK KEY"):
print_to_description("šø A pink lock blocks this door. You need a pink key!")
discovered_rooms.add(to_room) # You discovered this room exists
return True
# Room 008 requires green key
if to_room == ROOM_008 and not has_item_carried("GREEN KEY"):
print_to_description("š A green lock seals this passage. You need a green key!")
discovered_rooms.add(to_room) # You discovered this room exists
return True
# Room 014 requires yellow key
if to_room == ROOM_014 and not has_item_carried("YELLOW KEY"):
print_to_description("š A yellow lock prevents entry. You need a yellow key!")
discovered_rooms.add(to_room) # You discovered this room exists
return True
# Room 022 requires blue key
if to_room == ROOM_022 and not has_item_carried("BLUE KEY"):
print_to_description("š A blue lock blocks this final door. You need a blue key!")
discovered_rooms.add(to_room) # You discovered this room exists
return True
# Room 005 requires payment to guard in room 004
if to_room == ROOM_005 and from_room == ROOM_004:
if get_game_object("guard").visible: # Guard still there
print_to_description("āļø The guard blocks your path! You must pay him gold to pass!")
discovered_rooms.add(to_room) # You discovered this room exists
return True
return False
def check_dangerous_entry(room):
"""Check if entering a room without proper equipment is fatal"""
global end_of_game
# Room 002 - Snake kills you without sword
if room == ROOM_002 and not has_weapon(["RUSTY SWORD", "SPIDER KILLER SWORD"]):
snake = get_game_object("snake")
if snake and snake.location == ROOM_002 and snake.visible:
print_to_description("š As you enter, the snake strikes! Its venomous fangs pierce your flesh!")
print_to_description("š You collapse, dying from the snake's deadly bite!")
end_game_death()
return True
# Room 013 - Another snake
if room == ROOM_013 and not has_weapon(["RUSTY SWORD", "SPIDER KILLER SWORD"]):
snake = get_game_object("snake 2")
if snake and snake.location == ROOM_013 and snake.visible:
print_to_description("š Another snake lunges at you as you enter!")
print_to_description("š Without a weapon, you're doomed!")
end_game_death()
return True
return False
def perform_get_command(object_name):
global refresh_objects_visible
game_object = get_game_object(object_name)
if not (game_object is None):
if (game_object.location != current_location or game_object.visible == False):
print_to_description("You don't see one of those here!")
elif (game_object.movable == False):
print_to_description("You can't pick it up!")
elif (game_object.carried == True):
print_to_description("You are already carrying it")
else:
#handle special conditions
if (False):
print_to_description("special condition")
else:
#pick up the object
game_object.carried = True
game_object.visible = False
refresh_objects_visible = True
else:
print_to_description("You don't see one of those here!")
def perform_put_command(object_name):
global refresh_objects_visible
game_object = get_game_object(object_name)
if not (game_object is None):
if (game_object.carried == False):
print_to_description("You are not carrying one of those.")
else:
#put down the object
game_object.location = current_location
game_object.carried = False
game_object.visible = True
refresh_objects_visible = True
else:
print_to_description("You are not carrying one of those!")
def perform_look_command(object_name):
global refresh_location
global refresh_objects_visible
game_object = get_game_object(object_name)
if not (game_object is None):
if ((game_object.carried == True) or (game_object.visible and game_object.location == current_location)):
print_to_description(game_object.description)
else:
#recognized but not visible
print_to_description("You can't see one of those!")
#special cases - when certain objects are looked at, others are revealed!
# For example, looking at rats gives you the code hint
if object_name.upper() == "RATS":
print_to_description("š” You count the rats carefully... there are exactly FOUR of them!")
print_to_description("š¢ Perhaps this number is significant somewhere...")
else:
if (object_name == ""):
#generic LOOK
refresh_location = True
refresh_objects_visible = True
else:
#not visible recognized
print_to_description("You can't see one of those!")
def perform_x_command(object_name):
game_object = get_game_object(object_name)
if not (game_object is None):
print_to_description("You examine the " + object_name + ": " + game_object.description)
else:
print_to_description("There is no " + object_name)
def perform_attack_command(target_name):
global player_health, player_gold, refresh_objects_visible
target = get_game_object(target_name)
if not target or target.location != current_location or not target.visible:
print_to_description("š« There's nothing here to attack!")
return
# Check what weapons player has
weapons = get_carried_weapons()
if target_name.upper() == "SNAKE" or target_name.upper() == "SNAKE 2":
if has_weapon(["RUSTY SWORD", "SPIDER KILLER SWORD"]):
print_to_description("āļø You strike the snake with your sword! The serpent writhes and dies!")
target.visible = False
refresh_objects_visible = True
else:
print_to_description("š The snake bites you! You die from its venomous fangs!")
end_game_death()
elif target_name.upper() == "SPIDER":
if has_weapon(["RUSTY SWORD", "SPIDER KILLER SWORD"]):
print_to_description("š·ļø You slash at the spider! It falls dead to the ground!")
target.visible = False
refresh_objects_visible = True
else:
print_to_description("š The spider's venomous bite kills you!")
end_game_death()
elif target_name.upper() == "BIG SPIDER":
if has_weapon(["SPIDER KILLER SWORD"]):
print_to_description("š”ļø The Spider Killer Sword glows with power! You slay the giant spider!")
target.visible = False
player_gold += 50
print_to_description("š° You find 50 gold pieces under the spider's corpse!")
refresh_objects_visible = True
else:
print_to_description("š Your weapon is ineffective! The giant spider devours you!")
end_game_death()
elif target_name.upper() == "GIANT BAT":
if has_weapon(["BOW"]):
print_to_description("š¹ Your arrow finds its mark! The giant bat crashes to the ground!")
target.visible = False
# Make blue key available
blue_key.visible = True
blue_key.location = current_location
print_to_description("š A blue key falls from the bat's claws!")
refresh_objects_visible = True
else:
print_to_description("š The bat's claws tear you apart!")
end_game_death()
elif target_name.upper() == "MERCHANT":
if has_weapon(["RUSTY SWORD", "SPIDER KILLER SWORD"]):
print_to_description("š You kill the merchant! You can now take his bow.")
target.visible = False
bow.visible = True
refresh_objects_visible = True
else:
print_to_description("š”ļø The merchant defends himself! You need a weapon!")
else:
print_to_description("š« You can't attack that!")
def perform_use_command(item_name):
global current_location, refresh_location, refresh_objects_visible
if not has_item_carried(item_name):
print_to_description("š« You don't have that item!")
return
if item_name.upper() == "PINK KEY":
if current_location == ROOM_006 and get_location_to_east() == ROOM_007:
print_to_description("šø The pink key unlocks the door to the east!")
else:
print_to_description("šļø The pink key doesn't work here.")
elif item_name.upper() == "GREEN KEY":
if current_location == ROOM_007 and get_location_to_east() == ROOM_008:
print_to_description("š The green key unlocks the armory door!")
else:
print_to_description("šļø The green key doesn't work here.")
elif item_name.upper() == "BLUE KEY":
if current_location == ROOM_021 and get_location_to_east() == ROOM_022:
print_to_description("š The blue key unlocks the final chamber!")
else:
print_to_description("šļø The blue key doesn't work here.")
elif item_name.upper() == "YELLOW KEY":
if current_location == ROOM_013 and get_location_to_east() == ROOM_014:
print_to_description("š The yellow key opens the way to the emerald chamber!")
else:
print_to_description("šļø The yellow key doesn't work here.")
else:
print_to_description("𤷠You're not sure how to use that.")
def perform_buy_command(item_name):
global player_gold, refresh_objects_visible
if current_location != ROOM_016:
print_to_description("š« There's no merchant here!")
return
if not get_game_object("merchant").visible:
print_to_description("š« The merchant is dead!")
return
if item_name.upper() == "BOW":
if player_gold >= 50:
player_gold -= 50
bow.visible = False # Remove from shop
bow.carried = True # Player gets it
print_to_description("š¹ You buy the bow for 50 gold! What a fine weapon!")
refresh_objects_visible = True
else:
print_to_description("šø You need 50 gold to buy the bow!")
else:
print_to_description("š« The merchant doesn't sell that.")
def perform_give_command(item_name):
global current_location, refresh_location
if current_location == ROOM_004 and item_name.upper() == "GOLD":
if player_gold >= 10:
player_gold -= 10
print_to_description("š° You give the guard 10 gold. He steps aside!")
print_to_description("šŖ The way east is now open!")
else:
print_to_description("šø You need at least 10 gold to pay the guard!")
else:
print_to_description("š« Nobody here wants that.")
def perform_enter_command(code):
global refresh_objects_visible
if current_location == ROOM_011:
if code == "4":
print_to_description("ā
Correct! The lock clicks open! The door to room 8 is now accessible!")
print_to_description("šļø You can now reach the secret passage!")
else:
print_to_description("ā That code doesn't work. Look for clues around the dungeon...")
else:
print_to_description("š« There's nothing to unlock here.")
def perform_inventory_command():
describe_current_inventory()
def perform_health_command():
print_to_description(f"ā¤ļø Health: {player_health}/100 š° Gold: {player_gold}")
def perform_help_command():
help_text = """
š® ADVENTURE GAME COMMANDS š®
Movement: N, S, E, W (or NORTH, SOUTH, EAST, WEST)
Items: GET [item], PUT [item], LOOK [item]
Combat: ATTACK [creature], KILL [creature]
Special: USE [key], BUY [item], GIVE [item]
Info: INVENTORY (or I), HEALTH, HELP
š”ļø Combat Tips:
⢠Snakes/Spiders: Need sword to kill safely
⢠Giant Spider: Only Spider Killer Sword works
⢠Giant Bat: Only bow can kill it
⢠Get weapons before fighting!
šļø Keys unlock specific doors - try USE [key] near locked doors!
š° Collect gold to buy items or pay guards!
"""
print_to_description(help_text)
# Helper functions
def has_weapon(weapon_names):
for weapon_name in weapon_names:
if has_item_carried(weapon_name):
return True
return False
def has_item_carried(item_name):
for obj in game_objects:
if obj.carried and obj.name.upper() == item_name.upper():
return True
return False
def get_carried_weapons():
weapons = []
for obj in game_objects:
if obj.carried and any(weapon in obj.name.upper() for weapon in ["SWORD", "BOW"]):
weapons.append(obj.name)
return weapons
def end_game_death():
global end_of_game
print_to_description("š GAME OVER! You have died!")
print_to_description("š Restart the game to try again!")
end_of_game = True
def describe_current_location():
room_descriptions = {
ROOM_001: "š THE ENTRANCE CHAMBER š\nYou stand in a dimly lit stone chamber. Ancient torches flicker on the walls, casting dancing shadows. A dangerous tripwire glints in the dim light - one wrong step could be fatal!",
ROOM_002: "š THE SERPENT'S LAIR š\nA musty cavern filled with the sound of hissing. Bones litter the floor as a deadly snake coils in the corner, its eyes gleaming with malice. The air is thick with danger.",
ROOM_003: "šļø THE MARBLE CORRIDOR šļø\nAn elegant hallway with polished marble floors and ornate pillars. Sunlight streams through high windows, creating patterns of light and shadow on the pristine walls.",
ROOM_004: "āļø THE GUARD POST āļø\nA fortified checkpoint with iron gates. A stern guard in gleaming armor blocks your path, his hand resting on his sword hilt. A sign reads: 'GOLD REQUIRED FOR PASSAGE'",
ROOM_005: "š THE TREASURE ANTECHAMBER š\nA lavishly decorated room with golden tapestries and jeweled walls. This appears to be the entrance to something very important - victory feels close!",
ROOM_006: "šø THE ROSE GARDEN šø\nA beautiful underground garden with blooming roses and crystal fountains. The air is sweet but there's an underlying tension - something pink glimmers nearby.",
ROOM_007: "š·ļø THE SPIDER'S WEB š·ļø\nCobwebs drape from every surface in this dark chamber. A large spider watches you from its web, and you notice a green shimmer that might be a key trapped in the silk.",
ROOM_008: "āļø THE ARMORY āļø\nWeapons line the walls of this well-maintained armory. Swords, shields, and armor gleam in the torchlight. A particularly magnificent spider-killer sword catches your eye!",
ROOM_009: "šøļø THE GIANT SPIDER'S DOMAIN šøļø\nA massive cavern filled with enormous webs. In the center lurks the biggest spider you've ever seen - its legs span wider than you are tall. Gold glitters beneath its bulk.",
ROOM_010: "š¦ THE BAT CAVE š¦\nThe ceiling of this cavern is alive with the sound of beating wings. A giant bat hangs upside down, its red eyes fixed on you. Something blue glints in its talons.",
ROOM_011: "šļø THE KEY CHAMBER šļø\nA circular room with a mysterious combination lock on one wall. A bright pink key sits on a pedestal, but the lock mechanism displays four empty slots. What could the code be?",
ROOM_012: "š THE RAT WARREN š\nThis room teems with life as four large rats scurry about, their eyes glowing in the darkness. They seem to be trying to tell you something important - perhaps their number holds significance?",
ROOM_013: "š THE SECOND SERPENT'S DEN š\nAnother snake has made its home here, coiled around what appears to be a yellow key. The serpent's forked tongue flickers as it tastes your fear in the air.",
ROOM_014: "š THE EMERALD CHAMBER š\nGreen light emanates from the walls of this mystical chamber. Everything has an ethereal green glow, including a beautiful green key that pulses with magical energy.",
ROOM_015: "š·ļø THE SHADOW SPIDER'S LAIR š·ļø\nDarkness clings to this room like a living thing. A spider lurks in the shadows, nearly invisible until it moves. Your skin crawls as you sense its predatory gaze.",
ROOM_016: "šŖ THE MERCHANT'S SHOP šŖ\nA well-lit trading post filled with goods and weapons. A friendly merchant grins at you from behind his counter, a magnificent bow displayed prominently among his wares.",
ROOM_017: "šļø THE GREAT HALL šļø\nA vast chamber with soaring ceilings and grand architecture. Your footsteps echo in the enormous space, making you feel small and alone in this ancient place.",
ROOM_018: "ā” THE NEXUS CHAMBER ā”\nA hub of activity with passages leading in all directions. Strange energy crackles in the air, and you sense this room is somehow central to everything happening here.",
ROOM_019: "š THE CRYSTAL CAVERN š\nShimmering crystals of every color line the walls, creating a breathtaking natural cathedral. The light refracts into rainbow patterns that dance across the rocky surfaces.",
ROOM_020: "āļø THE ABANDONED ARMORY āļø\nRust and age have claimed this forgotten weapons cache. Among the debris, you spot the dull gleam of a rusty sword - still sharp despite its weathered appearance.",
ROOM_021: "š THE STARTING CHAMBER š \nYour adventure begins here! This comfortable stone chamber feels like a safe haven. A blue door to the east beckons you toward unknown adventures and treasures.",
ROOM_022: "šļø THE FINAL KEY CHAMBER šļø\nSunlight streams through a window in this bright chamber. A yellow key sits on a simple wooden table - perhaps this is what you need to unlock your destiny!"
}
if current_location in room_descriptions:
print_to_description(room_descriptions[current_location])
else:
print_to_description(f"š UNKNOWN LOCATION #{current_location} š\nYou find yourself in an mysterious place that defies description...")
def set_current_image():
"""Load room-specific images"""
try:
# Try to load the specific room image first
room_image_file = f'res/room_{current_location:03d}.png'
image_label.img = ImageTk.PhotoImage(Image.open(room_image_file))
image_label.config(image=image_label.img)
except Exception as e:
# Fallback to original images if room-specific image doesn't exist
try:
image_files = ['res/blank-1.gif', 'res/blank-2.gif', 'res/blank-3.gif', 'res/blank-4.gif']
image_index = (current_location - 1) % len(image_files)
image_file = image_files[image_index]
if image_file.endswith('.gif'):
image_label.img = PhotoImage(file=image_file)
else:
image_label.img = ImageTk.PhotoImage(Image.open(image_file))
image_label.config(image=image_label.img)
except:
# If everything fails, just show text
pass
def get_location_to_north():
if current_location in ROOM_CONNECTIONS:
return ROOM_CONNECTIONS[current_location][0] # North is index 0
return 0
def get_location_to_south():
if current_location in ROOM_CONNECTIONS:
return ROOM_CONNECTIONS[current_location][1] # South is index 1
return 0
def get_location_to_east():
if current_location in ROOM_CONNECTIONS:
return ROOM_CONNECTIONS[current_location][2] # East is index 2
return 0
def get_location_to_west():
if current_location in ROOM_CONNECTIONS:
return ROOM_CONNECTIONS[current_location][3] # West is index 3
return 0
def get_game_object(object_name):
sought_object = None
for current_object in game_objects:
if (current_object.name.upper() == object_name):
sought_object = current_object
break
return sought_object
def describe_current_visible_objects():
object_count = 0
object_list = ""
for current_object in game_objects:
if ((current_object.location == current_location) and (current_object.visible == True) and (current_object.carried == False)):
object_list = object_list + ("," if object_count > 0 else "") + current_object.name
object_count = object_count + 1
print_to_description("You see: " + (object_list + "." if object_count > 0 else "nothing special."))
def describe_current_inventory():
object_count = 0
object_list = ""
for current_object in game_objects:
if (current_object.carried):
object_list = object_list + ("," if object_count > 0 else "") + current_object.name
object_count = object_count + 1
inventory = f"ā¤ļø Health: {player_health}/100\nš° Gold: {player_gold}\n\nš Carrying: " + (object_list if object_count > 0 else "nothing")
inventory_widget.config(state = "normal")
inventory_widget.delete(1.0, END)
inventory_widget.insert(1.0, inventory)
inventory_widget.config(state = "disabled")
def handle_special_condition():
global end_of_game
# Check for victory condition - reaching the treasure chamber
if current_location == ROOM_005:
print_to_description("š CONGRATULATIONS! š")
print_to_description("š You have reached the legendary treasure chamber!")
print_to_description("⨠Countless riches surround you - gold, jewels, and magical artifacts!")
print_to_description("š YOU HAVE WON THE ADVENTURE! š")
print_to_description("š Thank you for playing this spectacular adventure game!")
end_of_game = True
# Check for tripwire in room 001
elif current_location == ROOM_001:
tripwire_obj = get_game_object("tripwire")
if tripwire_obj and tripwire_obj.visible:
print_to_description("ā ļø CAREFUL! There's a dangerous tripwire here!")
print_to_description("š” Try to examine it or step carefully around it...")
def print_to_description(output, user_input=False):
description_widget.config(state = 'normal')
description_widget.insert(END, output)
if (user_input):
description_widget.tag_add("blue_text", CURRENT + " linestart", END + "-1c")
description_widget.tag_configure("blue_text", foreground = 'blue')
description_widget.insert(END, '\n')
description_widget.config(state = 'disabled')
description_widget.see(END)
def create_map_display():
"""Create a simple, working ASCII map with room names"""
# Count rooms for stats
visited_count = len(visited_rooms)
discovered_count = len(discovered_rooms)
total_rooms = 22
# Define room names for legend
room_names = {
1: "Entrance Chamber",
2: "Serpent's Lair",
3: "Marble Corridor",
4: "Guard Post",
5: "Treasure Chamber",
6: "Rose Garden",
7: "Spider's Web",
8: "Armory",
9: "Giant Spider's Domain",
10: "Bat Cave",
11: "Key Chamber",
12: "Rat Warren",
13: "Second Serpent's Den",
14: "Emerald Chamber",
15: "Shadow Spider's Lair",
16: "Merchant's Shop",
17: "Great Hall",
18: "Nexus Chamber",
19: "Crystal Cavern",
20: "Abandoned Armory",
21: "Starting Chamber",
22: "Final Key Chamber"
}
# Start with the basic map template using numbers
template = [
" [001]<->[002]<->[003]<->[004]<->[005]",
" A ",
" | ",
" V ",
" [006]<->[007]<->[008] ",
" A ",
" | ",
" V ",
" [009] [010]<->[011] ",
" A A ",
" | | ",
" V V ",
" [012]<->[013]<->[014] [015]<->[016] ",
" A A ",
" | | ",
" V V ",
" [017]<->[018]<->[019] ",
" A A ",
" | | ",
" V V ",
" [020] [021]<->[022] "
]
# Convert template to string for processing
map_text = "\n".join(template)
# Replace room placeholders with status indicators
for room_num in range(1, 23):
old_text = f"[{room_num:03d}]"
if room_num == current_location:
new_text = f"[ā
{room_num:02d}]"
elif room_num in visited_rooms:
new_text = f"[ā{room_num:02d}]"
elif room_num in discovered_rooms:
new_text = "[???]"
else:
new_text = " " # Hide completely unknown rooms
map_text = map_text.replace(old_text, new_text)
# Clean up connections - remove arrows that connect to hidden rooms
import re
map_lines = map_text.split('\n')
cleaned_lines = []
for line in map_lines:
# Remove arrows that connect to empty spaces (hidden rooms)
# Pattern: <-> followed by spaces, or spaces followed by <->
cleaned_line = re.sub(r'<-> ', ' ', line) # Remove arrow going to hidden room
cleaned_line = re.sub(r' <->', ' ', cleaned_line) # Remove arrow coming from hidden room
cleaned_line = re.sub(r'<-> ', ' ', cleaned_line) # Remove longer connections to hidden
cleaned_line = re.sub(r' <->', ' ', cleaned_line) # Remove longer connections from hidden
# Only include lines that have visible rooms or connections between visible rooms
if any(char in cleaned_line for char in "ā
ā?"):
cleaned_lines.append(cleaned_line.rstrip())
map_text = "\n".join(cleaned_lines)
# Build legend for visible rooms
legend_lines = []
all_visible_rooms = visited_rooms.union(discovered_rooms)
if all_visible_rooms:
legend_lines.append("ROOM LEGEND:")
for room_num in sorted(all_visible_rooms):
if room_num in room_names:
status = "ā
HERE" if room_num == current_location else "ā VISITED" if room_num in visited_rooms else "? DISCOVERED"
legend_lines.append(f" {room_num:02d}: {room_names[room_num]} ({status})")
legend_text = "\n".join(legend_lines)
return f"""šŗļø EXPLORATION MAP šŗļø
{'='*35}
ā
= Current Location ā = Visited ? = Discovered
Visited: {visited_count} Discovered: {discovered_count} Total: {total_rooms}
{'='*35}
{map_text}
{legend_text}
"""
def update_map_display():
"""Update the map widget with current exploration status"""
global map_widget
if map_widget:
map_text = create_map_display()
map_widget.config(state="normal")
map_widget.delete(1.0, END)
map_widget.insert(1.0, map_text)
map_widget.config(state="disabled")
def build_interface():
global command_widget
global image_label
global description_widget
global inventory_widget
global map_widget
global north_button
global south_button
global east_button
global west_button
global root
root = Tk()
root.title("š° LEGENDARY ADVENTURE GAME š°")
root.resizable(0,0)
style = ttk.Style()
style.configure("BW.TLabel", foreground="black", background="white")
image_label = ttk.Label(root)
image_label.grid(row=0, column=0, rowspan=2, columnspan=1, padx=2, pady=2)
description_widget = Text(root, width=50, height=12, relief=GROOVE, wrap='word')
welcome_message = """š WELCOME TO THE LEGENDARY ADVENTURE! š
You are a brave adventurer seeking the ultimate treasure!
Navigate through 22 dangerous rooms filled with creatures,
puzzles, and ancient mysteries.
š”ļø Fight monsters with the right weapons!
šļø Collect keys to unlock secret doors!
š° Gather gold to buy equipment and pay guards!
š Reach the treasure chamber to claim victory!
Type HELP for commands. Your quest begins now!
Good luck, brave adventurer! āļøāØ
"""
description_widget.insert(1.0, welcome_message)
description_widget.config(state="disabled")
description_widget.grid(row=0, column=1, padx=2, pady=2)
# Add map widget
map_widget = Text(root, width=45, height=25, relief=GROOVE, wrap='none',
font=("Courier", 8), state="disabled")
map_widget.grid(row=0, column=2, rowspan=3, padx=2, pady=2)
command_widget = ttk.Entry(root, width=50, style="BW.TLabel")
command_widget.bind('<Return>', return_key_enter)
command_widget.grid(row=1, column=1, padx=2, pady=2)
button_frame = ttk.Frame(root)
button_frame.config(height=150, width=150, relief=GROOVE)
button_frame.grid(row=2, column=0, padx=2, pady=2)
north_button = ttk.Button(button_frame, text = "N", width = 5)
north_button.grid(row=0, column=1, padx = 2, pady = 2)
north_button.config(command = north_button_click)
south_button = ttk.Button(button_frame, text = "S", width = 5)
south_button.grid(row=2, column=1, padx = 2, pady = 2)
south_button.config(command = south_button_click)
east_button = ttk.Button(button_frame, text = "E", width = 5)
east_button.grid(row=1, column=2, padx = 2, pady = 2)
east_button.config(command = east_button_click)
west_button = ttk.Button(button_frame, text = "W", width = 5)
west_button.grid(row=1, column=0, padx = 2, pady = 2)
west_button.config(command = west_button_click)
inventory_widget = Text(root, width=50, height=6, relief=GROOVE, state=DISABLED)
inventory_widget.grid(row=2, column=1, padx=2, pady=2, sticky=W)
def set_current_state():
global refresh_location
global refresh_objects_visible
if (refresh_location):
describe_current_location()
set_current_image()
if (refresh_location or refresh_objects_visible):
describe_current_visible_objects()
handle_special_condition()
set_directions_to_move()
if (end_of_game == False):
describe_current_inventory()
# Update map display
update_map_display()
refresh_location = False
refresh_objects_visible = False
command_widget.config(state = ("disabled" if end_of_game else "normal"))
def north_button_click():
print_to_description("N", True)
perform_command("N", "")
set_current_state()
def south_button_click():
print_to_description("S", True)
perform_command("S", "")
set_current_state()
def east_button_click():
print_to_description("E", True)
perform_command("E", "")
set_current_state()
def west_button_click():
print_to_description("W", True)
perform_command("W", "")
set_current_state()
def return_key_enter(event):
if( event.widget == command_widget):
command_string = command_widget.get()
print_to_description(command_string, True)
command_widget.delete(0, END)
words = command_string.split(' ', 1)
verb = words[0]
noun = (words[1] if (len(words) > 1) else "")
perform_command(verb.upper(), noun.upper())
set_current_state()
def set_directions_to_move():
move_to_north = (get_location_to_north() > 0) and (end_of_game == False)
move_to_south = (get_location_to_south() > 0) and (end_of_game == False)
move_to_east = (get_location_to_east() > 0) and (end_of_game == False)
move_to_west = (get_location_to_west() > 0) and (end_of_game == False)
north_button.config(state = ("normal" if move_to_north else "disabled"))
south_button.config(state = ("normal" if move_to_south else "disabled"))
east_button.config(state = ("normal" if move_to_east else "disabled"))
west_button.config(state = ("normal" if move_to_west else "disabled"))
def play_audio(filename, asynchronous = True, loop = True):
import platform
operating_system = platform.system()
if (operating_system == 'Linux'):
from replit import audio
sound = audio.play_file(filename)
sound = audio.play_file('res/cold-moon.wav')
sound.paused = False
#according to documentation, setting .set_loop to -1 should create infinite loop in replit. Can't get it to work
sound.set_loop(-1)
elif (operating_system == 'Windows'):
import winsound
winsound.PlaySound(filename,winsound.SND_FILENAME + \
(winsound.SND_ASYNC if asynchronous else 0) + \
(winsound.SND_LOOP if loop else 0)
)
def main():
build_interface()
set_current_state()
root.mainloop()
main()
|