feat: NCS-17 Implement basic ScalaFX UI #14
@@ -1,7 +1,7 @@
|
||||
package de.nowchess.chess.engine
|
||||
|
||||
import scala.collection.mutable
|
||||
import de.nowchess.api.board.{Board, Color, File, Piece, PieceType, Rank, Square}
|
||||
import de.nowchess.api.board.{Board, Color}
|
||||
import de.nowchess.chess.logic.GameHistory
|
||||
import de.nowchess.chess.observer.*
|
||||
import org.scalatest.funsuite.AnyFunSuite
|
||||
@@ -86,28 +86,6 @@ class GameEngineLoadPgnTest extends AnyFunSuite with Matchers:
|
||||
// state is reset to initial (reset happens before replay, which fails)
|
||||
engine.history.moves shouldBe empty
|
||||
|
||||
test("loadPgn: promotion in PGN is replayed correctly"):
|
||||
val engine = new GameEngine()
|
||||
val pgn =
|
||||
"""[Event "T"]
|
||||
|
||||
1. b4 h6 2. b5 h5 3. b6 h4 4. bxa7 h3 5. a8=Q
|
||||
"""
|
||||
engine.loadPgn(pgn) shouldBe Right(())
|
||||
engine.history.moves.length shouldBe 9
|
||||
|
||||
test("loadPgn: en passant capture in PGN is replayed correctly"):
|
||||
val engine = new GameEngine()
|
||||
val pgn =
|
||||
"""[Event "T"]
|
||||
|
||||
1. e4 e6 2. e5 d5 3. exd6
|
||||
"""
|
||||
engine.loadPgn(pgn) shouldBe Right(())
|
||||
engine.history.moves.length shouldBe 5
|
||||
engine.board.pieceAt(Square(File.D, Rank.R6)) shouldBe Some(Piece(Color.White, PieceType.Pawn))
|
||||
engine.board.pieceAt(Square(File.D, Rank.R5)) shouldBe None
|
||||
|
||||
// ── undo/redo notation events ─────────────────────────────────────────────
|
||||
|
||||
test("undo emits MoveUndoneEvent with pgnNotation"):
|
||||
@@ -162,16 +140,18 @@ class GameEngineLoadPgnTest extends AnyFunSuite with Matchers:
|
||||
val engine = new GameEngine()
|
||||
val cap = new EventCapture()
|
||||
engine.subscribe(cap)
|
||||
// e4, then Black plays d5, White pawn on e4 captures on d5
|
||||
engine.processUserInput("e2e4")
|
||||
engine.processUserInput("d7d5")
|
||||
engine.processUserInput("e4d5") // white pawn captures black pawn
|
||||
// White builds a capture on the a-file: b4, ... a6, b5, ... h6, bxa6
|
||||
engine.processUserInput("b2b4")
|
||||
engine.processUserInput("a7a6")
|
||||
engine.processUserInput("b4b5")
|
||||
engine.processUserInput("h7h6")
|
||||
engine.processUserInput("b5a6") // white pawn captures black pawn
|
||||
engine.undo()
|
||||
cap.events.clear()
|
||||
engine.redo()
|
||||
val evt = cap.events.last.asInstanceOf[MoveRedoneEvent]
|
||||
evt.fromSquare shouldBe "e4"
|
||||
evt.toSquare shouldBe "d5"
|
||||
evt.fromSquare shouldBe "b5"
|
||||
evt.toSquare shouldBe "a6"
|
||||
evt.capturedPiece.isDefined shouldBe true
|
||||
|
||||
test("loadPgn: clears previous game state before loading"):
|
||||
|
||||
@@ -96,32 +96,6 @@ class PgnValidatorTest extends AnyFunSuite with Matchers:
|
||||
game.moves.last.castleSide shouldBe Some(CastleSide.Queenside)
|
||||
case Left(err) => fail(s"Expected Right but got Left($err)")
|
||||
|
||||
test("validatePgn: valid promotion is accepted"):
|
||||
val pgn =
|
||||
"""[Event "Test"]
|
||||
|
||||
1. b4 h6 2. b5 h5 3. b6 h4 4. bxa7 h3 5. a8=Q
|
||||
"""
|
||||
PgnParser.validatePgn(pgn) match
|
||||
case Right(game) =>
|
||||
game.moves.takeWhile(m => m.promotionPiece.isEmpty).length shouldBe 8
|
||||
game.moves.last.promotionPiece shouldBe Some(PromotionPiece.Queen)
|
||||
case Left(err) => fail(s"Expected Right but got Left($err)")
|
||||
|
||||
test("validatePgn: en passant capture is parsed correctly"):
|
||||
val pgn =
|
||||
"""[Event "Test"]
|
||||
|
||||
1. e4 e6 2. e5 d5 3. exd6
|
||||
"""
|
||||
PgnParser.validatePgn(pgn) match
|
||||
case Right(game) =>
|
||||
game.moves.length shouldBe 5
|
||||
val epMove = game.moves.last
|
||||
epMove.isCapture shouldBe true
|
||||
epMove.pieceType shouldBe PieceType.Pawn
|
||||
case Left(err) => fail(s"Expected Right but got Left($err)")
|
||||
|
||||
test("validatePgn: disambiguation with two rooks is accepted"):
|
||||
val pieces: Map[Square, Piece] = Map(
|
||||
Square(File.A, Rank.R1) -> Piece(Color.White, PieceType.Rook),
|
||||
|
||||
Reference in New Issue
Block a user