1

I've been having trouble writing the code for a text-based RPG in Python. This RPG uses a class for each location, and a function to scan the game directory for maps and add them to a big 3d list. Each element of this 3d list is a list itself, with 4 values: the coordinates, the name, a short description, and the raw data for the map.

However, when I use the function to update this map, despite appearing to run correctly, on printing an element of the list, it does not show the expected values.

I have 4 test map.txt files in subdirectories of my /maps folder, for each of which I have triple-checked the coordinates' accuracy.

I have reduced the problem to the code below:

# Imports:
import os
import sys
from random import randint


# Definitions

def create_maps_list():
    """Creates a blank list of 100*100*100 zeros."""
    x_list, y_list, z_list, attr_list = [], [], [], []

    for _ in range(4):
        attr_list.append(0)

    for _ in range(100):
        z_list.append(attr_list)

    for _ in range(100):
        y_list.append(z_list)

    for _ in range(100):
        x_list.append(y_list)
    global maps_list
    maps_list = x_list

def update_maps_list(maps_list):
    """Updates maplist by scanning the maps dir."""
    listdirs = os.listdir(os.getcwd() + "\maps")  # List folder names in /maps
    for mapdir in listdirs:
        mapfile = open("maps/{0}/map.txt".format(mapdir))  # Open map.txt
        linelist = list(mapfile)
        desc = open("maps/{0}/description.txt".format(mapdir)).read()
        mapdata = linelist[2:]
        name = linelist[1]
        coordsline = linelist[0]
        coords = []
        for num in coordsline.split():
            coords.append(int(num))
        x = coords[0]
        y = coords[1]
        z = coords[2]
        print("Name: ", name, "Assigned to coords: ", coords, "\n")
        maps_list[x][y][z] = [coords, name, desc, mapdata]
    return maps_list


# Assignments:
maps_list = []
list_data = []


# Execution
create_maps_list()
maps_list = update_maps_list(maps_list)


# Output
print()
print("Expected output: [0, 0, 0] Initial Building.")
print(maps_list[0][0][0][0], maps_list[0][0][0][1])

The actual output is as follows:

Name:  East Building
 Assigned to coords:  [1, 0, 0] 

Name:  Heaven!
 Assigned to coords:  [0, 0, 1] 

Name:  Initial Building
 Assigned to coords:  [0, 0, 0] 

Name:  North Building
 Assigned to coords:  [0, 1, 0] 


Expected output: [0, 0, 0] Initial Building.
[0, 1, 0] North Building

[Finished in 0.3s]

Any assistance would be much appreciated (including that not directly related to the question - I have a sneaking suspicion that storing the coordinates in this way isn't the best way of doing things!)

Anonymous
  • 171
  • 2
  • 10

1 Answers1

1

Your x_list contains 100 references to a single y_list. So changing one will make it look like all of them changed. Similarly, your y_list contains 100 references to a single z_list.

You probably want something like this:

maps_list = [[[[0 for i in range(4)] for z in range(100)] for y in range(100)] for x in range(100)]
happydave
  • 7,127
  • 1
  • 26
  • 25
  • Also, regarding the question of how to store co-ordinates - Unless you plan to fill in close to the million entries that you're allocating, you're probably better storing them as a dict, where the key is the tuple (x,y,z). – happydave Jan 21 '14 at 01:24
  • And the final 4-element list should probably be its own class. But that's a readability/maintainability issue, not a memory or performance issue. – happydave Jan 21 '14 at 01:26