home · contact · privacy
Add basic save file mechanism.
authorChristian Heller <c.heller@plomlompom.de>
Sun, 25 Oct 2020 03:58:49 +0000 (04:58 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Sun, 25 Oct 2020 03:58:49 +0000 (04:58 +0100)
new2/plomrogue/commands.py
new2/plomrogue/game.py
new2/plomrogue/io.py
new2/plomrogue/mapping.py
new2/plomrogue/parser.py
new2/rogue_chat.py

index 09f22c081beb346070f5bbc7175110577471378b..df347289f64459ce4718df6aefb6a87a6ec920d2 100644 (file)
@@ -37,4 +37,23 @@ cmd_QUERY.argtypes = 'string string'
 
 def cmd_PING(game, connection_id):
     game.io.send('PONG')
 
 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'
index 82e5d181c98d3562f4bcd73b215bd714634b9813..6325fd0d0849dc9ef37df9612046fcf92f54ba1d 100755 (executable)
@@ -1,6 +1,7 @@
 from plomrogue.tasks import Task_WAIT, Task_MOVE, Task_WRITE
 from plomrogue.errors import GameError
 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 
 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):
 
 
 class Game(GameBase):
 
-    def __init__(self, *args, **kwargs):
+    def __init__(self, save_file, *args, **kwargs):
+        import os
         super().__init__(*args, **kwargs)
         self.changed = True
         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}
         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,
         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)
                          '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
 
     def get_string_options(self, string_option_type):
         import string
index d740f8c42972879e9f911d21ba5edf5e6d9c1e84..2283a986d10717511778b1d79aa5dca4b4919557 100644 (file)
@@ -4,11 +4,12 @@ import queue
 
 class GameIO():
 
 
 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
         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."""
 
     def loop(self, q):
         """Handle commands coming through queue q, run game, send results back."""
index cd0c23def676edd8eb146fca15da7c781201fb28..39aff658bee8682fa738244879166fe6f0c250fe 100644 (file)
@@ -77,5 +77,21 @@ class Map():
     def size_i(self):
         return self.size.y * self.size.x
 
     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 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])
index a56b5d1bb64bd8b07f2aecb101d88a4dc4ee91f3..f23a7aaacb58e8f89604f85ec1b525e0e0ac9d01 100644 (file)
@@ -75,7 +75,11 @@ class Parser:
         for i in range(len(tmpl_tokens)):
             tmpl = tmpl_tokens[i]
             arg = args_tokens[i]
         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'):
                 args += [arg]
             elif tmpl[:len(string_string) + 1] == string_string + ':':
                 if not hasattr(self.game, 'get_string_options'):
index 415b8c11299d5ad41e0d170b2d31d39aad85e611..afaeef9835a52a96f23638d46bd1ce93982f04b4 100755 (executable)
@@ -1,5 +1,11 @@
 #!/usr/bin/env python3
 from plomrogue.game import Game 
 from plomrogue.io_websocket import PlomWebSocketServer
 #!/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)
 game.io.run_loop_with_server(8000, PlomWebSocketServer)