Handle ai first move
This commit is contained in:
parent
875516529b
commit
4908ab9d1f
|
@ -52,6 +52,10 @@ object AppApiC extends LilaController {
|
|||
Ok(api.activity(gameId, color).toString)
|
||||
}
|
||||
|
||||
def possibleMoves(gameId: String, color: String) = Action {
|
||||
JsonIOk(api.possibleMoves(gameId, color))
|
||||
}
|
||||
|
||||
def rematchAccept(gameId: String, color: String, newGameId: String) = Action { implicit request ⇒
|
||||
ValidIOk[RematchData](rematchForm)(r ⇒
|
||||
api.acceptRematch(gameId, newGameId, color, r._1, r._2, r._3))
|
||||
|
|
|
@ -12,11 +12,11 @@ object AppXhrC extends LilaController {
|
|||
private val syncer = env.appSyncer
|
||||
|
||||
def sync(gameId: String, color: String, version: Int, fullId: String) = Action {
|
||||
JsonOk(syncer.sync(gameId, color, version, Some(fullId)).unsafePerformIO)
|
||||
JsonIOk(syncer.sync(gameId, color, version, Some(fullId)))
|
||||
}
|
||||
|
||||
def syncPublic(gameId: String, color: String, version: Int) = Action {
|
||||
JsonOk(syncer.sync(gameId, color, version, None).unsafePerformIO)
|
||||
JsonIOk(syncer.sync(gameId, color, version, None))
|
||||
}
|
||||
|
||||
def move(fullId: String) = Action { implicit request ⇒
|
||||
|
@ -26,13 +26,13 @@ object AppXhrC extends LilaController {
|
|||
}
|
||||
|
||||
def ping() = Action { implicit request =>
|
||||
JsonOk(env.pinger.ping(
|
||||
JsonIOk(env.pinger.ping(
|
||||
username = get("username"),
|
||||
playerKey = get("player_key"),
|
||||
watcherKey = get("watcher"),
|
||||
getNbWatchers = get("get_nb_watchers"),
|
||||
hookId = get("hook_id")
|
||||
).unsafePerformIO)
|
||||
))
|
||||
}
|
||||
|
||||
def nbPlayers() = Action {
|
||||
|
|
|
@ -17,6 +17,8 @@ trait LilaController extends Controller with ContentTypes with RequestGetter {
|
|||
|
||||
def JsonOk(map: Map[String, Any]) = Ok(Json generate map) as JSON
|
||||
|
||||
def JsonIOk(map: IO[Map[String, Any]]) = JsonOk(map.unsafePerformIO)
|
||||
|
||||
def ValidOk(valid: Valid[Unit]) = valid.fold(
|
||||
e ⇒ BadRequest(e.list mkString "\n"),
|
||||
_ ⇒ Ok("ok")
|
||||
|
|
|
@ -16,12 +16,12 @@ object LobbyXhrC extends LilaController {
|
|||
def syncWithoutHook() = sync(None)
|
||||
|
||||
private def sync(hookId: Option[String]) = Action { implicit request =>
|
||||
JsonOk(syncer.sync(
|
||||
JsonIOk(syncer.sync(
|
||||
hookId,
|
||||
getIntOr("auth", 0) == 1,
|
||||
getIntOr("state", 0),
|
||||
getIntOr("messageId", 0),
|
||||
getIntOr("entryId", 0)
|
||||
).unsafePerformIO)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
1
bc
1
bc
|
@ -1,3 +1,4 @@
|
|||
Game.lastMove (and no more in pieces notation)
|
||||
clock time in milliseconds (and no more floating seconds)
|
||||
request promotion is not wrapped in options anymore
|
||||
Game.castles (new field in forsyth format)
|
||||
|
|
|
@ -2,6 +2,7 @@ package lila.chess
|
|||
|
||||
import Pos.posAt
|
||||
import format.Visual
|
||||
import com.roundeights.hasher.Hasher
|
||||
|
||||
case class Board(pieces: Map[Pos, Piece], history: History) {
|
||||
|
||||
|
@ -106,10 +107,7 @@ case class Board(pieces: Map[Pos, Piece], history: History) {
|
|||
})
|
||||
}
|
||||
|
||||
def positionHash = {
|
||||
import com.roundeights.hasher.Implicits._
|
||||
(actors.values map (_.hash) mkString).md5.toString
|
||||
}
|
||||
def positionHash = Hasher(actors.values map (_.hash) mkString).md5.toString
|
||||
|
||||
def visual = Visual >> this
|
||||
|
||||
|
@ -120,7 +118,8 @@ object Board {
|
|||
|
||||
import Pos._
|
||||
|
||||
def apply(pieces: Traversable[(Pos, Piece)]): Board = Board(pieces toMap, History())
|
||||
def apply(pieces: Traversable[(Pos, Piece)]): Board =
|
||||
Board(pieces toMap, History())
|
||||
|
||||
def apply(pieces: (Pos, Piece)*): Board = Board(pieces toMap, History())
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ POST /api/alive/:gameId/:color controllers.AppApiC.alive(gameId: String, col
|
|||
POST /api/draw/:gameId/:color controllers.AppApiC.draw(gameId: String, color: String)
|
||||
POST /api/draw-accept/:gameId/:color controllers.AppApiC.drawAccept(gameId: String, color: String)
|
||||
GET /api/activity/:gameId/:color controllers.AppApiC.activity(gameId: String, color: String)
|
||||
GET /api/possible-moves/:gameId/:color controllers.AppApiC.possibleMoves(gameId: String, color: String)
|
||||
GET /api/nb-players controllers.AppXhrC.nbPlayers
|
||||
|
||||
# Lobby XHR
|
||||
|
|
|
@ -8,6 +8,7 @@ import scalaz.effects._
|
|||
|
||||
case class AppApi(
|
||||
gameRepo: GameRepo,
|
||||
ai: Ai,
|
||||
versionMemo: VersionMemo,
|
||||
aliveMemo: AliveMemo,
|
||||
addEntry: (DbGame, String) ⇒ IO[Unit]) extends IOTools {
|
||||
|
@ -40,6 +41,12 @@ case class AppApi(
|
|||
def start(gameId: String, entryData: String): IO[Unit] = for {
|
||||
game ← gameRepo game gameId
|
||||
_ ← addEntry(game, entryData)
|
||||
_ ← if (game.player.isAi) for {
|
||||
aiResult ← ai(game) map (_.toOption err "AI failure")
|
||||
(newChessGame, move) = aiResult
|
||||
_ ← save(game, game.update(newChessGame, move))
|
||||
} yield ()
|
||||
else io()
|
||||
} yield ()
|
||||
|
||||
def acceptRematch(
|
||||
|
@ -92,6 +99,14 @@ case class AppApi(
|
|||
def activity(gameId: String, colorName: String): Int =
|
||||
Color(colorName) some { aliveMemo.activity(gameId, _) } none 0
|
||||
|
||||
def possibleMoves(gameId: String, colorName: String): IO[Map[String, Any]] =
|
||||
for {
|
||||
color ← ioColor(colorName)
|
||||
game ← gameRepo game gameId
|
||||
} yield game.toChess.situation.destinations map {
|
||||
case (from, dests) ⇒ from.key -> (dests.mkString)
|
||||
} toMap
|
||||
|
||||
private def decodeMessages(messages: String): List[MessageEvent] =
|
||||
(messages split '$').toList map { MessageEvent("system", _) }
|
||||
}
|
||||
|
|
|
@ -40,9 +40,9 @@ final class AppSyncer(
|
|||
clock.remainingTimes mapKeys (_.name)
|
||||
} none null)
|
||||
) filterValues (null !=)
|
||||
} getOrElse failMap
|
||||
} getOrElse Map("reload" -> true)
|
||||
}
|
||||
} except (e ⇒ io(failMap))
|
||||
}
|
||||
|
||||
private def renderEvents(events: List[Event], isPrivate: Boolean) =
|
||||
if (isPrivate) events map {
|
||||
|
@ -68,6 +68,4 @@ final class AppSyncer(
|
|||
}
|
||||
wait(max(1, duration / sleep))
|
||||
}
|
||||
|
||||
private val failMap = Map("reload" -> true)
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ final class SystemEnv(config: Config) {
|
|||
|
||||
lazy val appApi = new AppApi(
|
||||
gameRepo = gameRepo,
|
||||
ai = ai,
|
||||
versionMemo = versionMemo,
|
||||
aliveMemo = aliveMemo,
|
||||
addEntry = lobbyApi.addEntry)
|
||||
|
|
|
@ -54,6 +54,7 @@ class GameRepo(collection: MongoCollection)
|
|||
d("status", _.status)
|
||||
d("turns", _.turns)
|
||||
d("lastMove", _.lastMove)
|
||||
d("check", _.check)
|
||||
d("positionHashes", _.positionHashes)
|
||||
d("castles", _.castles)
|
||||
for (i ← 0 to 1) {
|
||||
|
|
|
@ -14,6 +14,7 @@ case class DbGame(
|
|||
turns: Int,
|
||||
clock: Option[Clock],
|
||||
lastMove: Option[String],
|
||||
check: Option[Pos],
|
||||
creatorColor: Color,
|
||||
positionHashes: String = "",
|
||||
castles: String = "KQkq",
|
||||
|
@ -115,7 +116,8 @@ case class DbGame(
|
|||
else if (situation.staleMate) Stalemate
|
||||
else if (situation.autoDraw) Draw
|
||||
else status,
|
||||
clock = game.clock
|
||||
clock = game.clock,
|
||||
check = if (game.situation.check) game.situation.kingPos else None
|
||||
)
|
||||
|
||||
if (abortable != updated.abortable || (Color.all exists { color ⇒
|
||||
|
|
|
@ -15,6 +15,7 @@ case class RawDbGame(
|
|||
turns: Int,
|
||||
clock: Option[RawDbClock],
|
||||
lastMove: Option[String],
|
||||
check: Option[String],
|
||||
creatorColor: String = "white",
|
||||
positionHashes: String = "",
|
||||
castles: String = "KQkq",
|
||||
|
@ -38,6 +39,7 @@ case class RawDbGame(
|
|||
turns = turns,
|
||||
clock = validClock,
|
||||
lastMove = lastMove,
|
||||
check = check flatMap posAt,
|
||||
creatorColor = trueCreatorColor,
|
||||
positionHashes = positionHashes,
|
||||
castles = castles,
|
||||
|
@ -58,6 +60,7 @@ object RawDbGame {
|
|||
turns = turns,
|
||||
clock = clock map RawDbClock.encode,
|
||||
lastMove = lastMove,
|
||||
check = check map (_.key),
|
||||
creatorColor = creatorColor.name,
|
||||
positionHashes = positionHashes,
|
||||
castles = castles,
|
||||
|
|
Loading…
Reference in a new issue