# Python 2.7 text adventure map and movement

I have been writing a python text adventure and the map module i wrote is very clunky. It is a list with compass dirs as the navigation. The problem with this is, i refer to each room by index number, and this is SUPER confusing. If anyone has any helpful advice it would be greatly appreciated.

map module (the sub-lists are just things that are in the room.):

map=[]
map.append({"name":"The Courtyard of the Castle Darkspur.",
"info":"You are in a courtyard with stone walls and moss covering the              ground.\nThere is a puddle of odd looking liquid south of you. \nTo the north is a large wooden door with a rusty iron handle.\n",
"connects":[{"north":1}],
"items":[Weapon("knife","Rusty Knife(lv 0)","It's pretty rusty...",2,4)],
"npcs":[NPC("davkas","Davkas",0,"Greetings, traveller.\nRead the scroll on the ground. It will cost you nothing.","The only advice I can give you is to read the scroll I have left in the room.")],
"npcitems":[],
"enemies":[Enemy(["onyx","spider"],"Onyx, Corrupted Spider","Fang","YOU INTRUDE UPON MY DOMAIN, HUMAN.",random.randint(0,5),5)],
"enemyitems":[Weapon("fang"," Corrupted Fang","It looks poisonous, but deadly.(lv 1)",5,5)],
"riddle":[],
"reward":[],
"scrolls":[Scroll("scroll","Scroll of Learning","scrollx","Hello, Traveller. It is I, the Prince Darkspur. I am the only one who made it out of this cursed fortress before the curse struck. I am leaving this scroll here in the hope that some valiant hero will attempt to restore the glory of my home. I tried many a time and the challenge proved too great for me.")]})
room=map[0]
map.append({"name":"The Castle Entry.",
"info": "\nA wrought iron Gargoyle looms above your head. On top of the gate is the crest of the family darkspur, who many years ago fell victim to a curse placed on the castle by a wizard.\n",
"connects":[{"south":0},{"north":2}],
"items":[Item("potion","Lesser Health Potion","It heals you, a little.",5,5),],
"npcs":[],
"npcitems":[],
"enemies":[],
"enemyitems":[],
"riddle":[Riddle("I weaken all men for hours each day.\nI show you strange visions while you are away.\nI take you by night, by day take you back,\nNone suffer to have me, but do from my lack.\n","sleep")],
"reward":[Item("key","Foyer Key","It opens the door to the castle.",0,0)],
"scrolls":[Scroll("scroll","Scroll of wisdom","scrolly","The story of the Family Darkspur.\nMany years ago, a family of valiant knights and warrior-women reigned over this land.\nThey were kind and generous to all that did them no harm.\nTo those that challenged their authority, a quick and painless death was their punishment.\nThe only thing more important to the Family Darkspur than power was wealth.\nThe family always ran into battle dressed in the finest dragon-scale mail with diamonds around their necks.\nLittle did they know that this would be their downfall.\nBEWARE OF MYSTERIOUS TREASURE.")]})

• FYI, backticks work best for inline code. If you want to post a block of code, the easiest way is to paste in select, highlight it, and (IIRC) Crtl-K. You could also manually indent four spaces – User319 May 5 '18 at 20:10
• Are you familiar with either of the following: linked list, graph – User319 May 5 '18 at 20:11
• @User319 I am not. is there a specific application of those that you think would work in this case? – Stone Cold Games May 5 '18 at 20:37

Being more familiar with appropriate data structures is going to help a lot here. I will suggest a better map structure that will make things less confusing at the end. First I want to suggest an intermediate cleanup which will let me think and talk about things more easily.

Room class: You have class for Weapon, Enemy, etc. It will help a lot to make a class to contain an element of the map. I'm going to call it Room. Maybe there's a term more appropriate for your game. Then your initialization could look something like this. (I'm leaving out the connects field for now. Hang on.)

map.append(Room(name="The Courtyard of Castle Darkspur",
info="A description of the room"))


Turning it into a graph: Now we have a nicer way to link rooms. Without going into too much detail, a graph is a common way to represent specific connections between objects. I'm sure there's a cool graph library we could use, but this should be all we need to get us going:

start_room = Room(name="The Courtyard...."
# etc
)
castle_entry = Room(name="The castle entry")


And add_connection just has to look like this:

def add_connection(self, direction, room):
self.connects[direction] = room


(direction is an Enum, by the way)

Now you can go straight to the connected room without worrying about indexing

But now what about all the local variables? This still isn't great. You're probably going to have a lot of local variables lying around, and this is mixing data and code pretty heavily. A cleaner solution would be to store the map in a .txt file. It might look something like this:

Room
Name: The Courtyard of Caslte Darkspur
Id: courtyard-darkspur
Info: Courtyard descr.
Weapons: rusty-knife-simple
connects: South, castle-entry

Room
Name: The castle entry
Id: castle-entry
Connects: North, room-entry


You would need a class or function to first parse each item individually, and then use the id fields to create all the links between nodes. Common ways to store configuration data like this are JSON (mainly) or XML.

You could also choose a hybrid of these approaches. Perhaps a class you could use in the REPL to dynamically construct a part of the map, then it saves it to your configuration file when you're done.

• Thank you so much! a text file is super inconvenient for me because i have puzzles where the rooms are not laid out in a realistic way. other than that, i’ll look into implementing that room class. I’m working on a web app for my game at the moment so it’s not the priority right now, but i’ll let you know how it turns out – Stone Cold Games May 6 '18 at 22:43