From a0660900ba493ee8876d8ec0bf89f855ad5beab1 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Sat, 25 Feb 2012 14:08:56 +0100 Subject: [PATCH] Reorganizing moving rules --- src/main/scala/model/Actor.scala | 135 +++++++++++++++++-------------- 1 file changed, 73 insertions(+), 62 deletions(-) diff --git a/src/main/scala/model/Actor.scala b/src/main/scala/model/Actor.scala index fa7ee01a19..b94b4371bb 100644 --- a/src/main/scala/model/Actor.scala +++ b/src/main/scala/model/Actor.scala @@ -6,44 +6,14 @@ import scalaz.Success case class Actor(piece: Piece, pos: Pos, board: Board) { lazy val implications: Implications = kingSafety(piece.role match { - case Pawn ⇒ dir(pos) map { next ⇒ - 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 one = Some(next) filterNot board.occupations - val moving = (pos2: Pos) ⇒ board.move(pos, pos2) - def capture(horizontal: Direction): Option[Implication] = for { - p ← horizontal(next); if (enemies(p)); - b ← board.taking(pos, p) - } yield (p, b) - def enpassant(horizontal: Direction): Option[Implication] = for { - victimPos ← horizontal(pos); if (passable) - victim ← board(victimPos); if victim == !color - Pawn - targetPos ← horizontal(next) - victimFrom ← dir(victimPos) flatMap dir - if board.history.lastMove == Some(victimFrom, victimPos) - b ← board.taking(pos, targetPos, Some(victimPos)) - } yield (targetPos, b) - List( - for (p ← one; b ← moving(p)) yield (p, b), - for { - p ← one; if (unmoved) - p2 ← dir(p); if (!board.occupations(p2)) - b ← moving(p2) - } yield (p2, b), - capture(_.left), - capture(_.right), - enpassant(_.left), - enpassant(_.right) - ).flatten toMap - } getOrElse Map.empty - case r if (r.trajectory) ⇒ implicationTrajectories(r.dirs, pos) + case Pawn ⇒ pawn - 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 + 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 @@ -54,6 +24,14 @@ case class Actor(piece: Piece, pos: Pos, board: Board) { 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 ⇒ + 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 ⇒ @@ -61,16 +39,35 @@ case class Actor(piece: Piece, pos: Pos, board: Board) { } } - // 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 castle: Implications = { + Map.empty + } - private def posTrajectories(dirs: Directions, from: Pos): List[Pos] = { + 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 @@ -79,24 +76,38 @@ case class Actor(piece: Piece, pos: Pos, board: Board) { case Some(next) ⇒ next :: forward(next, dir) } - dirs flatMap { dir ⇒ forward(from, dir) } + dirs flatMap { dir ⇒ forward(pos, dir) } } - private def implicationTrajectories(dirs: Directions, from: Pos): Implications = { + private def pawn = dir(pos) map { next ⇒ + 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 one = Some(next) filterNot board.occupations + val moving = (pos2: Pos) ⇒ board.move(pos, pos2) + def capture(horizontal: Direction): Option[Implication] = for { + p ← horizontal(next); if (enemies(p)); + b ← board.taking(pos, p) + } yield (p, b) + def enpassant(horizontal: Direction): Option[Implication] = for { + victimPos ← horizontal(pos); if (passable) + victim ← board(victimPos); if victim == !color - Pawn + targetPos ← horizontal(next) + victimFrom ← dir(victimPos) flatMap dir + if board.history.lastMove == Some(victimFrom, victimPos) + b ← board.taking(pos, targetPos, Some(victimPos)) + } yield (targetPos, b) + List( + for (p ← one; b ← moving(p)) yield (p, b), + for { + p ← one; if (unmoved) + p2 ← dir(p); if (!board.occupations(p2)) + b ← moving(p2) + } yield (p2, b), + capture(_.left), + capture(_.right), + enpassant(_.left), + enpassant(_.right) + ).flatten toMap + } getOrElse Map.empty - 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 - } }