Merge branch 'master' into websocket

* master:
  Don't create remote AI http class
  Use a byte array input stream in crafty server
  Delay AI service creation to continuously check remote AI health
  Fix user elo history game saving

Conflicts:
	app/Starter.scala
	todo
This commit is contained in:
Thibault Duplessis 2012-04-06 10:09:06 +02:00
commit 4a5c791989
7 changed files with 13 additions and 36 deletions

View file

@ -10,7 +10,7 @@ import scalaz.effects._
final class AppXhr(
val gameRepo: GameRepo,
messenger: Messenger,
ai: Ai,
ai: () Ai,
finisher: Finisher,
val versionMemo: VersionMemo,
aliveMemo: AliveMemo,
@ -39,7 +39,7 @@ final class AppXhr(
_ finisher.moveFinish(g3, color)
} yield ()
else if (g3.player.isAi && g3.playable) for {
aiResult ai(g3) map (_.err)
aiResult ai()(g3) map (_.err)
(newChessGame, move) = aiResult
g4 = g3.update(newChessGame, move)
_ save(g1, g4)

View file

@ -10,7 +10,7 @@ final class Starter(
entryRepo: EntryRepo,
val versionMemo: VersionMemo,
lobbySocket: lobby.Lobby,
ai: Ai) extends IOTools {
ai: () Ai) extends IOTools {
def start(game: DbGame, entryData: String): IO[DbGame] = for {
_ if (game.variant == Standard) io() else gameRepo saveInitialFen game
@ -18,7 +18,7 @@ final class Starter(
entry entryRepo add entry flatMap { _ lobbySocket addEntry entry },
io())
g2 if (game.player.isHuman) io(game) else for {
aiResult ai(game) map (_.err)
aiResult ai()(game) map (_.err)
(newChessGame, move) = aiResult
} yield game.update(newChessGame, move)
} yield g2

View file

@ -91,7 +91,7 @@ final class SystemEnv(config: Config) {
// frequently updated by a scheduled actor
var remoteAiHealth = false
def ai: Ai = config getString "ai.use" match {
def ai: () Ai = () config getString "ai.use" match {
case "remote" remoteAiHealth.fold(remoteAi, craftyAi)
case "crafty" craftyAi
case _ stupidAi

View file

@ -14,11 +14,11 @@ final class HistoryRepo(collection: MongoCollection) {
val tsKey = (System.currentTimeMillis / 1000).toString
collection.update(
DBObject("_id" -> username),
DBObject("$set" -> (("entries." + tsKey) -> DBObject(
$set (("entries." + tsKey) -> DBObject(
"t" -> entryType,
"e" -> elo,
"g" -> gameId
))),
)),
false, false
)
}

View file

@ -4,7 +4,7 @@ package ai
import lila.chess.{ Game, Move }
import model._
import java.io.File
import java.io.ByteArrayInputStream
import scala.io.Source
import scala.sys.process.Process
import scalaz.effects._
@ -18,10 +18,8 @@ final class CraftyServer(
else if (fen.isEmpty) "Empty fen".failNel
else success(runCrafty(fen, level))
def runCrafty(oldFen: String, level: Int): IO[String] = for {
file writeFile("lichess_crafty_", input(oldFen, level))
output io { Process(command(level)) #< file !! }
} yield extractFen(output)
def runCrafty(oldFen: String, level: Int): IO[String] =
io { Process(command(level)) #< input(oldFen, level) !! } map extractFen
private def extractFen(output: String) = {
output.lines.find(_ contains "setboard") map { line
@ -35,14 +33,14 @@ final class CraftyServer(
bookPath | "",
craftyTime(level))
private def input(fen: String, level: Int) = List(
private def input(fen: String, level: Int) = new ByteArrayInputStream(List(
"skill %d" format craftySkill(level),
"book random 1",
"book width 10",
"setboard %s" format fen,
"move",
"savepos",
"quit")
"quit") mkString "\n" getBytes "UTF-8")
private def craftyTime(level: Int) = (level / 10f).toString take 4
@ -50,21 +48,4 @@ final class CraftyServer(
case 8 100
case l l * 12
}
private def writeFile(prefix: String, data: List[String]): IO[File] = io {
File.createTempFile(prefix, ".tmp") ~ { file
try {
file.deleteOnExit
}
catch {
case e println("Error deleting crafty file on exit: " + e.getMessage)
}
printToFile(file)(p data foreach p.println)
}
}
private def printToFile(f: java.io.File)(op: java.io.PrintWriter Unit) {
val p = new java.io.PrintWriter(f)
try { op(p) } finally { p.close() }
}
}

View file

@ -9,15 +9,12 @@ import dispatch._
final class RemoteAi(remoteUrl: String) extends Ai with FenBased {
private class AiHttp extends Http with thread.Safety {
private lazy val http = new Http with thread.Safety {
override def make_logger = new Logger {
def info(msg: String, items: Any*) {}
def warn(msg: String, items: Any*) { println("WARN: " + msg.format(items: _*)) }
}
}
private lazy val http = new AiHttp
private lazy val urlObj = url(remoteUrl)
def apply(dbGame: DbGame): IO[Valid[(Game, Move)]] = {

1
todo
View file

@ -5,4 +5,3 @@ ping nbm
http://en.lichess.org/@/noworkingmen elo graph missing
need ability to cancel rematch
compress player.ps notation
move ai to marty