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 II1IIIExplanation / 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";
}
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.