Right now I'm making Connect Four in Java. I'm currently working on being able to drop the checker but I'm running into some problems. This is my code so far:
private static char board[][];
private static final int BOARD_WIDTH = 7;
private static final int BOARD_HEIGHT = 6;
private static boolean gameEnd = false;
public static void main(String[] args)
{ // Element #0 in the two-dimensional 'board' array is not used // so that the column numbers selected by the players match // with the actual internal element numbers of the array board = new char[BOARD_HEIGHT + 1][BOARD_WIDTH + 1]; Scanner input = new Scanner(System.in); char turn = 'x'; int dropColumn = 0; System.out.println("TWO PLAYER CONNECT FOUR GAME!"); InitializeBoard(); while (gameEnd == false) { DisplayBoard(); dropColumn = GetDropColumn(turn, input); if (turn == 'x') turn = 'o'; else turn = 'x'; if (DropChecker(turn, dropColumn) == true) board[BOARD_HEIGHT][dropColumn] = turn; }
}
// Set all elements of the two-dimensional 'board' array to spaces
private static void InitializeBoard()
{ char a = ' '; for (int i = 0; i < board.length; i++) { board[i][0] = a; } for (int e = 0; e < board.length; e++) { board[0][e] = a; }
}
// Display the game board (the board itself, along with the elements of
// the two-dimensional 'board' array); note that the lines of the game
// board are NOT stored in the two-dimensional 'board' array
private static void DisplayBoard()
{ for (int row = 0; row < board.length; row++) { for (int col = 0; col < board.length; col++) { System.out.print("|"); System.out.printf("%3c", board[row][col]); } System.out.println(); }
}
// Get (from the appropriate player) the number (1 – 'BOARD_WIDTH') of
// the column in which a checker should be dropped, and then return that
// number; if the player does not enter an integer, report the error and
// keep asking for a column number until an integer is entered; note that
// the check for an invalid column number (< 1 or > 'BOARD_WIDTH') can be
// performed in this method or in 'main', from where this method is called
private static int GetDropColumn(char turn, Scanner input)
{ int numInput = 0; int realInput = 0; while (realInput == 0) { try { System.out.println("Player " + turn + "'s turn: In which column would you like to place a checker? (1-7)"); numInput = input.nextInt(); if (numInput < 1 || numInput > BOARD_WIDTH) { numInput = 0; System.out.println("The number was out of bounds. Please try again."); } } catch (NumberFormatException e) { System.out.println("Invalid input. Please try again."); } realInput = numInput; } return realInput;
}
// "Drop" a checker into the designated column by setting the
// appropriate element of the two-dimensional 'board' array to
// either an 'x' or an 'o'; if the "drop" was successful, this
// method returns "true"; an attempt to "drop" the checker into
// a full column results in "false" being returned
private static boolean DropChecker(char turn, int dropColumn)
{ int count = 0; while (count < BOARD_HEIGHT) { if (board[BOARD_HEIGHT - count][dropColumn] == ' ') { return true; } count++; } return false;
}My problem currently is that the program won't drop the checker on the board. After I enter column 6, the program returns the board but the checker has not been dropped. What am I missing/doing wrong here?
12 Answers
There are a few issues with your code
The turn of the player's is reversed, so what you need to do is change the player AFTER they drop the piece, not before
The initialize board method is off, just use two for loops to initialize it
The index of placing the checker was incorrect, so start with the index at the bottom and then decrement whenever the space isn't "empty" (== ' ')
1.Main Game Loop Refactor
while (gameEnd == false)
{ DisplayBoard(); dropColumn = GetDropColumn(turn, input); if (DropChecker(turn, dropColumn) == true) { turn = 'x' == turn ? 'o' : 'x'; //ternary operator works great }
}2.Initialize Method refactor
private static void InitializeBoard()
{ char a = ' '; for (int i = 0; i < board.length; i++) { for (int e = 0; e < board[i].length; e++) board[i][e] = a; }
}3.Drop Checker Method Refactor
private static boolean DropChecker(char turn, int dropColumn)
{ int indexToPaceChecker = BOARD_HEIGHT; while (indexToPaceChecker >= 0) { if (board[indexToPaceChecker][dropColumn] == ' ') { //drop the checker, that's what this method is supposed to do anyways :) board[indexToPaceChecker][dropColumn] = turn; return true; } indexToPaceChecker--; } return false;
}I'd also recommend using private static final char emptySpace = ' '; that way in your code you can intitialize the board like board[i][e] = emptySpace;, and check for an empty space like if (board[indexToPaceChecker][dropColumn] == emptySpace). It's cleaner and easier to make changes if you wanted a different board fill.
DropChecker() just checks if there is a free place in the column. Instead you should return which line is the lowest one (the one with the highest index), if there is no you could return -1.
You are setting the wrong row with the following line: board[BOARD_HEIGHT][dropColumn] = turn this puts turn into last line.
You are also not initializing your board array (if you not initialize it, it's not the same as ' ', which is also a char)
This should work for you:
private static int DropChecker(char turn, int dropColumn) { int count = 0; while (count < BOARD_HEIGHT) { if (board[BOARD_HEIGHT - count][dropColumn] == ' ') { count++; } else { return --count; } }
}You set the place in the board with this:
board[DropChecker(turn, dropColumn)][dropColumn]Add this lines at the beginning of main, right after board = new char[][] :
for(int i = 0; i < BOARD_HEIGHT; i++) { for(int j = 0; j < BOARD_WIDTH; j++) { board[i][j] = ' '; }
}