Test and implement standard chess kingside castle

pull/1/merge
Thibault Duplessis 2012-02-25 14:50:27 +01:00
parent e7e0afef07
commit a5664c94a0
5 changed files with 68 additions and 24 deletions

View File

@ -7,19 +7,20 @@ case class Actor(piece: Piece, pos: Pos, board: Board) {
lazy val implications: Implications = kingSafety(piece.role match {
case Pawn pawn
case Pawn pawn
case King shortRange(King.dirs) ++ castle
case King shortRange(King.dirs) ++ castle
case role if (role.longRange) longRange(role.dirs)
case role shortRange(role.dirs)
case role shortRange(role.dirs)
})
lazy val moves: Set[Pos] = implications.keySet
def color = piece.color
def is(c: Color) = c == piece.color
def is(p: Piece) = p == piece
def friends: Set[Pos] = board occupation color
def enemies: Set[Pos] = board occupation !color
def dir: Direction = if (color == White) _.up else _.down
@ -29,7 +30,7 @@ case class Actor(piece: Piece, pos: Pos, board: Board) {
List(next.left, next.right) flatten
} getOrElse Nil
case role if (role.longRange) longRangePoss(role.dirs)
case role (role.dirs map { d d(pos) }).flatten
case role (role.dirs map { d d(pos) }).flatten
}) contains to)
private def kingSafety(implications: Implications): Implications =
@ -40,7 +41,21 @@ case class Actor(piece: Piece, pos: Pos, board: Board) {
}
private def castle: Implications = {
Map.empty
val kingSide: Option[Implication] = for {
kingPos board kingPosOf color
if board.history canCastleKingSide color
rook = color.rook
rookPos board actorsOf color collectFirst {
case a if (a is rook) && (a.pos.x > kingPos.x) a.pos
}
newKingPos kingPos > 2
newRookPos newKingPos.left
b1 board take rookPos
b2 b1.move(kingPos, newKingPos)
b3 b2.place(rook, newRookPos)
} yield (newKingPos, b3)
kingSide toMap
}
private def shortRange(dirs: Directions): Implications = {

View File

@ -38,6 +38,10 @@ case class Board(pieces: Map[Pos, Piece], history: History) {
else success(copy(pieces = pieces + ((at, piece))))
}
def place(piece: Piece, at: Pos) =
if (pieces contains at) None
else Some(copy(pieces = pieces + ((at, piece))))
def takeValid(at: Pos): Valid[Board] = take(at) toSuccess ("No piece at " + at + " to take")
def take(at: Pos): Option[Board] = pieces get at map { piece

View File

@ -14,3 +14,10 @@ case class History(
def canCastleKingSide(color: Color): Boolean = castles(color)._1
def canCastleQueenSide(color: Color): Boolean = castles(color)._2
}
object History {
def castle(color: Color, kingSide: Boolean, queenSide: Boolean) = History(
castles = Map(color -> (kingSide, queenSide))
)
}

View File

@ -21,4 +21,12 @@ trait LilaSpec
case p Visual.addNewLines(Visual.>>|(board, Map(p -> 'x'))) must_== visual
}
def beBoard(visual: String): Matcher[Valid[Board]] = beSuccess.like {
case b => b.visual must_== (Visual << visual).visual
}
def beSituation(visual: String): Matcher[Valid[Situation]] = beSuccess.like {
case s => s.board.visual must_== (Visual << visual).visual
}
}

View File

@ -11,35 +11,45 @@ class CastleTest extends LilaSpec {
"castle" in {
"king side" in {
val board: Board = """
PPPPPPPP
R QK R"""
"impossible" in {
"pieces in the way" in {
Board().movesFrom(E1) must bePoss()
}
"not allowed by history" in {
board movesFrom E1 must bePoss(F1)
}
}
"possible" in {
val board = """
val board2 = board withHistory History.castle(White, true, true)
val situation = board2 as White
"viable moves" in {
board2 movesFrom E1 must bePoss(F1, G1)
}
"correct new board" in {
situation.playMove(E1, G1) must beSituation("""
PPPPPPPP
R QK R"""
"viable moves" in {
board movesFrom E1 must bePoss(F1, G1)
}
}
}
"queen side" in {
"impossible" in {
"pieces in the way" in {
Board() movesFrom E1 must bePoss()
}
}
"possible" in {
val board = """
PPPPPP
R KB"""
"viable moves" in {
board movesFrom E1 must bePoss(D1, C1)
R Q RK """)
}
}
}
//"queen side" in {
//"impossible" in {
//"pieces in the way" in {
//Board() movesFrom E1 must bePoss()
//}
//}
//"possible" in {
//val board = """
//PPPPPP
//R KB"""
//"viable moves" in {
//board movesFrom E1 must bePoss(D1, C1)
//}
//}
//}
}
}
}