test and fix featured game heuristics
This commit is contained in:
parent
db548ea40f
commit
eb5c9928b7
|
@ -64,11 +64,9 @@ object Featured {
|
|||
|
||||
case object GetOne
|
||||
|
||||
def best(games: List[DbGame]) = (games sortBy { game ⇒
|
||||
1 - score(game)
|
||||
}).headOption
|
||||
def best(games: List[DbGame]) = (games sortBy score).lastOption
|
||||
|
||||
private def score(game: DbGame): Float = heuristics map {
|
||||
def score(game: DbGame): Float = heuristics map {
|
||||
case (fn, coefficient) ⇒ heuristicBox(fn(game)) * coefficient
|
||||
} sum
|
||||
|
||||
|
@ -76,7 +74,7 @@ object Featured {
|
|||
private val heuristicBox = box(0 to 1) _
|
||||
private val eloBox = box(1200 to 2000) _
|
||||
private val timeBox = box(60 to 300) _
|
||||
private val turnBox = box(1 to 20) _
|
||||
private val turnBox = box(1 to 21) _
|
||||
|
||||
private val heuristics: List[(Heuristic, Float)] = List(
|
||||
eloHeuristic(Color.White) -> 1,
|
||||
|
@ -84,16 +82,16 @@ object Featured {
|
|||
speedHeuristic -> 1,
|
||||
progressHeuristic -> 0.5f)
|
||||
|
||||
private def eloHeuristic(color: Color): Heuristic = game ⇒
|
||||
def eloHeuristic(color: Color): Heuristic = game ⇒
|
||||
eloBox(game.player(color).eloEstimation)
|
||||
|
||||
private def speedHeuristic: Heuristic = game ⇒
|
||||
def speedHeuristic: Heuristic = game ⇒
|
||||
1 - timeBox(game.estimateTotalTime)
|
||||
|
||||
private def progressHeuristic: Heuristic = game ⇒
|
||||
def progressHeuristic: Heuristic = game ⇒
|
||||
1 - turnBox(game.turns)
|
||||
|
||||
// boxes and reduce to 0..1 range
|
||||
private def box(in: Range.Inclusive)(v: Float): Float =
|
||||
math.max(in.start, math.min(v, in.end)) - in.start / (in.end - in.start).toFloat
|
||||
def box(in: Range.Inclusive)(v: Float): Float =
|
||||
(math.max(in.start, math.min(v, in.end)) - in.start) / (in.end - in.start).toFloat
|
||||
}
|
||||
|
|
106
test/FeaturedTest.scala
Normal file
106
test/FeaturedTest.scala
Normal file
|
@ -0,0 +1,106 @@
|
|||
package lila
|
||||
package game
|
||||
|
||||
import game._
|
||||
|
||||
class FeaturedTest extends LilaSpec {
|
||||
|
||||
import Featured._
|
||||
|
||||
"Featured" should {
|
||||
|
||||
"box 0 to 1" in {
|
||||
foreach(List(
|
||||
0f -> 0f,
|
||||
1f -> 1f,
|
||||
0.5f -> 0.5f,
|
||||
0.9f -> 0.9f,
|
||||
-1f -> 0f,
|
||||
2f -> 1f)) {
|
||||
case (a, b) ⇒ box(0 to 1)(a) must_== b
|
||||
}
|
||||
}
|
||||
|
||||
"box 1200 to 2000" in {
|
||||
foreach(List(
|
||||
1200f -> 0f,
|
||||
2000f -> 1f,
|
||||
1600f -> 0.5f,
|
||||
1900f -> 0.875f,
|
||||
-1f -> 0f,
|
||||
800f -> 0f,
|
||||
2200f -> 1f)) {
|
||||
case (a, b) ⇒ box(1200 to 2000)(a) must_== b
|
||||
}
|
||||
}
|
||||
|
||||
val game1 = DbGame(
|
||||
game = chess.Game(),
|
||||
whitePlayer = DbPlayer.white.copy(elo = 1600.some),
|
||||
blackPlayer = DbPlayer.black,
|
||||
ai = None,
|
||||
creatorColor = chess.Color.White,
|
||||
mode = chess.Mode.default,
|
||||
variant = chess.Variant.default)
|
||||
|
||||
val game2 = game1.copy(
|
||||
clock = chess.Clock(180,0).some,
|
||||
turns = 11)
|
||||
|
||||
val game3 = game1.copy(
|
||||
clock = chess.Clock(60,0).some,
|
||||
turns = 21)
|
||||
|
||||
val games = List(game1, game2, game3)
|
||||
|
||||
"elo" in {
|
||||
"game1 white" in {
|
||||
eloHeuristic(chess.Color.White)(game1) must_== 0.5f
|
||||
}
|
||||
"game1 black" in {
|
||||
eloHeuristic(chess.Color.Black)(game1) must_== 0f
|
||||
}
|
||||
}
|
||||
"speed" in {
|
||||
"game1" in {
|
||||
speedHeuristic(game1) must_== 0
|
||||
}
|
||||
"game2" in {
|
||||
speedHeuristic(game2) must_== 0.5f
|
||||
}
|
||||
"game3" in {
|
||||
speedHeuristic(game3) must_== 1f
|
||||
}
|
||||
}
|
||||
"progress" in {
|
||||
"game1" in {
|
||||
progressHeuristic(game1) must_== 1f
|
||||
}
|
||||
"game2" in {
|
||||
progressHeuristic(game2) must_== 0.5f
|
||||
}
|
||||
"game3" in {
|
||||
progressHeuristic(game3) must_== 0f
|
||||
}
|
||||
}
|
||||
"score" in {
|
||||
"game1" in {
|
||||
score(game1) must_== 0.5f + 0f + 1f * 0.5f
|
||||
}
|
||||
"game2" in {
|
||||
score(game2) must_== 0.5f + 0.5f + 0.5f * 0.5f
|
||||
}
|
||||
"game3" in {
|
||||
score(game3) must_== 0.5f + 1f + 0f * 0.5f
|
||||
}
|
||||
}
|
||||
"best" in {
|
||||
"3 games" in {
|
||||
best(games) must_== game3.some
|
||||
}
|
||||
"3 games reversed" in {
|
||||
best(games.reverse) must_== game3.some
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
test/LilaSpec.scala
Normal file
9
test/LilaSpec.scala
Normal file
|
@ -0,0 +1,9 @@
|
|||
package lila
|
||||
|
||||
import org.specs2.mutable._
|
||||
import ornicar.scalalib.test.OrnicarValidationMatchers
|
||||
|
||||
trait LilaSpec
|
||||
extends Specification
|
||||
with OrnicarValidationMatchers {
|
||||
}
|
Loading…
Reference in a new issue