Complete chess captcha implementation

This commit is contained in:
Thibault Duplessis 2012-05-05 13:27:51 +02:00
parent 50c1a5b540
commit ec60369cc0
7 changed files with 19 additions and 11 deletions

View file

@ -14,16 +14,16 @@ final class Captcha(gameRepo: GameRepo) {
gameRepo.findOneCheckmate map { gameOption
for {
game gameOption toValid "No checkmate available"
chess = game.toChess
rewinded rewind(chess)
} yield (game.id, fen(rewinded), !chess.player)
rewinded rewind(game.toChess)
} yield (game.id, fen(rewinded), rewinded.player)
}
def solve(id: String): IO[Valid[NonEmptyList[String]]] =
gameRepo game id map { gameOption
for {
game gameOption toValid "No such game"
moves mateMoves(game.toChess).toNel toValid "No solution found"
rewinded rewind(game.toChess)
moves mateMoves(rewinded).toNel toValid "No solution found"
} yield moves
}
@ -38,7 +38,10 @@ final class Captcha(gameRepo: GameRepo) {
lastMove game.board.history.lastMove toValid "No last move"
(orig, dest) = lastMove
rewindedBoard game.board.move(dest, orig) toValid "Can't rewind board"
} yield game withBoard rewindedBoard
g2 = game withBoard rewindedBoard
g3 = g2 withPlayer !game.player
g4 = g3 withTurns (game.turns - 1)
} yield g4
private def fen(game: Game): String = Forsyth >> game takeWhile (_ != ' ')
}

View file

@ -19,11 +19,9 @@ object CaptchaC extends LilaController {
}
def solve(gameId: String) = Action {
env.captcha.solve(gameId).unsafePerformIO.fold(
env.captcha.solve(gameId).unsafePerformIO.pp.fold(
err BadRequest(err.shows),
moves JsonOk(Map(
"moves" -> moves
))
moves JsonOk(moves.list)
)
}
}

View file

@ -16,6 +16,8 @@ trait LilaController extends Controller with ContentTypes with RequestGetter {
def JsonOk(map: Map[String, Any]) = Ok(Json generate map) as JSON
def JsonOk(list: List[String]) = Ok(Json generate list) as JSON
def JsonIOk(map: IO[Map[String, Any]]) = JsonOk(map.unsafePerformIO)
def ValidOk(valid: Valid[Unit]) = valid.fold(

View file

@ -52,4 +52,8 @@ case class Game(
def withBoard(b: Board) = copy(board = b)
def updateBoard(f: Board => Board) = withBoard(f(board))
def withPlayer(c: Color) = copy(player = c)
def withTurns(t: Int) = copy(turns = t)
}

View file

@ -20,6 +20,7 @@ object Main {
val command: Command = args.toList match {
case "info" :: Nil Info(env)
case "average-elo" :: Nil AverageElo(env)
case "index" :: Nil IndexDb(env.gameRepo)
case "finish" :: Nil new Command {
def apply() = env.gameFinishCommand.apply()

View file

@ -20,8 +20,9 @@ POST /api/rematch-accept/:gameId/:color/:newGameId lila.controllers.AppApiC.re
POST /api/adjust/:username lila.controllers.AppApiC.adjust(username: String)
GET /api/activity/:gameId/:color lila.controllers.AppApiC.activity(gameId: String, color: String)
GET /api/game-version/:gameId lila.controllers.AppApiC.gameVersion(gameId: String)
GET /api/captcha/create lila.controllers.CaptchaC.create
GET /api/captcha/solve lila.controllers.CaptchaC.solve(gameId: String)
GET /api/captcha/solve/:gameId lila.controllers.CaptchaC.solve(gameId: String)
# Lobby Public API
GET /lobby/cancel/:ownerId lila.controllers.LobbyC.cancel(ownerId: String)

1
todo
View file

@ -9,5 +9,4 @@ registered user disconnection delay
better spam protection than anon + http
bad visibility of online indicators during game
force resign
0x1 cannot post in chat
post <div> in chat