refactor: improve code readability by adjusting formatting and synchronization in GameEngine and tests

This commit is contained in:
2026-04-20 22:24:52 +02:00
committed by Janis
parent c567aacf56
commit 5fafd94ea8
4 changed files with 31 additions and 32 deletions
@@ -38,9 +38,9 @@ class GameEngine(
private implicit val ec: ExecutionContext = ExecutionContext.global
// Synchronized accessors for current state
def board: Board = synchronized(currentContext.board)
def turn: Color = synchronized(currentContext.turn)
def context: GameContext = synchronized(currentContext)
def board: Board = synchronized(currentContext.board)
def turn: Color = synchronized(currentContext.turn)
def context: GameContext = synchronized(currentContext)
def pendingDrawOfferBy: Option[Color] = synchronized(pendingDrawOffer)
/** Check if undo is available. */
@@ -194,8 +194,7 @@ class GameEngine(
currentContext = currentContext.withResult(Some(GameResult.Draw(DrawReason.ThreefoldRepetition)))
invoker.clear()
notifyObservers(DrawEvent(currentContext, DrawReason.ThreefoldRepetition))
else
notifyObservers(InvalidMoveEvent(currentContext, InvalidMoveReason.DrawCannotBeClaimed))
else notifyObservers(InvalidMoveEvent(currentContext, InvalidMoveReason.DrawCannotBeClaimed))
}
/** Load a game using the provided importer. If the imported context has moves, they are replayed through the command
@@ -250,7 +250,7 @@ class GameEngineDrawOfferTest extends AnyFunSuite with Matchers:
engine.pendingDrawOfferBy shouldBe None
test("applyDraw sets draw result when game not over"):
val engine = new GameEngine()
val engine = new GameEngine()
val observer = new DrawOfferMockObserver()
engine.subscribe(observer)
engine.applyDraw(DrawReason.Agreement)
@@ -263,7 +263,7 @@ class GameEngineDrawOfferTest extends AnyFunSuite with Matchers:
fail(s"Expected DrawEvent, but got $other")
test("applyDraw does nothing when game already over"):
val engine = new GameEngine()
val engine = new GameEngine()
val observer = new DrawOfferMockObserver()
engine.subscribe(observer)
// End the game with checkmate
@@ -276,7 +276,7 @@ class GameEngineDrawOfferTest extends AnyFunSuite with Matchers:
observer.events should have length 0
test("claimDraw with fifty-move rule when at half-move 100"):
val engine = new GameEngine()
val engine = new GameEngine()
val observer = new DrawOfferMockObserver()
engine.subscribe(observer)
// Play moves to reach fifty-move rule claim
@@ -288,7 +288,7 @@ class GameEngineDrawOfferTest extends AnyFunSuite with Matchers:
// This is hard to do naturally; skip for now if not critical
test("claimDraw when game already over"):
val engine = new GameEngine()
val engine = new GameEngine()
val observer = new DrawOfferMockObserver()
engine.subscribe(observer)
// End the game with checkmate
@@ -4,7 +4,7 @@ import de.nowchess.api.player.{PlayerId, PlayerInfo}
import de.nowchess.chess.engine.GameEngine
import io.quarkus.test.junit.QuarkusTest
import jakarta.inject.Inject
import org.junit.jupiter.api.{Test, DisplayName}
import org.junit.jupiter.api.{DisplayName, Test}
import org.junit.jupiter.api.Assertions.*
import scala.compiletime.uninitialized
@@ -4,7 +4,7 @@ import de.nowchess.api.dto.*
import de.nowchess.chess.exception.BadRequestException
import io.quarkus.test.junit.QuarkusTest
import jakarta.inject.Inject
import org.junit.jupiter.api.{Test, DisplayName}
import org.junit.jupiter.api.{DisplayName, Test}
import org.junit.jupiter.api.Assertions.*
import scala.compiletime.uninitialized
@@ -20,7 +20,7 @@ class GameResourceIntegrationTest:
@Test
@DisplayName("createGame returns 201")
def testCreateGame(): Unit =
val req = CreateGameRequestDto(None, None)
val req = CreateGameRequestDto(None, None)
val resp = resource.createGame(req)
assertEquals(201, resp.getStatus)
val dto = resp.getEntity.asInstanceOf[GameFullDto]
@@ -30,8 +30,8 @@ class GameResourceIntegrationTest:
@DisplayName("getGame returns 200")
def testGetGame(): Unit =
val createResp = resource.createGame(CreateGameRequestDto(None, None))
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val getResp = resource.getGame(gameId)
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val getResp = resource.getGame(gameId)
assertEquals(200, getResp.getStatus)
val dto = getResp.getEntity.asInstanceOf[GameFullDto]
assertEquals(gameId, dto.gameId)
@@ -40,8 +40,8 @@ class GameResourceIntegrationTest:
@DisplayName("makeMove advances game")
def testMakeMove(): Unit =
val createResp = resource.createGame(CreateGameRequestDto(None, None))
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val moveResp = resource.makeMove(gameId, "e2e4")
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val moveResp = resource.makeMove(gameId, "e2e4")
assertEquals(200, moveResp.getStatus)
val state = moveResp.getEntity.asInstanceOf[GameStateDto]
assertEquals("black", state.turn)
@@ -50,15 +50,15 @@ class GameResourceIntegrationTest:
@DisplayName("makeMove with invalid UCI throws")
def testMakeMoveInvalid(): Unit =
val createResp = resource.createGame(CreateGameRequestDto(None, None))
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
assertThrows(classOf[BadRequestException], () => resource.makeMove(gameId, "invalid"))
@Test
@DisplayName("getLegalMoves returns moves")
def testGetLegalMoves(): Unit =
val createResp = resource.createGame(CreateGameRequestDto(None, None))
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val movesResp = resource.getLegalMoves(gameId, "")
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val movesResp = resource.getLegalMoves(gameId, "")
assertEquals(200, movesResp.getStatus)
val dto = movesResp.getEntity.asInstanceOf[LegalMovesResponseDto]
assertFalse(dto.moves.isEmpty)
@@ -67,18 +67,18 @@ class GameResourceIntegrationTest:
@DisplayName("resignGame updates state")
def testResignGame(): Unit =
val createResp = resource.createGame(CreateGameRequestDto(None, None))
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val resignResp = resource.resignGame(gameId)
assertEquals(200, resignResp.getStatus)
val getResp = resource.getGame(gameId)
val state = getResp.getEntity.asInstanceOf[GameFullDto].state
val state = getResp.getEntity.asInstanceOf[GameFullDto].state
assertEquals("resign", state.status)
@Test
@DisplayName("undoMove reverts")
def testUndoMove(): Unit =
val createResp = resource.createGame(CreateGameRequestDto(None, None))
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
resource.makeMove(gameId, "e2e4")
val undoResp = resource.undoMove(gameId)
assertEquals(200, undoResp.getStatus)
@@ -89,7 +89,7 @@ class GameResourceIntegrationTest:
@DisplayName("redoMove restores")
def testRedoMove(): Unit =
val createResp = resource.createGame(CreateGameRequestDto(None, None))
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
resource.makeMove(gameId, "e2e4")
resource.undoMove(gameId)
val redoResp = resource.redoMove(gameId)
@@ -101,15 +101,15 @@ class GameResourceIntegrationTest:
@DisplayName("drawAction offer")
def testDrawActionOffer(): Unit =
val createResp = resource.createGame(CreateGameRequestDto(None, None))
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val resp = resource.drawAction(gameId, "offer")
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val resp = resource.drawAction(gameId, "offer")
assertEquals(200, resp.getStatus)
@Test
@DisplayName("drawAction accept")
def testDrawActionAccept(): Unit =
val createResp = resource.createGame(CreateGameRequestDto(None, None))
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
resource.drawAction(gameId, "offer")
val resp = resource.drawAction(gameId, "accept")
assertEquals(200, resp.getStatus)
@@ -117,8 +117,8 @@ class GameResourceIntegrationTest:
@Test
@DisplayName("importFen creates game")
def testImportFen(): Unit =
val fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
val req = ImportFenRequestDto(fen, None, None)
val fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
val req = ImportFenRequestDto(fen, None, None)
val resp = resource.importFen(req)
assertEquals(201, resp.getStatus)
val dto = resp.getEntity.asInstanceOf[GameFullDto]
@@ -127,7 +127,7 @@ class GameResourceIntegrationTest:
@Test
@DisplayName("importPgn creates game")
def testImportPgn(): Unit =
val req = ImportPgnRequestDto("1. e4 c5")
val req = ImportPgnRequestDto("1. e4 c5")
val resp = resource.importPgn(req)
assertEquals(201, resp.getStatus)
val dto = resp.getEntity.asInstanceOf[GameFullDto]
@@ -137,8 +137,8 @@ class GameResourceIntegrationTest:
@DisplayName("exportFen returns FEN")
def testExportFen(): Unit =
val createResp = resource.createGame(CreateGameRequestDto(None, None))
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val resp = resource.exportFen(gameId)
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val resp = resource.exportFen(gameId)
assertEquals(200, resp.getStatus)
assertTrue(resp.getEntity.asInstanceOf[String].contains("rnbqkbnr"))
@@ -146,7 +146,7 @@ class GameResourceIntegrationTest:
@DisplayName("exportPgn returns PGN")
def testExportPgn(): Unit =
val createResp = resource.createGame(CreateGameRequestDto(None, None))
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
val gameId = createResp.getEntity.asInstanceOf[GameFullDto].gameId
resource.makeMove(gameId, "e2e4")
val resp = resource.exportPgn(gameId)
assertEquals(200, resp.getStatus)