From 8180b5ad47cd74a9434f3ddb7d193c39fb0c3464 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 23 Dec 2025 16:43:25 -0600 Subject: [PATCH] Signed-off-by: Matt Bruce --- .../Blackjack/Engine/BlackjackEngine.swift | 26 +- .../Blackjack/Resources/Localizable.xcstrings | 304 ++++++------------ .../Blackjack/Views/Table/HintViews.swift | 4 + 3 files changed, 109 insertions(+), 225 deletions(-) diff --git a/Blackjack/Blackjack/Engine/BlackjackEngine.swift b/Blackjack/Blackjack/Engine/BlackjackEngine.swift index 3207e2f..e4eea6a 100644 --- a/Blackjack/Blackjack/Engine/BlackjackEngine.swift +++ b/Blackjack/Blackjack/Engine/BlackjackEngine.swift @@ -411,91 +411,91 @@ final class BlackjackEngine { // 16 vs 10: Stand when TC ≥ 0 (basic strategy says Hit) if playerValue == 16 && !isSoft && dealerValue == 10 { if tc >= 0 { - return String(localized: "Stand instead of Hit (TC \(tcDisplay), deck is neutral/rich)") + return String(localized: "Stand, not Hit (TC \(tcDisplay))") } } // 15 vs 10: Stand when TC ≥ +4 (basic strategy says Hit/Surrender) if playerValue == 15 && !isSoft && dealerValue == 10 { if tc >= 4 { - return String(localized: "Stand instead of Hit (TC \(tcDisplay), deck is very rich)") + return String(localized: "Stand, not Hit (TC \(tcDisplay))") } } // 12 vs 2: Stand when TC ≥ +3 (basic strategy says Hit) if playerValue == 12 && !isSoft && dealerValue == 2 { if tc >= 3 { - return String(localized: "Stand instead of Hit (TC \(tcDisplay), dealer likely to bust)") + return String(localized: "Stand, not Hit (TC \(tcDisplay))") } } // 12 vs 3: Stand when TC ≥ +2 (basic strategy says Hit) if playerValue == 12 && !isSoft && dealerValue == 3 { if tc >= 2 { - return String(localized: "Stand instead of Hit (TC \(tcDisplay), dealer likely to bust)") + return String(localized: "Stand, not Hit (TC \(tcDisplay))") } } // 12 vs 4: Hit when TC < 0 (basic strategy says Stand) if playerValue == 12 && !isSoft && dealerValue == 4 { if tc < 0 { - return String(localized: "Hit instead of Stand (TC \(tcDisplay), deck is poor)") + return String(localized: "Hit, not Stand (TC \(tcDisplay))") } } // 13 vs 2: Hit when TC < -1 (basic strategy says Stand) if playerValue == 13 && !isSoft && dealerValue == 2 { if tc < -1 { - return String(localized: "Hit instead of Stand (TC \(tcDisplay), deck is very poor)") + return String(localized: "Hit, not Stand (TC \(tcDisplay))") } } // 16 vs 9: Stand when TC ≥ +5 (basic strategy says Hit) if playerValue == 16 && !isSoft && dealerValue == 9 { if tc >= 5 { - return String(localized: "Stand instead of Hit (TC \(tcDisplay), deck is extremely rich)") + return String(localized: "Stand, not Hit (TC \(tcDisplay))") } } // 10 vs 10: Double when TC ≥ +4 (basic strategy says Hit) if playerValue == 10 && !isSoft && playerHand.cards.count == 2 && dealerValue == 10 { if tc >= 4 { - return String(localized: "Double instead of Hit (TC \(tcDisplay), high cards favor you)") + return String(localized: "Double, not Hit (TC \(tcDisplay))") } } // 10 vs Ace: Double when TC ≥ +4 (basic strategy says Hit) if playerValue == 10 && !isSoft && playerHand.cards.count == 2 && dealerValue == 1 { if tc >= 4 { - return String(localized: "Double instead of Hit (TC \(tcDisplay), high cards favor you)") + return String(localized: "Double, not Hit (TC \(tcDisplay))") } } // 9 vs 2: Double when TC ≥ +1 (basic strategy says Hit) if playerValue == 9 && !isSoft && playerHand.cards.count == 2 && dealerValue == 2 { if tc >= 1 { - return String(localized: "Double instead of Hit (TC \(tcDisplay), slight edge to double)") + return String(localized: "Double, not Hit (TC \(tcDisplay))") } } // 9 vs 7: Double when TC ≥ +3 (basic strategy says Hit) if playerValue == 9 && !isSoft && playerHand.cards.count == 2 && dealerValue == 7 { if tc >= 3 { - return String(localized: "Double instead of Hit (TC \(tcDisplay), deck favors doubling)") + return String(localized: "Double, not Hit (TC \(tcDisplay))") } } // Pair of 10s vs 5: Split when TC ≥ +5 (basic strategy says Stand) if playerHand.canSplit && playerHand.cards[0].blackjackValue == 10 && dealerValue == 5 { if tc >= 5 { - return String(localized: "Split instead of Stand (TC \(tcDisplay), dealer very likely to bust)") + return String(localized: "Split, not Stand (TC \(tcDisplay))") } } // Pair of 10s vs 6: Split when TC ≥ +4 (basic strategy says Stand) if playerHand.canSplit && playerHand.cards[0].blackjackValue == 10 && dealerValue == 6 { if tc >= 4 { - return String(localized: "Split instead of Stand (TC \(tcDisplay), dealer very likely to bust)") + return String(localized: "Split, not Stand (TC \(tcDisplay))") } } diff --git a/Blackjack/Blackjack/Resources/Localizable.xcstrings b/Blackjack/Blackjack/Resources/Localizable.xcstrings index 52f9db1..7f349ef 100644 --- a/Blackjack/Blackjack/Resources/Localizable.xcstrings +++ b/Blackjack/Blackjack/Resources/Localizable.xcstrings @@ -2687,78 +2687,6 @@ } } }, - "Double instead of Hit (TC %@, deck favors doubling)" : { - "comment" : "Text explaining a Blackjack strategy recommendation to double down when the true count is favorable. The argument is the formatted true count.", - "isCommentAutoGenerated" : true, - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Double instead of Hit (TC %@, deck favors doubling)" - } - }, - "es-MX" : { - "stringUnit" : { - "state" : "translated", - "value" : "Doblar en vez de Pedir (TC %@, la baraja favorece doblar)" - } - }, - "fr-CA" : { - "stringUnit" : { - "state" : "translated", - "value" : "Doubler au lieu de Tirer (TC %@, le jeu favorise le double)" - } - } - } - }, - "Double instead of Hit (TC %@, high cards favor you)" : { - "comment" : "A hint to double down when the true count and the dealer's upcard favor it. The argument is the formatted true count.", - "isCommentAutoGenerated" : true, - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Double instead of Hit (TC %@, high cards favor you)" - } - }, - "es-MX" : { - "stringUnit" : { - "state" : "translated", - "value" : "Doblar en vez de Pedir (TC %@, las cartas altas te favorecen)" - } - }, - "fr-CA" : { - "stringUnit" : { - "state" : "translated", - "value" : "Doubler au lieu de Tirer (TC %@, les cartes hautes vous favorisent)" - } - } - } - }, - "Double instead of Hit (TC %@, slight edge to double)" : { - "comment" : "Text explaining a situation where doubling is recommended in Blackjack, based on the true count and the dealer's upcard. The argument is the formatted true count.", - "isCommentAutoGenerated" : true, - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Double instead of Hit (TC %@, slight edge to double)" - } - }, - "es-MX" : { - "stringUnit" : { - "state" : "translated", - "value" : "Doblar en vez de Pedir (TC %@, ligera ventaja para doblar)" - } - }, - "fr-CA" : { - "stringUnit" : { - "state" : "translated", - "value" : "Doubler au lieu de Tirer (TC %@, léger avantage à doubler)" - } - } - } - }, "Double on 9, 10, or 11 only (some venues)." : { "localizations" : { "en" : { @@ -3301,52 +3229,6 @@ } } }, - "Hit instead of Stand (TC %@, deck is poor)" : { - "comment" : "A hint to the player based on the true count, suggesting they should hit instead of stand. The argument is the true count, displayed with a plus sign if positive.", - "isCommentAutoGenerated" : true, - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hit instead of Stand (TC %@, deck is poor)" - } - }, - "es-MX" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pedir en vez de Plantarse (TC %@, la baraja es pobre)" - } - }, - "fr-CA" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tirer au lieu de Rester (TC %@, le jeu est pauvre)" - } - } - } - }, - "Hit instead of Stand (TC %@, deck is very poor)" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hit instead of Stand (TC %@, deck is very poor)" - } - }, - "es-MX" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pedir en vez de Plantarse (TC %@, la baraja es muy pobre)" - } - }, - "fr-CA" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tirer au lieu de Rester (TC %@, le jeu est très pauvre)" - } - } - } - }, "Hit on soft 17 or less." : { "localizations" : { "en" : { @@ -5509,6 +5391,98 @@ } } }, + "Split, not Stand (TC %@)" : { + "comment" : "Short hint to split instead of stand based on true count.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Split, not Stand (TC %@)" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dividir, no Plantarse (TC %@)" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Séparer, pas Rester (TC %@)" + } + } + } + }, + "Stand, not Hit (TC %@)" : { + "comment" : "Short hint to stand instead of hit based on true count.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stand, not Hit (TC %@)" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Plantarse, no Pedir (TC %@)" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rester, pas Tirer (TC %@)" + } + } + } + }, + "Hit, not Stand (TC %@)" : { + "comment" : "Short hint to hit instead of stand based on true count.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hit, not Stand (TC %@)" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pedir, no Plantarse (TC %@)" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tirer, pas Rester (TC %@)" + } + } + } + }, + "Double, not Hit (TC %@)" : { + "comment" : "Short hint to double instead of hit based on true count.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Double, not Hit (TC %@)" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Doblar, no Pedir (TC %@)" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Doubler, pas Tirer (TC %@)" + } + } + } + }, "Split instead of Stand (TC %@, dealer very likely to bust)" : { "comment" : "A hint to split a pair of 10s when the true count is high enough.", "isCommentAutoGenerated" : true, @@ -5601,100 +5575,6 @@ } } }, - "Stand instead of Hit (TC %@, dealer likely to bust)" : { - "comment" : "Text explaining a Blackjack strategy recommendation based on the true count. The argument is the formatted true count.", - "isCommentAutoGenerated" : true, - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Stand instead of Hit (TC %@, dealer likely to bust)" - } - }, - "es-MX" : { - "stringUnit" : { - "state" : "translated", - "value" : "Plantarse en vez de Pedir (TC %@, el crupier probablemente se pase)" - } - }, - "fr-CA" : { - "stringUnit" : { - "state" : "translated", - "value" : "Rester au lieu de Tirer (TC %@, le croupier va probablement sauter)" - } - } - } - }, - "Stand instead of Hit (TC %@, deck is extremely rich)" : { - "comment" : "Text provided in the \"Count Adjusted\" hint section of the Blackjack game UI, explaining a recommended action based on the true count and the current game state. The argument is the formatted true count.", - "isCommentAutoGenerated" : true, - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Stand instead of Hit (TC %@, deck is extremely rich)" - } - }, - "es-MX" : { - "stringUnit" : { - "state" : "translated", - "value" : "Plantarse en vez de Pedir (TC %@, la baraja es extremadamente rica)" - } - }, - "fr-CA" : { - "stringUnit" : { - "state" : "translated", - "value" : "Rester au lieu de Tirer (TC %@, le jeu est extrêmement riche)" - } - } - } - }, - "Stand instead of Hit (TC %@, deck is neutral/rich)" : { - "comment" : "Explanation of a count-based deviation from the basic strategy, including the true count and a description of the deck situation.", - "isCommentAutoGenerated" : true, - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Stand instead of Hit (TC %@, deck is neutral/rich)" - } - }, - "es-MX" : { - "stringUnit" : { - "state" : "translated", - "value" : "Plantarse en vez de Pedir (TC %@, la baraja es neutral/rica)" - } - }, - "fr-CA" : { - "stringUnit" : { - "state" : "translated", - "value" : "Rester au lieu de Tirer (TC %@, le jeu est neutre/riche)" - } - } - } - }, - "Stand instead of Hit (TC %@, deck is very rich)" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Stand instead of Hit (TC %@, deck is very rich)" - } - }, - "es-MX" : { - "stringUnit" : { - "state" : "translated", - "value" : "Plantarse en vez de Pedir (TC %@, la baraja es muy rica)" - } - }, - "fr-CA" : { - "stringUnit" : { - "state" : "translated", - "value" : "Rester au lieu de Tirer (TC %@, le jeu est très riche)" - } - } - } - }, "Stand on 17+ always." : { "localizations" : { "en" : { diff --git a/Blackjack/Blackjack/Views/Table/HintViews.swift b/Blackjack/Blackjack/Views/Table/HintViews.swift index b69c4e7..be04dfc 100644 --- a/Blackjack/Blackjack/Views/Table/HintViews.swift +++ b/Blackjack/Blackjack/Views/Table/HintViews.swift @@ -27,6 +27,8 @@ struct HintView: View { Text(String(localized: "Hint: \(hint)")) .font(.system(size: fontSize, weight: .medium)) .foregroundStyle(.white.opacity(Design.Opacity.strong)) + .lineLimit(1) + .minimumScaleFactor(Design.MinScaleFactor.comfortable) } .padding(.horizontal, paddingH) .padding(.vertical, paddingV) @@ -82,6 +84,8 @@ struct BettingHintView: View { Text(hint) .font(.system(size: fontSize, weight: .medium)) .foregroundStyle(.white.opacity(Design.Opacity.strong)) + .lineLimit(1) + .minimumScaleFactor(Design.MinScaleFactor.comfortable) } .padding(.horizontal, paddingH) .padding(.vertical, paddingV)