
Project 2: Connect 4
Due by: Friday, February 28, 2020 at 11:59 p.m.
As the second stop on our retro-gaming tour, you have to implement the game of Connect 4. While the level of strategy and information available to an Uno player is limited, Connect 4 is a classic abstract strategy game of perfect information. In other words, you know everything that your opponent knows.
Writing an artificial intelligence to play Connect 4 would be an interesting project, but our goals are simpler: We want to create a graphical user interface (GUI) using the Java Swing library that will allow two humans to play the game. (Although it's instructive to write an AI player, Connect 4 is a solved game. It's been proven that the first player will always win if both players play perfectly, and there's an algorithm for playing perfectly.)
Specification
Game play
If you are unfamiliar with the game of Connect 4, it is played on a vertical grid with 6 rows and 7 columns and two colors of colored discs, red and black for our implementation. When a player drops a disc into one of the columns, it will fall down to the lowest row that doesn't already have a disc in it. The goal of the game is to get four pieces of your own color in a line while blocking your opponent from doing the same before you. Discs can make four in a line in a horizontal row, a vertical column, or a diagonal.
To simplify our game, the first player, Player 1, will always play black, and the second player, Player 2, will always play red.
GUI
Before you begin programming the mechanics of the game, you first need to create a GUI to display it. Create a project called Project2
, add a package to it called connect4
, and add a class called Game
to the package. Follow examples in the book to create a JFrame
that looks like the following when it is initially created.

Note that its title should be "Connect 4". Just below the title is a JLabel
stating which player's turn it is. By default, a JFrame
uses BorderLayout
, easily allowing you to put this JLabel
at the top while reserving the central area for the board itself.
The board is an ideal place to use GridLayout
, since it is formed of a number of rows and columns all identically sized. Although Connect 4 has 6 rows and 7 columns of playable space, your layout should have 7 rows and 7 columns where the first row is filled with JButton
objects. These objects are how a player will decide which column to play. The remaining 6 rows and 7 columns should be filled with JLabel
objects. Both the JButton
and JLabel
objects in the grid will be decorated with ImageIcon
objects.
You may use the following images to represent, respectively, an empty slot, a black piece, a black piece that could be played, a black piece that is part of a winning group, a red piece, a red piece that could be played, and a red piece that is part of a winning group. Right-click on each image and save it into your Project2
directory but not into the src
or bin
directories.
Note that, in order to look right, my JButton
objects needed to have their margins set (using their setMargin()
method) with insets that were -5 on every side.
Game state
Although it's tempting to somehow use the images on the JLabel
objects to represent the game state, it's much cleaner to use a separate data structure. I recommend that you make a 2D array of Piece
objects representing the current state of the game. You can use the following Piece
definition inside your Game
class.
public enum Piece { RED, BLACK, EMPTY }
You should initialize your 2D array to contain all Piece.EMPTY
values. Then, whenever a player makes a move, you should update both the array of Piece
objects and the appropriate JLabel
.
Actions
Each JButton
should have an ActionListener
added to it that drops a piece into the appropriate column. Since the code needed to place the piece is complex, I recommend writing a method called by each ActionListener
that drops a piece into the given column. Then, the ActionListener
should play the click sound that accompanies a dropped piece.
The method that plays a piece needs to do the following:
- Find the lowest row where the piece fits (either the last row that's empty or the very last row if no pieces are in that column)
- Update the location in the 2D array that represents game state
- Update the icon of the corresponding
JLabel
- If the game is won (ideally checked by calling another method):
- Remove the icons from all the
JButton
objects and disable them - Update a label to say who the winner is
- Otherwise, if the game is tied (easily done by counting the number of moves: 42 moves with no win is a tie):
- Remove the icons from all the
JButton
objects and disable them - Update a label to say that the game is tied
- Otherwise, if the game was neither won nor tied:
- Update the icons to be the other player's pieces for all the
JButton
objects on columns where a move is still possible - Remove the icons from all the
JButton
objects on columns where moves are impossible and disable them - Update a label to say whose turn it is now
The method that checks for a win needs to do the following:
- Loop through the column where the new piece was played to see if there are four or more in a line
- If there are, go back and mark them all as the appropriate winning icon
- Loop through the row where the new piece was played to see if there are four or more in a line (moving both left and right because there might be connected pieces on both sides)
- If there are, go back and mark them all as the appropriate winning icon
- Loop through the diagonal from lower left to upper right where the new piece was played to see if there are four or more in a line (moving both left and right because there might be connected pieces on both sides)
- If there are, go back and mark them all as the appropriate winning icon
- Loop through the diagonal from upper left to lower right where the new piece was played to see if there are four or more in a line (moving both left and right because there might be connected pieces on both sides)
- If there are, go back and mark them all as the appropriate winning icon
- If any of these directions had four or more in a line, return
true
, otherwisefalse
Playing a sound
Whenever a piece is played, your program must play a click noise. A file with the click noise is provided below. As with the images, right-click on the sound file and save it into your Project2
directory but not into the src
or bin
directories.
Use the code example in the textbook to load the sound into a Clip
. Whenever a piece is played, stop the clip, use the setMicroSecondPosition()
method to bring it back to the beginning, and then start the clip playing.
Game states
The image above shows the game just after it has been started. Here's a picture of the game after Player 1 has played. Note that the JButton
objects have changed to show the red piece and that the label says that it's Player 2's turn.

After several more moves, the top of the board has been reached on one column. Note that the JButton
there no longer has an icon and has been disabled, preventing anyone from playing in that location.

It's possible that this game could continue with no one winning, eventually reaching the tied state shown below.

Or, starting afresh, Player 1 might have reached an easy win.

Yet another game might have been a win for Player 2, highlighting all the ways that four or more in a line were reached.

Make sure your code handles all of these cases, looking as much like the samples as possible.
Testing
You must test your code to be sure that it does what it says that it does. Write down your testing plan describing your different approaches to playing the game to reveal any bugs. Include this file as a file called testing.txt
, testing.docx
, or testing.pdf
.
Turn In
Your Eclipse project should be called Project2
, but the class you create inside should be called Game
and should be in the package connect4
. Zip up Game.java
from the Project2\src\connect4
folder inside your workspace folder with your testing file and upload the zip file to Blackboard. You should not need to make more than one class to solve this problem, but if you do, you can include those other .java
files in your zip file. Only the team leader should turn in this file.
All work must be submitted before Friday, February 28, 2020 at 11:59 p.m. unless you are going to use a grace day.
All work must be done within assigned teams. You may discuss general concepts with your classmates, but it is never acceptable for you to look at another team's code. Please refer to the course policies if you have any questions about academic integrity. If you have trouble with the assignment, I am always available for assistance.
Grading
Your grade will be determined by the following categories:
Category | Weight |
---|---|
Dropping pieces into the correct location | 20% |
Updating turn information and buttons | 20% |
Checking for wins and ties | 20% |
Highlighting the winning pieces | 10% |
Announcing the winner or a tie | 5% |
Playing a click when a piece is played | 5% |
Visual polish | 5% |
Testing plan | 5% |
Style and comments, including Javadoc comments | 10% |
Code that does not compile will automatically score zero points.
Under no circumstances should any member of one group look at the code written by another group. Tools will be used to detect code similarity automatically.