Implement and test conditioned pos vectors

pull/1/merge
Thibault Duplessis 2012-02-25 17:10:49 +01:00
parent b6b3654edb
commit ffd2c6c724
3 changed files with 49 additions and 197 deletions

View File

@ -3,7 +3,7 @@ package model
import scala.math.{ abs, min, max }
sealed case class Pos private(x: Int, y: Int) extends Ordered[Pos] {
sealed case class Pos private (x: Int, y: Int) extends Ordered[Pos] {
import Pos.pos
@ -13,8 +13,8 @@ sealed case class Pos private(x: Int, y: Int) extends Ordered[Pos] {
lazy val left: Option[Pos] = this < 1
lazy val upLeft: Option[Pos] = up flatMap (_ left)
lazy val upRight: Option[Pos] = up flatMap (_ right)
lazy val downLeft: Option[Pos] = down flatMap(_ left)
lazy val downRight: Option[Pos] = down flatMap(_ right)
lazy val downLeft: Option[Pos] = down flatMap (_ left)
lazy val downRight: Option[Pos] = down flatMap (_ right)
def ^(n: Int): Option[Pos] = pos(x, y + n)
def v(n: Int): Option[Pos] = pos(x, y - n)
@ -24,25 +24,18 @@ sealed case class Pos private(x: Int, y: Int) extends Ordered[Pos] {
def |?(other: Pos) = y == other.y
def /?(other: Pos) = abs(x - other.x) == abs(y - other.y)
def *?(other: Pos) = (this -? other) || (this |? other) || (this /? other)
def ^^(n: Int): List[Pos] = <>(n, Pos.^)
def >>(n: Int): List[Pos] = <>(n, Pos.>)
def vv(n: Int): List[Pos] = <>(n, Pos.v)
def <<(n: Int): List[Pos] = <>(n, Pos.<)
def <>(n: Int, d: Option[Pos] => Option[Pos]): List[Pos] =
expand(n, List(Some(this)), d).flatten reverse
def >|(stop: Pos Boolean): List[Pos] = |<>|(stop, _.right)
def |<(stop: Pos Boolean): List[Pos] = |<>|(stop, _.left)
def |<>|(stop: Pos Boolean, dir: Direction): List[Pos] = dir(this) map { p
p :: (if (stop(p)) Nil else p.|<>|(stop, dir))
} getOrElse Nil
def xToString = Pos xToString x
def yToString = y.toString
def yToString = y.toString
override def toString = xToString + yToString
def compare(other: Pos) = toString compare other.toString
private def expand(i: Int, accumulator: List[Option[Pos]], direct: Option[Pos] Option[Pos]): List[Option[Pos]] = {
if (i > 0 && accumulator.head.isDefined)
expand(i - 1, direct(accumulator.head) :: accumulator, direct)
else accumulator
}
}
object Pos {

View File

@ -67,190 +67,56 @@ class BoardTest extends LilaSpec {
"allow chaining actions" in {
Board.empty.seq(
_ place White-Pawn at A2,
_ place White-Pawn at A3,
_ place White - Pawn at A2,
_ place White - Pawn at A3,
_ move A2 to A4
) must beSuccess.like {
case b => b(A4) mustEqual Some(White-Pawn)
}
case b b(A4) mustEqual Some(White - Pawn)
}
}
"fail on bad actions chain" in {
Board.empty.seq(
_ place White-Pawn at A2,
_ place White-Pawn at A3,
_ place White - Pawn at A2,
_ place White - Pawn at A3,
_ move B2 to B4
) must beFailure
}
"provide occupation map" in {
Board(
A2 -> (White-Pawn),
A3 -> (White-Pawn),
D1 -> (White-King),
E8 -> (Black-King),
H4 -> (Black-Queen)
A2 -> (White - Pawn),
A3 -> (White - Pawn),
D1 -> (White - King),
E8 -> (Black - King),
H4 -> (Black - Queen)
).occupation must havePairs(
White -> Set(A2, A3, D1),
Black -> Set(E8, H4)
)
White -> Set(A2, A3, D1),
Black -> Set(E8, H4)
)
}
//"advise which positions currently threaten a given position, given a side (opposing pawns)" in {
//val newBoard = board.place(White-Pawn).at(F6)
//(newBoard threatsTo Black at G7) must containPositions(F6)
//}
//"advise which positions currently threaten a given position, given a side (opposing non-threatening piece)" in {
//val newBoard = board.place(White-Knight).at(F6)
//(newBoard threatsTo Black at G7) must beEmpty
//}
//"advise which positions currently threaten a given position, given a side (multiple pawn opponents)" in {
//val newBoard = board.place(White-Pawn).at(F6).place(White-Pawn).at(H6)
//(newBoard threatsTo Black at G7) must containPositions(F6, H6)
//}
//"advise which positions currently threaten a given position, given a side (same side pawns)" in {
//val newBoard = board.place(Black-Pawn).at(F6)
//(newBoard threatsTo Black at G7) must beEmpty
//}
//"advise which positions currently threaten a given position, given a side (opposing rooks)" in {
//val newBoard = board.place(White-Rook).at(B5)
//(newBoard threatsTo Black at A5) must containPositions(B5)
//(newBoard threatsTo Black at H5) must containPositions(B5)
//(newBoard threatsTo Black at B8) must containPositions(B5)
//(newBoard threatsTo Black at B1) must containPositions(B5)
//}
//"advise which positions currently threaten a given position, given a side (same side rooks)" in {
//val newBoard = board.place(Black-Rook).at(B5)
//(newBoard threatsTo Black at A5) must beEmpty
//(newBoard threatsTo Black at H5) must beEmpty
//(newBoard threatsTo Black at B8) must beEmpty
//(newBoard threatsTo Black at B1) must beEmpty
//}
//"advise which positions currently threaten a given position, given a side (eclipsed rook)" in {
//val newBoard = board.place(White-Rook).at(B5).place(Black-Rook).at(D5)
//(newBoard threatsTo Black at E5) must beEmpty
//(newBoard threatsTo Black at D5) must containPositions(B5)
//(newBoard threatsTo Black at C5) must containPositions(B5)
//(newBoard threatsTo Black at B5) must beEmpty
//}
//"advise which positions currently threaten a given position, given a side (opposing bishops)" in {
//val newBoard = board.place(Black-Bishop).at(F7)
//(newBoard threatsTo White at G8) must containPositions(F7)
//(newBoard threatsTo White at G6) must containPositions(F7)
//(newBoard threatsTo White at E8) must containPositions(F7)
//(newBoard threatsTo White at A2) must containPositions(F7)
//}
//"advise which positions currently threaten a given position, given a side (same side bishops)" in {
//val newBoard = board.place(Black-Bishop).at(D6)
//(newBoard threatsTo Black at F4) must beEmpty
//(newBoard threatsTo Black at F8) must beEmpty
//(newBoard threatsTo Black at B8) must beEmpty
//(newBoard threatsTo Black at B4) must beEmpty
//}
//"advise which positions currently threaten a given position, given a side (eclipsed bishops)" in {
//val newBoard = board.place(White-Rook).at(B5).place(Black-Bishop).at(D7)
//(newBoard threatsTo White at A4) must beEmpty
//(newBoard threatsTo White at B5) must containPositions(D7)
//(newBoard threatsTo White at C6) must containPositions(D7)
//(newBoard threatsTo White at D7) must beEmpty
//}
//"advise which positions currently threaten a given position, given a side (opposing queens on rank/file)" in {
//val newBoard = board.place(White-Queen).at(B5)
//(newBoard threatsTo Black at A5) must containPositions(B5)
//(newBoard threatsTo Black at H5) must containPositions(B5)
//(newBoard threatsTo Black at B8) must containPositions(B5)
//(newBoard threatsTo Black at B1) must containPositions(B5)
//}
//"advise which positions currently threaten a given position, given a side (same side queen on rank/file)" in {
//val newBoard = board.place(Black-Queen).at(B5)
//(newBoard threatsTo Black at A5) must beEmpty
//(newBoard threatsTo Black at H5) must beEmpty
//(newBoard threatsTo Black at B8) must beEmpty
//(newBoard threatsTo Black at B1) must beEmpty
//}
//"advise which positions currently threaten a given position, given a side (eclipsed queen on rank/file)" in {
//val newBoard = board.place(White-Queen).at(B5).place(Black-Rook).at(D5)
//(newBoard threatsTo Black at E5) must beEmpty
//(newBoard threatsTo Black at D5) must containPositions(B5)
//(newBoard threatsTo Black at C5) must containPositions(B5)
//(newBoard threatsTo Black at B5) must beEmpty
//}
//"advise which positions currently threaten a given position, given a side (opposing queens on diagonal)" in {
//val newBoard = board.place(Black-Queen).at(F7)
//(newBoard threatsTo White at G8) must containPositions(F7)
//(newBoard threatsTo White at G6) must containPositions(F7)
//(newBoard threatsTo White at E8) must containPositions(F7)
//(newBoard threatsTo White at A2) must containPositions(F7)
//}
//"advise which positions currently threaten a given position, given a side (same side queen on diagonal)" in {
//val newBoard = board.place(Black-Queen).at(D6)
//(newBoard threatsTo Black at F4) must beEmpty
//(newBoard threatsTo Black at F8) must beEmpty
//(newBoard threatsTo Black at B8) must beEmpty
//(newBoard threatsTo Black at B4) must beEmpty
//}
//"advise which positions currently threaten a given position, given a side (eclipsed queen on diagonal)" in {
//val newBoard = board.place(White-Rook).at(B5).place(Black-Queen).at(D7)
//(newBoard threatsTo White at A4) must beEmpty
//(newBoard threatsTo White at B5) must containPositions(D7)
//(newBoard threatsTo White at C6) must containPositions(D7)
//(newBoard threatsTo White at D7) must beEmpty
//}
//}
//"advise which positions currently threaten a given position, given a side (opposing knights)" in {
//val newBoard = board.place(Black-Knight).at(F7)
//(newBoard threatsTo White at D8) must containPositions(F7)
//(newBoard threatsTo White at H8) must containPositions(F7)
//(newBoard threatsTo White at D6) must containPositions(F7)
//(newBoard threatsTo White at H6) must containPositions(F7)
//(newBoard threatsTo White at E5) must containPositions(F7)
//(newBoard threatsTo White at G5) must containPositions(F7)
//}
//"advise which positions currently threaten a given position, given a side (same side knights)" in {
//val newBoard = board.place(Black-Knight).at(F7)
//(newBoard threatsTo Black at D8) must beEmpty
//(newBoard threatsTo Black at H8) must beEmpty
//(newBoard threatsTo Black at D6) must beEmpty
//(newBoard threatsTo Black at H6) must beEmpty
//(newBoard threatsTo Black at E5) must beEmpty
//(newBoard threatsTo Black at G5) must beEmpty
//}
//"advise which positions currently threaten a given position, given a side (opposing kings)" in {
//val newBoard = board.place(Black-King).at(B4)
//(newBoard threatsTo White at B3) must containPositions(B4)
//(newBoard threatsTo White at B5) must containPositions(B4)
//(newBoard threatsTo White at A3) must containPositions(B4)
//(newBoard threatsTo White at A4) must containPositions(B4)
//(newBoard threatsTo White at A5) must containPositions(B4)
//(newBoard threatsTo White at C3) must containPositions(B4)
//(newBoard threatsTo White at C4) must containPositions(B4)
//(newBoard threatsTo White at C5) must containPositions(B4)
//}
//"advise which positions currently threaten a given position, given a side (same side kings)" in {
//val newBoard = board.place(Black-King).at(A3)
//(newBoard threatsTo Black at A4) must beEmpty
//(newBoard threatsTo Black at A2) must beEmpty
//(newBoard threatsTo Black at B2) must beEmpty
//(newBoard threatsTo Black at B3) must beEmpty
//(newBoard threatsTo Black at B4) must beEmpty
"navigate in pos based on pieces" in {
"right to end" in {
val board: Board = """
R K R"""
E1 >| (p board occupations p) must_== List(F1, G1, H1)
}
"right to next" in {
val board: Board = """
R KB R"""
E1 >| (p board occupations p) must_== List(F1)
}
"left to end" in {
val board: Board = """
R K R"""
E1 |< (p board occupations p) must_== List(D1, C1, B1, A1)
}
"right to next" in {
val board: Board = """
R BK R"""
E1 |< (p board occupations p) must_== List(D1)
}
}
}
}

View File

@ -36,17 +36,10 @@ class PosTest extends LilaSpec {
}
"be used to derive a relative list of positions" in {
"D4 ^^ 3" in { D4 ^^ 3 must contain(D4, D5, D6, D7) }
"D4 >> 3" in { D4 >> 3 must contain(D4, E4, F4, G4) }
"D4 vv 3" in { D4 vv 3 must contain(D4, D3, D2, D1) }
"D4 << 3" in { D4 << 3 must contain(D4, C4, B4, A4) }
}
"be used to derive a relative list of positions not including those off the board" in {
"D4 ^^ 8" in { D4 ^^ 8 must contain(D4, D5, D6, D7, D8) }
"D4 >> 8" in { D4 >> 8 must contain(D4, E4, F4, G4, H4) }
"D4 vv 8" in { D4 vv 8 must contain(D4, D3, D2, D1) }
"D4 << 8" in { D4 << 8 must contain(D4, C4, B4, A4) }
"D4 >| false" in { D4 >| (_ false) must contain(E4, F4, G4, H4) }
"D4 |< false" in { D4 |< (_ false) must contain(C4, B4, A4) }
"D4 >| (==G4)" in { D4 >| (G4 ==) must contain(E4, F4, G4) }
"D4 |< (==C4)" in { D4 |< (C4 ==) must contain(C4) }
}
"be a string" in {