The code for the Match3 game is thoroughly commented with explanations of what each line or section are for. This page will provide a higher level summary of the major components.
Hardware Principals
This game is designed around a few primary hardware peripherals: the HSTX connector with a DVI breakout for the display, a CH334F USB Hub and two USB Mice connected for player input.
HSTX Display
The code will use the built-in display from supervisor.runtime.display
. Depending on what version of CircuitPython you have, the default size that the display is configured for can be different. The code for this game checks the size of the display and automatically scales up the main_group
by 2
if it finds that it is running on the larger display resolution. That allows the game to look visually the same on the screen no matter which size it is configured for.
scale_factor = 1 if display.width > 360: scale_factor = 2 main_group.scale = scale_factor
The scale_factor
variable is also used in various other calculations within the code to account for the differences in resolution.
USB Mice
The USB mouse setup, data reading, and cursor movement are all documented on the Wrangling Two Mice guide page. See that page for more details.
Helper Classes
Inside of match3_game_helpers.py there are 4 class definitions and 2 functions which help with various parts of the game. A brief description of each can be found below. The code for each contains comments explaining them in more depth.
-
Match3Card
- This class encapsulates the graphics and functionality for a single Match3 card. It holds theTileGrid
andTilePaletteMapper
that work together to draw the card visually. See the Sprites & Colors guide page for more details on how they are used. When initialized,Match3Card
is passedcard_tuple
as an argument.card_tuple
contains four numbers that each range from0
to2
, this is a numerical representation of the unique card within the deck. The four numbers represent: color, shapes, fill, and count respectively. There is a commented block in the code which contains a table showing what all the possible values mean.Match3Card
also has acontains()
function which accepts x,y coordinates and returnsTrue
if the coordinate point is within the bounding box of the card. -
Match3Game
- TheMatch3Game
class manages most of the functionality of the game. It extendsGroup
and holds all of the other primary visual elements of the game. It uses a state machine with four possible states.- Title State - Showing the title screen, waiting for the user to click either the resume or new game buttons.
- Open Playing State - One of two game play states. This one is when the play is open meaning any player may call set by right clicking their mouse. During this state players may also click the "no set" button to indicate they can't find a set and would like more cards dealt. Both players must click before the cards are actually dealt.
- Playing Set Called State - Once set is called a countdown with a visible progress bar begins and the player who called must click three cards that they believe makes a set before it runs out.
- Game Over State - This state is used at the end of the game once there are no more cards in the deck and both players have declared they can find no more sets.
Match3Game
uses a GridLayout
to arrange the cards on the display. Mouse click events are sent in to the Game object with the functions handle_right_click()
and handle_left_click()
which carry out the appropriate action based on the current state. There are functions for saving and loading the game state which use the same technique shown on the Game Mechanics: Autosave & Resume guide page.
-
GameOverException
- A simpleException
wrapper class that gets raised when the game has ended. -
Match3TitleScreen
- A class that extendsGroup
and contains all of the visual elements used for the title screen. The class holds visual elements only, it does not handle functionality of the title screen.
Helper Functions
The two helper functions inside of match3_game_helpers.py are used by Match3Game
. They are:
-
random_selection()
- A function that accepts alist
and an intcount
as arguments. It selectscount
items fromlist
and removes them from thelist
then returns them. It gets used when the game needs to deal cards from the deck. -
validate_set()
- This function accepts threeMatch3Card
instances and returns True if they make up a valid set. It uses matrix addition and modulus on thecard_tuple
attribute values to determine whether the cards are a valid set. This technique is detailed in an excellent episode of Numberphile on Youtube. The video was instrumental in the making of this implementation of the game. Specifically the details of the numerical representation, and mathematical way to check for sets start around 5:40 into the video, but the whole thing is well worth a watch.
Page last edited April 14, 2025
Text editor powered by tinymce.