Use Python and Qt for a Skat game helper
Jan Walter September 20, 2023 [LANG] #python #qt #skatThis blog starts a series about using Python to implement some helper programs to learn the German Skat game (and keep track of things). Reading the rules on Wikipedia is a good introduction and gives you an overview, but to learn how to play the game I can recommend the Skat Island. So here is how a simple helper app might look like to keep track of which cards where played:
I have written such an app in Python using the Qt library for the graphical user interface (GUI). To get started with Qt for Python read the official documentation.
But back to the screenshot above. The idea is to keep track of the
cards which were played already, while playing a game (online or for
real) with two other players. The variant above was written to first
choose one of the supported varieties (see
Wikipedia article),
suit
, grand
, or null
, of the game. In addition to those
there is an unofficial variety, called Sächsische
Spitze, which is similar
to grand
, just with reversed order. So on the left you see the
jacks
. If you click on one of the top two jacks you will select the
grand
variant, the other two (lower) jacks select the Sächsische Spitze
. For a suit
game select one of the aces
(to the right of
the jacks
). Because there are four suits, Clubs
(♣), Spades
(♠), Hearts
(♥), and Diamonds
(♦), it matters which of the aces
you clicked. For the last variant, null
, just click one of the
sevens (7
), which one doesn't matter.
After selecting the variant of the Skat game, all cards get visible
(ordered for a suit
game), and you can click individual cards to
flip them:
In the screenshot above I clicked the Queen
of Hearts
(♥), so it
becomes invisible again. After having clicked all cards (and made them
invisible), the situation is pretty much the same as when you started
the helper program.
The first version of my Python program had a slightly different
purpose, which I will explain later, but I'm working on a new version,
which introduces counters to keep track of how many points each
individual player has collected while playing out tricks
. The
screenshot above shows the situation after the first trick
was
played (for a Clubs
suit game) and the full print out (to the shell
or console where you started the Python script) looks like this:
So, while clicking away cards, which were played out, the program
knows a little bit about the rules, knows which variant (in
this case Clubs
for the suit
game), was chosen, and adds the
values of each trick to the winner's counter, so it also knows how
to detect, who won the trick. Because the source code is still under
development, I'm not showing the entire Python code (or making it
public yet), but here is how the current class
structure and the
methods involved are structured:
Qt
Here some of the Qt classes used:
- QtWidgets
- QApplication (application’s control flow)
- QLCDNumber (for the counters)
- QSizePolicy
- QtGui (basic imaging)
- QtCore
Writing to a File
You might have noticed that the first screenshot (without the
counters) showed an option at the lower left, called Select two Skat cards first
. The reason for that was that this version was writing a
simple file to disk, which looks like this:
The c
stands for the Clubs
variant, the sl
for Skat last
,
whereas there is a sf
for Skat first
as well. The other numbers
simply encode the played cards without any knowledge of the Skat
rules. Where are those numbers coming from? In the past I started
writing some Rust code to play Skat on
the console (or in the shell). It had some options to record a game,
like this:
If you are the declarer you need to specify first which two cards to
drop for the Skat
, then you play the cards for all tricks. At the
end of the match you got a card distribution printed out as well as
the tricks being played:
All the details are not really relevant. The point is: Instead of tediously feeding the Rust program with numbers (which represent the Skat cards) you clicked all cards in an order, specifying if the first two cards (or the last ones) are representing the Skat, recorded the card order in a file (written by the Python code), and later used this option to display the card distribution and the tricks being played:
This time you get the two extra cards for the Skat
printed as
well. So, let's use Python again to show the card distribution
(without the two Skat cards) and make it playable:
This time the counter makes more sense, because you see one row per player:
The goal for the next version of the Python code is to combine both methods (recording, and re-playing) in a single application.