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'
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
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}
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
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."""
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])
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'):
#!/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)