make storm puzzle reviews unrated - closes #8008
This commit is contained in:
parent
25b4674c14
commit
2dfda8d5c2
|
@ -33,13 +33,20 @@ final class Puzzle(
|
|||
else
|
||||
env.puzzle.jsonView(puzzle = puzzle, theme = theme, replay = replay, user = newUser orElse ctx.me)
|
||||
|
||||
private def renderShow(puzzle: Puz, theme: PuzzleTheme, replay: Option[PuzzleReplay] = None)(implicit
|
||||
private def renderShow(
|
||||
puzzle: Puz,
|
||||
theme: PuzzleTheme,
|
||||
replay: Option[PuzzleReplay] = None
|
||||
)(implicit
|
||||
ctx: Context
|
||||
) =
|
||||
renderJson(puzzle, theme, replay) zip
|
||||
ctx.me.??(u => env.puzzle.session.getDifficulty(u) dmap some) map { case (json, difficulty) =>
|
||||
EnableSharedArrayBuffer(
|
||||
Ok(views.html.puzzle.show(puzzle, json, env.puzzle.jsonView.pref(ctx.pref), difficulty))
|
||||
Ok(
|
||||
views.html.puzzle
|
||||
.show(puzzle, json, env.puzzle.jsonView.pref(ctx.pref), difficulty)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -216,8 +223,11 @@ final class Puzzle(
|
|||
nextPuzzleForMe(theme.key) flatMap {
|
||||
renderShow(_, theme)
|
||||
}
|
||||
case None if themeOrId.size == 5 =>
|
||||
OptionFuResult(env.puzzle.api.puzzle find Puz.Id(themeOrId)) { renderShow(_, PuzzleTheme.mix) }
|
||||
case None if themeOrId.size == Puz.idSize =>
|
||||
OptionFuResult(env.puzzle.api.puzzle find Puz.Id(themeOrId)) { puz =>
|
||||
ctx.me.ifTrue(getBool("casual")) foreach { env.puzzle.api.casual.set(_, puz.id) }
|
||||
renderShow(puz, PuzzleTheme.mix)
|
||||
}
|
||||
case None =>
|
||||
themeOrId.toLongOption
|
||||
.flatMap(Puz.numericalId.apply)
|
||||
|
|
|
@ -146,4 +146,15 @@ final class PuzzleApi(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
object casual {
|
||||
|
||||
private val store = new lila.memo.ExpireSetMemo(30 minutes)
|
||||
|
||||
private def key(user: User, id: Puzzle.Id) = s"${user.id}:${id}"
|
||||
|
||||
def set(user: User, id: Puzzle.Id) = store.put(key(user, id))
|
||||
|
||||
def apply(user: User, id: Puzzle.Id) = store.get(key(user, id))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,87 +36,96 @@ final private[puzzle] class PuzzleFinisher(
|
|||
user: User,
|
||||
result: Result
|
||||
): Fu[Option[(PuzzleRound, Perf)]] =
|
||||
sequencer(id.value) {
|
||||
api.round.find(user, id) flatMap { prevRound =>
|
||||
api.puzzle.find(id) flatMap {
|
||||
_ ?? { puzzle =>
|
||||
val now = DateTime.now
|
||||
val formerUserRating = user.perfs.puzzle.intRating
|
||||
if (api.casual(user, id)) fuccess {
|
||||
PuzzleRound(
|
||||
id = PuzzleRound.Id(user.id, id),
|
||||
win = result.win,
|
||||
fixedAt = none,
|
||||
date = DateTime.now
|
||||
) -> user.perfs.puzzle
|
||||
} dmap some
|
||||
else
|
||||
sequencer(id.value) {
|
||||
api.round.find(user, id) flatMap { prevRound =>
|
||||
api.puzzle.find(id) flatMap {
|
||||
_ ?? { puzzle =>
|
||||
val now = DateTime.now
|
||||
val formerUserRating = user.perfs.puzzle.intRating
|
||||
|
||||
val (round, newPuzzleGlicko, userPerf) = prevRound match {
|
||||
case Some(prev) =>
|
||||
(
|
||||
prev.updateWithWin(result.win),
|
||||
none,
|
||||
user.perfs.puzzle
|
||||
)
|
||||
case None =>
|
||||
val userRating = user.perfs.puzzle.toRating
|
||||
val puzzleRating = new Rating(
|
||||
puzzle.glicko.rating atLeast Glicko.minRating,
|
||||
puzzle.glicko.deviation,
|
||||
puzzle.glicko.volatility,
|
||||
puzzle.plays,
|
||||
null
|
||||
)
|
||||
updateRatings(userRating, puzzleRating, result.glicko)
|
||||
val newPuzzleGlicko = ponder
|
||||
.puzzle(
|
||||
theme,
|
||||
result,
|
||||
puzzle.glicko -> Glicko(
|
||||
rating = puzzleRating.getRating
|
||||
.atMost(puzzle.glicko.rating + Glicko.maxRatingDelta)
|
||||
.atLeast(puzzle.glicko.rating - Glicko.maxRatingDelta),
|
||||
deviation = puzzleRating.getRatingDeviation,
|
||||
volatility = puzzleRating.getVolatility
|
||||
).cap,
|
||||
player = user.perfs.puzzle.glicko
|
||||
val (round, newPuzzleGlicko, userPerf) = prevRound match {
|
||||
case Some(prev) =>
|
||||
(
|
||||
prev.updateWithWin(result.win),
|
||||
none,
|
||||
user.perfs.puzzle
|
||||
)
|
||||
.some
|
||||
.filter(puzzle.glicko !=)
|
||||
.filter(_.sanityCheck)
|
||||
val round =
|
||||
PuzzleRound(
|
||||
id = PuzzleRound.Id(user.id, puzzle.id),
|
||||
win = result.win,
|
||||
fixedAt = none,
|
||||
date = DateTime.now
|
||||
case None =>
|
||||
val userRating = user.perfs.puzzle.toRating
|
||||
val puzzleRating = new Rating(
|
||||
puzzle.glicko.rating atLeast Glicko.minRating,
|
||||
puzzle.glicko.deviation,
|
||||
puzzle.glicko.volatility,
|
||||
puzzle.plays,
|
||||
null
|
||||
)
|
||||
val userPerf =
|
||||
user.perfs.puzzle
|
||||
.addOrReset(_.puzzle.crazyGlicko, s"puzzle ${puzzle.id}")(userRating, now) pipe { p =>
|
||||
p.copy(glicko =
|
||||
ponder.player(theme, result, user.perfs.puzzle.glicko -> p.glicko, puzzle.glicko)
|
||||
updateRatings(userRating, puzzleRating, result.glicko)
|
||||
val newPuzzleGlicko = ponder
|
||||
.puzzle(
|
||||
theme,
|
||||
result,
|
||||
puzzle.glicko -> Glicko(
|
||||
rating = puzzleRating.getRating
|
||||
.atMost(puzzle.glicko.rating + Glicko.maxRatingDelta)
|
||||
.atLeast(puzzle.glicko.rating - Glicko.maxRatingDelta),
|
||||
deviation = puzzleRating.getRatingDeviation,
|
||||
volatility = puzzleRating.getVolatility
|
||||
).cap,
|
||||
player = user.perfs.puzzle.glicko
|
||||
)
|
||||
}
|
||||
(round, newPuzzleGlicko, userPerf)
|
||||
}
|
||||
api.round.upsert(round, theme) zip
|
||||
colls.puzzle {
|
||||
_.update
|
||||
.one(
|
||||
$id(puzzle.id),
|
||||
$inc(Puzzle.BSONFields.plays -> $int(1)) ++ newPuzzleGlicko.?? { glicko =>
|
||||
$set(Puzzle.BSONFields.glicko -> Glicko.glickoBSONHandler.write(glicko))
|
||||
.some
|
||||
.filter(puzzle.glicko !=)
|
||||
.filter(_.sanityCheck)
|
||||
val round =
|
||||
PuzzleRound(
|
||||
id = PuzzleRound.Id(user.id, puzzle.id),
|
||||
win = result.win,
|
||||
fixedAt = none,
|
||||
date = DateTime.now
|
||||
)
|
||||
val userPerf =
|
||||
user.perfs.puzzle
|
||||
.addOrReset(_.puzzle.crazyGlicko, s"puzzle ${puzzle.id}")(userRating, now) pipe { p =>
|
||||
p.copy(glicko =
|
||||
ponder.player(theme, result, user.perfs.puzzle.glicko -> p.glicko, puzzle.glicko)
|
||||
)
|
||||
}
|
||||
)
|
||||
.void
|
||||
} zip
|
||||
(userPerf != user.perfs.puzzle).?? {
|
||||
userRepo.setPerf(user.id, PerfType.Puzzle, userPerf.clearRecent) zip
|
||||
historyApi.addPuzzle(user = user, completedAt = now, perf = userPerf) void
|
||||
} >>- {
|
||||
if (prevRound.isEmpty)
|
||||
Bus.publish(
|
||||
Puzzle.UserResult(puzzle.id, user.id, result, formerUserRating -> userPerf.intRating),
|
||||
"finishPuzzle"
|
||||
)
|
||||
} inject (round -> userPerf).some
|
||||
(round, newPuzzleGlicko, userPerf)
|
||||
}
|
||||
api.round.upsert(round, theme) zip
|
||||
colls.puzzle {
|
||||
_.update
|
||||
.one(
|
||||
$id(puzzle.id),
|
||||
$inc(Puzzle.BSONFields.plays -> $int(1)) ++ newPuzzleGlicko.?? { glicko =>
|
||||
$set(Puzzle.BSONFields.glicko -> Glicko.glickoBSONHandler.write(glicko))
|
||||
}
|
||||
)
|
||||
.void
|
||||
} zip
|
||||
(userPerf != user.perfs.puzzle).?? {
|
||||
userRepo.setPerf(user.id, PerfType.Puzzle, userPerf.clearRecent) zip
|
||||
historyApi.addPuzzle(user = user, completedAt = now, perf = userPerf) void
|
||||
} >>- {
|
||||
if (prevRound.isEmpty)
|
||||
Bus.publish(
|
||||
Puzzle.UserResult(puzzle.id, user.id, result, formerUserRating -> userPerf.intRating),
|
||||
"finishPuzzle"
|
||||
)
|
||||
} inject (round -> userPerf).some
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object ponder {
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ const renderHistory = (ctrl: StormCtrl): VNode =>
|
|||
h('div.storm--end__history__round', [
|
||||
h('a.storm--end__history__round__puzzle.mini-board.cg-wrap.is2d', {
|
||||
attrs: {
|
||||
href: `/training/${round.puzzle.id}`,
|
||||
href: `/training/${round.puzzle.id}?casual=1`,
|
||||
target: '_blank'
|
||||
},
|
||||
hook: onInsert(e => {
|
||||
|
|
Loading…
Reference in a new issue