Sebastian Lohff 6 years ago
parent
commit
abc5ef5ddc
8 changed files with 228 additions and 2 deletions
  1. 8
    0
      buttonreader.py
  2. 67
    0
      game.py
  3. 5
    0
      gamestate.py
  4. 48
    0
      player.py
  5. 7
    1
      question.py
  6. 1
    1
      questions/template.q
  7. 42
    0
      seopardy.py
  8. 50
    0
      windows.py

+ 8
- 0
buttonreader.py View File

@@ -0,0 +1,8 @@
1
+# write a thread that reads buttoninput from fifo or pyserial or something
2
+# https://gist.github.com/elshaka/2999082
3
+# and make this configureable
4
+from __future__ import print_function
5
+from PySide import QtCore
6
+
7
+class SerialThread(QtCore.QThread):
8
+	dataReady = QtCore.Signal(str)

+ 67
- 0
game.py View File

@@ -0,0 +1,67 @@
1
+from __future__ import print_function
2
+
3
+from PySide import QtCore, QtGui
4
+
5
+from player import Player
6
+from windows import QuestionWindow
7
+
8
+class SeopardyGame(QtGui.QWidget):
9
+	def __init__(self, questions, gamestate, parent=None):
10
+		super(SeopardyGame, self).__init__(parent)
11
+
12
+		self.questions = questions
13
+		self.gamestate = gamestate
14
+		self.players = [Player.gen_player(i) for i in range(1, 4)]
15
+
16
+		self._createGui()
17
+
18
+		self.showFullScreen()
19
+
20
+	def _createGui(self):
21
+		""" Create the board from questions. """
22
+
23
+		layout = QtGui.QVBoxLayout()
24
+		headerLayout = QtGui.QHBoxLayout()
25
+		header = QtGui.QLabel("Header")
26
+		headerLayout.addWidget(header)
27
+		headerLayout.setSizeConstraint(QtGui.QLayout.SetMinimumSize)
28
+		layout.addWidget(header, alignment=QtCore.Qt.AlignCenter)
29
+
30
+		# create board
31
+		#board = QtGui.QGridLayout(6, len(self.questions.get_sections()))
32
+		board = QtGui.QGridLayout()
33
+		board.setSizeConstraint(QtGui.QLayout.SetMaximumSize)
34
+		for i, sec in enumerate(self.questions.get_sections()):
35
+			seclabel = QtGui.QLabel(sec, alignment=QtCore.Qt.AlignCenter)
36
+			seclabel.setStyleSheet("QLabel { font-size: 30px; }")
37
+			board.addWidget(seclabel, 0, i)
38
+			for j in range(5):
39
+				b = QtGui.QPushButton(str((j+1)*100))
40
+				b.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
41
+				b.setAutoDefault(False)
42
+				b.setStyleSheet("QPushButton { font-size: 60px; }")
43
+				b.clicked.connect(lambda sec=sec, j=j: self.tfunc(sec, j+1))
44
+				board.addWidget(b, j+1, i)
45
+		layout.addLayout(board)
46
+
47
+		# create player bar
48
+		self.playerBar = QtGui.QHBoxLayout()
49
+		for i, player in enumerate(self.players):
50
+			self.playerBar.addWidget(player)
51
+			if i != len(self.players)-1:
52
+				self.playerBar.addStretch()
53
+		layout.addLayout(self.playerBar)
54
+
55
+		self.setLayout(layout)
56
+
57
+	def tfunc(self, section, number):
58
+		print("question window", section, number)
59
+
60
+		qwin = QuestionWindow(section, self.questions.get_question(section, number), self)
61
+		qwin.showFullScreen()
62
+		qwin.exec_()
63
+
64
+		results = qwin.get_results()
65
+		for result in results:
66
+			print("result", result)
67
+

+ 5
- 0
gamestate.py View File

