truncat start position full move number

pull/9135/head
Thibault Duplessis 2021-06-08 11:30:45 +02:00
parent aff5b54af9
commit b8735bd3c7
7 changed files with 29 additions and 16 deletions

View File

@ -172,11 +172,18 @@ object Form {
} }
object fen { object fen {
implicit private val fenFormat = formatter.stringFormatter[FEN](_.value, FEN.apply) implicit val fenFormat = formatter.stringFormatter[FEN](_.value, FEN.apply)
val playableStrict = playable(strict = true) val playableStrict = playable(strict = true)
def playable(strict: Boolean) = of[FEN](fenFormat) def playable(strict: Boolean) = of[FEN]
.transform[FEN](f => FEN(f.value.trim), identity) .transform[FEN](f => FEN(f.value.trim), identity)
.verifying("Invalid position", fen => (Forsyth <<< fen).exists(_.situation playable strict)) .verifying("Invalid position", fen => (Forsyth <<< fen).exists(_.situation playable strict))
.transform[FEN](if (strict) truncateMoveNumber else identity, identity)
def truncateMoveNumber(fen: FEN) =
(Forsyth <<< fen).fold(fen) { g =>
if (g.fullMoveNumber >= 150)
Forsyth >> g.copy(fullMoveNumber = g.fullMoveNumber % 100) // keep the start ply low
else fen
}
} }
def inTheFuture(m: Mapping[DateTime]) = def inTheFuture(m: Mapping[DateTime]) =

View File

