Keep held dice held between throws

Picking the same three dice again after every throw is work the screen can do.
A kept die does not move and does not change, so the hold a player just made is
still the hold they want, and clearing it was throwing away a decision they had
already expressed.

The selection has to go when the turn does, though. A turn opens with the dice
back in the cup and its first throw must keep nothing -- the rules refuse
anything else -- so a selection carried over from the last turn would be
rejected and Throw would look broken in exactly the way it did before.

Keyed on the round as well as the seat, because a solo game never changes seat:
turn stays at zero and only the round moves on.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Urn6eEBA6XzrnfoibL7faC
This commit is contained in:
Claude
2026-08-08 19:56:19 +00:00
parent 81914e9b34
commit 39ce5aa0ee
@@ -20,6 +20,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
@@ -82,6 +83,11 @@ fun YahtzeeScreen(
return return
} }
// A turn starts with the dice back in the cup, and its first throw must
// keep nothing — a selection carried over from the last turn would be
// refused, and the Throw button would look broken again.
LaunchedEffect(current.turn, current.round) { kept.clear() }
val yours = current.turn == localSeat && !current.isOver val yours = current.turn == localSeat && !current.isOver
val canRoll = legal.any { it is RollDice } val canRoll = legal.any { it is RollDice }
val writable = legal.filterIsInstance<ScoreIn>().map { it.category }.toSet() val writable = legal.filterIsInstance<ScoreIn>().map { it.category }.toSet()
@@ -114,9 +120,11 @@ fun YahtzeeScreen(
Button( Button(
onClick = { onClick = {
controller.submit(RollDice(kept.toSet())) controller.submit(RollDice(kept.toSet()))
// What was kept applied to the throw just made; the next // The selection stays. A kept die does not move or
// one starts from whatever is on the table now. // change, so the hold a player just made is still the
kept.clear() // hold they want — asking them to pick the same three
// again between every throw is work the screen can do
// for them.
}, },
) { ) {
Text(if (current.hasRolled) "Throw the rest" else "Throw") Text(if (current.hasRolled) "Throw the rest" else "Throw")