Progress on round setup

This commit is contained in:
Thibault Duplessis 2012-05-16 01:02:32 +02:00
parent ba38cee499
commit 701e4fc78a
17 changed files with 160 additions and 40 deletions

View file

@ -83,6 +83,8 @@ trait LilaController
def IOk[A](op: IO[A])(implicit writer: Writeable[A], ctype: ContentTypeOf[A]) =
Ok(op.unsafePerformIO)
def IORedirect(op: IO[Call]) = Redirect(op.unsafePerformIO)
// I like Unit requests.
implicit def wUnit: Writeable[Unit] =
Writeable[Unit](_ Codec toUTF8 "ok")

View file

@ -0,0 +1,9 @@
package controllers
import lila._
import views._
object Round extends LilaController {
def player(playerId: String) = TODO
}

View file

@ -7,6 +7,7 @@ import setup._
object Setup extends LilaController {
def forms = env.setup.formFactory
def processor = env.setup.processor
val aiForm = Open { implicit ctx
IOk(forms.aiFilled map { html.setup.ai(_) })
@ -16,7 +17,11 @@ object Setup extends LilaController {
implicit val req = ctx.body
forms.ai.bindFromRequest.fold(
_ Redirect(routes.Lobby.home),
_ Redirect(routes.Lobby.home)
config IORedirect(
processor ai config map { pov
routes.Round.player(pov.playerId)
}
)
)
}

View file

@ -2,7 +2,7 @@ package lila
package core
import com.mongodb.casbah.MongoConnection
import com.mongodb.{ Mongo, MongoOptions, ServerAddress MongoServer }
import com.mongodb.{ DBRef, Mongo, MongoOptions, ServerAddress MongoServer }
import akka.actor._
@ -11,7 +11,7 @@ import play.api.Application
import ui._
final class CoreEnv private(application: Application, settings: Settings) {
final class CoreEnv private (application: Application, settings: Settings) {
implicit val app = application
import settings._
@ -22,7 +22,8 @@ final class CoreEnv private(application: Application, settings: Settings) {
lazy val user = new lila.user.UserEnv(
settings = settings,
mongodb = mongodb.apply _)
mongodb = mongodb.apply _,
dbRef = namespace id new DBRef(mongodb.underlying, namespace, id))
lazy val lobby = new lila.lobby.LobbyEnv(
app = app,
@ -37,7 +38,8 @@ final class CoreEnv private(application: Application, settings: Settings) {
lazy val setup = new lila.setup.SetupEnv(
settings = settings,
mongodb = mongodb.apply _)
mongodb = mongodb.apply _,
gameRepo = game.gameRepo)
lazy val timeline = new lila.timeline.TimelineEnv(
settings = settings,
@ -101,7 +103,7 @@ final class CoreEnv private(application: Application, settings: Settings) {
object CoreEnv {
def apply(app: Application) = new CoreEnv(
app,
app,
new Settings(app.configuration.underlying)
)
}

View file

@ -2,6 +2,7 @@ package lila
package game
import round.{ Event, Progress }
import user.User
import chess.{ History ChessHistory, Board, Move, Pos, Game, Clock, Status, Color, Piece, Variant }
import Color._
import chess.format.{ PgnReader, Fen }
@ -259,4 +260,30 @@ object DbGame {
val fullIdSize = 12
def takeGameId(fullId: String) = fullId take gameIdSize
def apply(
game: Game,
whitePlayer: DbPlayer,
blackPlayer: DbPlayer,
ai: Option[(Color, Int)],
creatorColor: Color,
isRated: Boolean,
variant: Variant,
createdAt: DateTime): DbGame = DbGame(
id = IdGenerator.game,
whitePlayer = whitePlayer,
blackPlayer = blackPlayer,
pgn = "",
status = Status.Created,
turns = game.turns,
clock = game.clock,
lastMove = None,
check = None,
creatorColor = creatorColor,
positionHashes = "",
castles = "KQkq",
isRated = isRated,
variant = variant,
lastMoveTime = None,
createdAt = createdAt.some)
}

View file

@ -2,6 +2,7 @@ package lila
package game
import chess._
import user.User
import com.mongodb.DBRef
@ -27,6 +28,10 @@ case class DbPlayer(
}
} mkString " "
def withUser(user: User)(dbRef: User => DBRef): DbPlayer = copy(
user = dbRef(user).some,
elo = user.elo.some)
def isAi = aiLevel.isDefined
def isHuman = !isAi
@ -50,3 +55,22 @@ case class DbPlayer(
def removeTakebackProposition = copy(isProposingTakeback = false)
}
object DbPlayer {
def apply(
color: Color,
aiLevel: Option[Int]): DbPlayer = DbPlayer(
id = IdGenerator.player,
color = color,
ps = "",
aiLevel = aiLevel,
isWinner = None,
elo = None,
isOfferingDraw = false,
lastDrawOffer = None,
isProposingTakeback = false,
user = None,
moveTimes = "",
blurs = 0)
}

View file

@ -0,0 +1,11 @@
package lila
package game
import ornicar.scalalib.OrnicarRandom
object IdGenerator {
def game = OrnicarRandom nextAsciiString DbGame.gameIdSize
def player = OrnicarRandom nextAsciiString DbGame.playerIdSize
}

View file

@ -7,6 +7,8 @@ case class Pov(game: DbGame, color: Color) {
def player = game player color
def playerId = player.id
def opponent = game player !color
def isPlayerFullId(fullId: Option[String]): Boolean =

View file

@ -1,12 +1,29 @@
package lila
package setup
import chess.Variant
import chess.{ Game, Board, Variant, Color ChessColor }
import elo.EloRange
import game.{ DbGame, DbPlayer }
import org.joda.time.DateTime
case class AiConfig(variant: Variant, level: Int, color: Color) extends Config {
def >> = (variant.id, level, color.name).some
def game = DbGame(
game = Game(board = Board(pieces = variant.pieces)),
ai = Some(!creatorColor -> level),
whitePlayer = DbPlayer(
color = ChessColor.White,
aiLevel = creatorColor.black option level),
blackPlayer = DbPlayer(
color = ChessColor.Black,
aiLevel = creatorColor.white option level),
creatorColor = creatorColor,
isRated = false,
variant = variant,
createdAt = DateTime.now)
}
object AiConfig extends BaseConfig {
@ -17,8 +34,8 @@ object AiConfig extends BaseConfig {
color = Color(c) err "Invalid color " + c)
val default = AiConfig(
variant = variantDefault,
level = 1,
variant = variantDefault,
level = 1,
color = Color.default)
val levelChoices = (1 to 8).toList map { l l.toString -> l.toString }

View file

@ -3,6 +3,7 @@ package setup
import chess.{ Variant, Mode }
import elo.EloRange
import game.{ GameRepo, DbGame, Pov }
trait Config {
@ -11,6 +12,12 @@ trait Config {
// Creator player color
val color: Color
lazy val creatorColor = color.resolve
def game: DbGame
def pov = Pov(game, creatorColor)
}
trait HumanConfig extends Config with EloRange {

View file

@ -2,17 +2,21 @@ package lila
package setup
import http.Context
import game.{ GameRepo, Pov }
import chess.{ Game, Board }
import scalaz.effects._
final class Processor(
configRepo: UserConfigRepo) {
configRepo: UserConfigRepo,
gameRepo: GameRepo) {
def ai(config: AiConfig)(implicit ctx: Context): IO[Unit] = for {
def ai(config: AiConfig)(implicit ctx: Context): IO[Pov] = for {
_ ctx.me.fold(
user configRepo.update(user, ((c: UserConfig) c withAi config)),
io()
)
color = config.color.resolve
} yield ()
pov = config.pov
_ gameRepo insert pov.game
} yield pov
}

View file

@ -4,10 +4,12 @@ package setup
import com.mongodb.casbah.MongoCollection
import core.Settings
import game.GameRepo
final class SetupEnv(
settings: Settings,
mongodb: String MongoCollection) {
mongodb: String MongoCollection,
gameRepo: GameRepo) {
import settings._
@ -17,5 +19,6 @@ final class SetupEnv(
configRepo = configRepo)
lazy val processor = new Processor(
configRepo = configRepo)
configRepo = configRepo,
gameRepo = gameRepo)
}

View file

@ -9,8 +9,8 @@ import play.api.libs.concurrent._
// Keep uptodate with framework/src/play/src/main/scala/play/api/libs/iteratee/Iteratee.scala PushEnumerator (l.1020)
final class LilaEnumerator[E](
in: List[E],
onStart: => Unit = () => (),
onComplete: => Unit = () => (),
onStart: () => Unit = () => (),
onComplete: () => Unit = () => (),
onError: (String, Input[E]) => Unit = (_: String, _: Input[E]) => ())
extends Enumerator[E] with Enumerator.Pushee[E] {
@ -18,7 +18,7 @@ extends Enumerator[E] with Enumerator.Pushee[E] {
var promise: Promise[Iteratee[E, _]] with Redeemable[Iteratee[E, _]] = _
def apply[A](it: Iteratee[E, A]): Promise[Iteratee[E, A]] = {
onStart
onStart()
iteratee = it.asInstanceOf[Iteratee[E, _]]
in foreach push
val newPromise = new STMPromise[Iteratee[E, A]]()
@ -36,31 +36,29 @@ extends Enumerator[E] with Enumerator.Pushee[E] {
def push(item: E): Boolean = {
if (iteratee != null) {
iteratee = iteratee.pureFlatFold[E, Any](
iteratee = iteratee.pureFlatFold[E, Any] {
// DONE
(a, in) => {
onComplete
case Step.Done(a, in) => {
onComplete()
Done(a, in)
},
}
// CONTINUE
k => {
case Step.Cont(k) => {
val next = k(Input.El(item))
next.pureFlatFold(
(a, in) => {
onComplete
next.pureFlatFold {
case Step.Done(a, in) => {
onComplete()
next
},
_ => next,
(_, _) => next)
},
}
case _ => next
}
}
// ERROR
(e, in) => {
case Step.Error(e, in) => {
onError(e, in)
Error(e, in)
})
}
}
true
} else {
false

View file

@ -4,7 +4,6 @@ package socket
import play.api.libs.concurrent._
import play.api.libs.json._
import play.api.libs.iteratee._
import scala.util.Random
object Util {

View file

@ -2,18 +2,23 @@ package lila
package user
import com.mongodb.casbah.MongoCollection
import com.mongodb.casbah.Imports.ObjectId
import com.mongodb.DBRef
import core.Settings
final class UserEnv(
settings: Settings,
mongodb: String MongoCollection) {
mongodb: String MongoCollection,
dbRef: String ObjectId DBRef) {
import settings._
lazy val historyRepo = new HistoryRepo(mongodb(MongoCollectionHistory))
lazy val userRepo = new UserRepo(mongodb(MongoCollectionUser))
lazy val userRepo = new UserRepo(
collection = mongodb(MongoCollectionUser),
dbRef = user dbRef(MongoCollectionUser)(user.id))
lazy val eloUpdater = new EloUpdater(
userRepo = userRepo,

View file

@ -3,13 +3,15 @@ package user
import com.novus.salat._
import com.novus.salat.dao._
import com.mongodb.DBRef
import com.mongodb.casbah.MongoCollection
import com.mongodb.casbah.Imports._
import scalaz.effects._
import com.roundeights.hasher.Implicits._
class UserRepo(collection: MongoCollection)
extends SalatDAO[User, ObjectId](collection) {
class UserRepo(
collection: MongoCollection,
val dbRef: User => DBRef) extends SalatDAO[User, ObjectId](collection) {
def user(userId: String): IO[Option[User]] = user(new ObjectId(userId))

View file

@ -1,6 +1,9 @@
# Game
GET /games controllers.Game.list
# Round
GET /playerId controllers.Round.player(playerId: String)
# Setting
POST /setting/color controllers.Setting.color
POST /setting/sound controllers.Setting.sound