@@ -0,0 +1,5 @@
1
+from __future__ import print_function
2
+
3
+class GameState(object):
4
+	def __init__(self, statefile=None):
5
+		pass

+ 48
- 0
player.py View File

@@ -0,0 +1,48 @@
1
+from __future__ import print_function
2
+
3
+from PySide import QtGui, QtCore
4
+
5
+class Player(QtGui.QWidget):
6
+	DEFAULT_PLAYERS = [
7
+		("Foo",   QtGui.QColor(255,   0,   0)),
8
+		("Bar",   QtGui.QColor(0,   255,   0)),
9
+		("Baz",   QtGui.QColor(0,     0, 255)),
10
+		("Blubb", QtGui.QColor(0,   255, 255)),
11
+		("Murr",  QtGui.QColor(255,   0, 255)),
12
+	]
13
+
14
+	def __init__(self, name, color, points=0, parent=None):
15
+		super(Player, self).__init__(parent)
16
+		self.name = name
17
+		self.color = color
18
+		self.points = points
19
+
20
+		self.setup_gui()
21
+
22
+	def setup_gui(self):
23
+		self.layout = QtGui.QVBoxLayout()
24
+		self.name_label = QtGui.QLabel(self.name)
25
+		self.name_label.setStyleSheet("QLabel { font-size: 40px; background-color: %s; color: white; }" % (self.color.name(),))
26
+		self.layout.addWidget(self.name_label)
27
+
28
+		self.points_label = QtGui.QLabel(str(self.points))
29
+		self.points_label.setStyleSheet("QLabel { font-size: 40px;}")
30
+		self.layout.addWidget(self.points_label, alignment=QtCore.Qt.AlignRight)
31
+
32
+		self.setLayout(self.layout)
33
+
34
+	def change_name(self, new_name):
35
+		self.name = new_name
36
+		self.name_label.set_text(new_name)
37
+
38
+	def add_points(self, amount):
39
+		self.points += amount
40
+		self.points_label.set_text(str(self.points))
41
+
42
+	@classmethod
43
+	def gen_player(clazz, num):
44
+		if num > len(clazz.DEFAULT_PLAYERS):
45
+			raise ValueError("You tried to generate too many players")
46
+
47
+		return clazz(*clazz.DEFAULT_PLAYERS[num-1])
48
+

+ 7
- 1
question.py View File

@@ -1,12 +1,18 @@
1 1
 import os
2 2
 import yaml
3 3
 
4
+
4 5
 class QuestionException(Exception):
6
+	""" Exception to be thrown when there is something wrong with
7
+	    the question file. """
5 8
 	pass
6 9
 
7 10
 class Questions(object):
11
+	""" Object holding all the questions """
12
+
8 13
 	QUESTION_TYPES = ["Text", "Image", "Music"]
9 14
 	QUESTION_KEYS = ["Name", "Question", "Answer", "Type", "Double-Jeopardy"]
15
+
10 16
 	def __init__(self, qfile):
11 17
 		self.qfile = qfile
12 18
 		self._questions = None
@@ -80,7 +86,7 @@ class Questions(object):
80 86
 				raise QuestionException("Section %d (%s) needs to have exactly %d questions (has %d)" % (i, sec["Section"], 5, j))
81 87
 
82 88
 		# check for only having unique section names
83
-		sections = [s["Section"] for s in self._questions]
89
+		sections = [s["Section"] for s in ysrc]
84 90
 		if len(sections) != len(set(sections)):
85 91
 			raise QuestionException("All section names must be unique")
86 92
 

+ 1
- 1
questions/template.q View File

@@ -1,7 +1,7 @@
1 1
  - Section: A
2 2
    Questions:
3 3
      - Name: Question 1
4
-       Question: Foo.
4
+       Question: Foo. Bar. Lange Frage. Ich meine warum sollte das Jeopardy nicht auch mal so ne richtig lange frage haben? ;)
5 5
        Answer: Bar?
6 6
        Type: Text
