Skip to content
Merged
11 changes: 8 additions & 3 deletions modules/coreI18n/src/main/key.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1649,10 +1649,15 @@ object I18nKey:
val `openingExplorerAndTablebase`: I18nKey = "openingExplorerAndTablebase"
val `takeback`: I18nKey = "takeback"
val `proposeATakeback`: I18nKey = "proposeATakeback"
val `whiteProposesTakeback`: I18nKey = "whiteProposesTakeback"
val `blackProposesTakeback`: I18nKey = "blackProposesTakeback"
val `takebackPropositionSent`: I18nKey = "takebackPropositionSent"
val `takebackPropositionDeclined`: I18nKey = "takebackPropositionDeclined"
val `takebackPropositionAccepted`: I18nKey = "takebackPropositionAccepted"
val `takebackPropositionCanceled`: I18nKey = "takebackPropositionCanceled"
val `whiteDeclinesTakeback`: I18nKey = "whiteDeclinesTakeback"
val `blackDeclinesTakeback`: I18nKey = "blackDeclinesTakeback"
val `whiteAcceptsTakeback`: I18nKey = "whiteAcceptsTakeback"
val `blackAcceptsTakeback`: I18nKey = "blackAcceptsTakeback"
val `whiteCancelsTakeback`: I18nKey = "whiteCancelsTakeback"
val `blackCancelsTakeback`: I18nKey = "blackCancelsTakeback"
val `yourOpponentProposesATakeback`: I18nKey = "yourOpponentProposesATakeback"
val `bookmarkThisGame`: I18nKey = "bookmarkThisGame"
val `tournament`: I18nKey = "tournament"
Expand Down
53 changes: 33 additions & 20 deletions modules/round/src/main/Takebacker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,25 @@ final private class Takebacker(
events <-
if pov.opponent.proposeTakebackAt == pov.game.ply &&
color == pov.opponent.proposeTakebackAt.turn
then single(game)
else double(game)
then single(pov)
else double(pov)
_ = publishTakeback(pov)
yield events -> board.reset
case Pov(game, _) if pov.game.playableByAi =>
for
events <- single(game)
events <- single(pov)
_ = publishTakeback(pov)
yield events -> board
case Pov(game, _) if pov.opponent.isAi =>
for
events <- double(game)
events <- double(pov)
_ = publishTakeback(pov)
yield events -> board
case pov if canProposeTakeback(pov) && board.offerable =>
messenger.volatile(pov.game, trans.site.takebackPropositionSent.txt())
messenger.volatile(
pov.game,
pov.color.fold(trans.site.whiteProposesTakeback, trans.site.blackProposesTakeback).txt()
)
val progress = Progress(pov.game).map: g =>
g.updatePlayer(pov.color, _.copy(proposeTakebackAt = g.ply))
for
Expand All @@ -68,7 +71,10 @@ final private class Takebacker(
def no(board: TakebackBoard)(pov: Pov)(using proxy: GameProxy): Fu[(Events, TakebackBoard)] =
pov match
case Pov(game, color) if pov.player.isProposingTakeback =>
messenger.volatile(game, trans.site.takebackPropositionCanceled.txt())
messenger.volatile(
game,
pov.color.fold(trans.site.whiteCancelsTakeback, trans.site.blackCancelsTakeback).txt()
)
val progress = Progress(game).map: g =>
g.updatePlayer(color, _.removeTakebackProposition)
for
Expand All @@ -77,7 +83,10 @@ final private class Takebacker(
events = List(Event.TakebackOffers(white = false, black = false))
yield events -> board.decline
case Pov(game, color) if pov.opponent.isProposingTakeback =>
messenger.volatile(game, trans.site.takebackPropositionDeclined.txt())
messenger.volatile(
game,
pov.color.fold(trans.site.whiteDeclinesTakeback, trans.site.blackDeclinesTakeback).txt()
)
val progress = Progress(game).map: g =>
g.updatePlayer(!color, _.removeTakebackProposition)
for
Expand Down Expand Up @@ -108,26 +117,30 @@ final private class Takebacker(
if _ then f
else fufail(ClientError("[takebacker] disallowed by preferences " + game.id))

private def single(game: Game)(using GameProxy): Fu[Events] =
private def single(pov: Pov)(using GameProxy): Fu[Events] =
for
fen <- gameRepo.initialFen(game)
progress <- Rewind(game, fen).toFuture
_ <- fuccess(uciMemo.drop(game, 1))
events <- saveAndNotify(progress)
fen <- gameRepo.initialFen(pov.game)
progress <- Rewind(pov.game, fen).toFuture
_ <- fuccess(uciMemo.drop(pov.game, 1))
events <- saveAndNotify(progress, pov)
yield events

private def double(game: Game)(using GameProxy): Fu[Events] =
private def double(pov: Pov)(using GameProxy): Fu[Events] =
for
fen <- gameRepo.initialFen(game)
prog1 <- Rewind(game, fen).toFuture
fen <- gameRepo.initialFen(pov.game)
prog1 <- Rewind(pov.game, fen).toFuture
prog2 <- Rewind(prog1.game, fen).toFuture.dmap(progress => prog1.withGame(progress.game))
_ <- fuccess(uciMemo.drop(game, 2))
events <- saveAndNotify(prog2)
_ <- fuccess(uciMemo.drop(pov.game, 2))
events <- saveAndNotify(prog2, pov)
yield events

private def saveAndNotify(p1: Progress)(using proxy: GameProxy): Fu[Events] =
val p2 = p1 + Event.Reload
messenger.system(p2.game, trans.site.takebackPropositionAccepted.txt())
private def saveAndNotify(p1: Progress, pov: Pov)(using proxy: GameProxy): Fu[Events] =
val p2 = p1 + Event.Reload
val accepter = if pov.opponent.isProposingTakeback then pov.color else !pov.color
messenger.system(
p2.game,
accepter.fold(trans.site.whiteAcceptsTakeback, trans.site.blackAcceptsTakeback).txt()
)
proxy.save(p2).inject(p2.events)

private def publishTakebackOffer(game: Game): Unit =
Expand Down
11 changes: 8 additions & 3 deletions translation/source/site.xml
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,15 @@
<string name="openingExplorerAndTablebase">Opening explorer &amp; tablebase</string>
<string name="takeback">Takeback</string>
<string name="proposeATakeback">Propose a takeback</string>
<string name="whiteProposesTakeback">White proposes takeback</string>
<string name="blackProposesTakeback">Black proposes takeback</string>
<string name="takebackPropositionSent">Takeback sent</string>
<string name="takebackPropositionDeclined">Takeback declined</string>
<string name="takebackPropositionAccepted">Takeback accepted</string>
<string name="takebackPropositionCanceled">Takeback cancelled</string>
<string name="whiteDeclinesTakeback">White declines takeback</string>
<string name="blackDeclinesTakeback">Black declines takeback</string>
<string name="whiteAcceptsTakeback">White accepts takeback</string>
<string name="blackAcceptsTakeback">Black accepts takeback</string>
<string name="whiteCancelsTakeback">White cancels takeback</string>
<string name="blackCancelsTakeback">Black cancels takeback</string>
<string name="yourOpponentProposesATakeback">Your opponent proposes a takeback</string>
<string name="bookmarkThisGame">Bookmark this game</string>
<string name="tournament">Tournament</string>
Expand Down
22 changes: 16 additions & 6 deletions ui/@types/lichess/i18n.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2829,12 +2829,18 @@ interface I18n {
biographyDescription: string;
/** Black */
black: string;
/** Black accepts takeback */
blackAcceptsTakeback: string;
/** Black cancels takeback */
blackCancelsTakeback: string;
/** Black O-O */
blackCastlingKingside: string;
/** Black to checkmate in one move */
blackCheckmatesInOneMove: string;
/** Black declines draw */
blackDeclinesDraw: string;
/** Black declines takeback */
blackDeclinesTakeback: string;
/** Black didn't move */
blackDidntMove: string;
/** Black is victorious */
Expand All @@ -2845,6 +2851,8 @@ interface I18n {
blackOffersDraw: string;
/** Black to play */
blackPlays: string;
/** Black proposes takeback */
blackProposesTakeback: string;
/** Black resigned */
blackResigned: string;
/** Black time out */
Expand Down Expand Up @@ -4053,12 +4061,6 @@ interface I18n {
switchSides: string;
/** Takeback */
takeback: string;
/** Takeback accepted */
takebackPropositionAccepted: string;
/** Takeback cancelled */
takebackPropositionCanceled: string;
/** Takeback declined */
takebackPropositionDeclined: string;
/** Takeback sent */
takebackPropositionSent: string;
/** Please be nice in the chat! */
Expand Down Expand Up @@ -4293,12 +4295,18 @@ interface I18n {
whenCreateSimul: string;
/** White */
white: string;
/** White accepts takeback */
whiteAcceptsTakeback: string;
/** White cancels takeback */
whiteCancelsTakeback: string;
/** White O-O */
whiteCastlingKingside: string;
/** White to checkmate in one move */
whiteCheckmatesInOneMove: string;
/** White declines draw */
whiteDeclinesDraw: string;
/** White declines takeback */
whiteDeclinesTakeback: string;
/** White didn't move */
whiteDidntMove: string;
/** White / Draw / Black */
Expand All @@ -4311,6 +4319,8 @@ interface I18n {
whiteOffersDraw: string;
/** White to play */
whitePlays: string;
/** White proposes takeback */
whiteProposesTakeback: string;
/** White resigned */
whiteResigned: string;
/** White time out */
Expand Down
Loading