@ -19,7 +19,7 @@ case class AiConfig(
val strictFen = true val strictFen = true
def >> = (variant.id, timeMode.id, time, increment, days, level, color.name, fen.map(_.value)).some def >> = (variant.id, timeMode.id, time, increment, days, level, color.name, fen).some
def game(user: Option[User]) = def game(user: Option[User]) =
fenGame { chessGame => fenGame { chessGame =>
@ -54,7 +54,7 @@ case class AiConfig(
object AiConfig extends BaseConfig { object AiConfig extends BaseConfig {
def from(v: Int, tm: Int, t: Double, i: Int, d: Int, level: Int, c: String, fen: Option[String]) = def from(v: Int, tm: Int, t: Double, i: Int, d: Int, level: Int, c: String, fen: Option[FEN]) =
new AiConfig( new AiConfig(
variant = chess.variant.Variant(v) err "Invalid game variant " + v, variant = chess.variant.Variant(v) err "Invalid game variant " + v,
timeMode = TimeMode(tm) err s"Invalid time mode $tm", timeMode = TimeMode(tm) err s"Invalid time mode $tm",
@ -63,7 +63,7 @@ object AiConfig extends BaseConfig {
days = d, days = d,
level = level, level = level,
color = Color(c) err "Invalid color " + c, color = Color(c) err "Invalid color " + c,
fen = fen map FEN.apply fen = fen
) )
val default = AiConfig( val default = AiConfig(

View File

@ -71,7 +71,7 @@ object ApiAiConfig extends BaseConfig {
cl: Option[Clock.Config], cl: Option[Clock.Config],
d: Option[Int], d: Option[Int],
c: Option[String], c: Option[String],
pos: Option[String] pos: Option[FEN]
) = ) =
new ApiAiConfig( new ApiAiConfig(
variant = chess.variant.Variant.orDefault(~v), variant = chess.variant.Variant.orDefault(~v),
@ -79,6 +79,6 @@ object ApiAiConfig extends BaseConfig {
daysO = d, daysO = d,
color = Color.orDefault(~c), color = Color.orDefault(~c),
level = l, level = l,
fen = pos map FEN.apply fen = pos
).autoVariant ).autoVariant
} }

View File

@ -50,7 +50,7 @@ object ApiConfig extends BaseHumanConfig {
d: Option[Int], d: Option[Int],
r: Boolean, r: Boolean,
c: Option[String], c: Option[String],
pos: Option[String], pos: Option[FEN],
tok: Option[String], tok: Option[String],
msg: Option[String] msg: Option[String]
) = ) =
@ -60,7 +60,7 @@ object ApiConfig extends BaseHumanConfig {
days = d, days = d,
rated = r, rated = r,
color = Color.orDefault(~c), color = Color.orDefault(~c),
position = pos map FEN.apply, position = pos,
acceptByToken = tok, acceptByToken = tok,
message = msg map Template message = msg map Template
).autoVariant ).autoVariant

View File

@ -20,7 +20,7 @@ case class FriendConfig(
val strictFen = false val strictFen = false
def >> = (variant.id, timeMode.id, time, increment, days, mode.id.some, color.name, fen.map(_.value)).some def >> = (variant.id, timeMode.id, time, increment, days, mode.id.some, color.name, fen).some
def isPersistent = timeMode == TimeMode.Unlimited || timeMode == TimeMode.Correspondence def isPersistent = timeMode == TimeMode.Unlimited || timeMode == TimeMode.Correspondence
@ -29,7 +29,7 @@ case class FriendConfig(
object FriendConfig extends BaseHumanConfig { object FriendConfig extends BaseHumanConfig {
def from(v: Int, tm: Int, t: Double, i: Int, d: Int, m: Option[Int], c: String, fen: Option[String]) = def from(v: Int, tm: Int, t: Double, i: Int, d: Int, m: Option[Int], c: String, fen: Option[FEN]) =
new FriendConfig( new FriendConfig(
variant = chess.variant.Variant(v) err "Invalid game variant " + v, variant = chess.variant.Variant(v) err "Invalid game variant " + v,
timeMode = TimeMode(tm) err s"Invalid time mode $tm", timeMode = TimeMode(tm) err s"Invalid time mode $tm",
@ -38,7 +38,7 @@ object FriendConfig extends BaseHumanConfig {
days = d, days = d,
mode = m.fold(Mode.default)(Mode.orDefault), mode = m.fold(Mode.default)(Mode.orDefault),
color = Color(c) err "Invalid color " + c, color = Color(c) err "Invalid color " + c,
fen = fen map FEN.apply fen = fen
) )
val default = FriendConfig( val default = FriendConfig(

View File

@ -7,6 +7,7 @@ import chess.Mode
import chess.{ variant => V } import chess.{ variant => V }
import lila.rating.RatingRange import lila.rating.RatingRange
import lila.lobby.Color import lila.lobby.Color
import chess.format.FEN
private object Mappings { private object Mappings {
@ -40,5 +41,10 @@ private object Mappings {
val color = text.verifying(Color.names contains _) val color = text.verifying(Color.names contains _)
val level = number.verifying(AiConfig.levels contains _) val level = number.verifying(AiConfig.levels contains _)
val speed = number.verifying(Config.speeds contains _) val speed = number.verifying(Config.speeds contains _)
val fenField = optional(nonEmptyText) val fenField = optional {
import lila.common.Form.fen._
of[FEN]
.transform[FEN](f => FEN(f.value.trim), identity)
.transform[FEN](truncateMoveNumber, identity)
}
} }

View File

@ -31,13 +31,13 @@ object OpenConfig {
v: Option[String], v: Option[String],
cl: Option[Clock.Config], cl: Option[Clock.Config],
rated: Boolean, rated: Boolean,
pos: Option[String] pos: Option[FEN]
) = ) =
new OpenConfig( new OpenConfig(
name = n.map(_.trim).filter(_.nonEmpty), name = n.map(_.trim).filter(_.nonEmpty),
variant = chess.variant.Variant.orDefault(~v), variant = chess.variant.Variant.orDefault(~v),
clock = cl, clock = cl,
rated = rated, rated = rated,
position = pos map FEN.apply position = pos
).autoVariant ).autoVariant
} }