From ca1257ec655f95611de1cbbac2814509d23f6116 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Tue, 11 Dec 2018 23:27:21 +0100 Subject: [PATCH] Move hardcoding of world data to init process. --- client.py | 40 ++++++++++++++++++++++--------- server.py | 44 ++++++++++++++++++++++++++++++----- server_/game.py | 62 ++++++++++++++++++++++++++++++++++--------------- 3 files changed, 110 insertions(+), 36 deletions(-) diff --git a/client.py b/client.py index df5d7e3..c5d6fcd 100755 --- a/client.py +++ b/client.py @@ -9,12 +9,13 @@ from parser import ArgError, Parser class Game: turn = 0 log_text = '' - map_size = (5, 5) - terrain_map = ('?'*5)*5 + map_size = (0, 0) + terrain_map = '' things = [] class Thing: - def __init__(self, position, symbol): + def __init__(self, id_, position, symbol): + self.id_ = id_ self.position = position self.symbol = symbol @@ -22,15 +23,33 @@ class Game: """Prefix msg plus newline to self.log_text.""" self.log_text = msg + '\n' + self.log_text - def cmd_THING(self, type_, yx): - """Add to self.things at .position yx with .symbol defined by type_.""" + def get_thing(self, i): + for thing in self.things: + if i == thing.id_: + return thing + t = self.Thing(i, [0,0], '?') + self.things += [t] + return t + + def cmd_THING_TYPE(self, i, type_): + t = self.get_thing(i) symbol = '?' - if type_ == 'TYPE:human': + if type_ == 'human': symbol = '@' - elif type_ == 'TYPE:monster': + elif type_ == 'monster': symbol = 'm' - self.things += [self.Thing(yx, symbol)] - cmd_THING.argtypes = 'string yx_tuple:nonneg' + t.symbol = symbol + cmd_THING_TYPE.argtypes = 'int:nonneg string' + + def cmd_THING_POS(self, i, yx): + t = self.get_thing(i) + t.position = list(yx) + cmd_THING_POS.argtypes = 'int:nonneg yx_tuple:nonneg' + + def cmd_THING_POS(self, i, yx): + t = self.get_thing(i) + t.position = list(yx) + cmd_THING_POS.argtypes = 'int:nonneg yx_tuple:nonneg' def cmd_MAP_SIZE(self, yx): """Set self.map_size to yx, redraw self.terrain_map as '?' cells.""" @@ -38,8 +57,7 @@ class Game: self.map_size = (y, x) self.terrain_map = '' for y in range(self.map_size[0]): - self.terrain_map += '?' * self.map_size[1]# + '\n' - self.terrain_map = self.terrain_map[:-1] + self.terrain_map += '?' * self.map_size[1] cmd_MAP_SIZE.argtypes = 'yx_tuple:nonneg' def cmd_TURN_FINISHED(self, n): diff --git a/server.py b/server.py index e688f2c..16915e9 100755 --- a/server.py +++ b/server.py @@ -94,9 +94,9 @@ def fib(n): class CommandHandler: - def __init__(self, queues_out={}): + def __init__(self): from multiprocessing import Pool - self.queues_out = queues_out + self.queues_out = {} self.world = World() self.parser = Parser(self) # self.pool and self.pool_result are currently only needed by the FIB @@ -157,8 +157,8 @@ class CommandHandler: terrain_line = self.world.map_[y * width:(y + 1) * width] self.send_all('TERRAIN_LINE %5s %s' % (y, self.quoted(terrain_line))) for thing in self.world.things: - self.send_all('THING TYPE:' + thing.type_ + ' ' - + self.stringify_yx(thing.position)) + self.send_all('THING_TYPE %s %s' % (thing.id_, thing.type_)) + self.send_all('THING_POS %s %s' % (thing.id_, self.stringify_yx(thing.position))) def proceed(self): """Send turn finish signal, run game world, send new world data. @@ -170,20 +170,41 @@ class CommandHandler: self.world.proceed_to_next_player_turn() self.send_all_gamestate() + def get_player(self): + return self.world.get_thing(self.world.player_id) + def cmd_MOVE(self, direction, connection_id): """Set player task to 'move' with direction arg, finish player turn.""" if direction not in {'UP', 'DOWN', 'RIGHT', 'LEFT'}: raise ArgError('Move argument must be one of: ' 'UP, DOWN, RIGHT, LEFT') - self.world.player.set_task('move', direction=direction) + self.get_player().set_task('move', direction=direction) self.proceed() cmd_MOVE.argtypes = 'string' def cmd_WAIT(self, connection_id): """Set player task to 'wait', finish player turn.""" - self.world.player.set_task('wait') + self.get_player().set_task('wait') self.proceed() + def cmd_MAP_SIZE(self, yx, connection_id): + self.world.set_map_size(yx) + cmd_MAP_SIZE.argtypes = 'yx_tuple:nonneg' + + def cmd_TERRAIN_LINE(self, y, line, connection_id): + self.world.set_map_line(y, line) + cmd_TERRAIN_LINE.argtypes = 'int:nonneg string' + + def cmd_THING_TYPE(self, i, type_, connection_id): + t = self.world.get_thing(i) + t.type_ = type_ + cmd_THING_TYPE.argtypes = 'int:nonneg string' + + def cmd_THING_POS(self, i, yx, connection_id): + t = self.world.get_thing(i) + t.position = list(yx) + cmd_THING_POS.argtypes = 'int:nonneg yx_tuple:nonneg' + def cmd_GET_TURN(self, connection_id): """Send world.turn to caller.""" self.send_to(connection_id, str(self.world.turn)) @@ -279,6 +300,17 @@ if os.path.exists(game_file_name): line = lines[i] print("FILE INPUT LINE %s: %s" % (i, line), end='') commander.handle_input(line, abort_on_error=True) +else: + commander.handle_input('MAP_SIZE Y:5,X:5') + commander.handle_input('TERRAIN_LINE 0 "xxxxx"') + commander.handle_input('TERRAIN_LINE 1 "x...x"') + commander.handle_input('TERRAIN_LINE 2 "x.X.x"') + commander.handle_input('TERRAIN_LINE 3 "x...x"') + commander.handle_input('TERRAIN_LINE 4 "xxxxx"') + commander.handle_input('THING_TYPE 0 human') + commander.handle_input('THING_POS 0 Y:3,X:3') + commander.handle_input('THING_TYPE 1 monster') + commander.handle_input('THING_POS 1 Y:1,X:1') q = queue.Queue() c = threading.Thread(target=io_loop, daemon=True, args=(q, commander)) c.start() diff --git a/server_/game.py b/server_/game.py index e24b30a..f949289 100644 --- a/server_/game.py +++ b/server_/game.py @@ -17,18 +17,14 @@ class World: def __init__(self): self.turn = 0 - self.map_size = (5, 5) - self.map_ = 'xxxxx' +\ - 'x...x' +\ - 'x.X.x' +\ - 'x...x' +\ - 'xxxxx' - self.things = [ - Thing(self, 'human', [3, 3]), - Thing(self, 'monster', [1, 1]) - ] - self.player_i = 0 - self.player = self.things[self.player_i] + self.map_size = (0, 0) + self.map_ = '' + self.things = [] +# Thing(self, 'human', [3, 3]), +# Thing(self, 'monster', [1, 1]) +# ] + self.player_id = 0 +# self.player = self.things[self.player_i] def proceed_to_next_player_turn(self): """Run game world turns until player can decide their next step. @@ -43,15 +39,42 @@ class World: the player's task is finished, the loop breaks. """ while True: - for thing in self.things[self.player_i+1:]: + for thing in self.things[self.player_id+1:]: thing.proceed() self.turn += 1 - for thing in self.things[:self.player_i]: + for thing in self.things[:self.player_id]: thing.proceed() - self.player.proceed(is_AI=False) - if self.player.task is None: + player = self.get_thing(self.player_id) + player.proceed(is_AI=False) + if player.task is None: break + def set_map_size(self, yx): + y, x = yx + self.map_size = (y, x) + self.map_ = '' + for y in range(self.map_size[0]): + self.map_ += '?' * self.map_size[1] + + def set_map_line(self, y, line): + width_map = self.map_size[1] + if y >= self.map_size[0]: + raise ArgError('too large row number %s' % y) + width_line = len(line) + if width_line > width_map: + raise ArgError('too large map line width %s' % width_line) + self.map_ = self.map_[:y * width_map] + line + \ + self.map_[(y + 1) * width_map:] + + def get_thing(self, i): + for thing in self.things: + if i == thing.id_: + return thing + t = Thing(self, i, '?', [0,0]) + self.things += [t] + return t + + class Task: def __init__(self, thing, name, args=(), kwargs={}): @@ -81,8 +104,9 @@ class Task: class Thing: - def __init__(self, world, type_, position): + def __init__(self, world, id_, type_, position): self.world = world + self.id_ = id_ self.type_ = type_ self.position = position self.task = Task(self, 'wait') @@ -101,8 +125,8 @@ class Thing: else: self.set_task('wait') - def set_task(self, task, *args, **kwargs): - self.task = Task(self, task, args, kwargs) + def set_task(self, task_name, *args, **kwargs): + self.task = Task(self, task_name, args, kwargs) self.task.check() def proceed(self, is_AI=True): -- 2.30.2