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)
23 # Thing(self, 'human', [3, 3]),
24 # Thing(self, 'monster', [1, 1])
27 # self.player = self.things[self.player_i]
29 def proceed_to_next_player_turn(self):
30 """Run game world turns until player can decide their next step.
32 Iterates through all non-player things, on each step
33 furthering them in their tasks (and letting them decide new
34 ones if they finish). The iteration order is: first all things
35 that come after the player in the world things list, then
36 (after incrementing the world turn) all that come before the
37 player; then the player's .proceed() is run, and if it does
38 not finish his task, the loop starts at the beginning. Once
39 the player's task is finished, the loop breaks.
42 for thing in self.things[self.player_id+1:]:
45 for thing in self.things[:self.player_id]:
47 player = self.get_thing(self.player_id)
48 player.proceed(is_AI=False)
49 if player.task is None:
52 def set_map_size(self, yx):
54 self.map_size = (y, x)
56 for y in range(self.map_size[0]):
57 self.map_ += '?' * self.map_size[1]
59 def set_map_line(self, y, line):
60 width_map = self.map_size[1]
61 if y >= self.map_size[0]:
62 raise ArgError('too large row number %s' % y)
63 width_line = len(line)
64 if width_line > width_map:
65 raise ArgError('too large map line width %s' % width_line)
66 self.map_ = self.map_[:y * width_map] + line + \
67 self.map_[(y + 1) * width_map:]
69 def get_thing(self, i):
70 for thing in self.things:
73 t = Thing(self, i, '?', [0,0])
80 def __init__(self, thing, name, args=(), kwargs={}):
88 if self.name == 'move':
89 if len(self.args) > 0:
90 direction = self.args[0]
92 direction = self.kwargs['direction']
93 test_pos = self.thing.position[:]
94 move_pos(direction, test_pos)
95 if test_pos[0] < 0 or test_pos[1] < 0 or \
96 test_pos[0] >= self.thing.world.map_size[0] or \
97 test_pos[1] >= self.thing.world.map_size[1]:
98 raise GameError('would move outside map bounds')
99 pos_i = test_pos[0] * self.thing.world.map_size[1] + test_pos[1]
100 map_tile = self.thing.world.map_[pos_i]
102 raise GameError('would move into illegal terrain')
107 def __init__(self, world, id_, type_, position):
111 self.position = position
112 self.task = Task(self, 'wait')
117 def task_move(self, direction):
118 move_pos(direction, self.position)
120 def decide_task(self):
121 if self.position[1] > 1:
122 self.set_task('move', 'LEFT')
123 elif self.position[1] < 3:
124 self.set_task('move', 'RIGHT')
126 self.set_task('wait')
128 def set_task(self, task_name, *args, **kwargs):
129 self.task = Task(self, task_name, args, kwargs)
132 def proceed(self, is_AI=True):
133 """Further the thing in its tasks.
135 Decrements .task.todo; if it thus falls to <= 0, enacts method whose
136 name is 'task_' + self.task.name and sets .task = None. If is_AI, calls
137 .decide_task to decide a self.task.
140 if self.task.todo <= 0:
141 task = getattr(self, 'task_' + self.task.name)
142 task(*self.task.args, **self.task.kwargs)
144 if is_AI and self.task is None: