feat: Implement threefold repetition detection and update game rules
Build & Test (NowChessSystems) TeamCity build failed

This commit is contained in:
2026-04-16 21:00:32 +02:00
parent 5aa1691b32
commit f8d2858d98
21 changed files with 137 additions and 21633 deletions
@@ -1,7 +1,8 @@
package de.nowchess.ui.terminal
import java.util.concurrent.atomic.AtomicBoolean
import scala.io.StdIn
import de.nowchess.api.move.PromotionPiece
import de.nowchess.api.game.DrawReason
import de.nowchess.chess.engine.GameEngine
import de.nowchess.chess.observer.*
import de.nowchess.ui.utils.Renderer
@@ -10,8 +11,7 @@ import de.nowchess.ui.utils.Renderer
* I/O and user interaction in the terminal.
*/
class TerminalUI(engine: GameEngine) extends Observer:
private val running = new AtomicBoolean(true)
private val awaitingPromotion = new AtomicBoolean(false)
private val running = new AtomicBoolean(true)
/** Called by GameEngine whenever a game event occurs. */
override def onGameEvent(event: GameEvent): Unit =
@@ -63,9 +63,6 @@ class TerminalUI(engine: GameEngine) extends Observer:
print(Renderer.render(e.context.board))
printPrompt(e.context.turn)
case _: PromotionRequiredEvent =>
println("Promote to: q=Queen, r=Rook, b=Bishop, n=Knight")
awaitingPromotion.set(true)
case _: FiftyMoveRuleAvailableEvent =>
println("50-move rule is now available — type 'draw' to claim.")
@@ -91,24 +88,14 @@ class TerminalUI(engine: GameEngine) extends Observer:
while running.get() do
val input = Option(StdIn.readLine()).getOrElse("quit").trim
synchronized {
if awaitingPromotion.get() then
input.toLowerCase match
case "q" => awaitingPromotion.set(false); engine.completePromotion(PromotionPiece.Queen)
case "r" => awaitingPromotion.set(false); engine.completePromotion(PromotionPiece.Rook)
case "b" => awaitingPromotion.set(false); engine.completePromotion(PromotionPiece.Bishop)
case "n" => awaitingPromotion.set(false); engine.completePromotion(PromotionPiece.Knight)
case _ =>
println("Invalid choice. Enter q, r, b, or n.")
println("Promote to: q=Queen, r=Rook, b=Bishop, n=Knight")
else
input.toLowerCase match
case "quit" | "q" =>
running.set(false)
println("Game over. Goodbye!")
case "" =>
printPrompt(engine.turn)
case _ =>
engine.processUserInput(input)
input.toLowerCase match
case "quit" | "q" =>
running.set(false)
println("Game over. Goodbye!")
case "" =>
printPrompt(engine.turn)
case _ =>
engine.processUserInput(input)
}
// Unsubscribe when done