-
Notifications
You must be signed in to change notification settings - Fork 0
/
level_loader.py
executable file
·111 lines (96 loc) · 3.97 KB
/
level_loader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import os, constants, math
from board import Board
from geometry import *
from tile import Tile
from level import Level
import re
from powerup import ShieldPowerup, RepairPowerup, SplashPowerup
powerup_type_map = {
"SHIELD" : ShieldPowerup,
"REPAIR" : RepairPowerup,
"SPLASH" : SplashPowerup
}
def load(number_or_file):
if type(number_or_file) == int:
level_file = open(os.path.join(constants.DATA_DIR, "level%d.dat" % (number_or_file)), "r")
else:
level_file = open(os.path.join(constants.DATA_DIR, number_or_file), "r")
# read from level file, allowing comments starting with '#' and blank lines,
# returning the first meaningful line, stripped of its new line character.
def read():
line = None
while line is None or line is "" or line.isspace() or line.startswith("#"):
line = level_file.readline().strip()
return line
def process(line):
return list(filter(None, re.split("[(), ]", line)))
name = read()
# board size
board_size = process(read())
width = int(board_size[0])
height = int(board_size[1])
# player start position
player_info = process(read())
player_start = Point(float(player_info[0]), float(player_info[1]))
if not (0 <= player_start.x < width) or \
not (0 <= player_start.y < height):
raise Exception("Player start position (%d, %d) outside board." % (player_start.x, player_start.y))
player_direction = float(player_info[2])
if not 0 <= player_direction < 360:
raise Exception("Player direction should be between 0 and 359 degrees. Was %d." % player_direction)
# enemies
start_enemies = read()
if not start_enemies == "START ENEMIES":
raise Exception("Excepted 'START ENEMIES' but got %s" % start_enemies)
enemies = []
line = None
while True:
line = read()
if line == "END ENEMIES":
break
enemy_info = process(line)
position = Point(float(enemy_info[0]), float(enemy_info[1]))
if not (0 <= position.x < width) or \
not (0 <= position.y < height):
raise Exception("Enemy start position (%d, %d) outside board." % (x, y))
initial_direction = float(enemy_info[2])
if not 0 <= initial_direction < 360:
raise Exception("Initial direction should be between 0 and 359 degrees. Was %d." % initial_direction)
waypoint_type = enemy_info[3]
waypoints = []
for i in range(4, len(enemy_info), 2):
waypoints.append(Point(float(enemy_info[i]), float(enemy_info[i + 1])))
enemies.append((position, math.pi * initial_direction / 180.0, waypoint_type, waypoints))
start_powerups = read()
if not start_powerups == "START POWERUPS":
raise Exception("Excepted 'START POWERUPS' but got %s" % start_powerups)
powerups = []
while True:
line = read()
if line == "END POWERUPS":
break
powerup_info = process(line)
powerup_type = powerup_info[0]
position = Point(float(powerup_info[1]), float(powerup_info[2]))
powerups.append(powerup_type_map[powerup_type](position, powerup_type))
# tiles
board = Board(width, height)
for i in range(0, height):
line = read()
for j in range(0, width):
tile = Tile(line[j], j, i)
if tile.solid:
if i is player_start.y and j is player_start.x:
raise Exception("Player start position (%d, %d) is inside a solid tile." % (player_start.x, player_start.y))
for (p, d, waypoint_type, waypoints) in enemies:
if i is p.y and j is p.x:
raise Exception("Enemy start position (%d, %d) is inside a solid tile." % (p.x, p.y))
board.set_tile(j, i, tile)
# let each tile know if its walls are accessible (i.e., if they are blocked
# by another tile or not)
board.fix_accessibility()
return (name, player_start, player_direction, board, enemies, powerups)
def load_level(number, game):
(name, player_start, player_direction, board, enemies, powerups) = load(number)
player_direction_radians = math.pi * player_direction / 180.0
return Level(name, game, player_start, player_direction_radians, board, enemies, powerups)