Changed player into a class with getters. Added Unittests for GameBase.java

This commit is contained in:
lieght
2025-09-20 18:09:39 +02:00
parent f378897769
commit 2feeb5cc71
8 changed files with 114 additions and 16 deletions

View File

@@ -5,11 +5,10 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.eventbus.*;
import org.toop.eventbus.Events;
import org.toop.eventbus.GlobalEventBus;
import org.toop.game.*;
import org.toop.game.tictactoe.*;
import org.toop.game.tictactoe.ai.MinMaxTicTacToe;
public class ConsoleGui {
@@ -147,12 +146,12 @@ public class ConsoleGui {
Player current = game.getCurrentPlayer();
int move = -1;
if (ai1 != null && current.name() == ai1 || ai2 != null && current.name() == ai2) {
if (ai1 != null && current.getName() == ai1 || ai2 != null && current.getName() == ai2) {
move = ai.findBestMove(game);
} else {
System.out.printf(
"%s's (%c) turn. Please choose an empty cell between 0-8: ",
current.name(), current.move());
current.getName(), current.getSymbol());
String input = scanner.nextLine();
try {
@@ -180,7 +179,7 @@ public class ConsoleGui {
case WIN:
{
System.out.printf("%s has won the game.\n", current.name());
System.out.printf("%s has won the game.\n", current.getName());
keepRunning = false;
break;
}
@@ -197,7 +196,7 @@ public class ConsoleGui {
new Events.ServerEvents.SendCommand(
connectionId,
"gameid " + ticTacToeGameId,
"player " + current.name(),
"player " + current.getName(),
"MOVE",
String.valueOf(move)));

View File

@@ -1,3 +0,0 @@
package org.toop.game;
public record Player(String name, char move) {}

View File

@@ -1,4 +1,4 @@
package org.toop.game;
package org.toop.game.tictactoe;
public abstract class GameBase {
public enum State {

View File

@@ -0,0 +1,21 @@
package org.toop.game.tictactoe;
public class Player {
String name;
char symbol;
Player(String name, char symbol) {
this.name = name;
this.symbol = symbol;
}
public String getName() {
return this.name;
}
public char getSymbol() {
return this.symbol;
}
}

View File

@@ -6,7 +6,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.backend.tictactoe.ParsedCommand;
import org.toop.backend.tictactoe.TicTacToeServerCommand;
import org.toop.game.*;
public class TicTacToe extends GameBase implements Runnable {
@@ -98,7 +97,7 @@ public class TicTacToe extends GameBase implements Runnable {
if (state != State.INVALID) {
// Tell all players who made a move and what move was made
// TODO: What is the reaction of the game? WIN, DRAW etc?
String player = getCurrentPlayer().name();
String player = getCurrentPlayer().getName();
addSendToQueue(
"SVR GAME MOVE {PLAYER: \""
+ player
@@ -152,7 +151,7 @@ public class TicTacToe extends GameBase implements Runnable {
return State.INVALID;
}
grid[index] = getCurrentPlayer().move();
grid[index] = getCurrentPlayer().getSymbol();
movesLeft--;
if (checkWin()) {
@@ -214,7 +213,7 @@ public class TicTacToe extends GameBase implements Runnable {
/** This method copies the board, mainly for AI use. */
public TicTacToe copyBoard() {
TicTacToe clone = new TicTacToe(players[0].name(), players[1].name());
TicTacToe clone = new TicTacToe(players[0].getName(), players[1].getName());
System.arraycopy(this.grid, 0, clone.grid, 0, this.grid.length);
clone.movesLeft = this.movesLeft;
clone.currentPlayer = this.currentPlayer;

View File

@@ -2,7 +2,7 @@ package org.toop.game.tictactoe.ai;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.game.*;
import org.toop.game.tictactoe.GameBase;
import org.toop.game.tictactoe.TicTacToe;
public class MinMaxTicTacToe {

View File

@@ -0,0 +1,82 @@
package org.toop.game.tictactoe;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class GameBaseTest {
private static class TestGame extends GameBase {
public TestGame(int size, Player p1, Player p2) {
super(size, p1, p2);
}
@Override
public State play(int index) {
if (!isInside(index)) return State.INVALID;
grid[index] = getCurrentPlayer().getSymbol();
// Just alternate players for testing
currentPlayer = (currentPlayer + 1) % 2;
return State.NORMAL;
}
}
private GameBase game;
private Player player1;
private Player player2;
@BeforeEach
void setUp() {
player1 = new Player("A", 'X');
player2 = new Player("B", 'O');
game = new TestGame(3, player1, player2);
}
@Test
void testConstructor_initializesGridAndPlayers() {
assertEquals(3, game.getSize());
assertEquals(9, game.getGrid().length);
for (char c : game.getGrid()) {
assertEquals(GameBase.EMPTY, c);
}
assertEquals(player1, game.getPlayers()[0]);
assertEquals(player2, game.getPlayers()[1]);
assertEquals(player1, game.getCurrentPlayer());
}
@Test
void testIsInside_returnsTrueForValidIndices() {
for (int i = 0; i < 9; i++) {
assertTrue(game.isInside(i));
}
}
@Test
void testIsInside_returnsFalseForInvalidIndices() {
assertFalse(game.isInside(-1));
assertFalse(game.isInside(9));
assertFalse(game.isInside(100));
}
@Test
void testPlay_alternatesPlayersAndMarksGrid() {
// First move
assertEquals(GameBase.State.NORMAL, game.play(0));
assertEquals('X', game.getGrid()[0]);
assertEquals(player2, game.getCurrentPlayer());
// Second move
assertEquals(GameBase.State.NORMAL, game.play(1));
assertEquals('O', game.getGrid()[1]);
assertEquals(player1, game.getCurrentPlayer());
}
@Test
void testPlay_invalidIndexReturnsInvalid() {
assertEquals(GameBase.State.INVALID, game.play(-1));
assertEquals(GameBase.State.INVALID, game.play(9));
}
}

View File

@@ -4,7 +4,7 @@ import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.toop.game.GameBase;
import org.toop.game.tictactoe.GameBase;
import org.toop.game.tictactoe.TicTacToe;
/** Unit tests for MinMaxTicTacToe AI. */