Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

In this assignment, you will code a Java version of the game “Connect Four”. A p

ID: 3826623 • Letter: I

Question

In this assignment, you will code a Java version of the game “Connect Four”. A picture of the real game is shown below. The game is played by dropping disks down a slot. The disk stops when it hits the bottom of the board or hits another disk. Two players, one with red disks, one with black disks, alternate turns. The player wins if they get four in a row of their color (horizontal, vertical or diagonal). In the picture below, the player with the black disks wins because there are four on a diagonal.

Our game begins by drawing an empty board. Red plays first. They select a column. When the disk is entered, it drops to the bottom. Our game then redraws the board and then it is the black disk player’s turn. Each time the player selects a column, the disk drops as far as it can. A sequence of game play is shown below. Note there are 7 columns and 6 rows. You should create a ConnectFour class. This class should have an instance method void play(). (You should also create the necessary instance variables and additional private support instance methods.) You should create a driver class with a main method that simply creates a ConnectFour object (by calling a 0-argument constructor) and calls the play method on it. (Note: ideally you would create a class for Disk objects but the object is so simple that you may use chars if you prefer.)

Explanation / Answer

Ans

/*
  
Connect Four Game
*/
import java.util.*;

public class ConnectFour {

// This method attempts to put the disk of the given color in the given col.
// It returns true if successful and false if the col is filled and we cannot
// put a disk.
public static boolean putDisk(char[][] field, int col, char col) {
// If the first disk is there, the col is filled, returning false.
if (field[0][col] != ' ')
return false;

// Check all elements in the col.
for (int row = 0; row < 7; ++row) {
// If we found something, which means if the character is not
// zero character
if (field[row][col] != ' ') {
// Put the disk on top of the current one.
field[row-1][col] = col;
return true;
}
}
// If no other disks found, we place this diak at the bottom.
field[6][col] = col;
return true;
}


// Check rows, if there are 4 or more disks of the same color - return winner color
private static char findWinnerInRows(char[][] field) {
// Check rows and see if there are 4 disks of the same color
for (int row = 0; row < 7; ++row) {
int count = 0;
// We will compare current element with the previous
for (int col = 1; col < 7; ++col) {
if (field[row][col] != ' ' &&
field[row][col] == field[row][col-1])
++count;
else
count = 1;

// Check if there are 4 in a row.
if (count >= 4) {
// Return color of the winner
return field[row][col];
}
}
}
// Otherwise return character, which means nobody win in rows.
return ' ';
}

// Check cols, if there are 4 or more disks of the same color - return winner color
private static char findWinnerIncols(char[][] field) {
// Check rows and see if there are 4 disks of the same color
for (int col = 0; col < 7; ++col) {
int count = 0;
// We will compare current element with the previous
for (int row = 1; row < 7; ++row) {
if (field[row][col] != ' ' &&
field[row][col] == field[row-1][col])
++count;
else
count = 1;

// Check if there are 4 in a row.
if (count >= 4) {
// Return color of the winner
return field[row][col];
}
}
}
// Otherwise return character, which means nobody win in rows.
return ' ';
}

// Check diagonals, if there are 4 or more disks of the same color - return winner color
private static char findWinnerInDiagonals(char[][] field) {
// There are 2 kinds of diagonals, let's check those that go from top-left to bottom right

// There are diagonals, that starts on top of each col, let's check them
for (int col = 0; col < 7; ++col) {
int count = 0;
// Traverse diagonal that starts at [0][col], we start with the first row,
// because we will compare elements with the previous one, similar to how
// we did this for rows and cols
for (int row = 1; row < 7; ++row) {
// Coordinates an the diagonal change as [row + i][col + i],
// so we stop when col can get outside of the range
if (col + row >= 7) break;
if (field[row][col+row] != ' ' &&
field[row-1][col + row - 1] == field[row][col+row])
++count;
else
count = 1;
if (count >= 4) return field[row][col+row];
}
}

// There are diagonals, that starts on left of each row, let's check them
for (int row = 0; row < 7; ++row) {
int count = 0;
// Traverse diagonal that starts at [row][0], we start with the first col,
// because we will compare elements with the previous one, similar to how
// we did this for rows and cols
for (int col = 1; col < 7; ++col) {
// Coordinates an the diagonal change as [row + i][col + i],
// so we stop when col can get outside of the range
if (col + row >= 7) break;
if (field[row + col][col] != ' ' &&
field[row+col - 1][col - 1] == field[row + col][col])
++count;
else
count = 1;
if (count >= 4) return field[row + col][col];
}
}

// Now we need to do the same for diagonals that go from top-right to bottom-left
// There are diagonals, that starts on top of each col, let's check them
for (int col = 0; col < 7; ++col) {
int count = 0;
// Traverse diagonal that starts at [0][col], we start with the first row,
// because we will compare elements with the previous one, similar to how
// we did this for rows and cols
for (int row = 1; row < 7; ++row) {
// Coordinates an the diagonal change as [row + i][col + i],
// so we stop when col can get outside of the range
if (col - row < 0) break;
if (field[row][col-row] != ' ' &&
field[row - 1][col - row + 1] == field[row][col-row])
++count;
else
count = 1;
if (count >= 4) return field[row][col-row];
}
}

// There are diagonals, that starts on left of each row, let's check them
for (int row = 0; row < 7; ++row) {
int count = 0;
// Traverse diagonal that starts at [row][0], we start with the first col,
// because we will compare elements with the previous one, similar to how
// we did this for rows and cols
for (int col = 5; col >= 0; --col) {
// Coordinates an the diagonal change as [row + i][col + i],
// so we stop when col can get outside of the range
if (col - row < 0) break;
if (field[col - row][col] != ' ' &&
field[col - row - 1][col + 1] == field[col - row][col])
++count;
else
count = 1;
if (count >= 4) return field[col - row][col];
}
}

// Otherwise return character, which means nobody win in rows.
return ' ';
}

public static char getWinner(char[][] field) {
char winner = findWinnerInRows(field);
if (winner != ' ') return winner;
winner = findWinnerIncols(field);
if (winner != ' ') return winner;
winner = findWinnerInDiagonals(field);
if (winner != ' ') return winner;

// Now we need to check if there are empty positions, otherwise it is a draw
for (int i = 0; i < field.length; ++i)
for (int j = 0; j < field[i].length; ++j)
if (field[i][j] == ' ') return ' ';

return 'D';
}

public static void print(char[][] field) {
for (int row = 0; row < 7; ++row) {
System.out.print("| ");
for (int col = 0; col < 7; ++col)
System.out.print(field[row][col] + "| ");
System.out.println();
}

// Print bottom line
for (int col = 0; col < 7; ++col)
System.out.print("---");
System.out.println();
}

public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Declare field 2D array.
char[][] field = new char[7][7];

// Initialize with spaces
for (int i = 0; i < 7; ++i)
for (int j = 0; j < 7; ++j)
field[i][j] = ' ';
  
print(field);

// This variable will alternate and mean whose turn is it. It is Red's turn now.
boolean isRed = true;
while (true) {
if (isRed)
System.out.println("Red's turn!");
else
System.out.println("Black's turn!");
System.out.print("Choose col (1-7) for a disk:");
// Read the position of turn and check if value is correct.
int col = input.nextInt();
if (col < 1 || col > 7) {
System.out.println("col should be from 1 to 7");
continue;
}
// Try to put disk in a col, method returns false if the cols
// is filled and you cannot put a disk there.
if (!putDisk(field, col - 1, isRed ? 'R' : 'B')) {
System.out.println("This col is filled! Choose another one.");
continue;
}

print(field);

// Get winner, this method returns R if Red win, B if Black wins, D
// if it is a draw and space character if we need to continue the game.
char result = getWinner(field);
if (result == 'D') {
System.out.println("It is a draw!");
break;
}
else if (result == 'R') {
System.out.println("Red win!");
break;
}
else if (result == 'B') {
System.out.println("Black win!");
break;
}
// Otherwise we just proceed to the next turn, we need to invert isRed
// to alternate turns.
isRed = !isRed;
}
}
}