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

Connect Four is a two-player board game in which the players alterantely drop co

ID: 3718868 • Letter: C

Question

Connect Four is a two-player board game in which the players alterantely drop colored disks into a seven-column, six-row vertically suspended grid. The objective of the game is to connect four same-colored disks in a row, a column, or a diagonal before your opponent can do likewise. The program prompts two players to drop a red or yellow disk alternately. Whenever a disk is dropped, the program redisplays the board on the console and determines the status of the game (win, lose, or continue). Here is a sample run: (Must state: "Drop a red disk at column (0-6): " Have user enter a number from 0-6; "Drop a yellow disk at column (0-6): " Have user enter a number from 0-6")

Please incorporate this code:

public static boolean checkWin(char[][] b)

{
// Create four boolean variables, one for each set of rows. Initialize all of them to false.
boolean foundRow = false;
boolean foundCol = false;
boolean foundMjrD = false;
boolean foundMinD = false;
  
// Check to see if four consecutive cells in a row match.
// check rows
for (int r = 0; r <= 5; r++)
{
for (int c = 0; c <= 3; c++)
{
if (b[r][c] == b[r][c + 1] && b[r][c] == b[r][c + 2] && b[r][c] == b[r][c + 3] && b[r][c] != ' ')
{
foundRow = true;
break;
}
}
}
  
// Check to see if four columns in the same row match
// check columns
for (int r = 0 ; r <= 2; r++)
{
for (int c = 0; c <= 6; c++)
{
if (b[r][c] == b[r + 1][c] && b[r][c] == b[r + 2][c] && b[r][c] == b[r + 3][c] && b[r][c] != ' ')
{
foundCol = true;
break;
}
}
}
  
// Check to see if four diagonals match (top left to bottom right)
// check major diagonal
for (int r = 0; r <= 2; r++)
{
for (int c = 0; c <= 3; c++)
{
if (b[r][c] == b[r + 1][c + 1] && b[r][c] == b[r + 2][c + 2] && b[r][c] == b[r + 3][c + 3] && b[r][c] != ' ')
{
foundMjrD = true;
break;
}
}
}
  
// Check to see if four diagonals in the other direction match (top right to bottom left)
// check minor diagonal
for (int r = 0; r <= 2; r++)
{
for (int c = 3; c <= 6; c++)
{
if (b[r][c] == b[r + 1][c - 1] && b[r][c] == b[r + 2][c - 2] && b[r][c] == b[r + 3][c - 3] && b[r][c] != ' ')
{
foundMinD = true;
break;
}
}
}
  
// If ONE of the booleans is true, we have a winner.
// checks boolean for a true
if (foundRow || foundCol || foundMjrD || foundMinD)
return true;
else
return false;
} // end checkWin method

Example:

Drop a red disk at column (0-6): 0nr IRI II1III

Explanation / Answer

Board.java

import java.util.Objects;

public class Board {

/**

* The number of columns in the board.

*/

private static final int BOARD_WIDTH = 7;

/**

* The number of rows in the board.

*/

private static final int BOARD_HEIGHT = 6;

/**

* The minimum length of a winning pattern.

*/

private static final int WINNING_PATTERN_LENGTH = 4;

private final PlayerColor[][] board = new PlayerColor[BOARD_HEIGHT]

[BOARD_WIDTH];

public int getWidth() {

return board[0].length;

}

public int getHeight() {

return board.length;

}

/**

* Performs a ply of the player with the color {@code color} putting a new

* piece at column {@code x}.

*

* @param x the column index.

* @param color the player color.

*/

public void put(final int x, final PlayerColor color) {

checkX(x);

checkColumnNotFull(x);

Objects.requireNonNull(color, "The input color is null.");

int y = board.length - 1;

while (board[y][x] != null) {

--y;

}

board[y][x] = color;

}

public PlayerColor checkVictory() {

if (checkVictory(PlayerColor.RED)) {

return PlayerColor.RED;

}

if (checkVictory(PlayerColor.YELLOW)) {

return PlayerColor.YELLOW;

}

return null;

}

public boolean isFull() {

for (int y = 0; y < board.length; ++y) {

for (int x = 0; x < board[0].length; ++x) {

if (board[y][x] == null) {

return false;

}

}

}

return true;

}

@Override

public String toString() {

final StringBuilder sb = new StringBuilder();

for (int y = 0; y < board.length; ++y) {

sb.append("|");

for (int x = 0; x < board[0].length; ++x) {

final PlayerColor color = board[y][x];

sb.append(color != null ? color.toString() : " ");

sb.append("|");

}

sb.append(" ");

}

sb.append("--------------- ");

sb.append(" 1 2 3 4 5 6 7");

return sb.toString();

}

private boolean checkVictory(final PlayerColor color) {

// Check the horizontal patterns:

final int horizontalPatterns = getWidth() - WINNING_PATTERN_LENGTH + 1;

for (int startY = 0; startY < getHeight(); ++startY) {

next_pattern:

for (int startX = 0; startX < horizontalPatterns; ++startX) {

// Check a horizontal pattern:

for (int offset = 0;

offset < WINNING_PATTERN_LENGTH;

offset++) {

if (board[startY][startX + offset] != color) {

continue next_pattern;

}

}

return true;

}

}

// Check the vertical patterns:

final int verticalPatterns = getHeight() - WINNING_PATTERN_LENGTH + 1;

for (int startX = 0; startX < getWidth(); ++startX) {

next_pattern:

for (int startY = 0; startY < verticalPatterns; ++startY) {

for (int offset = 0;

offset < WINNING_PATTERN_LENGTH;

offset++) {

if (board[startY + offset][startX] != color) {

continue next_pattern;

}

}

return true;

}

}

// Check the diagonal patterns (from top-left to bottom-right):

for (int startY = 0; startY < verticalPatterns; ++startY) {

next_pattern:

for (int startX = 0; startX < horizontalPatterns; ++startX) {

for (int offset = 0;

offset < WINNING_PATTERN_LENGTH;

offset++) {

if (board[startY + offset][startX + offset] != color) {

continue next_pattern;

}

}

return true;

}

}

// Check the diagonal patterns (from top-right to bottom-left):

for (int startY = 0; startY < verticalPatterns; ++startY) {

next_pattern:

for (int startX = WINNING_PATTERN_LENGTH - 1;

startX < getWidth();

startX++) {

for (int offset = 0;

offset < WINNING_PATTERN_LENGTH;

offset++) {

if (board[startY + offset][startX - offset] != color) {

continue next_pattern;

}

}

return true;

}

}

// No victory yet for color 'color'.

return false;

}

public int getColumnHeight(final int x) {

int height = 0;

for (int y = board.length - 1; y >= 0; --y, ++height) {

if (board[y][x] == null) {

return height;

}

}

return height;

}

private void checkX(final int x) {

if (x < 0) {

throw new IndexOutOfBoundsException(

"The x-coordinate is negative: " + x);

}

if (x >= board[0].length) {

throw new IndexOutOfBoundsException(

"The x-coordinate is too large: " + x + ". Must be at " +

"most " + (board[0].length - 1) + ".");

}

}

private void checkColumnNotFull(final int x) {

if (getColumnHeight(x) == board.length) {

throw new IllegalStateException(

"The column at x-coordinate " + x + " is full.");

}

}

}

PlayerColor.java

package net.coderodde.game.connect4;

public enum PlayerColor {

    RED    ("X"),

    YELLOW ("O");

    private final String string;

    PlayerColor(final String string) {

        this.string = string;

    }

    @Override

    public String toString() {

        return string;

    }

    public PlayerColor invert() {

        switch (this) {

            case RED:

                return PlayerColor.YELLOW;

            case YELLOW:

                return PlayerColor.RED;

            default:

                throw new IllegalStateException("Should not get here.");

        }

    }

}

Main.java

package net.coderodde.game.connect4;

import java.util.Scanner;

public class Main {

private static final String NEW_GAME_REQUEST =

"Do you wish to play once more? Type "no" to exit, or anything " +

"else to replay.";

private static final String RED_WINS_MESSAGE =

"[GAME OVER] The red player wins!";

private static final String YELLOW_WINS_MESSAGE =

"[GAME OVER] The yellow player wins!";

private static final String TIE_MESSAGE = "[GAME OVER] It's a tie!";

private static final String EXIT_MESSAGE = "Bye!";

private static final String RED_PROMPT = "red> ";

private static final String YELLOW_PROMPT = "yellow> ";

private final Scanner scanner = new Scanner(System.in);

private Board board = new Board();

private PlayerColor currentPlayer;

public void run() {

while (true) {

PlayerColor winnerColor = gameLoop();

reportOutcome(winnerColor);

if (!newGameRequested()) {

break;

}

}

System.out.println(EXIT_MESSAGE);

}

private PlayerColor gameLoop() {

currentPlayer = PlayerColor.RED;

board = new Board();

System.out.println();

System.out.println(board);

while (true) {

PlayerColor winnerColor = board.checkVictory();

if (winnerColor != null || board.isFull()) {

return winnerColor;

}

final int column = readPly();

board.put(column, currentPlayer);

currentPlayer = currentPlayer.invert();

System.out.println();

System.out.println(board);

}

}

private void reportOutcome(final PlayerColor winnerColor) {

switch (winnerColor) {

case RED:

System.out.println(RED_WINS_MESSAGE);

break;

case YELLOW:

System.out.println(YELLOW_WINS_MESSAGE);

break;

default:

System.out.println(TIE_MESSAGE);

break;

}

}

private boolean newGameRequested() {

System.out.println(NEW_GAME_REQUEST);

final String input = scanner.next().trim().toLowerCase();

return !input.equals("no");

}

public static void main(final String[] args) {

final Main main = new Main();

main.run();

}

private int readPly() {

while (true) {

if (currentPlayer == PlayerColor.RED) {

System.out.print(RED_PROMPT);

} else if (currentPlayer == PlayerColor.YELLOW) {

System.out.print(YELLOW_PROMPT);

} else {

throw new IllegalStateException("Should not get here.");

}

final String command = scanner.next().trim();

try {

final int column = Integer.parseInt(command);

if (column < 1) {

System.out.println("Column index must be at least 1.");

continue;

} else if (column > board.getWidth()) {

System.out.println("Column index must be at most " +

board.getWidth());

continue;

}

final int columnIndex = column - 1;

if (board.getColumnHeight(columnIndex) == board.getHeight()) {

System.out.println("The " + nth(column) + " column is " +

"full.");

}

return columnIndex;

} catch (final NumberFormatException ex) {

System.out.println(""" + command + "" is not an integer!");

}

}

}

private static String nth(final int i) {

switch (i) {

case 1:

return "1st";

case 2:

return "2nd";

case 3:

return "3rd";

default:

return "" + i + "th";

}

}

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote