WordMatch Game in Python with PySimpleGUI

Introduction to WordMatch

WordMatch is a classic word game where one player thinks of a word and the other tries to guess it by suggesting letters within a certain number of guesses.

We have defined the WordMatch Class with several methods. Please read through the code in wordmatch.py. The random library is also used in this file to randomly choose a word from the list of possible words, which you are welcome to change.

WordMatch

Creating the Game Window

The create_window function is responsible for setting up the graphical interface of the game. Using PySimpleGUI, we create a window layout that includes text elements for the game title, the word to guess, and the number of attempts left. There are also buttons for each letter of the alphabet to allow the player to choose letters, and additional buttons to start a new game or exit.


def create_window(game):
    layout = [
        [sg.Text('WordMatch Game', font=('Helvetica', 16))],
        [sg.Text('Word:'), sg.Text(' '.join(game.get_display_word()), key='-WORD-')],
        [sg.Text('Attempts left:'), sg.Text(game.get_attempts_left(), key='-ATTEMPTS-')],
        [sg.Button(c, key=c, button_color=('white', 'blue')) for c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'],
        [sg.Button('New Game', key='-NEW-'), sg.Button('Exit', key='-EXIT-')]
    ]
    return sg.Window('WordMatch', layout)
        

The Game Loop

The while True loop in the play_game function is the main loop of the game, which continues to run until the game is over, either because the player has guessed the word or has run out of attempts. The loop checks for events, such as button clicks, and updates the game state accordingly.

Exiting the Game

The window.close() method is called when the game loop ends, which closes the game window and ends the PySimpleGUI program cleanly.

You can learn how to use GUI elements to interact with Python code, manage application state, and handle events in a loop. This knowledge can be applied to many other types of Python projects that require a graphical user interface.

Window Keys and Element Updating in PySimpleGUI

Understanding Window['-ATTEMPTS-'].update()

In PySimpleGUI, each element in a window can be accessed via a unique identifier known as a "key". This allows for dynamic interaction with the GUI elements. The line of code in question demonstrates how to update an element's content:

window['-ATTEMPTS-'].update(game.get_attempts_left())

This code performs two key actions:

  1. Element Selection: window['-ATTEMPTS-'] selects the GUI element with the key '-ATTEMPTS-'. This key is a unique string that identifies a specific element within the window, in this case, a text element displaying the number of attempts left in a game of WordMatch.
  2. Content Update: The .update() method changes the content of the selected element. game.get_attempts_left() calls a method from the WordMatch class instance to retrieve the current number of attempts left for the player. This value is then used to update the text displayed on the window.

Role of Window Keys in PySimpleGUI

A window key in PySimpleGUI is a powerful feature that allows developers to interact with the GUI elements after the window has been created. By assigning a key to an element, developers can:

Keys enable the creation of dynamic and responsive GUI applications, making PySimpleGUI an accessible library for both beginners and experienced developers looking to build interactive Python programs.

Keys in PySimpleGUI vs. Dictionary Keys

Similarities

Differences

Aspect PySimpleGUI Keys Dictionary Keys
Purpose Interact with GUI elements. Map to values in a data structure.
Data Association Associated with GUI objects. Associated with any data type.
Complexity Part of UI event management. Used for data storage and manipulation.
Scope Specific to PySimpleGUI library. Universal in Python, not limited to a specific library.

Read more about PySimpleGUI keys here

Explaining the GUI Text Element

In PySimpleGUI, the GUI layout is defined using lists of elements. Each list represents a row in the window, and each element within the list represents a component in that row. Let's break down the following line of code:

[sg.Text('Word:'), sg.Text(' '.join(game.get_display_word()), key='-WORD-')],

This line of code is constructing a row with two text elements for our GUI:

This setup allows the WordMatch game's GUI to display the word to the user with guessed letters revealed and unguessed letters hidden. The unique key enables the program to find and update this specific text element throughout the game.

Event Loop Explained

An event loop in PySimpleGUI is a control structure that listens for events such as button clicks or window close actions and responds accordingly. Here's an explanation of a typical event loop code snippet:

event, values = window.read()

if event == sg.WIN_CLOSED or event == '-EXIT-':
    break
  1. Reading Events: event, values = window.read() waits for the user to perform an action.
  2. Checking the Event: The line if event == sg.WIN_CLOSED or event == '-EXIT-': checks if the user has either closed the window or clicked an 'Exit' button.
  3. Exiting the Loop: If either condition is met, the break statement is executed, which terminates the nearest enclosing loop — in this case, the main event loop of the GUI.

This control flow allows the application to close gracefully when the user decides to exit, either by closing the window or clicking an 'Exit' button.

Understanding Event Handlers

In PySimpleGUI, the event loop listens for events and executes code in response. Let's examine how the game handles two specific events:


if event == '-NEW-':
    game.reset_game()
    window['-WORD-'].update(game.get_display_word())
    window['-ATTEMPTS-'].update(game.get_attempts_left())
    for c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
        window[c].update(button_color=('white', 'blue'), disabled=False)
elif event in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' and not game.has_lost():
    game.guess_letter(event)
    window['-WORD-'].update(game.get_display_word())
    window['-ATTEMPTS-'].update(game.get_attempts_left())
    window[event].update(button_color=('white', 'red'), disabled=True)
    

New Game Event

When the '-NEW-' event is triggered (typically by a button click), the following actions are taken:

  1. The game is reset using game.reset_game(), which initializes a new game state.
  2. The display word on the GUI is updated to reflect the new hidden word using window['-WORD-'].update().
  3. The attempts counter is reset, and its display is updated with window['-ATTEMPTS-'].update().
  4. All alphabet buttons are re-enabled, allowing the player to guess letters again.

Letter Guess Event

When the player clicks a letter button (an event for any letter 'A' to 'Z'), and the player has not yet lost the game:

  1. The game processes the guessed letter with game.guess_letter(event).
  2. The displayed word is updated, revealing any correct guesses or leaving it unchanged if the guess is incorrect.
  3. The number of attempts left is updated, which decreases if the guess was incorrect.
  4. The guessed letter's button is disabled and turned red to indicate that it has been used.

These event handlers are crucial for the interactivity of the game, responding to user inputs and updating the GUI accordingly.

Example of a popup when the game is won: Computer Vision Relevant code snippet: sg.popup('Congratulations, you won!', title='Game Over')