Video Poker with tkinter
This program demonstrates a video poker game with the tkinter library.
Programming Issues
This program uses my pcards library to provide the functionality for the cards, card deck, poker hand, and poker hand evaluation.
The tkinter
GUI
is relatively simple. We set up Label
widgets to hold the five
cards and other fields. An Entry
widget is used to accept and
display the player's bet. Finally, a Button
widget is used for
the push button. A menubar
widget is provided to enable the
user to quit the game (which can obviously also be done just by closing the
main window) and to show an “About” dialog box.
The behaviour of the pushbutton changes depending on context. For example, at the start of the game, the button label reads “Deal” and deals the first hand, whereas after that, it reads “Exchange / Skip” to optionally exchange some of the cards. Labels for the amount of money in the pot, and for status messages, are updated as appropriate during the game.
We record the game state to adjust the behaviour, e.g. the player should
only be able to flip the cards when self.game_postdeal
is
True
, and the functionality is disabled when it is not.
We add certain attributes to the Label
widgets containing
the card images:
- A
src
attribute is added to avoid Python's garbage collection routines losing the references to the images; - A
flipped
attribute is added to store whether or not the player has flipped that card; and - A
pos
attribute is added for convenience in calculating the filename of the appropriate card image to use.
We bind
the <Button-1>
event of each
card to the flip()
method, to flip the cards when the player
clicks on them. The command
of the push button is linked to
the button_clicked()
method to provide game functionality.
For those unfamiliar with GUI programming, the programming paradigm is
slightly different — with traditional programs we call all our own
functions to get input, but with a GUI the user's interactions are captured
by the underlying GUI functionality, so to get the user's input to our program
the library has to call our functions. User events can be passed to
a function of our choice using the bind()
function, and the
command
attribute fulfils the same purpose for actions
generated by widgets. (Note: the same paradigm is used
for native win32 programs where the
WndProc()
callback function is provided to Microsoft Windows,
to be called when our program should respond to a user (or other) event.)
We try
to catch a ValueError
exception to validate
the user's bet. If it is not an integer — i.e. if int(b_str)
throws a ValueError
exception — then we show a
messagebox
and reject the input, returning to the program until
the user enter's a valid bet. We also use a messagebox
if the
user does enter an integer, but it is either less than one or greater
than the amount of money in the pot. Since — to save typing — we
update the default bet amount each time the user enters in a new bet, we also
have to check (technically only after a lost hand) whether the default bet
now exceeds the amount of money in the pot, and if it does, to reduce the
default bet to that amount, otherwise the player could try to bet more than
he has.
The program — implemented as a Python class
—
interfaces with the cards.py
module in an appropriate way to
create a deck, exchange the cards, evaluate the hand, and calculate any
winnings. The functionality in that module is entirely separated from the
tkinter
interface. Refer to that module for more details.
Usage
Note: You will need Python 2.6 or later, and a compatible
Tkinter
library, installed on your machine before running
this program.
Refer to your system documentation for instructions on how to run
Python programs. Typically, you can run the program through the
command-line interface (e.g. python videopoker.py
) (you
will need to have an X server available to do this on a Unix system)
or from an integrated development environment such as Idle.
Screenshot
