From: Christian Heller Date: Sun, 25 Oct 2020 03:58:49 +0000 (+0100) Subject: Add basic save file mechanism. X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/do_tasks?a=commitdiff_plain;h=47d047c10bacf2463f48aec3e7f3cc3b92a78198;p=plomrogue2-experiments Add basic save file mechanism. --- diff --git a/new2/plomrogue/commands.py b/new2/plomrogue/commands.py index 09f22c0..df34728 100644 --- a/new2/plomrogue/commands.py +++ b/new2/plomrogue/commands.py @@ -37,4 +37,23 @@ cmd_QUERY.argtypes = 'string string' def cmd_PING(game, connection_id): game.io.send('PONG') -cmd_QUERY.argtypes = '' +cmd_PING.argtypes = '' + +def cmd_SAVE(game): + + def write(f, msg): + f.write(msg + '\n') + + with open(game.io.save_file, 'w') as f: + write(f, 'TURN %s' % game.turn) + for y, line in game.map.lines(): + write(f, 'MAP_LINE %5s %s' % (y, quote(line))) +cmd_SAVE.argtypes = '' + +def cmd_TURN(game, n): + game.turn = n +cmd_TURN.argtypes = 'int:nonneg' + +def cmd_MAP_LINE(game, y, line): + game.map.set_line(y, line) +cmd_MAP_LINE.argtypes = 'int:nonneg string' diff --git a/new2/plomrogue/game.py b/new2/plomrogue/game.py index 82e5d18..6325fd0 100755 --- a/new2/plomrogue/game.py +++ b/new2/plomrogue/game.py @@ -1,6 +1,7 @@ from plomrogue.tasks import Task_WAIT, Task_MOVE, Task_WRITE from plomrogue.errors import GameError -from plomrogue.commands import cmd_ALL, cmd_LOGIN, cmd_QUERY, cmd_PING +from plomrogue.commands import (cmd_ALL, cmd_LOGIN, cmd_QUERY, cmd_PING, + cmd_SAVE, cmd_TURN, cmd_MAP_LINE) from plomrogue.io import GameIO from plomrogue.misc import quote from plomrogue.things import Thing, ThingPlayer @@ -31,10 +32,11 @@ class GameBase: class Game(GameBase): - def __init__(self, *args, **kwargs): + def __init__(self, save_file, *args, **kwargs): + import os super().__init__(*args, **kwargs) self.changed = True - self.io = GameIO(self) + self.io = GameIO(self, save_file) self.tasks = {'WAIT': Task_WAIT, 'MOVE': Task_MOVE, 'WRITE': Task_WRITE} @@ -42,11 +44,24 @@ class Game(GameBase): self.commands = {'QUERY': cmd_QUERY, 'ALL': cmd_ALL, 'LOGIN': cmd_LOGIN, + 'SAVE': cmd_SAVE, + 'TURN': cmd_TURN, + 'MAP_LINE': cmd_MAP_LINE, 'PING': cmd_PING} self.thing_type = Thing self.thing_types = {'player': ThingPlayer} self.sessions = {} self.map = Map(self.map_geometry.size) + if os.path.exists(self.io.save_file): + if not os.path.isfile(self.io.save_file): + raise GameError('save file path refers to non-file') + else: + with open(self.io.save_file, 'r') as f: + lines = f.readlines() + for i in range(len(lines)): + line = lines[i] + print("FILE INPUT LINE %5s: %s" % (i, line), end='') + self.io.handle_input(line) def get_string_options(self, string_option_type): import string diff --git a/new2/plomrogue/io.py b/new2/plomrogue/io.py index d740f8c..2283a98 100644 --- a/new2/plomrogue/io.py +++ b/new2/plomrogue/io.py @@ -4,11 +4,12 @@ import queue class GameIO(): - def __init__(self, game): + def __init__(self, game, save_file='savefile'): from plomrogue.parser import Parser self.clients = {} self.parser = Parser(game) self.game = game + self.save_file = save_file def loop(self, q): """Handle commands coming through queue q, run game, send results back.""" diff --git a/new2/plomrogue/mapping.py b/new2/plomrogue/mapping.py index cd0c23d..39aff65 100644 --- a/new2/plomrogue/mapping.py +++ b/new2/plomrogue/mapping.py @@ -77,5 +77,21 @@ class Map(): def size_i(self): return self.size.y * self.size.x + def set_line(self, y, line): + height_map = self.size.y + width_map = self.size.x + if y >= height_map: + 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.terrain = self.terrain[:y * width_map] + line +\ + self.terrain[(y + 1) * width_map:] + def get_position_index(self, yx): return yx.y * self.size.x + yx.x + + def lines(self): + width = self.size.x + for y in range(self.size.y): + yield (y, self.terrain[y * width:(y + 1) * width]) diff --git a/new2/plomrogue/parser.py b/new2/plomrogue/parser.py index a56b5d1..f23a7aa 100644 --- a/new2/plomrogue/parser.py +++ b/new2/plomrogue/parser.py @@ -75,7 +75,11 @@ class Parser: for i in range(len(tmpl_tokens)): tmpl = tmpl_tokens[i] arg = args_tokens[i] - if tmpl == string_string: + if tmpl == 'int:nonneg': + if not arg.isdigit(): + raise ArgError('Argument must be non-negative integer.') + args += [int(arg)] + elif tmpl == string_string: args += [arg] elif tmpl[:len(string_string) + 1] == string_string + ':': if not hasattr(self.game, 'get_string_options'): diff --git a/new2/rogue_chat.py b/new2/rogue_chat.py index 415b8c1..afaeef9 100755 --- a/new2/rogue_chat.py +++ b/new2/rogue_chat.py @@ -1,5 +1,11 @@ #!/usr/bin/env python3 from plomrogue.game import Game from plomrogue.io_websocket import PlomWebSocketServer -game = Game() +import sys + +if len(sys.argv) != 2: + print('wrong number of arguments, expected one (save file)') + exit(1) +savefile = sys.argv[1] +game = Game(savefile) game.io.run_loop_with_server(8000, PlomWebSocketServer)