GameState loading/saving works
This commit is contained in:
parent
13690e493e
commit
d26c7a3a88
43
game.py
43
game.py
|
@ -13,9 +13,11 @@ class SeopardyGame(QtGui.QWidget):
|
|||
self.questions = questions
|
||||
self.gamestate = gamestate
|
||||
#self.players = [Player.gen_player(i, parent=self) for i in range(1, 4)]
|
||||
self.players = []
|
||||
self.players = self.gamestate.get_players()
|
||||
if len(self.players) == 0:
|
||||
for i in range(3):
|
||||
self.add_player()
|
||||
|
||||
self.currentPlayer = None
|
||||
|
||||
self._inOtherWindow = False
|
||||
|
@ -23,6 +25,7 @@ class SeopardyGame(QtGui.QWidget):
|
|||
self.showFullScreen()
|
||||
|
||||
# initiate starting the game!
|
||||
if self.gamestate.get_state() == "start":
|
||||
QtCore.QCoreApplication.postEvent(self, GameStartEvent())
|
||||
|
||||
def add_player(self):
|
||||
|
@ -40,22 +43,22 @@ class SeopardyGame(QtGui.QWidget):
|
|||
|
||||
# create board
|
||||
#board = QtGui.QGridLayout(6, len(self.questions.get_sections()))
|
||||
board = QtGui.QGridLayout()
|
||||
board.setSizeConstraint(QtGui.QLayout.SetMaximumSize)
|
||||
self.board = QtGui.QGridLayout()
|
||||
self.board.setSizeConstraint(QtGui.QLayout.SetMaximumSize)
|
||||
for i, sec in enumerate(self.questions.get_sections()):
|
||||
seclabel = QtGui.QLabel(sec, alignment=QtCore.Qt.AlignCenter)
|
||||
seclabel.setStyleSheet("QLabel { font-size: 30px; }")
|
||||
board.addWidget(seclabel, 0, i)
|
||||
self.board.addWidget(seclabel, 0, i)
|
||||
for j in range(5):
|
||||
b = QtGui.QPushButton(str((j+1)*100))
|
||||
b.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
b.setAutoDefault(False)
|
||||
b.setStyleSheet("QPushButton { font-size: 60px; }")
|
||||
#b.setStyleSheet("QPushButton { font-size: 60px; }")
|
||||
b.installEventFilter(FocusKeyGrabber(i+1, j+1, self))
|
||||
b.clicked.connect(lambda sec=sec, j=j: self.go_to_question(sec, j+1))
|
||||
board.addWidget(b, j+1, i)
|
||||
layout.addLayout(board)
|
||||
self.board = board
|
||||
self.board.addWidget(b, j+1, i)
|
||||
self._restyle_button(sec, j+1, self.gamestate.get_answers(sec, j+1))
|
||||
layout.addLayout(self.board)
|
||||
|
||||
# create player bar
|
||||
self.playerBar = QtGui.QHBoxLayout()
|
||||
|
@ -81,6 +84,8 @@ class SeopardyGame(QtGui.QWidget):
|
|||
x = PlayerStartWindow(self.players, self)
|
||||
x.exec_()
|
||||
self._inOtherWindow = False
|
||||
self.gamestate.set_state("playing")
|
||||
self.gamestate.save()
|
||||
|
||||
return True
|
||||
else:
|
||||
|
@ -136,6 +141,7 @@ class SeopardyGame(QtGui.QWidget):
|
|||
self._set_player_points(newAnswers)
|
||||
self.gamestate.set_answers(section, number, newAnswers)
|
||||
self._restyle_button(section, number, newAnswers)
|
||||
self.gamestate.save()
|
||||
|
||||
def show_victory_window(self):
|
||||
self._inOtherWindow = True
|
||||
|
@ -176,6 +182,23 @@ class SeopardyGame(QtGui.QWidget):
|
|||
# restyle the button
|
||||
self._restyle_button(section, number, answers)
|
||||
|
||||
# safe current gamestate
|
||||
self.gamestate.save()
|
||||
|
||||
# check if we are done
|
||||
foundUnanswered = False
|
||||
for sec in self.questions.get_sections():
|
||||
for j in range(5):
|
||||
boardAnswers = self.gamestate.get_answers(sec, j+1)
|
||||
if boardAnswers is None or not answers.is_answered():
|
||||
foundUnanswered = True
|
||||
if foundUnanswered:
|
||||
break
|
||||
|
||||
if not foundUnanswered:
|
||||
self.show_victory_window()
|
||||
|
||||
|
||||
def _set_player_points(self, answers, rollback=False):
|
||||
for i, (player, correct) in enumerate(answers.get_tries()):
|
||||
prefix = 1
|
||||
|
@ -199,8 +222,8 @@ class SeopardyGame(QtGui.QWidget):
|
|||
btnstr = ""
|
||||
btncolor = None
|
||||
|
||||
if not answers.is_answered():
|
||||
btn.setText(str(answers.points()))
|
||||
if answers is None or not answers.is_answered():
|
||||
btn.setText(str(qno*100))
|
||||
btn.setStyleSheet("QPushButton { font-size: 60px; }")
|
||||
return
|
||||
|
||||
|
|
51
gamestate.py
51
gamestate.py
|
@ -1,6 +1,8 @@
|
|||
from __future__ import print_function
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import yaml
|
||||
from collections import defaultdict
|
||||
|
||||
class GameState(object):
|
||||
|
@ -10,17 +12,30 @@ class GameState(object):
|
|||
savedir: dir to save gamestate into, should be overwritable
|
||||
board: dict of section with list of questions
|
||||
"""
|
||||
GAMESTATE = ["start", "playing", "end"]
|
||||
|
||||
def __init__(self, savedir):
|
||||
self.savedir = savedir
|
||||
|
||||
self._board = defaultdict(lambda: [None]*5)
|
||||
self._players = None
|
||||
#self._board = defaultdict(lambda: [None]*5)
|
||||
self._board = defaultdict(_mk_empty_board_column)
|
||||
self._players = []
|
||||
self._state = self.GAMESTATE[0]
|
||||
|
||||
if not os.path.exists(self.savedir):
|
||||
os.mkdir(self.savedir)
|
||||
elif not os.path.isdir(self.savedir):
|
||||
raise ValueError("'%s' is not a directory but something else!" % self.savedir)
|
||||
|
||||
|
||||
def set_state(self, state):
|
||||
if state not in self.GAMESTATE:
|
||||
raise ValueError("'%s' is not a valid gamestate, valid choices are %s" % (state, self.GAMESTATE))
|
||||
self._state = state
|
||||
|
||||
def get_state(self):
|
||||
return self._state
|
||||
|
||||
def set_answers(self, section, qnumber, answers):
|
||||
self._board[section][qnumber-1] = answers
|
||||
|
||||
|
@ -28,14 +43,38 @@ class GameState(object):
|
|||
return self._board[section][qnumber-1]
|
||||
|
||||
def set_players(self, players):
|
||||
self.players = players
|
||||
self._players = players
|
||||
|
||||
def get_players(self):
|
||||
return self._players
|
||||
|
||||
def _make_structure(self):
|
||||
return {
|
||||
"state": self._state,
|
||||
"players": self._players,
|
||||
"board": self._board
|
||||
}
|
||||
|
||||
def save(self):
|
||||
pass
|
||||
fname = datetime.datetime.now().strftime("seopardy.%Y-%m-%d-_%H:%M:%S.save")
|
||||
fstream = open("%s/%s" % (self.savedir, fname), "w")
|
||||
yaml.dump(self._make_structure(), fstream)
|
||||
fstream.close()
|
||||
|
||||
@classmethod
|
||||
def load(clazz, fpath):
|
||||
pass
|
||||
def load(clazz, sstream, savedir):
|
||||
gs = clazz(savedir)
|
||||
data = yaml.load(sstream)
|
||||
gs._state = data["state"]
|
||||
gs._players = data["players"]
|
||||
gs._board = data["board"]
|
||||
|
||||
return gs
|
||||
|
||||
def _mk_empty_board_column():
|
||||
""" We can't use a lambda here, as we want the default dict to be
|
||||
easily serializeable by yaml. """
|
||||
return [None]*5
|
||||
|
||||
class QuestionAnswers(object):
|
||||
def __init__(self, section, qnumber, dj_points=None):
|
||||
|
|
21
player.py
21
player.py
|
@ -1,5 +1,6 @@
|
|||
from __future__ import print_function
|
||||
|
||||
import yaml
|
||||
from PySide import QtGui, QtCore
|
||||
|
||||
class Player(QtGui.QWidget):
|
||||
|
@ -9,6 +10,7 @@ class Player(QtGui.QWidget):
|
|||
("Baz", QtGui.QColor(0, 0, 255)),
|
||||
("Blubb", QtGui.QColor(0, 255, 255)),
|
||||
("Murr", QtGui.QColor(255, 0, 255)),
|
||||
("Maunz", QtGui.QColor(255, 255, 0)),
|
||||
]
|
||||
|
||||
def __init__(self, name, color, points=0, parent=None):
|
||||
|
@ -46,6 +48,21 @@ class Player(QtGui.QWidget):
|
|||
|
||||
return clazz(*clazz.DEFAULT_PLAYERS[num-1], parent=parent)
|
||||
|
||||
@classmethod
|
||||
def _yaml_representer(clazz, dumper, data):
|
||||
#def __init__(self, name, color, points=0, parent=None):
|
||||
return dumper.represent_mapping(u'!player', {
|
||||
'name': data.name,
|
||||
'points': data.points,
|
||||
'color': data.color.name()
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def _yaml_constructor(clazz, loader, node):
|
||||
pdict = loader.construct_mapping(node)
|
||||
pdict["color"] = QtGui.QColor(pdict["color"])
|
||||
return Player(**pdict)
|
||||
|
||||
|
||||
class ButtonEvent(QtCore.QEvent):
|
||||
eventType = QtCore.QEvent.Type(QtCore.QEvent.registerEventType())
|
||||
|
@ -60,3 +77,7 @@ class ButtonEvent(QtCore.QEvent):
|
|||
return self.playerno
|
||||
|
||||
nobodyColor = QtGui.QColor(128, 128, 128)
|
||||
|
||||
# yaml dumpers/loaders
|
||||
yaml.add_representer(Player, Player._yaml_representer)
|
||||
yaml.add_constructor(u'!player', Player._yaml_constructor)
|
||||
|
|
17
seopardy.py
17
seopardy.py
|
@ -31,12 +31,27 @@ if __name__ == '__main__':
|
|||
os.mkfifo(args.fifo)
|
||||
except OSError as e:
|
||||
print("Error: Could not create fifo: %s" % (str(e),), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
questions = Questions(args.questions)
|
||||
gamestate = GameState(args.savedir)
|
||||
|
||||
# start gui
|
||||
app = QtGui.QApplication([])
|
||||
|
||||
# create or load gamestate
|
||||
gamestate = None
|
||||
if args.gamestate:
|
||||
sstream = None
|
||||
try:
|
||||
sstream = open(args.gamestate, "r")
|
||||
except IOError as e:
|
||||
print("Error: Could not load gamestate: %s" % (str(e),), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
gamestate = GameState.load(sstream, args.savedir)
|
||||
else:
|
||||
gamestate = GameState(args.savedir)
|
||||
|
||||
# create board
|
||||
board = SeopardyGame(questions, gamestate)
|
||||
board.show()
|
||||
app.exec_()
|
||||
|
|
Loading…
Reference in New Issue