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
+12
View File
@@ -79,3 +79,15 @@
* NCS-21 Write Scripts to automate certain tasks ([#15](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/15)) ([8051871](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/80518719d536a087d339fe02530825dc07f8b388))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-29 JSON - Cherry Picked ([#28](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/28)) ([dbcafd2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/dbcafd286993e0604a6fa286c5543581a149439e))
## (2026-04-16)
### Features
* NCS-10 Implement Pawn Promotion ([#12](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/12)) ([13bfc16](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/13bfc16cfe25db78ec607db523ca6d993c13430c))
* NCS-13 Implement Threefold Repetition ([#31](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/31)) ([767d305](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/767d3051a76c266050b6335774d66e2db2273c16))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-16 Core Separation via Patterns ([#10](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/10)) ([1361dfc](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/1361dfc89553b146864fb8ff3526cf12cf3f293a))
* NCS-17 Implement basic ScalaFX UI ([#14](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/14)) ([3ff8031](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3ff80318b4f16c59733a46498581a5c27f048287))
* NCS-21 Write Scripts to automate certain tasks ([#15](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/15)) ([8051871](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/80518719d536a087d339fe02530825dc07f8b388))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-29 JSON - Cherry Picked ([#28](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/28)) ([dbcafd2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/dbcafd286993e0604a6fa286c5543581a149439e))
-5
View File
@@ -38,11 +38,6 @@ tasks.withType<ScalaCompile> {
scalaCompileOptions.additionalParameters = listOf("-encoding", "UTF-8")
}
// Disable scalafix for UI module due to mutable state requirements
tasks.matching { it.name.startsWith("scalafix") }.configureEach {
enabled = false
}
tasks.named<JavaExec>("run") {
jvmArgs("-Dfile.encoding=UTF-8", "-Dstdout.encoding=UTF-8", "-Dstderr.encoding=UTF-8")
standardInput = System.`in`
@@ -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
+1 -1
View File
@@ -1,3 +1,3 @@
MAJOR=0
MINOR=10
MINOR=11
PATCH=0