integrate horde chess

pull/382/head
Thibault Duplessis 2015-03-09 15:22:54 +01:00
parent 343bb71115
commit 347cb02c59
19 changed files with 53 additions and 20 deletions

View File

@ -121,6 +121,7 @@ object User extends LilaController {
threeCheck env.cached topPerf PerfType.ThreeCheck.key
antichess <- env.cached topPerf PerfType.Antichess.key
atomic <- env.cached topPerf PerfType.Atomic.key
horde <- env.cached topPerf PerfType.Horde.key
nbAllTime env.cached topNbGame nb map2 { (user: UserModel) =>
user -> user.count.game
}

View File

@ -52,6 +52,7 @@ trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHel
case chess.variant.ThreeCheck => "Three checks"
case chess.variant.Antichess => "Lose all your pieces to win"
case chess.variant.Atomic => "Explode or mate your opponent's king to win"
case chess.variant.Horde => "Destroy the horde to win"
case _ => "Variant ending"
}
case _ => "Game is still being played"

View File

@ -31,14 +31,15 @@ trait UserHelper { self: I18nHelper with StringHelper =>
PerfType.ThreeCheck,
PerfType.Correspondence,
PerfType.Antichess,
PerfType.Atomic)
PerfType.Atomic,
PerfType.Horde)
private def best3Of(u: User, perfTypes: List[PerfType]) =
perfTypes.sortBy { pt => -u.perfs(pt).nb } take 3
def miniViewSortedPerfTypes(u: User): List[PerfType] =
best3Of(u, List(PerfType.Bullet, PerfType.Blitz, PerfType.Classical, PerfType.Correspondence)) :::
best3Of(u, List(PerfType.Chess960, PerfType.KingOfTheHill, PerfType.ThreeCheck, PerfType.Antichess, PerfType.Atomic))
best3Of(u, List(PerfType.Chess960, PerfType.KingOfTheHill, PerfType.ThreeCheck, PerfType.Antichess, PerfType.Atomic, PerfType.Horde))
def showPerfRating(rating: Int, name: String, nb: Int, icon: Char, klass: String) = Html {
val title = s"$name rating over $nb games"

View File

@ -8,6 +8,7 @@ case chess.variant.ThreeCheck => {http://en.wikipedia.org/wiki/Three-check_chess
case chess.variant.Antichess => {http://en.wikipedia.org/wiki/Losing_chess}
case chess.variant.FromPosition => {@routes.Editor.index?fen=@initialFen}
case chess.variant.Atomic => {http://www.freechess.org/Help/HelpFiles/atomic.html}
case chess.variant.Horde => {http://en.wikipedia.org/wiki/Dunsany%27s_chess}
case _ => {}
}
}

View File

@ -48,6 +48,9 @@
@if(u.perfs.atomic.nonEmpty) {
@showPerf(u.perfs.atomic, PerfType.Atomic)
}
@if(u.perfs.horde.nonEmpty) {
@showPerf(u.perfs.horde, PerfType.Horde)
}
<br />
}
@showPerf(u.perfs.puzzle, PerfType.Puzzle)

@ -1 +1 @@
Subproject commit 3dd69f529bfdce8f1af127577bfb4104e57d72d7
Subproject commit 97c55ada4ae78d797730f24e83b137d69c7af6a7

View File

@ -56,7 +56,7 @@ object Evaluation {
import play.api.libs.functional.syntax._
private[evaluation] def watchPerfs(p: Perfs): List[Perf] =
List(p.bullet, p.blitz, p.classical, p.chess960, p.antichess, p.atomic, p.kingOfTheHill, p.threeCheck)
List(p.bullet, p.blitz, p.classical, p.chess960, p.antichess, p.atomic, p.kingOfTheHill, p.threeCheck, p.horde)
private[evaluation] object heuristics {

View File

@ -2,8 +2,8 @@ package lila.game
import chess.Color.{ White, Black }
import chess.Pos.piotr, chess.Role.forsyth
import chess.{ History => ChessHistory, CheckCount, Castles, Role, Board, Move, Pos, Game => ChessGame, Clock, Status, Color, Piece, Mode, PositionHash }
import chess.variant.Variant
import chess.{ History => ChessHistory, CheckCount, Castles, Role, Board, Move, Pos, Game => ChessGame, Clock, Status, Color, Piece, Mode, PositionHash }
import org.joda.time.DateTime
import lila.db.ByteArray
@ -147,7 +147,7 @@ case class Game(
def copyPlayer(player: Player) = player.copy(
blurs = math.min(
playerMoves(player.color),
playerMoves(player.color),
player.blurs + (blur && move.color == player.color).fold(1, 0))
)
@ -430,6 +430,7 @@ object Game {
val variantsWhereWhiteIsBetter: Set[Variant] = Set(
chess.variant.ThreeCheck,
chess.variant.Atomic,
chess.variant.Horde,
chess.variant.Antichess)
val gameIdSize = 8

View File

@ -8,8 +8,9 @@ case class History(
chess960: RatingsMap,
kingOfTheHill: RatingsMap,
antichess: RatingsMap,
atomic: RatingsMap,
threeCheck: RatingsMap,
atomic: RatingsMap,
horde: RatingsMap,
bullet: RatingsMap,
blitz: RatingsMap,
classical: RatingsMap,
@ -25,8 +26,9 @@ case class History(
case PerfType.Chess960 => chess960
case PerfType.KingOfTheHill => kingOfTheHill
case PerfType.Antichess => antichess
case PerfType.Atomic => atomic
case PerfType.ThreeCheck => threeCheck
case PerfType.Atomic => atomic
case PerfType.Horde => horde
case PerfType.Puzzle => puzzle
}
}
@ -55,6 +57,7 @@ object History {
threeCheck = ratingsMap("threeCheck"),
antichess = ratingsMap("antichess"),
atomic = ratingsMap("atomic"),
horde = ratingsMap("horde"),
bullet = ratingsMap("bullet"),
blitz = ratingsMap("blitz"),
classical = ratingsMap("classical"),

View File

@ -22,6 +22,7 @@ final class HistoryApi(coll: Coll) {
game.variant.threeCheck.option("threeCheck" -> perfs.threeCheck),
game.variant.antichess.option("antichess" -> perfs.antichess),
game.variant.atomic.option("atomic" -> perfs.atomic),
game.variant.horde.option("horde" -> perfs.horde),
(isStd && game.speed == Speed.Bullet).option("bullet" -> perfs.bullet),
(isStd && game.speed == Speed.Blitz).option("blitz" -> perfs.blitz),
(isStd && game.speed == Speed.Classical).option("classical" -> perfs.classical),

View File

@ -51,7 +51,7 @@ final class RatingChartApi(
Json stringify {
Json.toJson {
import lila.rating.PerfType._
List(Bullet, Blitz, Classical, Correspondence, Chess960, KingOfTheHill, Antichess, Atomic, ThreeCheck, Puzzle).map { pt =>
List(Bullet, Blitz, Classical, Correspondence, Chess960, KingOfTheHill, Antichess, ThreeCheck, Atomic, Horde, Puzzle).map { pt =>
pt -> history(pt)
} sortBy (-_._2.size) map {
case (pt, rm) => ratingsMapToJson(pt, rm)

View File

@ -72,6 +72,12 @@ object PerfType {
title = "Three-check variant",
iconChar = '.')
case object Horde extends PerfType(
key = "horde",
name = chess.variant.Horde.name,
title = "Horde variant",
iconChar = '_')
case object Puzzle extends PerfType(
key = "puzzle",
name = "Training",
@ -84,7 +90,7 @@ object PerfType {
title = "Opening trainer",
iconChar = ']')
val all: List[PerfType] = List(Bullet, Blitz, Classical, Correspondence, Standard, Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic, Puzzle, Opening)
val all: List[PerfType] = List(Bullet, Blitz, Classical, Correspondence, Standard, Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic, Horde, Puzzle, Opening)
val byKey = all map { p => (p.key, p) } toMap
val default = Standard
@ -94,7 +100,7 @@ object PerfType {
def name(key: Perf.Key): Option[String] = apply(key) map (_.name)
val nonPuzzle: List[PerfType] = List(Bullet, Blitz, Classical, Correspondence, Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic)
val leaderboardable: List[PerfType] = List(Bullet, Blitz, Classical, Correspondence, Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic)
val variants: List[PerfType] = List(Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic)
val nonPuzzle: List[PerfType] = List(Bullet, Blitz, Classical, Correspondence, Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic, Horde)
val leaderboardable: List[PerfType] = List(Bullet, Blitz, Classical, Correspondence, Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic, Horde)
val variants: List[PerfType] = List(Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic, Horde)
}

View File

@ -33,6 +33,8 @@ final class PerfsUpdater(historyApi: HistoryApi) {
updateRatings(ratingsW.antichess, ratingsB.antichess, result, system)
case chess.variant.Atomic =>
updateRatings(ratingsW.atomic, ratingsB.atomic, result, system)
case chess.variant.Horde =>
updateRatings(ratingsW.horde, ratingsB.horde, result, system)
case chess.variant.Standard => game.speed match {
case Speed.Bullet =>
updateRatings(ratingsW.bullet, ratingsB.bullet, result, system)
@ -69,6 +71,7 @@ final class PerfsUpdater(historyApi: HistoryApi) {
threeCheck: Rating,
antichess: Rating,
atomic: Rating,
horde: Rating,
bullet: Rating,
blitz: Rating,
classical: Rating,
@ -80,6 +83,7 @@ final class PerfsUpdater(historyApi: HistoryApi) {
threeCheck = perfs.threeCheck.toRating,
antichess = perfs.antichess.toRating,
atomic = perfs.atomic.toRating,
horde = perfs.horde.toRating,
bullet = perfs.bullet.toRating,
blitz = perfs.blitz.toRating,
classical = perfs.classical.toRating,
@ -117,6 +121,7 @@ final class PerfsUpdater(historyApi: HistoryApi) {
threeCheck = game.variant.threeCheck.fold(perfs.threeCheck.add(ratings.threeCheck, date), perfs.threeCheck),
antichess = game.variant.antichess.fold(perfs.antichess.add(ratings.antichess, date), perfs.antichess),
atomic = game.variant.atomic.fold(perfs.atomic.add(ratings.atomic, date), perfs.atomic),
horde = game.variant.horde.fold(perfs.horde.add(ratings.horde, date), perfs.horde),
bullet = (isStd && speed == Speed.Bullet).fold(perfs.bullet.add(ratings.bullet, date), perfs.bullet),
blitz = (isStd && speed == Speed.Blitz).fold(perfs.blitz.add(ratings.blitz, date), perfs.blitz),
classical = (isStd && speed == Speed.Classical).fold(perfs.classical.add(ratings.classical, date), perfs.classical),

View File

@ -43,7 +43,7 @@ final class DataForm(isDev: Boolean) {
"minPlayers" -> numberIn(minPlayerChoices),
"system" -> number.verifying(Set(System.Arena.id, System.Swiss.id) contains _),
"variant" -> number.verifying(Set(chess.variant.Standard.id, chess.variant.Chess960.id, chess.variant.KingOfTheHill.id,
chess.variant.ThreeCheck.id, chess.variant.Antichess.id, chess.variant.Atomic.id) contains _),
chess.variant.ThreeCheck.id, chess.variant.Antichess.id, chess.variant.Atomic.id, chess.variant.Horde.id) contains _),
"mode" -> optional(number.verifying(Mode.all map (_.id) contains _)),
"private" -> optional(text.verifying("on" == _))
)(TournamentSetup.apply)(TournamentSetup.unapply)

View File

@ -13,6 +13,7 @@ case class Perfs(
threeCheck: Perf,
antichess: Perf,
atomic: Perf,
horde: Perf,
bullet: Perf,
blitz: Perf,
classical: Perf,
@ -27,6 +28,7 @@ case class Perfs(
"threeCheck" -> threeCheck,
"antichess" -> antichess,
"atomic" -> atomic,
"horde" -> horde,
"bullet" -> bullet,
"blitz" -> blitz,
"classical" -> classical,
@ -46,7 +48,7 @@ case class Perfs(
}
def bestRating: Int = {
val ps = List(bullet, blitz, classical, correspondence, chess960, kingOfTheHill, threeCheck, antichess, atomic)
val ps = List(bullet, blitz, classical, correspondence, chess960, kingOfTheHill, threeCheck, antichess, atomic, horde)
val minNb = ps.foldLeft(0)(_ + _.nb) / 10
ps.foldLeft(none[Int]) {
case (ro, p) if p.nb >= minNb => ro.fold(p.intRating.some) { r =>
@ -62,6 +64,7 @@ case class Perfs(
"threeCheck" -> threeCheck,
"antichess" -> antichess,
"atomic" -> atomic,
"horde" -> horde,
"bullet" -> bullet,
"blitz" -> blitz,
"classical" -> classical,
@ -86,6 +89,7 @@ case class Perfs(
case PerfType.ThreeCheck => threeCheck
case PerfType.Antichess => antichess
case PerfType.Atomic => atomic
case PerfType.Horde => horde
case PerfType.Puzzle => puzzle
case PerfType.Opening => opening
}
@ -117,7 +121,7 @@ case object Perfs {
val default = {
val p = Perf.default
Perfs(p, p, p, p, p, p, p, p, p, p, p, p)
Perfs(p, p, p, p, p, p, p, p, p, p, p, p, p)
}
def variantLens(variant: chess.variant.Variant): Option[Perfs => Perf] = variant match {
@ -127,6 +131,7 @@ case object Perfs {
case chess.variant.ThreeCheck => Some(_.threeCheck)
case chess.variant.Antichess => Some(_.antichess)
case chess.variant.Atomic => Some(_.atomic)
case chess.variant.Horde => Some(_.horde)
case _ => none
}
@ -151,6 +156,7 @@ case object Perfs {
threeCheck = perf("threeCheck"),
antichess = perf("antichess"),
atomic = perf("atomic"),
horde = perf("horde"),
bullet = perf("bullet"),
blitz = perf("blitz"),
classical = perf("classical"),
@ -168,6 +174,7 @@ case object Perfs {
"threeCheck" -> notNew(o.threeCheck),
"antichess" -> notNew(o.antichess),
"atomic" -> notNew(o.atomic),
"horde" -> notNew(o.horde),
"bullet" -> notNew(o.bullet),
"blitz" -> notNew(o.blitz),
"classical" -> notNew(o.classical),

View File

@ -96,6 +96,7 @@ trait UserRepo {
"threeCheck" -> (_.threeCheck),
"antichess" -> (_.antichess),
"atomic" -> (_.atomic),
"horde" -> (_.horde),
"bullet" -> (_.bullet),
"blitz" -> (_.blitz),
"classical" -> (_.classical),

View File

@ -70,8 +70,8 @@ time {
}
@font-face {
font-family: "lichess";
src: url("../font32/fonts/lichess.eot");
src: url("../font32/fonts/lichess.eot?#iefix") format("embedded-opentype"), url("../font32/fonts/lichess.woff") format("woff"), url("../font32/fonts/lichess.ttf") format("truetype"), url("../font32/fonts/lichess.svg#lichess") format("svg");
src: url("../font33/fonts/lichess.eot");
src: url("../font33/fonts/lichess.eot?#iefix") format("embedded-opentype"), url("../font33/fonts/lichess.woff") format("woff"), url("../font33/fonts/lichess.ttf") format("truetype"), url("../font33/fonts/lichess.svg#lichess") format("svg");
font-weight: normal;
font-style: normal;
}

View File

@ -8,6 +8,7 @@ module.exports = {
kingOfTheHill: "(",
threeCheck: ".",
antichess: "@",
atomic: ">"
atomic: ">",
horde: "_"
}
};

View File

@ -3,7 +3,8 @@ var variantConfirms = {
'kingOfTheHill': "This is a King of the Hill game!\n\nThe game can be won by bringing the king to the center.\nRead more: http://lichess.org/king-of-the-hill",
'threeCheck': "This is a Three-check game!\n\nThe game can be won by checking the opponent 3 times.\nRead more: http://en.wikipedia.org/wiki/Three-check_chess",
"antichess": "This is an antichess chess game!\n\n If you can take a piece, you must. The game can be won by losing all your pieces.",
"atomic": "This is an atomic chess game!\n\n. Capturing a piece causes an explosion, taking out your piece and surrounding non-pawns. Win by mating or exploding your opponent's king."
"atomic": "This is an atomic chess game!\n\n. Capturing a piece causes an explosion, taking out your piece and surrounding non-pawns. Win by mating or exploding your opponent's king.",
"horde": "This is a horde chess game!\n\n. White must take all black pawns to win. Black must checkmate white king."
};
function storageKey(key) {