7 7
 

+ 42
- 0
seopardy.py View File

@@ -0,0 +1,42 @@
1
+#!/usr/bin/python
2
+from __future__ import print_function
3
+
4
+import argparse
5
+import os
6
+import sys
7
+#from PySide import QtCore, QtGui
8
+from PySide import QtGui
9
+
10
+from question import Questions
11
+from gamestate import GameState
12
+from game import SeopardyGame
13
+
14
+def _parser():
15
+	parser = argparse.ArgumentParser(description="Sebas jeopardy/beopardy clone")
16
+	parser.add_argument("--fifo", action="store", default="/tmp/seopardy-fifo", help="Name of the fifo to create")
17
+	parser.add_argument("--gamestate", action="store", default=None, help="Gamestate to load to recover a crashed game")
18
+	parser.add_argument("questions", action="store", help="Path to questionfile")
19
+
20
+	return parser
21
+
22
+if __name__ == '__main__':
23
+	parser = _parser()
24
+	args = parser.parse_args()
25
+
26
+	fifo = None
27
+	try:
28
+		if os.path.exists(args.fifo):
29
+			os.unlink(args.fifo)
30
+		os.mkfifo(args.fifo)
31
+	except OSError as e:
32
+		print("Error: Could not create fifo: %s" % (str(e),), file=sys.stderr)
33
+
34
+	questions = Questions(args.questions)
35
+	gamestate = GameState(args.gamestate)
36
+
37
+	# start gui
38
+	app = QtGui.QApplication([])
39
+	board = SeopardyGame(questions, gamestate)
40
+	board.show()
41
+	app.exec_()
42
+	sys.exit()

+ 50
- 0
windows.py View File

@@ -0,0 +1,50 @@
1
+from PySide import QtGui, QtCore
2
+
3
+#class QuestionWindow(QtGui.QWidget):
4
+class QuestionWindow(QtGui.QDialog):
5
+	def __init__(self, section, question, parent=None):
6
+		super(QuestionWindow, self).__init__(parent)
7
+
8
+		self.section = section
9
+		self.question = question
10
+		self.results = []
11
+
12
+		self._setupGui()
13
+		self.setWindowTitle("Seopardy")
14
+
15
+	def get_results(self):
16
+		return self.results
17
+
18
+	def _mkQuestionLabel(self, text):
19
+		question = QtGui.QLabel(text, alignment=QtCore.Qt.AlignCenter)
20
+		question.setWordWrap(True)
21
+		question.setStyleSheet("QLabel { font-size: 40px; }")
22
+
23
+		return question
24
+
25
+	def _setupGui(self):
26
+		self.layout = QtGui.QVBoxLayout()
27
+
28
+		seclabel = QtGui.QLabel(self.section)
29
+		seclabel.setStyleSheet("QLabel { font-size: 30px; }")
30
+		self.layout.addWidget(seclabel, alignment=QtCore.Qt.AlignCenter)
31
+		self.layout.addStretch()
32
+
33
+		qlabel = None
34
+		if self.question["Type"] == "Text":
35
+			qlabel = self.mkQuestionLabel(self.question["Question"])
36
+		elif self.question["Type"] == "Music":
37
+			qlabel = self.mkQuestionLabel("Listen...")
38
+		elif self.question["Type"] == "Image":
39
+			qlabel = QtGui.QLabel()
40
+			pixmap = QtGui.QPixmap()
41
+			pixmap.loadFromData(open(self.question["Question"]).read())
42
+			qlabel.setPixmap(pixmap)
43
+		else:
44
+			raise ValueError("%s is an unknown type for section %s question name %s" % (self.question["Type"], self.section, self.question["Name"]))
45
+
46
+		self.layout.addWidget(qlabel, alignment=QtCore.Qt.AlignCenter)
47
+		self.layout.addStretch()
48
+
49
+		self.setLayout(self.layout)
50
+

Loading…
Cancel
Save