principlejavaMinor
Connect Four (the OO approach)
Viewed 0 times
fourconnecttheapproach
Problem
I saw some approaches to the Connect Four game on a site. None of them seemed very OO like, therefore I'd like to present my implementation and request suggestions on how to make this code more readable.
For example, I dislike the "oddball solution" where I get the current positions stone from the field in class
```
import java.util.Arrays;
import java.util.Scanner;
public class ConnectFourOo {
private static final int COLUMN_COUNT = 7;
private static final int ROW_COUNT = 5;
private static final int TOP_ROW_INDEX = 0;
private static final int REQUIRED_CONSECUTIVE_FIELDS = 4;
private final Stone[][] field;
private Scanner scanner;
private Stone currentPlayer;
private Boundary boundary;
public ConnectFourOo(Boundary boundary) {
this.boundary = boundary;
scanner = new Scanner(System.in);
// Player NONE transfers to player 1 before first input
currentPlayer = Stone.NONE;
field = new Stone[boundary.upper.y][boundary.upper.x];
// initialize array so we don't have to deal with NULLs
for (Player[] row : field) {
Arrays.fill(row, Stone.NONE);
}
}
public static void main(String[] args) {
new ConnectFourOo(new Boundary(COLUMN_COUNT, ROW_COUNT)).play();
}
private void play() {
Player winner;
do {
currentPlayer = currentPlayer.next();
winner = nextMove();
} while (Stone.NONE == winner);
showGame();
System.out.println("the winner is " + winner.name());
For example, I dislike the "oddball solution" where I get the current positions stone from the field in class
ConnectFourOo (playerAt()) because the setPlayer() method is in class Position. It feels more natural to have it there since then I'd reduce the places where the meaning of x and y could be mixed up. But when I move playerAt() to class Position then I find it hard to come up with a good name for it. I'd like to get any comments or suggestions on that and of course anything else which is doubtful in this code.```
import java.util.Arrays;
import java.util.Scanner;
public class ConnectFourOo {
private static final int COLUMN_COUNT = 7;
private static final int ROW_COUNT = 5;
private static final int TOP_ROW_INDEX = 0;
private static final int REQUIRED_CONSECUTIVE_FIELDS = 4;
private final Stone[][] field;
private Scanner scanner;
private Stone currentPlayer;
private Boundary boundary;
public ConnectFourOo(Boundary boundary) {
this.boundary = boundary;
scanner = new Scanner(System.in);
// Player NONE transfers to player 1 before first input
currentPlayer = Stone.NONE;
field = new Stone[boundary.upper.y][boundary.upper.x];
// initialize array so we don't have to deal with NULLs
for (Player[] row : field) {
Arrays.fill(row, Stone.NONE);
}
}
public static void main(String[] args) {
new ConnectFourOo(new Boundary(COLUMN_COUNT, ROW_COUNT)).play();
}
private void play() {
Player winner;
do {
currentPlayer = currentPlayer.next();
winner = nextMove();
} while (Stone.NONE == winner);
showGame();
System.out.println("the winner is " + winner.name());
Solution
- Connect Four is usually played on a 7 × 6 board, not 7 × 5.
- The
ConnectFourOoclass currently does two things: managing the state of the game and interacting with the UI. These two things should be in separate classesBoardandTextUserInterface, so that you can easily write unit tests for theBoardclass.
Position.setPlayershould be in theBoardclass, since it modifies the board.
- Having 5 stones in a row also wins the game. The current code only checks for exactly 4.
Stone.NONE.next()should throw anUnsupportedOperationExceptionsince it must never be called. At the beginning of the game, it should already be initialized toPLAYER_1.
- The
playmethod must also work when the game ends in a draw.
Context
StackExchange Code Review Q#148213, answer score: 5
Revisions (0)
No revisions yet.