This commit is contained in:
Thibault Duplessis 2012-03-14 17:14:18 +01:00
parent f6cf5e8ff1
commit aa00870a89
7 changed files with 182 additions and 190 deletions

View file

@ -43,7 +43,7 @@ class Benchmark extends SimpleScalaBenchmark {
val repo = env.gameRepo
val server = env.server
def move(game: DbGame, m: String = "d2 d4") = server.playMove(game fullIdOf White, m)
def move(game: DbGame, m: String = "d2 d4") = server.playMove(game fullIdOf White, m).unsafePerformIO
val moves = List("e2 e4", "d7 d5", "e4 d5", "d8 d5", "b1 c3", "d5 a5", "d2 d4", "c7 c6", "g1 f3", "c8 g4", "c1 f4", "e7 e6", "h2 h3", "g4 f3", "d1 f3", "f8 b4", "f1 e2", "b8 d7", "a2 a3", "e8 c8", "a3 b4", "a5 a1", "e1 d2", "a1 h1", "f3 c6", "b7 c6", "e2 a6")

View file

@ -30,4 +30,6 @@ case class Move(
def castles = castle.isDefined
def color = piece.color
override def toString = orig + " " + dest
}

View file

@ -19,7 +19,7 @@ trait Dependencies {
val casbah = "com.mongodb.casbah" %% "casbah" % "2.1.5-1"
val salat = "com.novus" %% "salat-core" % "0.0.8-SNAPSHOT"
val slf4j = "org.slf4j" % "slf4j-nop" % "1.6.4"
val scalalib = "com.github.ornicar" %% "scalalib" % "1.20"
val scalalib = "com.github.ornicar" %% "scalalib" % "1.23"
val hasher = "com.roundeights" % "hasher" % "0.3" from "http://cloud.github.com/downloads/Nycto/Hasher/hasher_2.9.1-0.3.jar"
val config = "com.typesafe.config" % "config" % "0.3.0"
@ -66,17 +66,18 @@ object ApplicationBuild extends Build with Resolvers with Dependencies {
// `fullClasspath in Runtime` is a TaskKey, so we need to
// jump through these hoops here in order to
// feed the result of the latter into the former
onLoad in Global ~= { previous => state =>
previous {
state get key match {
case None =>
// get the runtime classpath, turn into a colon-delimited string
val classPath = Project.runTask(fullClasspath in Runtime, state).get._2.toEither.right.get.files.mkString(":")
// return a state with javaOptionsPatched = true and javaOptions set correctly
Project.extract(state).append(Seq(javaOptions in run ++= Seq("-cp", classPath)), state.put(key, true))
case Some(_) => state // the javaOptions are already patched
onLoad in Global ~= { previous
state
previous {
state get key match {
case None
// get the runtime classpath, turn into a colon-delimited string
val classPath = Project.runTask(fullClasspath in Runtime, state).get._2.toEither.right.get.files.mkString(":")
// return a state with javaOptionsPatched = true and javaOptions set correctly
Project.extract(state).append(Seq(javaOptions in run ++= Seq("-cp", classPath)), state.put(key, true))
case Some(_) state // the javaOptions are already patched
}
}
}
}
) dependsOn (chess, system)

View file

@ -19,11 +19,10 @@ final class Server(repo: GameRepo, ai: Ai) {
}
def doPlay(
game: Valid[DbGame],
g1: DbGame,
fullId: String,
moveString: String,
promString: Option[String]): Valid[DbGame] = for {
g1 game
g2 if (g1.playable) success(g1) else failure("Game is not playable" wrapNel)
moveParts decodeMoveString(moveString) toValid "Wrong move"
(origString, destString) = moveParts

View file

@ -12,7 +12,7 @@ case class DbPlayer(
evts: String = "",
elo: Option[Int]) {
def eventStack = EventStack decode evts
def eventStack: EventStack = EventStack decode evts
def newEvts(events: List[Event]): String =
(eventStack withEvents events).optimize.encode

View file

@ -15,15 +15,11 @@ class GameRepoTest extends SystemTest {
"find a game" in {
"by ID" in {
"non existing" in {
repo game "haha" must beIO.like {
case g g must beFailure
}
repo game "haha" must beIO.failure
}
"existing" in {
repo game anyGame.id must beIO.like {
case vg vg must beSuccess.like {
case g g.id must_== anyGame.id
}
case g g.id must_== anyGame.id
}
}
}
@ -31,33 +27,25 @@ class GameRepoTest extends SystemTest {
"find a player" in {
"by private ID" in {
"non existing" in {
repo player "huhu" must beIO.like {
case p p must beFailure
}
repo player "huhu" must beIO.failure
}
"existing" in {
val player = anyGame.players.head
anyGame fullIdOf player map repo.player must beSome.like {
case iop iop must beIO.like {
case vgp vgp must beSuccess.like {
case (g, p) p.id must_== player.id
}
case (g, p) p.id must_== player.id
}
}
}
}
"by ID and color" in {
"non existing" in {
repo.player("haha", White) must beIO.like {
case vp vp must beFailure
}
repo.player("haha", White) must beIO.failure
}
"existing" in {
val player = anyGame.players.head
repo.player(anyGame.id, player.color) must beIO.like {
case vgp vgp must beSuccess.like {
case (g, p) p.id must_== player.id
}
case (g, p) p.id must_== player.id
}
}
}
@ -69,9 +57,7 @@ class GameRepoTest extends SystemTest {
_ repo insert game
newGame repo game game.id
} yield newGame) must beIO.like {
case iog iog must beSuccess.like {
case g g must_== game
}
case g g must_== game
}
}
}
@ -84,9 +70,7 @@ class GameRepoTest extends SystemTest {
_ repo save updated
newGame repo game game.id
} yield newGame) must beIO.like {
case iog iog must beSuccess.like {
case g g must_== updated
}
case g g must_== updated
}
}
}

View file

@ -22,168 +22,174 @@ class ServerTest extends SystemTest {
game: DbGame = newDbGameWithRandomIds,
m: String = "d2 d4"): IO[Valid[DbGame]] = for {
inserted insert(game)
res move(inserted)
updated res.fold(
res move(inserted, m)
updatedGame res.fold(
e io(Failure(e)),
_ repo game game.id
_ repo game game.id map (x success(x))
)
} yield updated
} yield updatedGame
"the server" should {
//"play a single move" in {
//"wrong player" in {
//insert() flatMap { move(_, "d7 d5") } must beIO.like {
//case g g must beFailure
//}
//}
//"report success" in {
//insert() flatMap { move(_) } must beIO.like {
//case g g must beSuccess
//}
//}
//"be persisted" in {
//"update turns" in {
//updated() must beIO.like {
//case vg vg must beSuccess.like {
//case g g.turns must_== 1
//}
//}
//}
//"update board" in {
//updated() must beIO.like {
//case vg vg must beSuccess.like {
//case g addNewLines(g.toChess.board.visual) must_== """
//rnbqkbnr
//pppppppp
def play(game: IO[DbGame], ms: List[String]): IO[Valid[DbGame]] =
ms.foldLeft(game map { g Success(g) }: IO[Valid[DbGame]]) {
case (ioGame, move) for {
vGame ioGame
newGame vGame.fold(
e io(Failure(e)),
game updated(game, move)
)
} yield newGame
}
//P
//PPP PPPP
//RNBQKBNR
//"""
//}
//}
//}
//}
//}
"play the Peruvian Immortal" in {
val moves = List("e2 e4", "d7 d5", "e4 d5", "d8 d5", "b1 c3", "d5 a5", "d2 d4", "c7 c6", "g1 f3", "c8 g4", "c1 f4", "e7 e6", "h2 h3", "g4 f3", "d1 f3", "f8 b4", "f1 e2", "b8 d7", "a2 a3", "e8 c8", "a3 b4", "a5 a1", "e1 d2", "a1 h1", "f3 c6", "b7 c6", "e2 a6")
def play(game: IO[DbGame]): IO[Valid[DbGame]] =
moves.foldLeft(game map { g Success(g) }: IO[Valid[DbGame]]) {
case (ioGame, move) for {
vGame ioGame
newGame vGame.fold(
e io(Failure(e)),
game updated(game, move)
)
} yield newGame
}
//A List[B] (A B IO[Validation[E, A]]) IO[Validation[E, A]]
"report success" in {
play(insert()) must beIO.like {
case vg vg must beSuccess
"play a single move" in {
"wrong player" in {
insert() flatMap { move(_, "d7 d5") } must beIO.like {
case g g must beFailure
}
}
"report success" in {
insert() flatMap { move(_) } must beIO.like {
case g g must beSuccess
}
}
"be persisted" in {
"update turns" in {
updated() must beIO.like {
case vg vg must beSuccess.like {
case g g.turns must_== 1
}
}
}
//"be persisted" in {
//val found = for {
//game insert()
//found repo game game.id
//} yield found
"update board" in {
updated() must beIO.like {
case vg vg must beSuccess.like {
case g addNewLines(g.toChess.board.visual) must_== """
rnbqkbnr
pppppppp
//"update turns" in {
//found must beIO.like {
//case vg vg must beSuccess.like {
//case g g.turns must_== 27
//}
//}
//}
//"update board" in {
//found must beIO.like {
//case vg vg must beSuccess.like {
//case g addNewLines(g.toChess.board.visual) must_== """
//kr nr
//p n ppp
//B p p
//P P B
//N P
//PPK PP
//q
//"""
//}
//}
//}
//"event stacks" in {
//val stack = for {
//valid found
//} yield for {
//game valid
//} yield game player White eventStack
P
//"high version number" in {
//stack must beIO.like {
//case vs vs must beSuccess.like {
//case s s.version must be_>(20)
//}
//}
//}
//"rotated" in {
//stack must beIO.like {
//case vs vs must beSuccess.like {
//case s s.events.size must_== EventStack.maxEvents
//}
//}
//}
//}
//}
PPP PPPP
RNBQKBNR
"""
}
}
}
}
//"play to threefold repetition" in {
//val moves = List("b1 c3", "b8 c6", "c3 b1", "c6 b8", "b1 c3", "b8 c6", "c3 b1", "c6 b8", "b1 c3", "b8 c6")
}
"play the Peruvian Immortal" in {
//def play(game: DbGame) = for (m moves) yield move(game, m)
val moves = List("e2 e4", "d7 d5", "e4 d5", "d8 d5", "b1 c3", "d5 a5", "d2 d4", "c7 c6", "g1 f3", "c8 g4", "c1 f4", "e7 e6", "h2 h3", "g4 f3", "d1 f3", "f8 b4", "f1 e2", "b8 d7", "a2 a3", "e8 c8", "a3 b4", "a5 a1", "e1 d2", "a1 h1", "f3 c6", "b7 c6", "e2 a6")
//"report success" in {
//val game = insert()
//sequenceValid(play(game)) must beSuccess
//}
//"be persisted" in {
//val game = insert()
//play(game)
//val found = repo game game.id
//val events = found map (_ player White) map (_.eventStack.events)
//"propose threefold" in {
//events must beSome.like {
//case es es map (_._2) must contain(ThreefoldEvent())
//}
//}
//}
//}
//"play on playing game" in {
//val dbGame = insert(randomizeIds(newDbGameWithBoard("""
//PP kr
//K
//""")))
//move(dbGame, "a1 b1") must beSuccess
//}
//"play on finished game" in {
//"by checkmate" in {
//val game = insert(randomizeIds(newDbGameWithBoard("""
//PP
//K r
//""")))
//move(game, "a1 b1") must beFailure
//}
//"by autodraw" in {
//val game = insert(randomizeIds(newDbGameWithBoard("""
//k
//K B""")))
//move(game, "a1 b1") must beFailure
//}
//}
"report success" in {
play(insert(), moves) must beIO.like {
case vg vg must beSuccess
}
}
"be persisted" in {
def found: IO[Valid[DbGame]] = for {
game play(insert(), moves)
found game.fold(
e io(Failure(e)),
a repo game a.id map Success.apply
)
} yield found
"update turns" in {
found must beIO.like {
case vg vg must beSuccess.like {
case g g.turns must_== 27
}
}
}
"update board" in {
found must beIO.like {
case vg vg must beSuccess.like {
case g addNewLines(g.toChess.board.visual) must_== """
kr nr
p n ppp
B p p
P P B
N P
PPK PP
q
"""
}
}
}
"event stacks" in {
"high version number" in {
found must beIO.like {
case vg vg must beSuccess.like {
case g g.player(White).eventStack.version must be_>(20)
}
}
}
"rotated" in {
found must beIO.like {
case vg vg must beSuccess.like {
case g g.player(White).eventStack.events.size must_== EventStack.maxEvents
}
}
}
}
}
}
"play to threefold repetition" in {
val moves = List("b1 c3", "b8 c6", "c3 b1", "c6 b8", "b1 c3", "b8 c6", "c3 b1", "c6 b8", "b1 c3", "b8 c6")
"report success" in {
play(insert(), moves) must beIO.like {
case vg vg must beSuccess.like {
case g g.player(White).eventStack.events map (_._2) must contain(ThreefoldEvent())
}
}
}
"be persisted" in {
def found: IO[Valid[DbGame]] = for {
game play(insert(), moves)
found game.fold(
e io(Failure(e)),
a repo game a.id map Success.apply
)
} yield found
"propose threefold" in {
found must beIO.like {
case vg vg must beSuccess.like {
case g g.player(White).eventStack.events map (_._2) must contain(ThreefoldEvent())
}
}
}
}
}
"play on playing game" in {
val dbGame = insert(randomizeIds(newDbGameWithBoard("""
PP kr
K
""")))
play(dbGame, List("a1 b1")) must beIO.like {
case vg vg must beSuccess
}
}
"play on finished game" in {
"by checkmate" in {
val dbGame = insert(randomizeIds(newDbGameWithBoard("""
PP
K r
""")))
play(dbGame, List("a1 b1")) must beIO.like {
case vg vg must beFailure
}
}
"by autodraw" in {
val dbGame = insert(randomizeIds(newDbGameWithBoard("""
k
K B""")))
play(dbGame, List("a1 b1")) must beIO.like {
case vg vg must beFailure
}
}
}
}