Implement and test conditioned pos vectors
parent
b6b3654edb
commit
ffd2c6c724
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue