Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2025-12-26 11:59:57 -06:00
parent 2c5b264f9b
commit d56b0b71d7

View File

@ -77,6 +77,12 @@ final class GameState {
/// Whether an action is currently being processed (prevents double-tap issues). /// Whether an action is currently being processed (prevents double-tap issues).
private(set) var isProcessingAction: Bool = false private(set) var isProcessingAction: Bool = false
/// Time of the last player action (prevents rapid double-taps).
private var lastActionTime: Date = .distantPast
/// Minimum interval between player actions in seconds.
private let actionDebounceInterval: TimeInterval = 0.2
/// The active player hand. /// The active player hand.
var activeHand: BlackjackHand? { var activeHand: BlackjackHand? {
guard activeHandIndex < playerHands.count else { return nil } guard activeHandIndex < playerHands.count else { return nil }
@ -598,6 +604,12 @@ final class GameState {
/// Player hits (takes another card). /// Player hits (takes another card).
func hit() async { func hit() async {
guard canHit else { return } guard canHit else { return }
// Debounce: ignore rapid taps
let now = Date()
guard now.timeIntervalSince(lastActionTime) >= actionDebounceInterval else { return }
lastActionTime = now
isProcessingAction = true isProcessingAction = true
defer { isProcessingAction = false } defer { isProcessingAction = false }
@ -619,6 +631,12 @@ final class GameState {
/// Player stands. /// Player stands.
func stand() async { func stand() async {
guard canStand else { return } guard canStand else { return }
// Debounce: ignore rapid taps
let now = Date()
guard now.timeIntervalSince(lastActionTime) >= actionDebounceInterval else { return }
lastActionTime = now
isProcessingAction = true isProcessingAction = true
defer { isProcessingAction = false } defer { isProcessingAction = false }
@ -629,6 +647,12 @@ final class GameState {
/// Player doubles down. /// Player doubles down.
func doubleDown() async { func doubleDown() async {
guard canDouble else { return } guard canDouble else { return }
// Debounce: ignore rapid taps
let now = Date()
guard now.timeIntervalSince(lastActionTime) >= actionDebounceInterval else { return }
lastActionTime = now
isProcessingAction = true isProcessingAction = true
defer { isProcessingAction = false } defer { isProcessingAction = false }
@ -655,6 +679,12 @@ final class GameState {
/// Player splits the hand. /// Player splits the hand.
func split() async { func split() async {
guard canSplit else { return } guard canSplit else { return }
// Debounce: ignore rapid taps
let now = Date()
guard now.timeIntervalSince(lastActionTime) >= actionDebounceInterval else { return }
lastActionTime = now
isProcessingAction = true isProcessingAction = true
defer { isProcessingAction = false } defer { isProcessingAction = false }
@ -701,6 +731,12 @@ final class GameState {
/// Player surrenders. /// Player surrenders.
func surrender() async { func surrender() async {
guard canSurrender else { return } guard canSurrender else { return }
// Debounce: ignore rapid taps
let now = Date()
guard now.timeIntervalSince(lastActionTime) >= actionDebounceInterval else { return }
lastActionTime = now
isProcessingAction = true isProcessingAction = true
defer { isProcessingAction = false } defer { isProcessingAction = false }