167 lines
5.7 KiB
Markdown
167 lines
5.7 KiB
Markdown
Seopardy
|
|
========
|
|
What this is
|
|
------------
|
|
Seopardy is an implementation of the game "Jeopardy" and a
|
|
reimplementation/clone of the software "beopardy", mostly known for being
|
|
used in the Chaos Communication Congress Hacker-Jeopardy.
|
|
|
|
|
|
Installation & Requirements
|
|
---------------------------
|
|
To run this software you need:
|
|
|
|
* python (python2)
|
|
* python-pyside
|
|
* python-pyside.phonon (for music)
|
|
* python-yaml / PyYAML
|
|
* python-serial / pyserial
|
|
|
|
To play a game I recommend:
|
|
|
|
* a question file
|
|
* music!
|
|
* start song (played while naming players)
|
|
* question song (played while question is displayed)
|
|
* end song (played while victory window is shown)
|
|
* a configuration file - just copy seopardy.conf.dist to seopardy.conf
|
|
* buttons for player input
|
|
|
|
|
|
The Question File
|
|
-----------------
|
|
The game needs questions to run the game. A question file is a yaml-file
|
|
containing either all questions or a link to the respective files containing
|
|
said questions.
|
|
|
|
The top-level question file contains two keys:
|
|
|
|
- Name (name of the round, displayed on top of the board)
|
|
- Sections (a list of question files with sections to include)
|
|
|
|
Example:
|
|
|
|
Name: Round 2
|
|
Sections:
|
|
- test.q
|
|
- cpu.q
|
|
- extra/foo.q
|
|
- xkcd.q
|
|
|
|
A question file containing sections can contain an arbitrary number of sections.
|
|
Each section needs to have exactly five questions. A question can have the
|
|
following keys:
|
|
|
|
- Name (to remind you of the question number)
|
|
- Question (text/image/... displayed on screen)
|
|
- Answer (to remind you of the answer, not used in the program)
|
|
- Type (type of question)
|
|
- Double-Jeopardy (if the question is a Double-Jeopardy, default false)
|
|
- Audio (for videos, if the video should have audio or not, default false)
|
|
|
|
Five *Types* of question are supported:
|
|
|
|
- Text: The text is normally displayed on screen
|
|
- Code: The code is displayed with a monospace font, tabs are replaced with
|
|
four spaces
|
|
- Image: The Question key is a path to an image, which is displayed on screen
|
|
- Music: The Question key is a path to a music file, which is played
|
|
- Video: The Question key is a path to a video file, which is played
|
|
|
|
Example:
|
|
|
|
- Section: Test
|
|
Questions:
|
|
- Name: Question 1
|
|
Question: This text is displayed
|
|
Answer: This is never displayed, only for you to remember the answer
|
|
Type: Text
|
|
|
|
- Name: Question 2
|
|
Question: path/to/test.png
|
|
Answer: Bar
|
|
Type: Image
|
|
...
|
|
|
|
Gamestate
|
|
---------
|
|
To prevent you from losing the current gamestate in case of a crash,
|
|
seopardy saves its interal state as a yaml file after each question.
|
|
You can specify a directory where the gamestates are stored in the config
|
|
file and load a state with the --gamestate parameter.
|
|
|
|
|
|
Player Input
|
|
------------
|
|
To get the input from a button (aka "the outside world") into the game,
|
|
two classes are available:
|
|
|
|
*Fifo* creates a fifo in your local filesystem, first argument being the
|
|
path to where the fifo should be created. To emit a button press you can
|
|
simply write an ASCII-number into the fifo, corresponding to the player
|
|
which pressed a button. All other characters are ignored.
|
|
|
|
*Serial* reads from a serial device using pyserial. Parameters are path to the
|
|
device, baudrate (default 9600), parity (default N) and stop-bits (default 1).
|
|
As with the fifo, an ASCII-number for the player which pressed a button is
|
|
expected. All other characters are ignored.
|
|
|
|
*BeopardySerial* mimics the protocol used by the Beopary software. It reads
|
|
from a serial device and takes the same arguments as *Serial*, but in addition
|
|
to taking button presses from the serial it also gives feedback about the
|
|
current gamestate.
|
|
|
|
*Unix* opens up a unix domain socket on your local filesystem, first argument
|
|
being the path to where it should be created. To send a player button press,
|
|
send its ASCII number ('1'-'9' is supported). The board will send a 'O' if
|
|
the buzzers (buttons) are open and a 'C' when they are closed. To indicate
|
|
that it is a player's turn the board will send a "TX", where X is the current
|
|
player's number (e.g. "T3" for player 3).
|
|
|
|
Examples:
|
|
|
|
# use BeopardySerial
|
|
playerInput:
|
|
- Type: BeopardySerial
|
|
Args:
|
|
- /dev/ttyUSB0
|
|
- 19200
|
|
|
|
# use a unix domain socket
|
|
playerInput:
|
|
- Type: Unix
|
|
Args:
|
|
- /tmp/seopardy.sock
|
|
|
|
Writing an own class for player input should be fairly easy. Within its own
|
|
thread the class can do whatever it wants (including blocking I/O). When it
|
|
wants to signal a button was pressed it just needs to emit a ButtonEvent.
|
|
An input class has two functions which are called while a question is on
|
|
display:
|
|
|
|
- `buzzersOpen(isOpen)` is called, when the question is first displayed,
|
|
when the question is reopened after a false answer, when the question is
|
|
closed after either a correct answer or no answer at all or when a
|
|
button for an unknown player was submitted.
|
|
|
|
- `playerGotQuestion(playerNo)` is called, whenever a player pressed
|
|
their button *and* got the turn to answer. Note that no extra
|
|
buzzers-are-closed (`buzzersOpen(False)`) event is sent, when a button
|
|
is pressed.
|
|
|
|
|
|
Known Bugs
|
|
----------
|
|
|
|
* The focus order and focus setting for the question-answer-editing and the
|
|
double-jeopardy window is somewhat broken.
|
|
* The input threads are currently not shut down correctly, leaving some ugly
|
|
output on the console when exiting the game.
|
|
* Stylesheets for buttons/labels could be more centrally managed and more
|
|
consistent.
|
|
* The audio sounds a bit glitchy on some pulseaudio systems. Setting
|
|
`flat-volume = no` in `/etc/pulse/daemon.conf` fixes this for some users.
|
|
* The volume for the first played song is at 100%, no matter what. This is
|
|
currently circumvented by playing a media song and immediately stopping it
|
|
at the beginning of the game.
|