Browse Source

tictactoe: refactored and formatted whole code

tictactoe
Malte Schellhardt 3 years ago
committed by Lorenz Hohmann
parent
commit
c556fe867d
  1. 43
      src/main/java/de/tims/tictactoe/GameLogic.java
  2. 193
      src/test/java/de/tims/tictactoe/GameLogicTest.java

43
src/main/java/de/tims/tictactoe/GameLogic.java

@ -10,12 +10,14 @@ import javax.swing.JPanel;
public class GameLogic implements ActionListener { public class GameLogic implements ActionListener {
private static final char EMPTY_FIELD = '-';
private static final char PLAYER_1 = 'x'; private static final char PLAYER_1 = 'x';
private static final char PLAYER_2 = 'o'; private static final char PLAYER_2 = 'o';
private char[][] board; private char[][] board;
private final char[] occupiedFields = { PLAYER_1, PLAYER_2 }; private final char[] occupiedFields = { PLAYER_1, PLAYER_2 };
private char currentPlayer = PLAYER_1; private char currentPlayer = PLAYER_1;
private boolean gui = false;
private JButton[][] fields; private JButton[][] fields;
private JPanel contentPanel; private JPanel contentPanel;
@ -24,12 +26,7 @@ public class GameLogic implements ActionListener {
size = 3; size = 3;
} }
this.board = new char[size][size]; this.board = new char[size][size];
for (int i = 0; i < this.board.length; i++) {
for (int j = 0; j < this.board[0].length; j++) {
this.setField(i, j, '-');
}
}
this.resetBoard();
} }
public GameLogic(char[][] board) { public GameLogic(char[][] board) {
@ -45,8 +42,13 @@ public class GameLogic implements ActionListener {
} }
public void setField(int column, int row, char player) { public void setField(int column, int row, char player) {
if (fieldIsEmpty(column, row))
if (this.fieldIsEmpty(column, row)) {
this.board[column][row] = player; this.board[column][row] = player;
if (gui) {
this.fields[column][row].setText("" + this.getCurrentPlayer());
this.updateGUI();
}
}
} }
public boolean fieldIsEmpty(int column, int row) { public boolean fieldIsEmpty(int column, int row) {
@ -103,13 +105,13 @@ public class GameLogic implements ActionListener {
} }
public boolean checkEndOfGame() { public boolean checkEndOfGame() {
return checkForWin(PLAYER_1) || checkForWin(PLAYER_2);
return this.checkForWin(PLAYER_1) || this.checkForWin(PLAYER_2);
} }
public char getCurrentPlayer() { public char getCurrentPlayer() {
return this.currentPlayer; return this.currentPlayer;
} }
public void switchPlayer() { public void switchPlayer() {
this.currentPlayer = this.currentPlayer == PLAYER_1 ? PLAYER_2 : PLAYER_1; this.currentPlayer = this.currentPlayer == PLAYER_1 ? PLAYER_2 : PLAYER_1;
} }
@ -117,7 +119,7 @@ public class GameLogic implements ActionListener {
public void resetBoard() { public void resetBoard() {
for (int i = 0; i < this.board.length; i++) { for (int i = 0; i < this.board.length; i++) {
for (int j = 0; j < this.board.length; j++) { for (int j = 0; j < this.board.length; j++) {
this.board[i][j] = '-';
this.board[i][j] = EMPTY_FIELD;
} }
} }
} }
@ -126,7 +128,7 @@ public class GameLogic implements ActionListener {
this.fields = new JButton[this.board.length][this.board.length]; this.fields = new JButton[this.board.length][this.board.length];
this.contentPanel = new JPanel(); this.contentPanel = new JPanel();
this.contentPanel.setLayout(new GridLayout(this.board.length, this.board.length)); this.contentPanel.setLayout(new GridLayout(this.board.length, this.board.length));
for (int i = 0; i < this.fields.length; i++) { for (int i = 0; i < this.fields.length; i++) {
for (int j = 0; j < this.fields.length; j++) { for (int j = 0; j < this.fields.length; j++) {
this.fields[i][j] = new JButton(); this.fields[i][j] = new JButton();
@ -134,21 +136,22 @@ public class GameLogic implements ActionListener {
this.contentPanel.add(this.fields[i][j]); this.contentPanel.add(this.fields[i][j]);
} }
} }
this.gui = true;
return this.contentPanel; return this.contentPanel;
} }
public JButton getGUIField(int column, int row) { public JButton getGUIField(int column, int row) {
return this.fields[column][row]; return this.fields[column][row];
} }
private void updateGUI() {
private void updateGUI() {
if (this.checkEndOfGame()) { if (this.checkEndOfGame()) {
for (int i = 0; i < this.fields.length; i++) { for (int i = 0; i < this.fields.length; i++) {
for (int j = 0; j < this.fields.length; j++) { for (int j = 0; j < this.fields.length; j++) {
this.fields[i][j].setEnabled(false); this.fields[i][j].setEnabled(false);
} }
} }
JOptionPane.showMessageDialog(contentPanel, "Spieler " + this.currentPlayer + " hat gewonnen.");
JOptionPane.showMessageDialog(contentPanel, "Spieler " + this.currentPlayer + " hat gewonnen.");
this.resetGUI(); this.resetGUI();
} }
this.switchPlayer(); this.switchPlayer();
@ -169,14 +172,12 @@ public class GameLogic implements ActionListener {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
for (int i = 0; i < this.fields.length; i++) { for (int i = 0; i < this.fields.length; i++) {
for (int j = 0; j < this.fields[0].length; j++) { for (int j = 0; j < this.fields[0].length; j++) {
if (e.getSource() == this.fields[i][j]) {
if (e.getSource() == this.fields[i][j]) {
this.setField(i, j, currentPlayer); this.setField(i, j, currentPlayer);
this.fields[i][j].setText("" + this.getCurrentPlayer());
updateGUI();
this.fields[i][j].getText();
} }
} }
} }
} }
}
}

193
src/test/java/de/tims/tictactoe/GameLogicTest.java

@ -7,7 +7,6 @@ import java.awt.Component;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel; import javax.swing.JPanel;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
@ -23,7 +22,7 @@ class GameLogicTest {
private final int SIZE = 3; private final int SIZE = 3;
private GameLogic game; private GameLogic game;
@BeforeAll @BeforeAll
void setUpBeforeClass() throws Exception { void setUpBeforeClass() throws Exception {
this.game = new GameLogic(SIZE); this.game = new GameLogic(SIZE);
@ -33,153 +32,160 @@ class GameLogicTest {
void createGameLogicTest() { void createGameLogicTest() {
GameLogic expectedResult = this.game; GameLogic expectedResult = this.game;
GameLogic realResult = new GameLogic(SIZE); GameLogic realResult = new GameLogic(SIZE);
assertEquals(expectedResult.getClass(), realResult.getClass()); assertEquals(expectedResult.getClass(), realResult.getClass());
} }
@Test @Test
void getBoardTest() { void getBoardTest() {
// @formatter:off
char[][] expectedResult = new char[][]{{'-', '-', '-'}, char[][] expectedResult = new char[][]{{'-', '-', '-'},
{'-', '-', '-'}, {'-', '-', '-'},
{'-', '-', '-'}}; {'-', '-', '-'}};
// @formatter:on
char[][] realResult = this.game.getBoard(); char[][] realResult = this.game.getBoard();
assertArrayEquals(expectedResult, realResult); assertArrayEquals(expectedResult, realResult);
} }
@Test @Test
void createGameLogicWithGivenBoardTest() { void createGameLogicWithGivenBoardTest() {
// @formatter:off
char[][] expectedResult = new char[][]{{'x', '-', '-'}, char[][] expectedResult = new char[][]{{'x', '-', '-'},
{'-', 'o', '-'}, {'-', 'o', '-'},
{'x', '-', '-'}}; {'x', '-', '-'}};
// @formatter:on
char[][] givenBoard = expectedResult; char[][] givenBoard = expectedResult;
char[][] realResult = new GameLogic(givenBoard).getBoard(); char[][] realResult = new GameLogic(givenBoard).getBoard();
assertArrayEquals(expectedResult, realResult); assertArrayEquals(expectedResult, realResult);
} }
@Test @Test
void generateGUITest() { void generateGUITest() {
JPanel expectedResult = new JPanel(); JPanel expectedResult = new JPanel();
JPanel realResult = game.generateGUI();
JPanel realResult = this.game.generateGUI();
assertEquals(expectedResult.getClass(), realResult.getClass()); assertEquals(expectedResult.getClass(), realResult.getClass());
} }
@Test @Test
void numberOfGUIFieldsTest() { void numberOfGUIFieldsTest() {
int realResult = 0;
int expectedResult = (int) Math.pow(SIZE, 2); int expectedResult = (int) Math.pow(SIZE, 2);
JPanel gui = game.generateGUI();
int realResult = 0;
JPanel gui = this.game.generateGUI();
Component[] components = gui.getComponents(); Component[] components = gui.getComponents();
for (Component component : components) { for (Component component : components) {
if (component instanceof JButton) realResult++;
if (component instanceof JButton)
realResult++;
} }
assertEquals(expectedResult, realResult); assertEquals(expectedResult, realResult);
} }
@Test @Test
void getCurrentPlayerTest() { void getCurrentPlayerTest() {
GameLogic game = new GameLogic(SIZE); GameLogic game = new GameLogic(SIZE);
char expectedResult = game.getCurrentPlayer();
char realResult = 'x';
char expectedResult = 'x';
char realResult = game.getCurrentPlayer();
assertEquals(expectedResult, realResult); assertEquals(expectedResult, realResult);
} }
@Test @Test
void switchPlayerTest() { void switchPlayerTest() {
GameLogic game = new GameLogic(SIZE); GameLogic game = new GameLogic(SIZE);
game.switchPlayer(); game.switchPlayer();
char expectedResult = game.getCurrentPlayer();
char realResult = 'o';
char expectedResult = 'o';
char realResult = game.getCurrentPlayer();
assertEquals(expectedResult, realResult); assertEquals(expectedResult, realResult);
} }
@Test @Test
void resetBoardTest() { void resetBoardTest() {
GameLogic game = new GameLogic(SIZE); GameLogic game = new GameLogic(SIZE);
game.setField(1, 2, 'x'); game.setField(1, 2, 'x');
// @formatter:off
char[][] expectedResult = new char[][]{{'-', '-', '-'}, char[][] expectedResult = new char[][]{{'-', '-', '-'},
{'-', '-', '-'}, {'-', '-', '-'},
{'-', '-', '-'}};;
{'-', '-', '-'}};
// @formatter:on
game.resetBoard(); game.resetBoard();
char[][] realResult = game.getBoard(); char[][] realResult = game.getBoard();
assertArrayEquals(expectedResult, realResult); assertArrayEquals(expectedResult, realResult);
} }
@ParameterizedTest(name = "[{index}] {0} -> {2} fields")
@MethodSource("testCasesForCountPlayfields")
void fieldCountTest(String testName, int size, int expectedResult) {
GameLogic game = new GameLogic(size);
int realResult = game.countFields();
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}")
@MethodSource("testCasesForSetField")
void setFieldTest(String testName, int column, int row, char player, char[][] expectedResult) {
this.game.setField(column, row, player);
char[][] realResult = this.game.getBoard();
assertArrayEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}")
@MethodSource("testCasesForCheckEmptyField")
void fieldIsEmptyTest(String testName, int columnToCheck, int rowToCheck, boolean expectedResult, char[][] board) {
GameLogic game = new GameLogic(board);
boolean realResult = game.fieldIsEmpty(columnToCheck, rowToCheck);
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}: should be {2}")
@MethodSource("testCasesForCheckForWin")
void checkForWinTest(String testName, char player, boolean expectedResult, char[][] boardToCheck) {
boolean realResult = new GameLogic(boardToCheck).checkForWin(player);
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}: should be {1}")
@MethodSource("testCasesForCheckEndOfGame")
void checkEndOfGameTest(String testName, boolean expectedResult, char[][] boardToCheck) {
boolean realResult = new GameLogic(boardToCheck).checkEndOfGame();
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}: should be {1}")
@MethodSource("testCasesForCheckButtonState")
void buttonStateTest(String testName, boolean expectedResult, boolean doClick, int column, int row) {
game.generateGUI();
JButton currentField = game.getGUIField(column, row);
if (doClick) currentField.doClick();
boolean realResult = !currentField.getText().isEmpty();
assertEquals(expectedResult, realResult);
}
private static Stream<Arguments> testCasesForCountPlayfields() {
return Stream.of(
Arguments.of("1x1 board with too few fields", 1, 9),
Arguments.of("2x2 board with too few fields", 2, 9),
Arguments.of("3x3 board with 9 playfields", 3, 9),
Arguments.of("4x4 board with 16 playfields", 4, 16),
Arguments.of("5x5 board with 25 playfields", 5,25)
);
}
@ParameterizedTest(name = "[{index}] {0} -> {2} fields")
@MethodSource("testCasesForCountPlayfields")
void fieldCountTest(String testName, int size, int expectedResult) {
GameLogic game = new GameLogic(size);
int realResult = game.countFields();
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}")
@MethodSource("testCasesForSetField")
void setFieldTest(String testName, int column, int row, char player, char[][] expectedResult) {
this.game.setField(column, row, player);
char[][] realResult = this.game.getBoard();
assertArrayEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}")
@MethodSource("testCasesForCheckEmptyField")
void fieldIsEmptyTest(String testName, int columnToCheck, int rowToCheck, boolean expectedResult, char[][] board) {
GameLogic game = new GameLogic(board);
boolean realResult = game.fieldIsEmpty(columnToCheck, rowToCheck);
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}: should be {2}")
@MethodSource("testCasesForCheckForWin")
void checkForWinTest(String testName, char player, boolean expectedResult, char[][] boardToCheck) {
boolean realResult = new GameLogic(boardToCheck).checkForWin(player);
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}: should be {1}")
@MethodSource("testCasesForCheckEndOfGame")
void checkEndOfGameTest(String testName, boolean expectedResult, char[][] boardToCheck) {
boolean realResult = new GameLogic(boardToCheck).checkEndOfGame();
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}: should be {1}")
@MethodSource("testCasesForCheckButtonState")
void buttonStateTest(String testName, boolean expectedResult, boolean doClick, int column, int row) throws InterruptedException {
GameLogic game = new GameLogic(SIZE);
game.generateGUI();
JButton currentField = game.getGUIField(0, 0);
if (doClick)
currentField.doClick();
boolean realResult = !currentField.getText().isEmpty();
assertEquals(expectedResult, realResult);
}
// @formatter:off
private static Stream<Arguments> testCasesForCountPlayfields() {
return Stream.of(Arguments.of("1x1 board with too few fields", 1, 9),
Arguments.of("2x2 board with too few fields", 2, 9),
Arguments.of("3x3 board with 9 playfields", 3, 9),
Arguments.of("4x4 board with 16 playfields", 4, 16),
Arguments.of("5x5 board with 25 playfields", 5, 25));
}
private static Stream<Arguments> testCasesForSetField() { private static Stream<Arguments> testCasesForSetField() {
return Stream.of( return Stream.of(
Arguments.of("set field [0][0] for player 1", 0, 0, 'x', new char[][] Arguments.of("set field [0][0] for player 1", 0, 0, 'x', new char[][]
@ -326,5 +332,6 @@ class GameLogicTest {
Arguments.of("dont't trigger gui field [1][1]", false, false, 1, 1) Arguments.of("dont't trigger gui field [1][1]", false, false, 1, 1)
); );
} }
// @formatter:on
} }
Loading…
Cancel
Save