Test and implement autodraw by lack of material

This commit is contained in:
Thibault Duplessis 2012-02-29 20:51:34 +01:00
parent c70d781cdc
commit f161e67854
2 changed files with 45 additions and 19 deletions

View file

@ -1,6 +1,6 @@
package lila.chess package lila.chess
import Pos._ import Pos.posAt
import format.Visual import format.Visual
case class Board(pieces: Map[Pos, Piece], history: History) { case class Board(pieces: Map[Pos, Piece], history: History) {
@ -9,7 +9,7 @@ case class Board(pieces: Map[Pos, Piece], history: History) {
def apply(at: Pos): Option[Piece] = pieces get at def apply(at: Pos): Option[Piece] = pieces get at
def apply(x: Int, y: Int): Option[Piece] = makePos(x, y) flatMap pieces.get def apply(x: Int, y: Int): Option[Piece] = posAt(x, y) flatMap pieces.get
lazy val actors: Map[Pos, Actor] = pieces map { lazy val actors: Map[Pos, Actor] = pieces map {
case (pos, piece) (pos, Actor(piece, pos, this)) case (pos, piece) (pos, Actor(piece, pos, this))
@ -18,6 +18,10 @@ case class Board(pieces: Map[Pos, Piece], history: History) {
lazy val colorActors: Map[Color, List[Actor]] = lazy val colorActors: Map[Color, List[Actor]] =
actors.values groupBy (_.color) mapValues (_.toList) actors.values groupBy (_.color) mapValues (_.toList)
def rolesOf(c: Color): List[Role] = pieces.values.toList collect {
case piece if piece.color == c piece.role
}
def actorsOf(c: Color): List[Actor] = colorActors get c getOrElse Nil def actorsOf(c: Color): List[Actor] = colorActors get c getOrElse Nil
def actorAt(at: Pos): Option[Actor] = actors get at def actorAt(at: Pos): Option[Actor] = actors get at
@ -85,7 +89,20 @@ case class Board(pieces: Map[Pos, Piece], history: History) {
def updateHistory(f: History History) = copy(history = f(history)) def updateHistory(f: History History) = copy(history = f(history))
def count(p: Piece) = pieces.values count (_ == p) def count(p: Piece): Int = pieces.values count (_ == p)
def count(c: Color): Int = pieces.values count (_.color == c)
def autoDraw: Boolean = {
Color.all map rolesOf forall { roles
(roles filterNot (_ == King)) match {
case roles if roles.size > 1 false
case List(Knight) true
case List(Bishop) true
case Nil true
case _ false
}
}
}
def visual = Visual >> this def visual = Visual >> this
@ -100,18 +117,24 @@ object Board {
def apply(pieces: (Pos, Piece)*): Board = Board(pieces toMap, History()) def apply(pieces: (Pos, Piece)*): Board = Board(pieces toMap, History())
def apply(): Board = { def apply(): Board = standard
lazy val standard: Board = {
val lineUp = IndexedSeq(Rook, Knight, Bishop, Queen, King, Bishop, Knight, Rook) val lineUp = IndexedSeq(Rook, Knight, Bishop, Queen, King, Bishop, Knight, Rook)
val pairs = for (y Seq(1, 2, 7, 8); x 1 to 8) yield (Pos.unsafe(x, y), y match { val pairs = for (y Seq(1, 2, 7, 8); x 1 to 8) yield {
case 1 White - lineUp(x - 1) posAt(x, y) map { pos
case 2 White - Pawn (pos, y match {
case 7 Black - Pawn case 1 White - lineUp(x - 1)
case 8 Black - lineUp(x - 1) case 2 White.pawn
}) case 7 Black.pawn
case 8 Black - lineUp(x - 1)
})
}
}
Board(pairs toMap, History()) Board(pairs.flatten toMap, History())
} }
def empty = new Board(Map.empty, History()) def empty = new Board(Map.empty, History())

View file

@ -122,8 +122,8 @@ R BK R"""
} }
"two kings and one pawn" in { "two kings and one pawn" in {
""" """
k P k
K P""".autoDraw must_== false K """.autoDraw must_== false
} }
"two kings and one bishop" in { "two kings and one bishop" in {
""" """
@ -135,10 +135,10 @@ R BK R"""
k k
K n B""".autoDraw must_== true K n B""".autoDraw must_== true
} }
"two kings, one bishop and one knight of same colors" in { "two kings, one bishop and one knight of same color" in {
""" """
k B k
K N B""".autoDraw must_== false K N """.autoDraw must_== false
} }
"two kings, one bishop and one rook of different colors" in { "two kings, one bishop and one rook of different colors" in {
""" """
@ -147,9 +147,6 @@ R BK R"""
} }
} }
"by fifty moves" in { "by fifty moves" in {
"empty" in {
Board.empty.autoDraw must_== false
}
"new" in { "new" in {
Board().autoDraw must_== false Board().autoDraw must_== false
} }
@ -158,6 +155,12 @@ R BK R"""
g.board.autoDraw g.board.autoDraw
} must beSuccess(false) } must beSuccess(false)
} }
"tons of pointless moves" in {
val moves = List.fill(30)(List(B1 -> C3, B8 -> C6, C3 -> B1, C6 -> B8))
Game().playMoves(moves.flatten: _*) must beSuccess.like {
case g g.board.autoDraw must_== true
}
}
} }
} }
} }