Reorganizing moving rules
This commit is contained in:
parent
bee9d5a75b
commit
a0660900ba
|
@ -6,7 +6,80 @@ import scalaz.Success
|
||||||
case class Actor(piece: Piece, pos: Pos, board: Board) {
|
case class Actor(piece: Piece, pos: Pos, board: Board) {
|
||||||
|
|
||||||
lazy val implications: Implications = kingSafety(piece.role match {
|
lazy val implications: Implications = kingSafety(piece.role match {
|
||||||
|
|
||||||
|
case Pawn ⇒ pawn
|
||||||
|
|
||||||
|
case King ⇒ shortRange(King.dirs) ++ castle
|
||||||
|
|
||||||
|
case role if (role.trajectory) ⇒ trajectory(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 friends: Set[Pos] = board occupation color
|
||||||
|
def enemies: Set[Pos] = board occupation !color
|
||||||
|
def dir: Direction = if (color == White) _.up else _.down
|
||||||
|
|
||||||
|
def threatens(to: Pos): Boolean = enemies(to) && ((piece.role match {
|
||||||
case Pawn ⇒ dir(pos) map { next ⇒
|
case Pawn ⇒ dir(pos) map { next ⇒
|
||||||
|
List(next.left, next.right) flatten
|
||||||
|
} getOrElse Nil
|
||||||
|
case role if (role.trajectory) ⇒ trajectoryPoss(role.dirs)
|
||||||
|
case role ⇒ (role.dirs map { d ⇒ d(pos) }).flatten
|
||||||
|
}) contains to)
|
||||||
|
|
||||||
|
private def kingSafety(implications: Implications): Implications =
|
||||||
|
implications filterNot {
|
||||||
|
case (p, b) ⇒ b actorsOf !color exists { enemy ⇒
|
||||||
|
b kingPosOf color map (enemy threatens _) getOrElse false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private def castle: Implications = {
|
||||||
|
Map.empty
|
||||||
|
}
|
||||||
|
|
||||||
|
private def shortRange(dirs: Directions): Implications = {
|
||||||
|
(dirs map { d ⇒ d(pos) }).flatten filterNot friends map { to ⇒
|
||||||
|
(if (enemies(to)) board.taking(pos, to) else board.move(pos, to)) map (to -> _)
|
||||||
|
} flatten
|
||||||
|
} toMap
|
||||||
|
|
||||||
|
private def trajectory(dirs: Directions): Implications = {
|
||||||
|
|
||||||
|
val moving = (to: Pos) ⇒ board.move(pos, to)
|
||||||
|
|
||||||
|
def forward(p: Pos, dir: Direction): List[Implication] = dir(p) match {
|
||||||
|
case None ⇒ Nil
|
||||||
|
case Some(next) if friends(next) ⇒ Nil
|
||||||
|
case Some(next) if enemies(next) ⇒ board.taking(pos, next) map { b ⇒
|
||||||
|
(next, b)
|
||||||
|
} toList
|
||||||
|
case Some(next) ⇒ moving(next) map { b ⇒
|
||||||
|
(next, b) :: forward(next, dir)
|
||||||
|
} getOrElse Nil
|
||||||
|
}
|
||||||
|
|
||||||
|
(dirs flatMap { dir ⇒ forward(pos, dir) }) toMap
|
||||||
|
}
|
||||||
|
|
||||||
|
private def trajectoryPoss(dirs: Directions): List[Pos] = {
|
||||||
|
|
||||||
|
def forward(p: Pos, dir: Direction): List[Pos] = dir(p) match {
|
||||||
|
case None ⇒ Nil
|
||||||
|
case Some(next) if friends(next) ⇒ Nil
|
||||||
|
case Some(next) if enemies(next) ⇒ List(next)
|
||||||
|
case Some(next) ⇒ next :: forward(next, dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
dirs flatMap { dir ⇒ forward(pos, dir) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private def pawn = dir(pos) map { next ⇒
|
||||||
val unmoved = if (color == White) pos.y == 2 else pos.y == 7
|
val unmoved = if (color == White) pos.y == 2 else pos.y == 7
|
||||||
val passable = if (color == White) pos.y == 5 else pos.y == 4
|
val passable = if (color == White) pos.y == 5 else pos.y == 4
|
||||||
val one = Some(next) filterNot board.occupations
|
val one = Some(next) filterNot board.occupations
|
||||||
|
@ -37,66 +110,4 @@ case class Actor(piece: Piece, pos: Pos, board: Board) {
|
||||||
).flatten toMap
|
).flatten toMap
|
||||||
} getOrElse Map.empty
|
} getOrElse Map.empty
|
||||||
|
|
||||||
case r if (r.trajectory) ⇒ implicationTrajectories(r.dirs, pos)
|
|
||||||
|
|
||||||
case role ⇒ {
|
|
||||||
(role.dirs map { d ⇒ d(pos) }).flatten filterNot friends map { to ⇒
|
|
||||||
(if (enemies(to)) board.taking(pos, to) else board.move(pos, to)) map (to -> _)
|
|
||||||
} flatten
|
|
||||||
} toMap
|
|
||||||
})
|
|
||||||
|
|
||||||
lazy val moves: Set[Pos] = implications.keySet
|
|
||||||
|
|
||||||
def color = piece.color
|
|
||||||
def is(c: Color) = c == piece.color
|
|
||||||
def friends: Set[Pos] = board occupation color
|
|
||||||
def enemies: Set[Pos] = board occupation !color
|
|
||||||
def dir: Direction = if (color == White) _.up else _.down
|
|
||||||
|
|
||||||
private def kingSafety(implications: Implications): Implications =
|
|
||||||
implications filterNot {
|
|
||||||
case (p, b) ⇒ b actorsOf !color exists { enemy ⇒
|
|
||||||
b kingPosOf color map (enemy threatens _) getOrElse false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// can it threaten the opponent king?
|
|
||||||
def threatens(to: Pos): Boolean = enemies(to) && ((piece.role match {
|
|
||||||
case Pawn ⇒ dir(pos) map { next ⇒
|
|
||||||
List(next.left, next.right) flatten
|
|
||||||
} getOrElse Nil
|
|
||||||
case role if (role.trajectory) ⇒ posTrajectories(role.dirs, pos)
|
|
||||||
case role ⇒ (role.dirs map { d ⇒ d(pos) }).flatten
|
|
||||||
}) contains to)
|
|
||||||
|
|
||||||
private def posTrajectories(dirs: Directions, from: Pos): List[Pos] = {
|
|
||||||
|
|
||||||
def forward(p: Pos, dir: Direction): List[Pos] = dir(p) match {
|
|
||||||
case None ⇒ Nil
|
|
||||||
case Some(next) if friends(next) ⇒ Nil
|
|
||||||
case Some(next) if enemies(next) ⇒ List(next)
|
|
||||||
case Some(next) ⇒ next :: forward(next, dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
dirs flatMap { dir ⇒ forward(from, dir) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private def implicationTrajectories(dirs: Directions, from: Pos): Implications = {
|
|
||||||
|
|
||||||
val moving = (to: Pos) ⇒ board.move(from, to)
|
|
||||||
|
|
||||||
def forward(p: Pos, dir: Direction): List[Implication] = dir(p) match {
|
|
||||||
case None ⇒ Nil
|
|
||||||
case Some(next) if friends(next) ⇒ Nil
|
|
||||||
case Some(next) if enemies(next) ⇒ board.taking(from, next) map { b ⇒
|
|
||||||
(next, b)
|
|
||||||
} toList
|
|
||||||
case Some(next) ⇒ moving(next) map { b ⇒
|
|
||||||
(next, b) :: forward(next, dir)
|
|
||||||
} getOrElse Nil
|
|
||||||
}
|
|
||||||
|
|
||||||
(dirs flatMap { dir ⇒ forward(from, dir) }) toMap
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue