| 425 | |
| 426 | |
| 427 | def readLevelsFile(filename): |
| 428 | assert os.path.exists(filename), 'Cannot find the level file: %s' % (filename) |
| 429 | mapFile = open(filename, 'r') |
| 430 | # Each level must end with a blank line |
| 431 | content = mapFile.readlines() + ['\r\n'] |
| 432 | mapFile.close() |
| 433 | |
| 434 | levels = [] # Will contain a list of level objects. |
| 435 | levelNum = 0 |
| 436 | mapTextLines = [] # contains the lines for a single level's map. |
| 437 | mapObj = [] # the map object made from the data in mapTextLines |
| 438 | for lineNum in range(len(content)): |
| 439 | # Process each line that was in the level file. |
| 440 | line = content[lineNum].rstrip('\r\n') |
| 441 | |
| 442 | if ';' in line: |
| 443 | # Ignore the ; lines, they're comments in the level file. |
| 444 | line = line[:line.find(';')] |
| 445 | |
| 446 | if line != '': |
| 447 | # This line is part of the map. |
| 448 | mapTextLines.append(line) |
| 449 | elif line == '' and len(mapTextLines) > 0: |
| 450 | # A blank line indicates the end of a level's map in the file. |
| 451 | # Convert the text in mapTextLines into a level object. |
| 452 | |
| 453 | # Find the longest row in the map. |
| 454 | maxWidth = -1 |
| 455 | for i in range(len(mapTextLines)): |
| 456 | if len(mapTextLines[i]) > maxWidth: |
| 457 | maxWidth = len(mapTextLines[i]) |
| 458 | # Add spaces to the ends of the shorter rows. This |
| 459 | # ensures the map will be rectangular. |
| 460 | for i in range(len(mapTextLines)): |
| 461 | mapTextLines[i] += ' ' * (maxWidth - len(mapTextLines[i])) |
| 462 | |
| 463 | # Convert mapTextLines to a map object. |
| 464 | for x in range(len(mapTextLines[0])): |
| 465 | mapObj.append([]) |
| 466 | for y in range(len(mapTextLines)): |
| 467 | for x in range(maxWidth): |
| 468 | mapObj[x].append(mapTextLines[y][x]) |
| 469 | |
| 470 | # Loop through the spaces in the map and find the @, ., and $ |
| 471 | # characters for the starting game state. |
| 472 | startx = None # The x and y for the player's starting position |
| 473 | starty = None |
| 474 | goals = [] # list of (x, y) tuples for each goal. |
| 475 | stars = [] # list of (x, y) for each star's starting position. |
| 476 | for x in range(maxWidth): |
| 477 | for y in range(len(mapObj[x])): |
| 478 | if mapObj[x][y] in ('@', '+'): |
| 479 | # '@' is player, '+' is player & goal |
| 480 | startx = x |
| 481 | starty = y |
| 482 | if mapObj[x][y] in ('.', '+', '*'): |
| 483 | # '.' is goal, '*' is star & goal |
| 484 | goals.append((x, y)) |