Authors: Nicolas Poitoux, Maxime Joubert, Julien Doche, François Mazeau.
This project aim is to create a match-3 game running on the STM32F429 using Ada and the Ada Drivers Library.
The principle of a match-3 game is to align 3 squares of the same color in order to make them disappear and gain points. The player is able to swap some squares if the result of the swap makes for a alignment of at least 3 squares. When an alignment of blocks disappear the gravity takes place in order to fill the hole. If further alignments are created by gravity, this constitutes a chains that gives extra points with a bonus multiplier. When no combination are possible, the game stops.
- A STM32F429I-DISCO board
- A linux distribution
A Makefile is provided to generate the binary that can be flashed. You might need to provide the Makefile a PATH variable that contains the path to your ARM toolchain. You can choose to build in debug mod (the default mode, has contracts enabled), or in release mode by provide BUILD=Release. A rule "flash" compiles the binary and flashes it on the board automatically using st-flash. The game will start immediately after the flash is completed.
The program starts by initializing the desired functionalities of the board. Then we enter the loop that will restart the game once the game is over, it starts by initializing the grid randomly using the board's rng. We make sure that the grid doesn't start with squares already aligned. Then we enter our main game loop.
First we manage the inputs, we retrieve all touch points on the touch screen and if there is only one, we map it to a square in our grid. When two adjacent squares are touched consecutively, we start checking if the move is valid, that is, if one of the move squared would make an alignment of 3 or more. If it isn't, nothing is done. Else, the blocks aligned are placed in a worklist.
Here is the fun part of our algorithm: We have two worklist, they are ordered set, sorted by height of the squares included. The first worklist is for the squares that are going to change color. We traverse our worklist in order, and for each square in this worklist, we take the first square above it that is not in the worklist. The current square takes its square and this square is placed in the worklist. If there is no square above, the square take a random value. Once a square from the first worklist is treated we place it in a second worklist and we remove it from the first. We continue until the first worklist is empty. The second worklist is there to check if there is an alignment. For each square in this worklist we check if there is an alignment in which he is involved. If there is, it helps repopulate the first worklist. This allows, to treat all the alignment in the same chain at once, thus it allows us to have a consistent chain mechanic for the scoring. We continue to check the move until the second worklist is empty, and we repeat it all until both worklist are empty. During this time no input will be read. Each time there is a combination, we make the block involved blink for more clarity. It's also at that time that we increment the swore.
Finally, we render the grid and print the score, and the game loop restarts.
Almost all the functions have contract to ensure their behavior.