# Tile-Matching Game on the Fruit Jam and Metro RP2350

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/137/346/medium800/gaming_main.jpg?1749079139)

This project demonstrates how to run a [tile-matching game](https://en.wikipedia.org/wiki/Tile-matching_video_game) on the Metro RP2350 using the mouse attached through its USB host pins. It includes controls such as an event button to perform a reset. This is a take on tile-matching games such as [Candy Crush Saga](https://en.wikipedia.org/wiki/Candy_Crush_Saga) and [Bejeweled](https://en.wikipedia.org/wiki/Bejeweled_(video_game)) using some of your favorite Adafruit characters such as Blinka, Hans, and Cappy. It demonstrates some animation techniques that take advantage of CircuitPython's displayio graphics system.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/347/medium800thumb/gaming_ExamplePlaying-ezgif.com-optimize.jpg?1749079416)

The game is displayed on any HDMI compatible display using the HSTX ribbon connector on the Metro RP2350 and a DVI breakout.

## Parts

This project can be done with either the Fruit Jam or the Metro RP2350.

If using the Fruit Jam, you will need:

### Adafruit Fruit Jam - Mini RP2350 Computer

[Adafruit Fruit Jam - Mini RP2350 Computer](https://www.adafruit.com/product/6200)
We were catching up on a recent [hackaday hackchat with eben upton](https://hackaday.io/event/202122-raspberry-pi-hack-chat-with-eben-upton)&nbsp;and learned some fun facts: such as the DVI hack for the RP2040 was inspired by <a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/6200)
[Related Guides to the Product](https://learn.adafruit.com/products/6200/guides)
![Angled shot of assembled mini computer PCB with plate.](https://cdn-shop.adafruit.com/640x480/6200-10.jpg)

or if using the Metro RP2350:

### Adafruit Metro RP2350 with PSRAM

[Adafruit Metro RP2350 with PSRAM](https://www.adafruit.com/product/6267)
Choo! Choo! This is the RP2350 Metro Line, making all station stops at "Dual Cortex M33 mountain", "528K RAM round-about" and "16 Megabytes of Flash town" and a bonus stop at "8 Megabytes of PSRAM village". This train is piled high with hardware that...

In Stock
[Buy Now](https://www.adafruit.com/product/6267)
[Related Guides to the Product](https://learn.adafruit.com/products/6267/guides)
![Angled shot of black, credit card-sized microcontroller.](https://cdn-shop.adafruit.com/640x480/6267-00.jpg)

### Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays

[Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays](https://www.adafruit.com/product/6055)
You may have noticed that our [RP2350 Feather](https://www.adafruit.com/product/6000) has an FPC output connector on the end&nbsp;for accessing the HSTX (High Speed Transmission)&nbsp;peripheral. This new capability, not available on the RP2040, is specifically designed to allow the...

In Stock
[Buy Now](https://www.adafruit.com/product/6055)
[Related Guides to the Product](https://learn.adafruit.com/products/6055/guides)
![black, square-shaped breakout board with DVI and 22-pin FPC connectors connected to a black, rectangular microcontroller.](https://cdn-shop.adafruit.com/640x480/6055-01.jpg)

### 22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX - 20cm

[22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX - 20cm](https://www.adafruit.com/product/6036)
Connect this to that when a 22-pin FPC connector is needed. This 20 cm long cable is made of a flexible PCB. It's A-B style, meaning that pin one on one side will match with pin one on the other. How handy!

[We're stocking this to...](https://www.adafruit.com/category/360)

In Stock
[Buy Now](https://www.adafruit.com/product/6036)
[Related Guides to the Product](https://learn.adafruit.com/products/6036/guides)
![Angled shot of 20cm long, 22-pin FPC cable.](https://cdn-shop.adafruit.com/640x480/6036-00.jpg)

### USB Type A Jack Breakout Cable with Premium Female Jumpers

[USB Type A Jack Breakout Cable with Premium Female Jumpers](https://www.adafruit.com/product/4449)
If you'd like to connect a USB-host-capable chip to your USB peripheral, this cable will make the task very simple.&nbsp; **There is no converter chip in this cable!** &nbsp;It's basically a plain USB cable that's cut in half and with jumper sockets on the power and data...

In Stock
[Buy Now](https://www.adafruit.com/product/4449)
[Related Guides to the Product](https://learn.adafruit.com/products/4449/guides)
![USB Type A Socket Breakout Cable with Premium Female Jumpers](https://cdn-shop.adafruit.com/640x480/4449-02.jpg)

### Break-away 0.1" 36-pin strip male header - Black - 10 pack

[Break-away 0.1" 36-pin strip male header - Black - 10 pack](https://www.adafruit.com/product/392)
Breakaway header is like the duct tape of electronics. It's great for connecting things together, soldering to perf-boards, fits into any breakout or breadboard, etc. We go through these guys real fast, and thought that given how handy they are, we'd offer them in a pack of ten!<br...></br...>

In Stock
[Buy Now](https://www.adafruit.com/product/392)
[Related Guides to the Product](https://learn.adafruit.com/products/392/guides)
![10 pieces of Break-away 0.1 inch 36-pin strip male header](https://cdn-shop.adafruit.com/640x480/392-01.jpg)

For either:

### USB Wired Mouse - Two Buttons plus Wheel

[USB Wired Mouse - Two Buttons plus Wheel](https://www.adafruit.com/product/2025)
This is a mouse. &nbsp;A nice, simple mouse. &nbsp;No bells or whistles. &nbsp;Just a mouse.  
  
But that doesn't mean it's not the best simple mouse!&nbsp; We compared a few and liked this one quite a bit. &nbsp;It's optical for good resolution and precision, has two...

In Stock
[Buy Now](https://www.adafruit.com/product/2025)
[Related Guides to the Product](https://learn.adafruit.com/products/2025/guides)
![Angled Shot of the USB Wired Mouse - Two Buttons plus Wheel](https://cdn-shop.adafruit.com/640x480/2025-05.jpg)

### USB Type A to Type C Cable - approx 1 meter / 3 ft long

[USB Type A to Type C Cable - approx 1 meter / 3 ft long](https://www.adafruit.com/product/4474)
As technology changes and adapts, so does Adafruit. This&nbsp;&nbsp; **USB Type A to Type C** cable will help you with the transition to USB C, even if you're still totin' around a USB Type A hub, computer or laptop.

USB C is the latest industry-standard connector for...

In Stock
[Buy Now](https://www.adafruit.com/product/4474)
[Related Guides to the Product](https://learn.adafruit.com/products/4474/guides)
![Angled shot of a coiled black, USB-C to USB-A cable.](https://cdn-shop.adafruit.com/640x480/4474-02.jpg)

### HDMI Cable - 1 meter

[HDMI Cable - 1 meter](https://www.adafruit.com/product/608)
Connect two HDMI devices together with this basic HDMI cable. It has nice molded grips for easy installation, and is 1 meter long (about 3 feet). This is a HDMI 1.3 cable.

We're now stocking a very fancy Official Raspberry Pi cable with overmolding and a Pi logo. Please note...

In Stock
[Buy Now](https://www.adafruit.com/product/608)
[Related Guides to the Product](https://learn.adafruit.com/products/608/guides)
![Official Raspberry Pi HDMI Cable - 1 meter](https://cdn-shop.adafruit.com/640x480/608-03.jpg)

# Tile-Matching Game on the Fruit Jam and Metro RP2350

## Preparing the Metro RP2350

Primary: If you have a Fruit Jam instead of a Metro RP2350, you can go to the next page.

The USB Host port is the only part of this project that required soldering and only if you use standard header pins.&nbsp;

The USB Host pin connections are highlighted on the Metro image to the left. You will need a small piece of 0.1 inch male header, with 4 pins, to fit the holes.

You can cut header with diagonal cutters or break them with pliers or even your fingers. Just be sure to wear eye protection as they can fly when cut.&nbsp;

![The Metro RP2350 board with the USB Host connection highlighted](https://cdn-learn.adafruit.com/assets/assets/000/135/532/medium640/raspberry_pi_adafruit_products_pinouts_usbhost_highlight.png?1740704493)

![Male header strip, full, "hammer" in](https://cdn-learn.adafruit.com/assets/assets/000/136/240/medium640/gaming_four.png?1744210071)

Put the short end of the header into the holes in the Metro marked USB Host.&nbsp;

If you are using solderless header then they are press fit into the holes. You will need some pressure to get them in if they are the Press-Fit version, pliers will be required. While they are designed to make electrical contact, you might want to solder them to be sure.

If using standard header, secure them with putty, blutack, tape, etc.

Turn the Metro over and you should see the header barely poking out of the bottom of the board. If the pins stick through a great deal you may have the header pins upside down, double check the short end is sticking into the board.

Solder the 4 pin "nubbins" to the board.

![A Hakko soldering iron, a roll of solder and a Metro RP2350 board](https://cdn-learn.adafruit.com/assets/assets/000/135/534/medium640/raspberry_pi_20250226_110701.jpg?1740705385)

![The back of the Metro RP2350 board showing the short end of the header pins sticking through the board](https://cdn-learn.adafruit.com/assets/assets/000/135/535/medium640/raspberry_pi_20250226_110712.jpg?1740705653)

![The Metro back off the PC board with the pins soldered](https://cdn-learn.adafruit.com/assets/assets/000/135/536/medium640/gaming_raspberry_pi_20250226_110952.jpg?1754938894)

Turn the board over and remove the material securing the pins. Now there is a new 4-pin header.&nbsp;

Get the USB Host cable and wire as follows:

**GRD** to **Black**

**D+** to **Green**

**D-** to **White**

**5V** to **Red**

![The Metro, right side up, with the USB Host pins installed](https://cdn-learn.adafruit.com/assets/assets/000/135/537/medium640/raspberry_pi_20250226_111019.jpg?1740705869)

![An Adafruit Metro RP2350 board with a USB Host port cable assembly attached in the middle and an HSTX cable on the left extending to an HSTX to HDMI breakout board](https://cdn-learn.adafruit.com/assets/assets/000/135/538/medium800/raspberry_pi_20250227_192553.jpg?1754939038 )

## HSTX Connection to DVI
![An Adafruit Metro RP2350 board with an HSTX cable on the left extending to an HSTX to HDMI breakout board](https://cdn-learn.adafruit.com/assets/assets/000/135/597/medium800/gaming_hstx.png?1754939026 )

Get the HSTX cable. Any length Adafruit sells is fine. CAREFULLY lift the dark grey bar up on the Metro, insert the cable silver side down, blue side up, then put the bar CAREFULLY down, ensuring it locks. If it feels like it doesn't want to go, do not force it.

Do the same with the other end and the DVI breakout. Note that the DVI breakout will be inverted/upside down when compared to the Metro - this is normal for these boards and the Adafruit cables.

# Tile-Matching Game on the Fruit Jam and Metro RP2350

## CircuitPython for the Metro RP2350

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_metro_rp2350/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![](https://cdn-learn.adafruit.com/assets/assets/000/135/292/medium800/adafruit_products_boot_reset_btn_highlights.png?1739467365)

To enter the bootloader, hold down the **BOOT/**** BOOTSEL button**(highlighted in red above), and while continuing to hold it (don't let go!), press and release the**reset button**(highlighted in red or blue above).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RP2350 drive appears!**

If the drive does not appear, release all the buttons, and then repeat the process above.

You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **RP2350**.

&nbsp;

Drag the **adafruit-circuitpython-_boardname_-_language_-_version_.uf2** file to **RP2350.**

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111518.png](https://cdn-learn.adafruit.com/assets/assets/000/132/253/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111518.png?1726067809)

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111742.png](https://cdn-learn.adafruit.com/assets/assets/000/132/254/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111742.png?1726067866)

The **RP2350** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111843.png](https://cdn-learn.adafruit.com/assets/assets/000/132/255/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111843.png?1726067932)

## Safe Mode

You want to edit your **code.py** or modify the files on your **CIRCUITPY** drive, but find that you can't. Perhaps your board has gotten into a state where **CIRCUITPY** is read-only. You may have turned off the **CIRCUITPY** drive altogether. Whatever the reason, safe mode can help.

Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode _bypasses any code in_ **boot.py** (where you can set **CIRCUITPY** read-only or turn it off completely). Second, _it does not run the code in_ **code.py**. And finally, _it does not automatically soft-reload when data is written to the_ **CIRCUITPY** _drive_.

Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the **CIRCUITPY** drive.

### Entering Safe Mode
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)

### In Safe Mode

If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.

If you connect to the serial console, you'll find the following message.

```terminal
Auto-reload is off.
Running in safe mode! Not running saved code.

CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
```

You can now edit the contents of the **CIRCUITPY** drive. Remember, _your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode._

## Flash Resetting UF2

If your board ever gets into a really _weird_ state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RP2350. which will do a 'deep clean' on your Flash Memory. **You will lose all the files on the board** , but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.

[Download flash erasing "nuke" UF2 for RP2350](https://cdn-learn.adafruit.com/assets/assets/000/132/526/original/rp2350_flash_nuke.uf2)
# Tile-Matching Game on the Fruit Jam and Metro RP2350

## CircuitPython for the Fruit Jam

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

Warning: Please use the latest release of 10.x or higher for the Fruit Jam. Also use the latest libraries for the best functionality.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_fruit_jam/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![reset and boot highlighted](https://cdn-learn.adafruit.com/assets/assets/000/138/708/medium800/adafruit_products_Resetboot.jpg?1754331128 )

To enter the bootloader, hold down the **BOOT/**** BOOTSEL button**(highlighted in red above), and while continuing to hold it (don't let go!), press and release the**reset button**(highlighted in red or blue above).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RP2350 drive appears!**

If the drive does not appear, release all the buttons, and then repeat the process above.

You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **RP2350**.

&nbsp;

Drag the **adafruit-circuitpython-_boardname_-_language_-_version_.uf2** file to **RP2350.**

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111518.png](https://cdn-learn.adafruit.com/assets/assets/000/132/253/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111518.png?1726067809)

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111742.png](https://cdn-learn.adafruit.com/assets/assets/000/132/254/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111742.png?1726067866)

The **RP2350** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111843.png](https://cdn-learn.adafruit.com/assets/assets/000/132/255/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111843.png?1726067932)

## Safe Mode

You want to edit your **code.py** or modify the files on your **CIRCUITPY** drive, but find that you can't. Perhaps your board has gotten into a state where **CIRCUITPY** is read-only. You may have turned off the **CIRCUITPY** drive altogether. Whatever the reason, safe mode can help.

Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode _bypasses any code in_ **boot.py** (where you can set **CIRCUITPY** read-only or turn it off completely). Second, _it does not run the code in_ **code.py**. And finally, _it does not automatically soft-reload when data is written to the_ **CIRCUITPY** _drive_.

Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the **CIRCUITPY** drive.

### Entering Safe Mode
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)

### In Safe Mode

If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.

If you connect to the serial console, you'll find the following message.

```terminal
Auto-reload is off.
Running in safe mode! Not running saved code.

CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
```

You can now edit the contents of the **CIRCUITPY** drive. Remember, _your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode._

## Flash Resetting UF2

If your board ever gets into a really _weird_ state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RP2350. which will do a 'deep clean' on your Flash Memory. **You will lose all the files on the board** , but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.

[Download flash erasing "nuke" UF2 for RP2350](https://cdn-learn.adafruit.com/assets/assets/000/132/526/original/rp2350_flash_nuke.uf2)
# Tile-Matching Game on the Fruit Jam and Metro RP2350

## Software Setup

## CircuitPython Usage

To use the game, you need to add the&nbsp;game program files to the&nbsp; **CIRCUITPY** drive. The game consists of a handful of Python files and bitmaps.

Thankfully, installing everything be done in one go. In the code block below, click the **Download Project Bundle** button to download the necessary libraries and game files in a zip file.

Connect your board to your computer via a known good data+power USB cable. The board should show up in your File Explorer/Finder (depending on your operating system) as a flash drive named **CIRCUITPY**.

Extract the contents of the zip file, copy the **lib** directory files to **CIRCUITPY/lib**. Copy the entire contents of the appropriate CircuitPython folder to your **CIRCUITPY** drive. The program should self start.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Metro/Metro_RP2350_Matching_Game/code.py

## Display Size

Some versions of CircuitPython default to a higher resolution. To ensure the display gets automatically configured for the 320x240 resolution, which the Matching game is designed for, add a&nbsp;`CIRCUITPY_DISPLAY_WIDTH`&nbsp;variable with value&nbsp;`320`&nbsp;to the&nbsp; **settings.toml** &nbsp;file in the root directory of the&nbsp; **CIRCUITPY** &nbsp;drive. If you do not already have a&nbsp; **settings.toml** &nbsp;file, follow the instructions on&nbsp;[this guide page](https://learn.adafruit.com/pico-w-wifi-with-circuitpython/create-your-settings-toml-file)&nbsp;to create one.

```python
# This file is where you keep private settings, passwords, and tokens!
# If you put them in the code you risk committing that info or sharing it

CIRCUITPY_DISPLAY_WIDTH=320
```

## Drive Structure

After copying the files, your drive should look like the listing below. It can contain other files as well, but must contain these at a minimum.

![CIRCUITPY](https://raw.githubusercontent.com/adafruit/Adafruit_Learning_System_Guides/refs/heads/folder-images/Metro_Metro_RP2350_Matching_Game.png )

# Tile-Matching Game on the Fruit Jam and Metro RP2350

## Code Overview

The code for the tile-matching game is divided into 3 files: The main code (which glues everything together), the game logic, and a custom UI element that was reused from the&nbsp;[Minesweeper on Metro RP2350](https://learn.adafruit.com/minesweeper-on-metro-rp2350) guide. In many games, I try and separate the game logic from the user interface, which makes porting to other platforms much easier.

### Main Code

The main **code.py** file handles setting everything up, responding to the user inputs, and updating the User Interface. Everything within the UI is handled by CircuitPython's&nbsp;[displayio](https://docs.circuitpython.org/en/latest/shared-bindings/displayio/index.html). There are some custom controls such as dialogs made using the [TextBox](https://github.com/adafruit/Adafruit_CircuitPython_Display_Text/blob/main/adafruit_display_text/text_box.py)&nbsp;component of the [adafruit\_display\_text](https://github.com/adafruit/Adafruit_CircuitPython_Display_Text) library as well as an event button, which will be looked at in more detail below. This file is fairly self explanatory with comments throughout the file.

The setup mainly consists of setting up the game board, setting up the dialogs, and setting up the score label and reset button. It also creates some tilegrids that are used to animate the piece swaps.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Metro/Metro_RP2350_Matching_Game/code.py

### Game Logic

The game logic handles the Tile-matching game logic. I came up with the majority of the code and used [Claude](https://claude.ai/) to come up with the logic to check for remaining moves, which I then used to check if the game was over as well as showing hints.

The file includes a couple of different classes. That is the `GameBoard` class, which helps keep track of the state of various elements, and the `GameLogic` class, which applies game logic based on the current conditions.

This file also includes a few settings, but they really shouldn't be altered unless you have a good reason. The `GAMEBOARD_POSITION` is meant to represent the upper left-hand corner of where the game board starts. The `SPRITE` variables are for the sprite indices and the `DEBOUNCE_TIME` is the amount of delay in seconds so that the mouse doesn't accidentally double click.

```python
GAMEBOARD_POSITION = (55, 8)

SELECTOR_SPRITE = 9
EMPTY_SPRITE = 10
DEBOUNCE_TIME = 0.1  # seconds for debouncing mouse clicks
```

One of the more interesting functions in the Game Logic is `apply_gravity`. This scans through the board column by column and if there is an empty tile, the piece above it is moved down. If the top row is empty, a new piece is generated. It keeps doing this until nothing changes.

The `update` function is where the score is calculated. It checks for any matches, removes the tiles, and updates the score. The score is calculated based on the number of pieces in a match, the number of simultaneous matches, and the length of the chain of moves done.

The code to check if there are any move moves is interesting as well. The functions `check_match_after_move`, `check_horizontal_match`, `check_vertical_match`, and `find_all_possible_matches` work together to find these matches. This is done by scanning each piece and then attempting to make a move using a virtual board. This virtual board is simply a copy of the board as an array made through the Game Board's `game_grid_copy` function. By doing all of this using simple structures, the algorithm is fairly quick, but is only performed during an update and saved into an available moves list to avoid lag.

The other interesting functionality is the code to show a hint. It takes one of the moves from the available moves list and performs a swap animation. Animating the tile swaps will be covered in more detail in the Animations section of this guide.

Most of the mouse handling code was also placed into the game logic because while the pieces are being shifted around, the mouse needs to continue to be updated or the buffer gets full and it stops responding.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Metro/Metro_RP2350_Matching_Game/gamelogic.py

### Event Button

This button was reused from the [Minesweeper](https://learn.adafruit.com/minesweeper-on-metro-rp2350) guide. The event button builds on the&nbsp;[standard button](https://github.com/adafruit/Adafruit_CircuitPython_Display_Button/blob/main/adafruit_button/button.py)&nbsp;available in the&nbsp;[adafruit\_button](https://github.com/adafruit/Adafruit_CircuitPython_Display_Button)&nbsp;library. It adds the option to specify a callback function when the button is clicked as well as some mouse handling code so that a click is only registered if another element wasn't already selected and the click is within the boundaries of the button. This way if another UI element is selected and the mouse is dragged onto the button, it is handled properly.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Metro/Metro_RP2350_Matching_Game/eventbutton.py

# Tile-Matching Game on the Fruit Jam and Metro RP2350

## Animations

There are several animations that make the game work. They use different techniques and I wanted to cover each of them here.

## Piece Drops

The first type is piece drops. This is a relatively simple animation where the values of the tilegrid are simply updated with the corresponding value. The dropping effect is achieved by updating the columns from the bottom up. Initially, I was going to try and make each piece a separate tilegrid and move them all at the same time, but that both increased the game's complexity and caused a lot of lag, especially in the initial piece drop.

Even with using a single tilegrid, there's still a bit of lag when everything drops after a reset. The delay during the animation can cause issues with the mouse buffer getting full and this causes it to not respond until a reset has been performed. To get around this, the mouse update function is called within the gravity function.

One interesting bit is when matches are made, in order to show which pieces were matches, a half second delay before dropping highlights where the pieces were removed before dropping them again. Although the technique is simple, it is very effective.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/336/medium800thumb/gaming_InitialDrop-ezgif.com-optimize.jpg?1749059222)

## Selecting Pieces

Selecting pieces is accomplished with a `displayio` group. This group contains 2 tilegrids stacked on top of each other. The lower tilegrid is the sprite of the piece that is selected and the upper tilegrid contains the selector sprite. When a piece is clicked, the group is moved above the clicked piece. The tilegrid is set in the selected layer, the group is made visible, and the piece on the game board is replaced with an empty sprite. This helps prepare it for swapping. If the piece is clicked again, it is deselected by reversing the process.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/344/medium800thumb/gaming_SelectDeselect-ezgif.com-optimize.jpg?1749076189)

## Swapping Positions

Swapping the positions of pieces is done in a very clever way. The first piece is already selected and placed in a tilegrid as described above. When a second piece adjacent to the first is clicked, the swap piece is loaded into another tilegrid in a manner similar to the first piece. The steps that the pieces need to move are then calculated. This is to help figure out which direction each piece should go, based on the current position and the target position, to perform the swap animation. After that the tilegrids are simply moved and displayio takes care of the rest. Once both pieces have been moved, the pieces are unloaded from the tilegrids and the game board is updated.

Hints are similar to the piece swapping, except the selector is hidden during the process.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/345/medium800thumb/gaming_PieceSwap-ezgif.com-optimize.jpg?1749076937)

# Tile-Matching Game on the Fruit Jam and Metro RP2350

## Usage

The goal of the game is to get the highest score you can by matching at least 3 tiles in a row. If you are able to match 4 or 5, you can get additional points. Also, making 2 simultaneous matches with the same piece will increase your score.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/348/medium800thumb/gaming_ExamplePlaying-ezgif.com-optimize.jpg?1749079818)

If swapping the pieces doesn't create a match, the pieces will be unswapped and gameplay will continue.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/505/medium640thumb/gaming_NoMatch-ezgif.com-optimize.jpg?1749666930)

If a piece is clicked that in not adjacent to the selected piece, then nothing will happen.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/510/medium640thumb/gaming_Unswappable-ezgif.com-optimize.jpg?1749667030)

If you take a while to make a move, a hint will be displayed by swapping a random one of the possible moves and swapping them back.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/513/medium640thumb/gaming_Hint-ezgif.com-optimize.jpg?1749667159)

Once there are no more moves available, the Game Over screen is display with your final score.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/349/medium640/gaming_Game_Over.jpg?1749666955)

Have fun playing and feel free to add additional features such as continuous play by clearing the board when there are no moves without resetting the score to continue playing as long as you'd like.


## Featured Products

### Adafruit Fruit Jam - Mini RP2350 Computer

[Adafruit Fruit Jam - Mini RP2350 Computer](https://www.adafruit.com/product/6200)
We were catching up on a recent [hackaday hackchat with eben upton](https://hackaday.io/event/202122-raspberry-pi-hack-chat-with-eben-upton)&nbsp;and learned some fun facts: such as the DVI hack for the RP2040 was inspired by <a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/6200)
[Related Guides to the Product](https://learn.adafruit.com/products/6200/guides)
### Adafruit Metro RP2350 with PSRAM

[Adafruit Metro RP2350 with PSRAM](https://www.adafruit.com/product/6267)
Choo! Choo! This is the RP2350 Metro Line, making all station stops at "Dual Cortex M33 mountain", "528K RAM round-about" and "16 Megabytes of Flash town" and a bonus stop at "8 Megabytes of PSRAM village". This train is piled high with hardware that...

In Stock
[Buy Now](https://www.adafruit.com/product/6267)
[Related Guides to the Product](https://learn.adafruit.com/products/6267/guides)
### Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays

[Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays](https://www.adafruit.com/product/6055)
You may have noticed that our [RP2350 Feather](https://www.adafruit.com/product/6000) has an FPC output connector on the end&nbsp;for accessing the HSTX (High Speed Transmission)&nbsp;peripheral. This new capability, not available on the RP2040, is specifically designed to allow the...

In Stock
[Buy Now](https://www.adafruit.com/product/6055)
[Related Guides to the Product](https://learn.adafruit.com/products/6055/guides)
### 22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX - 20cm

[22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX - 20cm](https://www.adafruit.com/product/6036)
Connect this to that when a 22-pin FPC connector is needed. This 20 cm long cable is made of a flexible PCB. It's A-B style, meaning that pin one on one side will match with pin one on the other. How handy!

[We're stocking this to...](https://www.adafruit.com/category/360)

In Stock
[Buy Now](https://www.adafruit.com/product/6036)
[Related Guides to the Product](https://learn.adafruit.com/products/6036/guides)
### USB Type A Jack Breakout Cable with Premium Female Jumpers

[USB Type A Jack Breakout Cable with Premium Female Jumpers](https://www.adafruit.com/product/4449)
If you'd like to connect a USB-host-capable chip to your USB peripheral, this cable will make the task very simple.&nbsp; **There is no converter chip in this cable!** &nbsp;It's basically a plain USB cable that's cut in half and with jumper sockets on the power and data...

In Stock
[Buy Now](https://www.adafruit.com/product/4449)
[Related Guides to the Product](https://learn.adafruit.com/products/4449/guides)
### USB Wired Mouse - Two Buttons plus Wheel

[USB Wired Mouse - Two Buttons plus Wheel](https://www.adafruit.com/product/2025)
This is a mouse. &nbsp;A nice, simple mouse. &nbsp;No bells or whistles. &nbsp;Just a mouse.  
  
But that doesn't mean it's not the best simple mouse!&nbsp; We compared a few and liked this one quite a bit. &nbsp;It's optical for good resolution and precision, has two...

In Stock
[Buy Now](https://www.adafruit.com/product/2025)
[Related Guides to the Product](https://learn.adafruit.com/products/2025/guides)
### Break-away 0.1" 36-pin strip male header - Black - 10 pack

[Break-away 0.1" 36-pin strip male header - Black - 10 pack](https://www.adafruit.com/product/392)
Breakaway header is like the duct tape of electronics. It's great for connecting things together, soldering to perf-boards, fits into any breakout or breadboard, etc. We go through these guys real fast, and thought that given how handy they are, we'd offer them in a pack of ten!<br...></br...>

In Stock
[Buy Now](https://www.adafruit.com/product/392)
[Related Guides to the Product](https://learn.adafruit.com/products/392/guides)
### USB Type A to Type C Cable - approx 1 meter / 3 ft long

[USB Type A to Type C Cable - approx 1 meter / 3 ft long](https://www.adafruit.com/product/4474)
As technology changes and adapts, so does Adafruit. This&nbsp;&nbsp; **USB Type A to Type C** cable will help you with the transition to USB C, even if you're still totin' around a USB Type A hub, computer or laptop.

USB C is the latest industry-standard connector for...

In Stock
[Buy Now](https://www.adafruit.com/product/4474)
[Related Guides to the Product](https://learn.adafruit.com/products/4474/guides)

## Related Guides

- [Adafruit RP2350 22-pin FPC HSTX to DVI Adapter](https://learn.adafruit.com/adafruit-rp2350-22-pin-fpc-hstx-to-dvi-adapter.md)
- [Adafruit Metro RP2350](https://learn.adafruit.com/adafruit-metro-rp2350.md)
- [Using a Mouse with USB Host](https://learn.adafruit.com/using-a-mouse-with-usb-host.md)
- [Adafruit Fruit Jam](https://learn.adafruit.com/adafruit-fruit-jam.md)
- [Create a Memory Game on Fruit Jam Metro RP2350](https://learn.adafruit.com/create-a-memory-game-on-metro-rp2350.md)
- [Flappy Nyan Cat Game on Fruit Jam and Metro RP2350](https://learn.adafruit.com/flappy-nyan-cat-game-on-metro-rp2350.md)
- [Using DVI Video in CircuitPython](https://learn.adafruit.com/using-dvi-video-in-circuitpython.md)
- [Breakout Game on the Metro RP2350 and Fruit Jam](https://learn.adafruit.com/breakout-game-on-metro-rp2350-and-fruit-jam.md)
- [Match3 Game on the Fruit Jam and  Adafruit Metro RP2350](https://learn.adafruit.com/match3-game-on-metro-rp2350.md)
- [Larsio Paint Music](https://learn.adafruit.com/larsio-paint-music.md)
- [Chip's Challenge on Fruit Jam and Metro RP2350](https://learn.adafruit.com/256-color-gaming-on-the-metro-rp2350.md)
- [Return to The Matrix with the Metro RP2350 or Fruit Jam](https://learn.adafruit.com/return-to-the-matrix-with-the-metro-rp2350.md)
- [Minesweeper on the Fruit Jam and Metro RP2350](https://learn.adafruit.com/minesweeper-on-metro-rp2350.md)
- [Snake Game on Metro RP2350](https://learn.adafruit.com/snake-game-on-metro-rp2350.md)
- [PyPortal Adafruit Quote Book](https://learn.adafruit.com/pyportal-adafruit-quote-board.md)
- [Christmas Soundboard with NeoTrellis M4](https://learn.adafruit.com/xmas-sound-board.md)
- [LED Rocket Lamp](https://learn.adafruit.com/led-rocket-lamp.md)
