user4204014
user4204014

Reputation:

(Python) Creating a 2d list (map) from a file

So I'm trying to get my program to read the elements of a text file then create a 2d list that is 20x30 with the elements of the text file. My expected outcome of this is essentially a game map in which I can find certain elements and move them as need be.

The two functions i have so far for trying to do this are as follows, but I can't seem to get it to do what I want it to do, and I'm kind of stumped as to why I can't.

def create_level(level):
     """ Create the level based off of reading positions of agents, player, buildings
water, etc..."""

     a_maze = []

     level_data = level.read()
     for r in range (0, ROWS, 1):
        a_maze.append ([])
        for c in range (0, COLUMNS, 1):
             a_maze[r].append (level_data)
     print(a_maze)



def load_level():
     while True:
          print("Enter the name/directory of the level file you wish to load\
     .txt or .lvl are the only accepted formats")

          level_in = input(">>: ")
          if (level_in.endswith(".txt") or level_in.endswith(".lvl")):
               try:
                    level = open(level_in, "r")

               except IOError:
                    print("Not a valid file")
          else:
               print("Not a suitable format for level")

          return level

Upvotes: 4

Views: 1752

Answers (1)

furkle
furkle

Reputation: 5059

What you're missing here is the parsing of the file. All open does in python is create a file object (in this case, a text file object), which you can read or write to. Assuming each tile in the map is a separate character, and each line is the full width of the map, here's how you could construct the map line-by-line:

your_map = []
with open(level_in, 'r') as level:
    for line in level:
        your_map.append([a for a in line.split()])

Edit: If your map file has no delimiters at all between tiles, just change the append line to:

your_map.append(list(line))

Padraic Cunningham also suggests that the your_map assignment could be further condensed like so, with delimiters:

your_map = [line.split(your_delimiters) for line in level]

or like so, without delimiters:

your_map = [list(line) for line in level]

Both of these would completely remove the need for a for loop.

A few notes:

The with keyword is used to automatically destruct objects like file objects when you're done with them - this is a whole lot easier and safer than having to remember to call level.close() after you're done.

The for line in level iterates through the file object on a line-by-line basis, which will automatically end when the end of file is reached.

The [a for a in line.split] is a list comprehension, but what it boils down to in this case is that you're creating a new list where every index is one of the non-space tokens in your line string.

This code I wrote above makes a couple assumptions - firstly, that your text file has the same number of tiles in each line, and secondly that each tile is delimited from the previous tile by a space. Here's an example of what I'm imagining:

` ` ` o # ` . . .
` ` o # # # . . .
` o # # # # # . .

where any given character corresponds to say, desert, water, etc.

Upvotes: 3

Related Questions