feat(coordinator): add Redis integration and improve configuration for game state management
Build & Test (NowChessSystems) TeamCity build was removed from queue
Build & Test (NowChessSystems) TeamCity build was removed from queue
This commit is contained in:
@@ -116,7 +116,7 @@ tasks.jar {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
tasks.withType(org.gradle.api.tasks.scala.ScalaCompile::class).configureEach {
|
||||
tasks.withType(ScalaCompile::class).configureEach {
|
||||
if (name == "compileScoverageScala") {
|
||||
source = source.asFileTree.matching {
|
||||
exclude("**/grpc/*.scala")
|
||||
|
||||
@@ -2,7 +2,7 @@ package de.nowchess.rules.grpc
|
||||
|
||||
import de.nowchess.api.board.{CastlingRights as DomainCastlingRights, *}
|
||||
import de.nowchess.api.game.{DrawReason, GameContext, GameResult, WinReason}
|
||||
import de.nowchess.api.move.{MoveType, PromotionPiece, Move as DomainMove}
|
||||
import de.nowchess.api.move.{Move as DomainMove, MoveType, PromotionPiece}
|
||||
import de.nowchess.rules.proto.*
|
||||
|
||||
import scala.jdk.CollectionConverters.*
|
||||
@@ -57,7 +57,12 @@ object ProtoMapper:
|
||||
case _ => MoveType.Normal(false)
|
||||
|
||||
def toProtoMove(m: DomainMove): ProtoMove =
|
||||
ProtoMove.newBuilder().setFrom(m.from.toString).setTo(m.to.toString).setMoveKind(toProtoMoveKind(m.moveType)).build()
|
||||
ProtoMove
|
||||
.newBuilder()
|
||||
.setFrom(m.from.toString)
|
||||
.setTo(m.to.toString)
|
||||
.setMoveKind(toProtoMoveKind(m.moveType))
|
||||
.build()
|
||||
|
||||
def fromProtoMove(m: ProtoMove): Option[DomainMove] =
|
||||
for
|
||||
@@ -66,16 +71,33 @@ object ProtoMapper:
|
||||
yield DomainMove(from, to, fromProtoMoveKind(m.getMoveKind))
|
||||
|
||||
def toProtoBoard(board: Board): java.util.List[ProtoSquarePiece] =
|
||||
board.pieces.map { (sq, piece) =>
|
||||
ProtoSquarePiece
|
||||
.newBuilder()
|
||||
.setSquare(sq.toString)
|
||||
.setPiece(ProtoPiece.newBuilder().setColor(toProtoColor(piece.color)).setPieceType(toProtoPieceType(piece.pieceType)).build())
|
||||
.build()
|
||||
}.toSeq.asJava
|
||||
board.pieces
|
||||
.map { (sq, piece) =>
|
||||
ProtoSquarePiece
|
||||
.newBuilder()
|
||||
.setSquare(sq.toString)
|
||||
.setPiece(
|
||||
ProtoPiece
|
||||
.newBuilder()
|
||||
.setColor(toProtoColor(piece.color))
|
||||
.setPieceType(toProtoPieceType(piece.pieceType))
|
||||
.build(),
|
||||
)
|
||||
.build()
|
||||
}
|
||||
.toSeq
|
||||
.asJava
|
||||
|
||||
def fromProtoBoard(pieces: java.util.List[ProtoSquarePiece]): Board =
|
||||
Board(pieces.asScala.flatMap(sp => Square.fromAlgebraic(sp.getSquare).map(_ -> Piece(fromProtoColor(sp.getPiece.getColor), fromProtoPieceType(sp.getPiece.getPieceType)))).toMap)
|
||||
Board(
|
||||
pieces.asScala
|
||||
.flatMap(sp =>
|
||||
Square
|
||||
.fromAlgebraic(sp.getSquare)
|
||||
.map(_ -> Piece(fromProtoColor(sp.getPiece.getColor), fromProtoPieceType(sp.getPiece.getPieceType))),
|
||||
)
|
||||
.toMap,
|
||||
)
|
||||
|
||||
def toProtoResultKind(r: Option[GameResult]): ProtoGameResultKind = r match
|
||||
case None => ProtoGameResultKind.ONGOING
|
||||
@@ -130,12 +152,13 @@ object ProtoMapper:
|
||||
def fromProtoGameContext(p: ProtoGameContext): GameContext =
|
||||
val cr = p.getCastlingRights
|
||||
GameContext(
|
||||
board = fromProtoBoard(p.getBoardList),
|
||||
turn = fromProtoColor(p.getTurn),
|
||||
castlingRights = DomainCastlingRights(cr.getWhiteKingSide, cr.getWhiteQueenSide, cr.getBlackKingSide, cr.getBlackQueenSide),
|
||||
board = fromProtoBoard(p.getBoardList),
|
||||
turn = fromProtoColor(p.getTurn),
|
||||
castlingRights =
|
||||
DomainCastlingRights(cr.getWhiteKingSide, cr.getWhiteQueenSide, cr.getBlackKingSide, cr.getBlackQueenSide),
|
||||
enPassantSquare = Option(p.getEnPassantSquare).filter(_.nonEmpty).flatMap(Square.fromAlgebraic),
|
||||
halfMoveClock = p.getHalfMoveClock,
|
||||
moves = p.getMovesList.asScala.flatMap(fromProtoMove).toList,
|
||||
result = fromProtoResultKind(p.getResult),
|
||||
initialBoard = fromProtoBoard(p.getInitialBoardList),
|
||||
halfMoveClock = p.getHalfMoveClock,
|
||||
moves = p.getMovesList.asScala.flatMap(fromProtoMove).toList,
|
||||
result = fromProtoResultKind(p.getResult),
|
||||
initialBoard = fromProtoBoard(p.getInitialBoardList),
|
||||
)
|
||||
|
||||
@@ -12,15 +12,22 @@ import io.quarkus.grpc.GrpcService
|
||||
class RuleGrpcService extends RuleServiceGrpc.RuleServiceImplBase:
|
||||
|
||||
private def parseSquare(s: String): Square =
|
||||
Square.fromAlgebraic(s).getOrElse(
|
||||
throw Status.INVALID_ARGUMENT.withDescription(s"Invalid square: $s").asRuntimeException(),
|
||||
)
|
||||
Square
|
||||
.fromAlgebraic(s)
|
||||
.getOrElse(
|
||||
throw Status.INVALID_ARGUMENT.withDescription(s"Invalid square: $s").asRuntimeException(),
|
||||
)
|
||||
|
||||
override def candidateMoves(req: ProtoSquareRequest, resp: StreamObserver[ProtoMoveList]): Unit =
|
||||
val ctx = ProtoMapper.fromProtoGameContext(req.getContext)
|
||||
val sq = parseSquare(req.getSquare)
|
||||
val moves = DefaultRules.candidateMoves(ctx)(sq)
|
||||
resp.onNext(ProtoMoveList.newBuilder().addAllMoves(moves.map(ProtoMapper.toProtoMove).asInstanceOf[java.util.List[ProtoMove]]).build())
|
||||
resp.onNext(
|
||||
ProtoMoveList
|
||||
.newBuilder()
|
||||
.addAllMoves(moves.map(ProtoMapper.toProtoMove).asInstanceOf[java.util.List[ProtoMove]])
|
||||
.build(),
|
||||
)
|
||||
resp.onCompleted()
|
||||
|
||||
override def legalMoves(req: ProtoSquareRequest, resp: StreamObserver[ProtoMoveList]): Unit =
|
||||
@@ -52,10 +59,12 @@ class RuleGrpcService extends RuleServiceGrpc.RuleServiceImplBase:
|
||||
respond(resp, boolResult(DefaultRules.isThreefoldRepetition(ProtoMapper.fromProtoGameContext(req))))
|
||||
|
||||
override def applyMove(req: ProtoMoveRequest, resp: StreamObserver[ProtoGameContext]): Unit =
|
||||
val ctx = ProtoMapper.fromProtoGameContext(req.getContext)
|
||||
val move = ProtoMapper.fromProtoMove(req.getMove).getOrElse(
|
||||
throw Status.INVALID_ARGUMENT.withDescription("Invalid move").asRuntimeException(),
|
||||
)
|
||||
val ctx = ProtoMapper.fromProtoGameContext(req.getContext)
|
||||
val move = ProtoMapper
|
||||
.fromProtoMove(req.getMove)
|
||||
.getOrElse(
|
||||
throw Status.INVALID_ARGUMENT.withDescription("Invalid move").asRuntimeException(),
|
||||
)
|
||||
respond(resp, ProtoMapper.toProtoGameContext(DefaultRules.applyMove(ctx)(move)))
|
||||
|
||||
override def postMoveStatus(req: ProtoGameContext, resp: StreamObserver[ProtoPostMoveStatus]): Unit =
|
||||
|
||||
Reference in New Issue
Block a user