Skip to content

Commit

Permalink
test and fix featured game heuristics
Browse files Browse the repository at this point in the history
  • Loading branch information
ornicar committed Jun 21, 2012
1 parent db548ea commit eb5c992
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 10 deletions.
18 changes: 8 additions & 10 deletions app/game/Featured.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,36 +64,34 @@ 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

private type Heuristic = DbGame Float
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,
eloHeuristic(Color.Black) -> 1,
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 changes: 106 additions & 0 deletions test/FeaturedTest.scala
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions test/LilaSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package lila

import org.specs2.mutable._
import ornicar.scalalib.test.OrnicarValidationMatchers

trait LilaSpec
extends Specification
with OrnicarValidationMatchers {
}

0 comments on commit eb5c992

Please sign in to comment.