validate chess960 fen in api challenges

no-howler
Thibault Duplessis 2020-08-28 09:08:45 +02:00
parent 6d936f2472
commit 5076720790
4 changed files with 40 additions and 41 deletions

View File

@ -1,5 +1,7 @@
package controllers
import play.api.libs.json.Json
import play.api.mvc.Result
import scala.annotation.nowarn
@ -231,16 +233,17 @@ final class Challenge(
} orElse config.days.map {
TimeControl.Correspondence.apply
} getOrElse TimeControl.Unlimited
val challenge = lila.challenge.Challenge.make(
variant = config.variant,
initialFen = config.position,
timeControl = timeControl,
mode = config.mode,
color = config.color.name,
challenger = ChallengeModel.toRegistered(config.variant, timeControl)(me),
destUser = destUser,
rematchOf = none
)
val challenge = lila.challenge.Challenge
.make(
variant = config.variant,
initialFen = config.position,
timeControl = timeControl,
mode = config.mode,
color = config.color.name,
challenger = ChallengeModel.toRegistered(config.variant, timeControl)(me),
destUser = destUser,
rematchOf = none
)
(destUser, config.acceptByToken) match {
case (Some(dest), Some(strToken)) => apiChallengeAccept(dest, challenge, strToken)
case _ =>

View File

@ -23,19 +23,20 @@ final private class Joiner(
def makeChess(variant: chess.variant.Variant): chess.Game =
chess.Game(situation = Situation(variant), clock = c.clock.map(_.config.toClock))
val baseState = c.initialFen.ifTrue(c.variant.fromPosition) flatMap { fen =>
Forsyth.<<<@(chess.variant.FromPosition, fen.value)
val baseState = c.initialFen.ifTrue(c.variant.fromPosition || c.variant.chess960) flatMap { fen =>
Forsyth.<<<@(c.variant, fen.value)
}
val (chessGame, state) = baseState.fold(makeChess(c.variant) -> none[SituationPlus]) {
case sit @ SituationPlus(s, _) =>
case SituationPlus(sit, turns) =>
val game = chess.Game(
situation = s,
turns = sit.turns,
startedAtTurn = sit.turns,
situation = sit,
turns = turns,
startedAtTurn = turns,
clock = c.clock.map(_.config.toClock)
)
if (Forsyth.>>(game) == Forsyth.initial) makeChess(chess.variant.Standard) -> none
else game -> baseState
if (c.variant.fromPosition && Forsyth.>>(game) == Forsyth.initial)
makeChess(chess.variant.Standard) -> none
else game -> baseState
}
val perfPicker = (perfs: lila.user.Perfs) => perfs(c.perfType)
val game = Game
@ -55,10 +56,7 @@ final private class Joiner(
g.copy(
chess = g.chess.copy(
situation = g.situation.copy(
board = g.board.copy(
history = board.history,
variant = chess.variant.FromPosition
)
board = g.board.copy(history = board.history)
),
turns = sit.turns
)

View File

@ -1,11 +1,14 @@
package lila.setup
import chess.{ Clock, Speed }
import chess.format.{ FEN, Forsyth }
import chess.variant.Chess960
import chess.variant.FromPosition
import chess.{ Clock, Speed }
import lila.game.PerfPicker
import lila.lobby.Color
import lila.rating.PerfType
import lila.game.PerfPicker
import chess.variant.Variant
final case class ApiConfig(
variant: chess.variant.Variant,
@ -17,18 +20,11 @@ final case class ApiConfig(
acceptByToken: Option[String] = None
) {
val strictFen = false
def >> = (variant.key.some, clock, days, rated, color.name.some, position.map(_.value), acceptByToken).some
def perfType: Option[PerfType] = PerfPicker.perfType(chess.Speed(clock), variant, days)
def validFen =
variant != FromPosition || {
position ?? { f =>
~(Forsyth <<< f.value).map(_.situation playable strictFen)
}
}
def validFen = ApiConfig.validFen(variant, position)
def validSpeed(isBot: Boolean) =
!isBot || clock.fold(true) { c =>
@ -64,4 +60,12 @@ object ApiConfig extends BaseHumanConfig {
position = pos map FEN,
acceptByToken = tok
).autoVariant
def validFen(variant: Variant, fen: Option[FEN]) =
if (variant.chess960) fen.forall(f => Chess960.positionNumber(f).isDefined)
else if (variant.fromPosition)
fen exists { f =>
(Forsyth <<< f.value).exists(_.situation playable false)
}
else true
}

View File

@ -3,8 +3,9 @@ package lila.setup
import chess.Clock
import chess.format.{ FEN, Forsyth }
import chess.variant.FromPosition
import lila.rating.PerfType
import lila.game.PerfPicker
import lila.rating.PerfType
final case class OpenConfig(
variant: chess.variant.Variant,
@ -12,18 +13,11 @@ final case class OpenConfig(
position: Option[FEN] = None
) {
val strictFen = false
def >> = (variant.key.some, clock, position.map(_.value)).some
def perfType: Option[PerfType] = PerfPicker.perfType(chess.Speed(clock), variant, none)
def validFen =
variant != FromPosition || {
position ?? { f =>
~(Forsyth <<< f.value).map(_.situation playable strictFen)
}
}
def validFen = ApiConfig.validFen(variant, position)
def autoVariant =
if (variant.standard && position.exists(_.value != Forsyth.initial)) copy(variant = FromPosition)