import model.Board; import model.IllegalGameStateException; import model.Player; import model.WinChecker; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import java.util.Random; import java.util.stream.Stream; public class WinCheckerTests { private final static Random rng = new Random(); public static Stream isGameOverTestData() { Board randomBoard = new Board(); Player currentBox; for (int i = 1; i <= 3; ++i) for (int j = 1; j <= 3; ++j) { int rand = rng.nextInt(3); Player p = switch (rand){ case 1 -> Player.X; case 2 -> Player.O; default -> null; }; randomBoard.setBox(i, j, p); } boolean expected = false; currentBox = randomBoard.getBox(1, 1); if(currentBox != null){ if (currentBox == randomBoard.getBox(1, 2) && currentBox == randomBoard.getBox(1, 3)) expected = true; if (currentBox == randomBoard.getBox(2, 2) && currentBox == randomBoard.getBox(3, 3)) expected = true; if (currentBox == randomBoard.getBox(2, 1) && currentBox == randomBoard.getBox(3, 1)) expected = true; } currentBox = randomBoard.getBox(2, 1); if(currentBox != null && currentBox == randomBoard.getBox(2, 2) && currentBox == randomBoard.getBox(2, 3)){ expected = true; } currentBox = randomBoard.getBox(3, 1); if(currentBox != null){ if (currentBox == randomBoard.getBox(1, 3) && currentBox == randomBoard.getBox(2, 2)) { expected = true; } if (currentBox == randomBoard.getBox(3, 2) && currentBox == randomBoard.getBox(3, 3)) { expected = true; } } currentBox = randomBoard.getBox(1, 2); if(currentBox != null && currentBox == randomBoard.getBox(2, 2) && currentBox == randomBoard.getBox(3, 2)){ expected = true; } currentBox = randomBoard.getBox(1, 3); if(currentBox != null && currentBox == randomBoard.getBox(2, 3) && currentBox == randomBoard.getBox(3, 3)){ expected = true; } return Stream.of( Arguments.of(new Board(), false), Arguments.of(topRowXWins(), true), Arguments.of(midRowOWins(), true), Arguments.of(bottomRow(), true), Arguments.of(leftColumn(), true), Arguments.of(midColumn(), true), Arguments.of(rightColumn(), true), Arguments.of(diagUp(), true), Arguments.of(diagDown(), true), Arguments.of(stalemate(), true), Arguments.of(randomBoard, expected) ); } private static Board stalemate() { Board b = new Board(); b.setBox(1, 1, Player.X); b.setBox(1, 2, Player.O); b.setBox(1, 3, Player.X); b.setBox(2, 1, Player.O); b.setBox(2, 2, Player.O); b.setBox(2, 3, Player.X); b.setBox(3, 1, Player.X); b.setBox(3, 2, Player.X); b.setBox(3, 3, Player.O); return b; } private static Board diagDown() { Board b = new Board(); b.setBox(3, 1, Player.O); b.setBox(2, 2, Player.O); b.setBox(1, 3, Player.O); return b; } private static Board diagUp() { Board b = new Board(); b.setBox(1, 1, Player.O); b.setBox(2, 2, Player.O); b.setBox(3, 3, Player.O); return b; } private static Board rightColumn() { Board b = new Board(); b.setBox(3, 1, Player.X); b.setBox(3, 2, Player.X); b.setBox(3, 3, Player.X); return b; } private static Board midColumn() { Board b = new Board(); b.setBox(2, 1, Player.O); b.setBox(2, 2, Player.O); b.setBox(2, 3, Player.O); return b; } private static Board leftColumn() { Board b = new Board(); b.setBox(1, 1, Player.O); b.setBox(1, 2, Player.O); b.setBox(1, 3, Player.O); return b; } private static Board bottomRow() { Board b = new Board(); b.setBox(1, 3, Player.X); b.setBox(2, 3, Player.X); b.setBox(3, 3, Player.X); return b; } private static Board midRowOWins() { Board b = new Board(); b.setBox(1, 2, Player.O); b.setBox(2, 2, Player.O); b.setBox(3, 2, Player.O); return b; } private static Board topRowXWins() { Board b = new Board(); b.setBox(1, 1, Player.X); b.setBox(2, 1, Player.X); b.setBox(3, 1, Player.X); return b; } public static Stream getWinnerTestNormalData() { return Stream.of( Arguments.of(new Board(), null), Arguments.of(stalemate(), null), Arguments.of(topRowXWins(), Player.X), Arguments.of(midRowOWins(), Player.O) ); } @ParameterizedTest @MethodSource("isGameOverTestData") public void isGameOverTest(Object[] args){ Board b = (Board) args[0]; boolean expected = (boolean) args[1]; boolean actual = new WinChecker().isGameOver(b); Assertions.assertEquals(expected, actual); } @ParameterizedTest @MethodSource("getWinnerTestNormalData") public void getWinnerTestNormal(Object[] args){ Board b = (Board) args[0]; Player expected = (Player) args[1]; Player actual = new WinChecker().getWinner(b); Assertions.assertEquals(expected, actual); } @Test public void getWinnerTestThrows(){ Board b = new Board(); b.setBox(1, 1, Player.X); b.setBox(1, 2, Player.X); b.setBox(1, 3, Player.X); b.setBox(2, 1, Player.O); b.setBox(2, 2, Player.O); b.setBox(2, 3, Player.O); Assertions.assertThrows(IllegalGameStateException.class, () -> new WinChecker().getWinner(b)); } @Test public void getWinnerTestRandom(){ Player currentBox; Board b = new Board(); Player expected = null; boolean shouldThrow = false; for (int i = 1; i <= 3; ++i) for (int j = 1; j <= 3; ++j) { int rand = rng.nextInt(3); Player p = switch (rand){ case 1 -> Player.X; case 2 -> Player.O; default -> null; }; b.setBox(i, j, p); } currentBox = b.getBox(1, 1); if(currentBox != null){ if (currentBox == b.getBox(1, 2) && currentBox == b.getBox(1, 3)) expected = currentBox; if (currentBox == b.getBox(2, 2) && currentBox == b.getBox(3, 3)) expected = currentBox; if (currentBox == b.getBox(2, 1) && currentBox == b.getBox(3, 1)) expected = currentBox; } currentBox = b.getBox(2, 1); if(currentBox != null && currentBox == b.getBox(2, 2) && currentBox == b.getBox(2, 3)){ if (expected == null) expected = currentBox; else if (expected != currentBox) shouldThrow = true; } currentBox = b.getBox(3, 1); if(currentBox != null && !shouldThrow){ if (currentBox == b.getBox(1, 3) && currentBox == b.getBox(2, 2)) { if (expected == null) expected = currentBox; else if (expected != currentBox) shouldThrow = true; } if (currentBox == b.getBox(3, 2) && currentBox == b.getBox(3, 3)) { if (expected == null) expected = currentBox; else if (expected != currentBox) shouldThrow = true; } } currentBox = b.getBox(1, 2); if(!shouldThrow && currentBox != null && currentBox == b.getBox(2, 2) && currentBox == b.getBox(3, 2)){ if (expected == null) expected = currentBox; else if (expected != currentBox) shouldThrow = true; } currentBox = b.getBox(1, 3); if(!shouldThrow && currentBox != null && currentBox == b.getBox(2, 3) && currentBox == b.getBox(3, 3)){ if (expected == null) expected = currentBox; else if (expected != currentBox) shouldThrow = true; } if (shouldThrow) Assertions.assertThrows(IllegalGameStateException.class, () -> new WinChecker().getWinner(b)); else Assertions.assertEquals(expected, new WinChecker().getWinner(b)); } }