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

This commit is contained in:
Matt Bruce 2025-12-23 16:43:25 -06:00
parent 1df1796b12
commit 8180b5ad47
3 changed files with 109 additions and 225 deletions

View File

@ -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))")
}
}

View File

@ -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" : {

View File

@ -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)