Last active
November 9, 2021 23:24
-
-
Save Pinacolada64/5e810e109f15cff2a459d7744900f829 to your computer and use it in GitHub Desktop.
Getting so close to making movement possible, I think!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# from prompt_toolkit import prompt # this doesn't work on Windows | |
# Test walking around on a map | |
""" | |
Data format on C64: | |
* Room number (rm) | |
* Location name (lo$) | |
* items: monster, item, weapon, food | |
* exits: north, east, south, west | |
RC (room command: 1=move up, | |
2=move down), | |
RT (Room exit transports you to: | |
room #, or 0=Shoppe) | |
https://github.com/Pinacolada64/TADA-old/blob/master/text/s_t_level-1-data.txt | |
""" | |
item_dict = {62: "ADVENTURER'S GUIDE"} | |
""" | |
tanabi: | |
game_map = { | |
"number": 1, | |
"room_name": "MERCHANT LOBBY", | |
etc etc | |
} | |
""" | |
def grammatical_list(item_list): | |
result_list = [] | |
for item in item_list: | |
if item.endswith("s"): | |
result_list.append(f"some {item}") | |
elif item.startswith(('a', 'e', 'i', 'o', 'u')): | |
result_list.append(f"an {item}") | |
else: | |
result_list.append(f"a {item}") | |
# tanabi: Add 'and' if we need it | |
if len(result_list) > 1: | |
result_list[-1] = f"and {result_list[-1]}" | |
# Join it together | |
return ", ".join(result_list) | |
class Exit(object): | |
def __init__(self, destination_room, exit_dir): | |
""" | |
:param destination_room: the room you travel to via exit_dir | |
:param exit_dir: direction or letter typed to use exit | |
NOTE: order of parameters matters, function will not work if switched around | |
example exit: (4, 'e') -- 'e' will exit to room 4 | |
""" | |
self.destination_room = destination_room | |
self.exit_dir = exit_dir | |
def __str__(self): | |
""" | |
https://letstalkdata.com/2014/08/how-to-write-a-text-adventure-in-python-part-1-items-and-enemies/ | |
Without a __str__ method, calling print() on an object will display something unhelpful like | |
<__main__.Item object at 0x101f7d978>. | |
whatever this returns is what happens if you convert a class to a str | |
which is what print does -- print(Exit(player_room)) | |
""" | |
return f"an exit '{self.exit_dir}' that goes to room '{self.destination_room}'" | |
class Room(object): | |
room_sequence = 0 | |
def __init__(self, number, name, alignment, items, desc): | |
self.number = number | |
self.name = name | |
self.alignment = alignment | |
self.items = items | |
self.desc = desc | |
self.exits = [] | |
def __str__(self): | |
return f'{self.number=} {self.name=} {self.alignment=} {self.items=}' \ | |
f'{self.desc} {self.exits}' | |
@staticmethod | |
def create_room(name, alignment, items, desc): | |
Room.room_sequence += 1 | |
return Room(Room.room_sequence, name, alignment, items, desc) | |
class Map(object): | |
def __init__(self): | |
"""dict Room{name: str, alignment: str, items: list, desc: str}""" | |
self.db = {} # dict | |
new_room = 0 | |
def __str__(self): | |
return Map() # display map dict? | |
def add_room(self, name, alignment, items, desc): | |
new_room = Room.create_room(name, alignment, items, desc) | |
self.db[new_room.number] = new_room | |
return new_room.number | |
def link_room(self, source_room, dest_room, direction): | |
""" | |
source_room: room the exit is in | |
dest_room: room the exit links to | |
direction: direction to create exit between self.db[source_room].exits [list] | |
""" | |
logging.info(f'Map.link_room: {source_room=} {direction=} -> {dest_room=}') | |
if source_room not in self.db: | |
raise RuntimeError(f"{source_room} does not exist") | |
if dest_room not in self.db: | |
raise RuntimeError(f"{dest_room} does not exist") | |
self.db[source_room].exits.append(Exit(dest_room, direction)) | |
def show_room(self, room_number): | |
"""Show room name, alignment, players/NPCs here, exits""" | |
print(f'{map.db[room_number].name}', end='') | |
if debug: | |
print(f' (#{room_number}) ', end='') | |
print(f'{map.db[room_number].alignment}') | |
# print(Room(player_room)) # should display connections? | |
# room descs: | |
if descriptions: | |
print(f'\n{map.db[room_number].desc}') | |
"""# FIXME: some experimentation with dicts, but maybe storing in a list would be better? | |
# add exit: | |
exit_dict = {'e': 4] | |
# find exit: | |
exit_dict['e']: 4 | |
""" | |
# To show a list of exits: | |
# for exit in map.db[room_1].exits: | |
# print(exit.exit) | |
def get_exits(self, room_number, quiet=False): | |
"""Get (and optionally display) exits for room room_number | |
quiet=True: return dict of exits like {'n': 28, 'e': 14...} | |
(maybe for monster moving between rooms) | |
Don't display "Ye may travel:" message | |
quiet=False: Display 'Ye may travel:' and list exit""" | |
if quiet: | |
logging.info(f'{Exit(room_number)}') | |
return map.db[room_number].exits | |
# a list is used since lists can be added to | |
exit_list = [] | |
for i in map.db[room_number].exits: | |
if i.exit_dir == 'n': | |
text = "North" | |
if debug: | |
text = f'North (to {i.destination_room})' | |
exit_list.append(text) | |
if i.exit_dir == 'e': | |
text = "East" | |
if debug: | |
text = f'East (to {i.destination_room})' | |
exit_list.append(text) | |
if i.exit_dir == 's': | |
text = "South" | |
if debug: | |
text = f'South (to {i.destination_room})' | |
exit_list.append(text) | |
if i.exit_dir == 'w': | |
text = "West" | |
if debug: | |
text = f'West (to {i.destination_room})' | |
exit_list.append(text) | |
if i.exit_dir == 'u': | |
text = "Up" | |
if debug: | |
text = f'Up (to {i.destination_room})' | |
exit_list.append(text) | |
if i.exit_dir == 'd': | |
text = "Down" | |
if debug: | |
text = f'Down (to {i.destination_room})' | |
exit_list.append(text) | |
print(f'\nYe may travel: {" ".join(exit_list)}') | |
# grammatical_list(exit_list) | |
# print(f' Exit {i.exit} to {map.db[i.destination_room].name}') | |
def move(self, room, exit_dir): | |
""" | |
:param room: room player is in | |
:param exit_dir: direction trying to move | |
:return: None | |
""" | |
try: | |
for i in map.db[room].exits: | |
if i.exit_dir == exit_dir: | |
logging.info(f'Before: {room=}, {exit_dir=}') | |
player_room = i.destination_room | |
logging.info(f'After: {player_room=}') | |
print(f'You move {exit_dir}.') | |
except IndexError: | |
# exit not in list | |
print("You can't go that way.") | |
if __name__ == '__main__': | |
import logging | |
logging.basicConfig(level=logging.DEBUG, format='[%(levelname)s] | %(message)s') | |
debug = True | |
descriptions = True | |
# should print "You see some bells, an apple, and a candle": | |
stuff_here = grammatical_list(['accordion']) | |
print(f'You see: {stuff_here}') | |
stuff_here = grammatical_list(['large chest', 'dry bones']) | |
print(f'You see: {stuff_here}') | |
stuff_here = grammatical_list(["bells", 'apple', 'candle']) | |
print(f'You see: {stuff_here}.') | |
# Create your world | |
map = Map() | |
# Define room objects first, then use Map.link_room() to link them together | |
# name, alignment, items[list], description | |
room_1 = map.add_room("MERCHANT'S LOBBY +", | |
"neutral", | |
["B.ADVENTURER'S GUIDE"], | |
"""You are at the entrance to the store. | |
There is a passage leading downward to the market area.""" | |
# [0, 2, 0, 0, 0, -1] # negative room # = Down to Shoppe | |
) | |
room_2 = map.add_room("SECOND ROOM", | |
"foxy", | |
[], | |
"This is the second room." | |
# [1, 0, 3, 0, 0, 0] | |
) | |
room_3 = map.add_room("CAVERN HEAD +", | |
"neutral", | |
["M.SAND CRAB"], | |
"You have reached the entrance to a large cavern." | |
# [2, 0, 0, 0, 0, 0] | |
) | |
room_4 = map.add_room("ROOM FOUR", | |
"neutral", | |
[], | |
"This is room four." | |
) | |
# game_map = [1, [0, 2, 0, 0]], [2, [0, 0, 0, 4]], [3, [1, 0, 0, 0], 4, [0, 0, 0, 3]] | |
""" | |
------ ------ | |
| | | | | |
| 1 ---> 2 | | |
| | | | | |
---^-- --|--- | |
| | | |
------ --v--- | |
| | | | | |
| 3 <--- 4 | | |
| | | | | |
------ ------ | |
""" | |
""" | |
FIXME: trying to add the direction of travel the player can go | |
""" | |
map.link_room(room_1, room_2, 'e') | |
map.link_room(room_2, room_4, 's') | |
map.link_room(room_4, room_3, 'w') | |
map.link_room(room_3, room_1, 'n') | |
# https://pastebin.com/a58YsuiB | |
# map.db has your rooms in it. | |
print(f'Second room name: {map.db[room_2].name}\n') | |
# Where does your exit go to? | |
# print(f'First room ({map.db[room_1]}) links to:') | |
# for exit in map.db[room_1].exits: | |
# print(f'{exit.exit} to {exit.destination_room}') | |
# Normally, exits are listed thusly: | |
# Ye may travel: North, West and Up. | |
# TODO: "Goggles of Cartography" item could expand exits by listing room names thusly: | |
# Ye may travel: North (to DRAGON DROP), West (to WATERSDEEP), and Up (to SNOWY PEAK). | |
# answer = prompt('Give me some input: ') # this no worky on Win10 | |
# print(f'You said: {answer}.') | |
player_room = 1 | |
# While game_running = True, the game runs. | |
# if 'q' entered, game_running changes to False and the game stops running. | |
game_running = True | |
while game_running is True: | |
map.show_room(player_room) | |
map.get_exits(player_room, quiet=False) | |
command = input("\nCommand? ").lower()[0] # take leftmost char, lowercase it | |
logging.info(f'{command=}') | |
if command == "q": | |
# TODO: add "Are you sure?" prompt | |
print("Quitting.") | |
game_running = False | |
if command in ['n', 'e', 's', 'w', 'u', 'd']: | |
map.move(player_room, command) | |
# To show a list of exits: | |
# for exit in map.db[room_1].exits: | |
# print(exit.exit_dir) | |
# FIXME: if uncommented: after move, it continues to "Command 'e' not understood' | |
# print(f"Command '{command}' not understood.") | |
# https://inventwithpython.com/blog/2014/12/02/why-is-object-oriented-programming-useful-with-a-role-playing-game-example/ | |
# for translating ASCII -> PetSCII: | |
# https://github.com/irmen/cbmcodecs2 |
tanabi
commented
Nov 3, 2021
Change your exit class thusly:
class Exit(object):
def __init__(self, destination_room, exit_dir):
"""
:param destination_room: the room you travel to via exit_dir
:param exit_dir: direction or letter typed to use exit
NOTE: order of parameters matters, function will not work if switched around
example: (4, 'e')
"""
self.destination_room = destination_room
self.exit_dir = exit_dir
def __str__(self):
# whatever this returns is what happens if you convert a class to a str
# which is what print does
return f"an exit '{self.exit_dir}' that goes to room '{self.destination_room}'"
To use a global:
def move(self, room, exit_dir):
"""
:param room: room player is in
:param exit_dir: direction trying to move
:return: None
"""
global player_room ### this makes your global writable, not just readable
try:
for i in map.db[room].exits:
if i.exit_dir == exit_dir:
logging.info(f'Before: {room=}, {exit_dir=}')
player_room = i.destination_room
logging.info(f'After: {player_room=}')
print(f'You move {exit_dir}.')
except IndexError:
# exit not in list
print("You can't go that way.")
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment