Skip to content

Commit

Permalink
Scala tweak
Browse files Browse the repository at this point in the history
  • Loading branch information
lenguyenthanh committed Mar 20, 2024
1 parent 334559e commit 3beec38
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 39 deletions.
2 changes: 2 additions & 0 deletions src/main/scala/bitboard/Bitboard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 3 additions & 6 deletions src/main/scala/format/UciCharPair.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down Expand Up @@ -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
6 changes: 2 additions & 4 deletions src/main/scala/format/pgn/Reader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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))
)
10 changes: 2 additions & 8 deletions src/main/scala/format/pgn/parsingModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand Down Expand Up @@ -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)
8 changes: 3 additions & 5 deletions src/main/scala/variant/Atomic.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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 }
Expand Down
5 changes: 1 addition & 4 deletions src/main/scala/variant/KingOfTheHill.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
23 changes: 11 additions & 12 deletions src/main/scala/variant/Standard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down

0 comments on commit 3beec38

Please sign in to comment.