Skip to content

Instantly share code, notes, and snippets.

@Pinacolada64
Last active November 9, 2021 23:24
Show Gist options
  • Save Pinacolada64/5e810e109f15cff2a459d7744900f829 to your computer and use it in GitHub Desktop.
Save Pinacolada64/5e810e109f15cff2a459d7744900f829 to your computer and use it in GitHub Desktop.
Getting so close to making movement possible, I think!
# 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
Copy link

tanabi commented Nov 3, 2021

for exit in map.db[first_room_id].exits:
    print(exit.exit)

@tanabi
Copy link

tanabi commented Nov 5, 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}'"

@tanabi
Copy link

tanabi commented Nov 9, 2021

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