From 5fafd94ea883998c2d944bd29a452c7564a1e79f Mon Sep 17 00:00:00 2001 From: Janis Date: Mon, 20 Apr 2026 22:24:52 +0200 Subject: [PATCH] refactor: improve code readability by adjusting formatting and synchronization in GameEngine and tests --- .../de/nowchess/chess/engine/GameEngine.scala | 9 ++-- .../engine/GameEngineDrawOfferTest.scala | 8 ++-- .../chess/registry/GameRegistryImplTest.scala | 2 +- .../GameResourceIntegrationTest.scala | 44 +++++++++---------- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala b/modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala index f7e20f4..43f099b 100644 --- a/modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala +++ b/modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala @@ -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 diff --git a/modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineDrawOfferTest.scala b/modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineDrawOfferTest.scala index be12ffd..03b39a6 100644 --- a/modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineDrawOfferTest.scala +++ b/modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineDrawOfferTest.scala @@ -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 diff --git a/modules/core/src/test/scala/de/nowchess/chess/registry/GameRegistryImplTest.scala b/modules/core/src/test/scala/de/nowchess/chess/registry/GameRegistryImplTest.scala index 97d02ba..6bea0c0 100644 --- a/modules/core/src/test/scala/de/nowchess/chess/registry/GameRegistryImplTest.scala +++ b/modules/core/src/test/scala/de/nowchess/chess/registry/GameRegistryImplTest.scala @@ -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 diff --git a/modules/core/src/test/scala/de/nowchess/chess/resource/GameResourceIntegrationTest.scala b/modules/core/src/test/scala/de/nowchess/chess/resource/GameResourceIntegrationTest.scala index aca8bb2..bf165cc 100644 --- a/modules/core/src/test/scala/de/nowchess/chess/resource/GameResourceIntegrationTest.scala +++ b/modules/core/src/test/scala/de/nowchess/chess/resource/GameResourceIntegrationTest.scala @@ -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)