seopardy/game.py

242 lines
7.1 KiB
Python
Raw Normal View History

2013-11-06 20:42:00 +01:00
from __future__ import print_function
from PySide import QtCore, QtGui
2013-11-25 12:06:07 +01:00
from player import Player, nobodyColor
2013-11-23 17:51:52 +01:00
from windows import QuestionWindow, EditAnswersWindow, PlayerStartWindow, VictoryWindow
2013-11-18 17:47:03 +01:00
from gamestate import QuestionAnswers
2013-11-06 20:42:00 +01:00
class SeopardyGame(QtGui.QWidget):
def __init__(self, questions, gamestate, parent=None):
super(SeopardyGame, self).__init__(parent)
self.questions = questions
self.gamestate = gamestate
2013-11-22 00:01:09 +01:00
#self.players = [Player.gen_player(i, parent=self) for i in range(1, 4)]
self.players = []
for i in range(3):
self.add_player()
2013-11-06 20:42:00 +01:00
2013-11-22 00:01:09 +01:00
self._inOtherWindow = False
2013-11-06 20:42:00 +01:00
self._createGui()
self.showFullScreen()
2013-11-22 00:01:09 +01:00
# initiate starting the game!
QtCore.QCoreApplication.postEvent(self, GameStartEvent())
def add_player(self):
self.players.append(Player.gen_player(len(self.players)+1, self))
2013-11-06 20:42:00 +01:00
def _createGui(self):
""" Create the board from questions. """
layout = QtGui.QVBoxLayout()
headerLayout = QtGui.QHBoxLayout()
header = QtGui.QLabel("Header")
headerLayout.addWidget(header)
headerLayout.setSizeConstraint(QtGui.QLayout.SetMinimumSize)
layout.addWidget(header, alignment=QtCore.Qt.AlignCenter)
# create board
#board = QtGui.QGridLayout(6, len(self.questions.get_sections()))
board = QtGui.QGridLayout()
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)
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; }")
2013-11-18 18:33:43 +01:00
b.installEventFilter(FocusKeyGrabber(i+1, j+1, self))
2013-11-11 00:52:37 +01:00
b.clicked.connect(lambda sec=sec, j=j: self.go_to_question(sec, j+1))
2013-11-06 20:42:00 +01:00
board.addWidget(b, j+1, i)
layout.addLayout(board)
2013-11-11 00:52:37 +01:00
self.board = board
2013-11-06 20:42:00 +01:00
# create player bar
self.playerBar = QtGui.QHBoxLayout()
for i, player in enumerate(self.players):
self.playerBar.addWidget(player)
if i != len(self.players)-1:
self.playerBar.addStretch()
layout.addLayout(self.playerBar)
self.setLayout(layout)
2013-11-18 18:33:43 +01:00
def setFocusToQuestion(self, secno, number):
if secno < 1 or secno > len(self.questions.get_sections()) or number > 5 or number < 1:
return
self.board.itemAtPosition(number, secno-1).widget().setFocus()
2013-11-11 00:52:37 +01:00
2013-11-22 00:01:09 +01:00
def event(self, e):
if e.type() == GameStartEvent.eventType:
# start window
if not self._inOtherWindow:
self._inOtherWindow = True
x = PlayerStartWindow(self.players, self)
x.exec_()
self._inOtherWindow = False
return True
else:
return super(SeopardyGame, self).event(e)
2013-11-07 01:19:50 +01:00
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Escape:
self.close()
2013-11-22 02:28:12 +01:00
elif e.key() == QtCore.Qt.Key_R:
x = PlayerStartWindow(self.players, self)
self._inOtherWindow = True
x.exec_()
self._inOtherWindow = False
2013-11-23 17:51:52 +01:00
elif e.key() == QtCore.Qt.Key_V:
self.show_victory_window()
2013-11-13 21:16:50 +01:00
elif e.key() == QtCore.Qt.Key_E:
if self._inOtherWindow:
return
2013-11-18 17:47:03 +01:00
# find current question
section = None
qno = None
found = False
for secno, section in enumerate(self.questions.get_sections(), 0):
for qno in range(1, 6):
btn = self.board.itemAtPosition(qno, secno).widget()
if btn == self.focusWidget():
found = True
break
if found:
break
if not found:
return
self.edit_question_answers(section, qno)
def edit_question_answers(self, section, number):
2013-11-13 21:16:50 +01:00
self._inOtherWindow = True
2013-11-18 17:47:03 +01:00
answers = self.gamestate.get_answers(section, number)
if answers is None:
answers = QuestionAnswers(section, number)
editAnswersWin = EditAnswersWindow(self.players, answers, self)
editAnswersWin.exec_()
2013-11-13 21:16:50 +01:00
self._inOtherWindow = False
2013-11-07 01:19:50 +01:00
2013-11-18 17:47:03 +01:00
oldAnswers = self.gamestate.get_answers(section, number)
newAnswers = editAnswersWin.get_new_answers()
if oldAnswers:
self._set_player_points(oldAnswers, rollback=True)
self._set_player_points(newAnswers)
self.gamestate.set_answers(section, number, newAnswers)
self._restyle_button(section, number, newAnswers)
2013-11-23 17:51:52 +01:00
def show_victory_window(self):
self._inOtherWindow = True
victoryWindow = VictoryWindow(self.players, self)
victoryWindow.exec_()
self._inOtherWindow = False
2013-11-11 00:52:37 +01:00
def go_to_question(self, section, number):
2013-11-13 21:16:50 +01:00
if self._inOtherWindow:
2013-11-11 00:52:37 +01:00
return
2013-11-13 21:16:50 +01:00
self._inOtherWindow = True
answers = self.gamestate.get_answers(section, number)
wasAnswered = (answers is not None and answers.is_answered())
2013-11-06 20:42:00 +01:00
question = self.questions.get_question(section, number)
if question["Double-Jeopardy"]:
print("maunz")
return
qwin = QuestionWindow(self.players, section, number, question, answers, self)
2013-11-06 20:42:00 +01:00
qwin.showFullScreen()
qwin.exec_()
2013-11-13 21:16:50 +01:00
self._inOtherWindow = False
2013-11-11 00:52:37 +01:00
# add points to players
if not wasAnswered:
answers = qwin.get_answers()
self.gamestate.set_answers(section, number, answers)
self._set_player_points(answers)
2013-11-11 00:52:37 +01:00
# restyle the button
self._restyle_button(section, number, answers)
2013-11-13 21:16:50 +01:00
def _set_player_points(self, answers, rollback=False):
for player, correct in answers.get_tries():
prefix = 1
if rollback:
prefix *= -1
if not correct:
prefix *= -1
2013-11-21 15:23:48 +01:00
player.add_points(answers.points()*prefix)
2013-11-11 00:52:37 +01:00
def _restyle_button(self, sec, qno, answers):
2013-11-18 17:47:03 +01:00
2013-11-11 00:52:37 +01:00
secno = self.questions.get_number_from_section(sec)
btn = self.board.itemAtPosition(qno, secno-1).widget()
btnstr = ""
btncolor = None
2013-11-18 17:47:03 +01:00
if not answers.is_answered():
btn.setText(str(answers.points()))
btn.setStyleSheet("QPushButton { font-size: 60px; }")
return
2013-11-11 00:52:37 +01:00
# restrict number of tries shown
numTries = 4 if answers.got_answered() else 3
tries = answers.get_tries()
if len(tries) > numTries:
btnstr = "...\n"
for player, correct in answers.get_tries()[-numTries:]:
if correct:
btncolor = player.color
prefix = "+"
else:
prefix = "-"
btnstr += "%s%s\n" % (prefix, player.name)
if not answers.got_answered():
btnstr += "+nobody"
2013-11-25 12:06:07 +01:00
btncolor = nobodyColor
2013-11-11 00:52:37 +01:00
btn.setStyleSheet("QPushButton { background-color: %s; color: white; font-size: 20px; border: none; }" % (btncolor.name(),))
btn.setText(btnstr.strip())
2013-11-18 18:33:43 +01:00
class FocusKeyGrabber(QtCore.QObject):
def __init__(self, secno, number, parent, *args, **kwargs):
super(FocusKeyGrabber, self).__init__(parent, *args, **kwargs)
self._secno = secno
self._number = number
self._parent = parent
def eventFilter(self, obj, e):
if e.type() == QtCore.QEvent.KeyPress:
if e.key() == QtCore.Qt.Key.Key_Left:
self._parent.setFocusToQuestion(self._secno-1, self._number)
return True
elif e.key() == QtCore.Qt.Key.Key_Right:
self._parent.setFocusToQuestion(self._secno+1, self._number)
return True
elif e.key() == QtCore.Qt.Key.Key_Up:
self._parent.setFocusToQuestion(self._secno, self._number-1)
return True
elif e.key() == QtCore.Qt.Key.Key_Down:
self._parent.setFocusToQuestion(self._secno, self._number+1)
return True
return QtCore.QObject.eventFilter(self, obj, e)
2013-11-22 00:01:09 +01:00
class GameStartEvent(QtCore.QEvent):
eventType = QtCore.QEvent.Type(QtCore.QEvent.registerEventType())
def __init__(self):
super(GameStartEvent, self).__init__(self.eventType)