1 class GameError(Exception):
5 def move_pos(direction, pos_yx):
8 elif direction == 'DOWN':
10 elif direction == 'RIGHT':
12 elif direction == 'LEFT':
20 self.map_size = (0, 0)
25 def proceed_to_next_player_turn(self):
26 """Run game world turns until player can decide their next step.
28 Iterates through all non-player things, on each step
29 furthering them in their tasks (and letting them decide new
30 ones if they finish). The iteration order is: first all things
31 that come after the player in the world things list, then
32 (after incrementing the world turn) all that come before the
33 player; then the player's .proceed() is run, and if it does
34 not finish his task, the loop starts at the beginning. Once
35 the player's task is finished, the loop breaks.
38 for thing in self.things[self.player_id+1:]:
41 for thing in self.things[:self.player_id]:
43 player = self.get_thing(self.player_id)
44 player.proceed(is_AI=False)
45 if player.task is None:
48 def set_map_size(self, yx):
50 self.map_size = (y, x)
52 for y in range(self.map_size[0]):
53 self.terrain_map += '?' * self.map_size[1]
55 def set_map_line(self, y, line):
56 width_map = self.map_size[1]
57 if y >= self.map_size[0]:
58 raise ArgError('too large row number %s' % y)
59 width_line = len(line)
60 if width_line > width_map:
61 raise ArgError('too large map line width %s' % width_line)
62 self.terrain_map = self.terrain_map[:y * width_map] + line + \
63 self.terrain_map[(y + 1) * width_map:]
65 def get_thing(self, i):
66 for thing in self.things:
69 t = Thing(self, i, '?', [0,0])
76 def __init__(self, thing, name, args=(), kwargs={}):
84 if self.name == 'move':
85 if len(self.args) > 0:
86 direction = self.args[0]
88 direction = self.kwargs['direction']
89 test_pos = self.thing.position[:]
90 move_pos(direction, test_pos)
91 if test_pos[0] < 0 or test_pos[1] < 0 or \
92 test_pos[0] >= self.thing.world.map_size[0] or \
93 test_pos[1] >= self.thing.world.map_size[1]:
94 raise GameError('would move outside map bounds')
95 pos_i = test_pos[0] * self.thing.world.map_size[1] + test_pos[1]
96 map_tile = self.thing.world.terrain_map[pos_i]
98 raise GameError('would move into illegal terrain')
103 def __init__(self, world, id_, type_, position):
107 self.position = position
108 self.task = Task(self, 'wait')
113 def task_move(self, direction):
114 move_pos(direction, self.position)
116 def decide_task(self):
117 if self.position[1] > 1:
118 self.set_task('move', 'LEFT')
119 elif self.position[1] < 3:
120 self.set_task('move', 'RIGHT')
122 self.set_task('wait')
124 def set_task(self, task_name, *args, **kwargs):
125 self.task = Task(self, task_name, args, kwargs)
128 def proceed(self, is_AI=True):
129 """Further the thing in its tasks.
131 Decrements .task.todo; if it thus falls to <= 0, enacts method whose
132 name is 'task_' + self.task.name and sets .task = None. If is_AI, calls
133 .decide_task to decide a self.task.
136 if self.task.todo <= 0:
137 task = getattr(self, 'task_' + self.task.name)
138 task(*self.task.args, **self.task.kwargs)
140 if is_AI and self.task is None: