This is the implementation for the second requirement.
Players introduce discs on the top of the columns. An introduced disc drops down the board if the column is empty. Future discs introduced in the same column will stack over the previous ones.
We can split this requirement into the following tests:
- When a disc is inserted into an empty column, its position is 0
- When a second disc is inserted into the same column, its position is 1
- When a disc is inserted into the board, the total number of discs increases
- When a disc is put outside the boundaries, a Runtime Exception is thrown
- When a disc is inserted into a column and there's no room available for it, then a Runtime Exception is thrown
Also, these other tests are derived from the first requirement. They are related to the board limits or board behavior.
The Java implementation of the aforementioned tests is as follows:
@Test public void whenDiscOutsideBoardThenRuntimeException() { int column = -1; exception.expect(RuntimeException.class); exception.expectMessage("Invalid column " + column); tested.putDiscInColumn(column); } @Test public void whenFirstDiscInsertedInColumnThenPositionIsZero() { int column = 1; assertThat(tested.putDiscInColumn(column), is(0)); } @Test public void whenSecondDiscInsertedInColumnThenPositionIsOne() { int column = 1; tested.putDiscInColumn(column); assertThat(tested.putDiscInColumn(column), is(1)); } @Test public void whenDiscInsertedThenNumberOfDiscsIncreases() { int column = 1; tested.putDiscInColumn(column); assertThat(tested.getNumberOfDiscs(), is(1)); } @Test public void whenNoMoreRoomInColumnThenRuntimeException() { int column = 1; int maxDiscsInColumn = 6; // the number of rows for (int times = 0; times < maxDiscsInColumn; ++times) { tested.putDiscInColumn(column); } exception.expect(RuntimeException.class); exception.expectMessage("No more room in column " + column); tested.putDiscInColumn(column); }
This is the necessary code to satisfy the tests:
private static final int ROWS = 6; private static final int COLUMNS = 7; private static final String EMPTY = " "; private String[][] board = new String[ROWS][COLUMNS]; public Connect4TDD() { for (String[] row : board) Arrays.fill(row, EMPTY); } public int getNumberOfDiscs() { return IntStream
.range(0, COLUMNS)
.map(this::getNumberOfDiscsInColumn)
.sum(); } private int getNumberOfDiscsInColumn(int column) { return (int) IntStream
.range(0, ROWS) .filter(row -> !EMPTY.equals(board[row][column])) .count(); } public int putDiscInColumn(int column) { checkColumn(column); int row = getNumberOfDiscsInColumn(column); checkPositionToInsert(row, column); board[row][column] = "X"; return row; } private void checkColumn(int column) { if (column < 0 || column >= COLUMNS) throw new RuntimeException("Invalid column " + column); } private void checkPositionToInsert(int row, int column) { if (row == ROWS) throw new RuntimeException("No more room in column " + column); }