Connect-4 game

Kailey Coats

Overview

For my project, I wanted to develop an electronic analog of the classic two-player Connect-4 game using an LCD-display. The game begins by displaying a 6x7 Connect-4 board with all spaces blank and one chip suspended above the upper-leftmost corner of the board. The player uses a joystick to move left or right to select a column, with the chip display updating each time to keep track of their current position. When the player is satisfied, pressing down on the joystick will drop the chip into the lowest available spot in that column. After each move, the computer assesses whether the chip just played produced a line of 4 chips of the same color going vertically, horizontally, or diagonally. If so, the display switches to the victory screen for that player and the game ends. If not, play passes to the next player and the process repeats.

Classic game My version

Hardware

The hardware used for this project consisted of a microcontroller, LCD board, joystick, and buzzer. The microcontroller I used for my project is the BG22-EK4108A Development Kit Board from Silicon Labs. The LCD board I used was the Waveshare 2-inch Mini LCD Screen with 240x320 resolution and 262K RGB color, embedded ST7789VW driver, and SPI Interface. The joystick I used was the TE Connectivity ALCOSWITCH Switch 2434804-1. The buzzer I used was from TDK with resonant frequency 4000 Hz.

Schematic Yellow wins Red wins Illegal move

Software

In my app_init() method, I first initialize the LCD Screen and then called a method to set up the buzzer by initializing the CC0 channel for the PWM, the CC1 channel for the complementary PWM, setting the PWM frequency to 4000 Hz and the duty cycle to 50% for both channels, and configuring PC0 and PC1 for output. I then initialized and started the joystick so it sets a variable to different integer values to represent which direction it is pressed. I then initialized a 2-dimensional array to represent the game board, setting all index values to 0s to represent that the board is empty. I then called a method to create an empty game board on the LCD screen. I then called a method to draw a chip in the upper left corner of the screen for the player to move above the game board. I then have a delay of 3 seconds and begin the timer so the player can start using the joystick.

In my app_process() method, everything is nested within an if statement verifying if the joystick has been pressed. If it is pressed, its pressed status is reset. If the joystick has been moved left or right, an integer representing the chips current position is initialized and an integer representing where the chip will be moving is incremented or decremented respectively, with wrap-around logic to make sure its value is between 0 and 6. A method is then called to simulate the chip moving left or right by blacking out the circle at its original position and coloring a new chip in its new position.

If the joystick has been pressed down, the computer checks if the topmost position in the chip's column is set to 0, meaning that there is a legal move in that column. If there is a valid move, it then calls a method to simulate dropping the chip by blacking it out at its current position and recoloring it one space below while the space below it is vacant. Once the chip cannot fall anymore, the game board at the index equal to the chip's position is set to the value of whose turn it is to indicate that that space has been claimed by the player. I then call a method to check vertically, horizontally, and diagonally from the chip just placed to determine if the player has made a connection of 4 chips in a row. Since any new 4 connection would only have been created as a result of the current turn, there is no reason to check for any connections not linked to the chip last played in order to save time. If the player has won, a method is called to print the appropriate victory statement, followed by a method to reset our game board array to all 0s. Regardless of whether or not the player has won, the turn is then changed, a method is called to display the next player's chip above the game board and reset its original column position to 0.

If there is not a valid move, we call a method to black out the chip above the game board, a method to display and then black out text indicating an that the move was invalid, and finally call a method to restore the chip and allow the player to try a new move.

Final Thoughts

I really enjoyed working on this project and determining how to have the computer track the status of the game while the LCD displayed it for the player. Overall, I think it plays quite well, though I do wish it was more interactive for the player (allowing the player to choose who goes first, displaying any rules for gameplay, etc.) and it does not know how to deal with ties. Professor Sergei suggested further improvements I could make outside of the class, such as allowing one player to use Bluetooth to input their moves, allowing an option to have the computer play, and playing an error noise when an invalid move is made. While I didn't have time to finish these upgrades during the semester, I am planning to keep working on my project over the summer to make it even better.

Downloads