From 3beec384cec2f08ed2caa11f2bf04df748202e69 Mon Sep 17 00:00:00 2001 From: Thanh Le Date: Wed, 20 Mar 2024 15:57:32 +0700 Subject: [PATCH] Scala tweak --- src/main/scala/bitboard/Bitboard.scala | 2 ++ src/main/scala/format/UciCharPair.scala | 9 +++----- src/main/scala/format/pgn/Reader.scala | 6 ++--- src/main/scala/format/pgn/parsingModel.scala | 10 ++------- src/main/scala/variant/Atomic.scala | 8 +++---- src/main/scala/variant/KingOfTheHill.scala | 5 +---- src/main/scala/variant/Standard.scala | 23 ++++++++++---------- 7 files changed, 24 insertions(+), 39 deletions(-) diff --git a/src/main/scala/bitboard/Bitboard.scala b/src/main/scala/bitboard/Bitboard.scala index 02f74a335..5d5640418 100644 --- a/src/main/scala/bitboard/Bitboard.scala +++ b/src/main/scala/bitboard/Bitboard.scala @@ -12,6 +12,8 @@ object Bitboard: val empty: Bitboard = 0L val all: Bitboard = -1L + // E4, D4, E5, D5 + val center = 0x1818000000L val firstRank: Bitboard = 0xffL val lastRank: Bitboard = 0xffL << 56 diff --git a/src/main/scala/format/UciCharPair.scala b/src/main/scala/format/UciCharPair.scala index 93b7c913f..6e016fa68 100644 --- a/src/main/scala/format/UciCharPair.scala +++ b/src/main/scala/format/UciCharPair.scala @@ -26,11 +26,7 @@ object UciCharPair: uci match case Uci.Move(orig, dest, None) => UciCharPair(toChar(orig), toChar(dest)) case Uci.Move(orig, dest, Some(role)) => UciCharPair(toChar(orig), toChar(dest.file, role)) - case Uci.Drop(role, square) => - UciCharPair( - toChar(square), - dropRole2charMap.getOrElse(role, voidChar) - ) + case Uci.Drop(role, square) => UciCharPair(toChar(square), dropRole2charMap.getOrElse(role, voidChar)) object implementation: @@ -68,5 +64,6 @@ object UciCharPair: export char2dropRoleMap.apply as unsafeCharToDropRole private[chess] def lastRank(from: Square): Rank = - if from.rank == Rank.Second then Rank.First + if from.rank == Rank.Second + then Rank.First else Rank.Eighth diff --git a/src/main/scala/format/pgn/Reader.scala b/src/main/scala/format/pgn/Reader.scala index b93f7a39f..3b8e6dea3 100644 --- a/src/main/scala/format/pgn/Reader.scala +++ b/src/main/scala/format/pgn/Reader.scala @@ -34,8 +34,7 @@ object Reader: def movesWithSans(sans: Iterable[SanStr], op: Sans => Sans, tags: Tags): Either[ErrorStr, Result] = Parser .moves(sans) - .map: moves => - makeReplay(makeGame(tags), op(moves)) + .map(moves => makeReplay(makeGame(tags), op(moves))) private def makeReplay(game: Game, sans: Sans): Result = sans.value @@ -47,6 +46,5 @@ object Reader: case Right(replay) => Result.Complete(replay) private def makeGame(tags: Tags) = - Game(variantOption = tags.variant, fen = tags.fen).pipe(self => + Game(variantOption = tags.variant, fen = tags.fen).pipe: self => self.copy(startedAtPly = self.ply, clock = tags.clockConfig.map(Clock.apply)) - ) diff --git a/src/main/scala/format/pgn/parsingModel.scala b/src/main/scala/format/pgn/parsingModel.scala index 402852108..ca61aa78b 100644 --- a/src/main/scala/format/pgn/parsingModel.scala +++ b/src/main/scala/format/pgn/parsingModel.scala @@ -40,8 +40,7 @@ case class Std( situation.board .byPiece(situation.color - role) .first: square => - if compare(file, square.file) && - compare(rank, square.rank) + if compare(file, square.file) && compare(rank, square.rank) then situation.generateMovesAt(square).find(_.dest == dest) else None .toRight(ErrorStr(s"No move found: $this\n$situation")) @@ -78,12 +77,7 @@ case class Castle(side: Side) extends San: opaque type Sans = List[San] object Sans extends TotalWrapper[Sans, List[San]] -case class Metas( - check: Check, - checkmate: Boolean, - comments: List[Comment], - glyphs: Glyphs -) +case class Metas(check: Check, checkmate: Boolean, comments: List[Comment], glyphs: Glyphs) object Metas: val empty = Metas(Check.No, checkmate = false, Nil, Glyphs.empty) diff --git a/src/main/scala/variant/Atomic.scala b/src/main/scala/variant/Atomic.scala index 9297033a9..f868f98ea 100644 --- a/src/main/scala/variant/Atomic.scala +++ b/src/main/scala/variant/Atomic.scala @@ -27,9 +27,8 @@ case object Atomic private def genKing(situation: Situation, mask: Bitboard) = import situation.{ genUnsafeKing, genCastling } - situation.ourKing.fold(Nil) { king => + situation.ourKing.fold(Nil): king => genCastling(king) ++ genUnsafeKing(king, mask) - } /** Move threatens to explode the opponent's king */ private def explodesOpponentKing(situation: Situation)(move: Move): Boolean = @@ -45,10 +44,9 @@ case object Atomic */ override def kingThreatened(board: Board, color: Color): Check = Check: import board.{ kingPosOf, kingOf, occupied } - kingPosOf(color).exists { k => + kingPosOf(color).exists: k => k.kingAttacks.isDisjoint(kingOf(!color)) && - attackersWithoutKing(board, occupied, k, !color).nonEmpty - } + attackersWithoutKing(board, occupied, k, !color).nonEmpty private def attackersWithoutKing(board: Board, occupied: Bitboard, s: Square, attacker: Color) = import board.board.{ byColor, rooks, queens, bishops, knights, pawns } diff --git a/src/main/scala/variant/KingOfTheHill.scala b/src/main/scala/variant/KingOfTheHill.scala index 575e8375e..8cc67e619 100644 --- a/src/main/scala/variant/KingOfTheHill.scala +++ b/src/main/scala/variant/KingOfTheHill.scala @@ -19,11 +19,8 @@ case object KingOfTheHill override def valid(situation: Situation, strict: Boolean): Boolean = Standard.valid(situation, strict) - // E4, D4, E5, D5 - private val center = 0x1818000000L - override def specialEnd(situation: Situation) = - situation.kingOf(!situation.color).intersects(center) + situation.kingOf(!situation.color).intersects(bitboard.Bitboard.center) /** You only need a king to be able to win in this variant */ diff --git a/src/main/scala/variant/Standard.scala b/src/main/scala/variant/Standard.scala index 2b571f55f..3ee321154 100644 --- a/src/main/scala/variant/Standard.scala +++ b/src/main/scala/variant/Standard.scala @@ -20,18 +20,17 @@ case object Standard def validMoves(situation: Situation): List[Move] = import situation.{ genNonKing, genSafeKing, genCastling, color, board, ourKing } val enPassantMoves = situation.genEnPassant(situation.us & board.pawns) - ourKing - .fold(Nil): king => - val checkers = board.attackers(king, !situation.color) - val candidates = - if checkers.isEmpty then - val targets = ~situation.us - genNonKing(targets) ::: genSafeKing(king, targets) ::: genCastling(king) ::: enPassantMoves - else genEvasions(king, situation, checkers) ::: enPassantMoves - val sliderBlockers = board.sliderBlockers(king, color) - if sliderBlockers.nonEmpty || enPassantMoves.nonEmpty then - candidates.filter(isSafe(situation, king, sliderBlockers)) - else candidates + ourKing.fold(Nil): king => + val checkers = board.attackers(king, !situation.color) + val candidates = + if checkers.isEmpty then + val targets = ~situation.us + genNonKing(targets) ::: genSafeKing(king, targets) ::: genCastling(king) ::: enPassantMoves + else genEvasions(king, situation, checkers) ::: enPassantMoves + val sliderBlockers = board.sliderBlockers(king, color) + if sliderBlockers.nonEmpty || enPassantMoves.nonEmpty then + candidates.filter(isSafe(situation, king, sliderBlockers)) + else candidates // Used for filtering candidate moves that would leave put the king in check. def isSafe(situation: Situation, king: Square, blockers: Bitboard)(move: Move): Boolean =