Implémenter la stratégie de base du blackjack en JavaScript
Un guide complet pour développeurs : représenter la stratégie de base en JSON et effectuer des recherches ultra-rapides dans le code.
Pourquoi la stratégie de base a sa place dans le code
La stratégie de base est une table de décision déterministe qui ramène l'avantage de la maison à seulement 0,5 %. Si vous développez un simulateur, un entraîneur ou un croupier assisté par IA, encoder cette table sous forme de données structurées (JSON) et utiliser une fonction de recherche rapide est bien plus simple et plus facile à maintenir que des centaines de conditions imbriquées.
Cette approche sépare les données de la logique : votre code devient plus lisible, plus facile à tester et à adapter à différentes variantes de règles. Que vous construisiez un jeu de casino, une application d'entraînement ou un outil d'analyse statistique, ce modèle vous fera gagner du temps et limitera les bugs.
Modèle de données : une table de correspondance JSON
Stockez le tableau de stratégie dans un objet JSON. Chaque clé représente la ligne de la main du joueur (totaux durs, totaux souples et paires), et chaque valeur associe la carte visible du croupier au code de l'action :
// small excerpt (full table would include all rows)
const blackjackStrategy = {
"5-8": {"2":"H","3":"H","4":"H","5":"H","6":"H","7":"H","8":"H","9":"H","10":"H","A":"H"},
"9": {"2":"H","3":"D","4":"D","5":"D","6":"D","7":"H","8":"H","9":"H","10":"H","A":"H"},
"10": {"2":"D","3":"D","4":"D","5":"D","6":"D","7":"D","8":"D","9":"D","10":"H","A":"H"},
"11": {"2":"D","3":"D","4":"D","5":"D","6":"D","7":"D","8":"D","9":"D","10":"D","A":"D"},
"12": {"2":"H","3":"H","4":"S","5":"S","6":"S","7":"H","8":"H","9":"H","10":"H","A":"H"},
"13": {"2":"S","3":"S","4":"S","5":"S","6":"S","7":"H","8":"H","9":"H","10":"H","A":"H"},
"14": {"2":"S","3":"S","4":"S","5":"S","6":"S","7":"H","8":"H","9":"H","10":"H","A":"H"},
"15": {"2":"S","3":"S","4":"S","5":"S","6":"S","7":"H","8":"H","9":"H","10":"SR","A":"SR"},
"16": {"2":"S","3":"S","4":"S","5":"S","6":"S","7":"H","8":"H","9":"SR","10":"SR","A":"SR"},
"A2": {"2":"H","3":"H","4":"H","5":"D","6":"D","7":"H","8":"H","9":"H","10":"H","A":"H"},
"A3": {"2":"H","3":"H","4":"H","5":"D","6":"D","7":"H","8":"H","9":"H","10":"H","A":"H"},
"A4": {"2":"H","3":"H","4":"D","5":"D","6":"D","7":"H","8":"H","9":"H","10":"H","A":"H"},
"A5": {"2":"H","3":"H","4":"D","5":"D","6":"D","7":"H","8":"H","9":"H","10":"H","A":"H"},
"A6": {"2":"H","3":"D","4":"D","5":"D","6":"D","7":"H","8":"H","9":"H","10":"H","A":"H"},
"A7": {"2":"D/S","3":"D/S","4":"D/S","5":"D/S","6":"D/S","7":"S","8":"S","9":"H","10":"H","A":"H"},
"2-2": {"2":"P","3":"P","4":"P","5":"P","6":"P","7":"P","8":"H","9":"H","10":"H","A":"H"},
"3-3": {"2":"P","3":"P","4":"P","5":"P","6":"P","7":"P","8":"H","9":"H","10":"H","A":"H"},
"4-4": {"2":"H","3":"H","4":"H","5":"P","6":"P","7":"H","8":"H","9":"H","10":"H","A":"H"},
"6-6": {"2":"P","3":"P","4":"P","5":"P","6":"P","7":"H","8":"H","9":"H","10":"H","A":"H"},
"7-7": {"2":"P","3":"P","4":"P","5":"P","6":"P","7":"P","8":"H","9":"H","10":"H","A":"H"},
"8-8": {"2":"P","3":"P","4":"P","5":"P","6":"P","7":"P","8":"P","9":"P","10":"P","A":"SP"},
"9-9": {"2":"P","3":"P","4":"P","5":"P","6":"P","7":"S","8":"P","9":"P","10":"S","A":"S"}
};
Cet extrait suit le tableau de stratégie de base pour : 6 jeux, le croupier tire sur 17 souple, double sur deux cartes quelconques, double après séparation autorisé, abandon tardif.
- H
- Tirer
- S
- Rester
- D
- Doubler (sinon tirer)
- P
- Séparer
- SR
- Abandonner (sinon tirer)
- SP
- Abandonner (sinon séparer)
- D/S
- Doubler, sinon rester
La fonction de recherche : simple et rapide
Utilisez une petite fonction pour trouver le coup recommandé à partir de la clé de la table et de la carte visible du croupier. Elle renvoie directement le code de l'action, avec une complexité en O(1).
// fonction de recherche
function getBlackjackAction(playerHand, dealerCard, strategyTable) {
if (!strategyTable) strategyTable = blackjackStrategy; // repli sur la table globale si aucune n'est passée
playerHand = String(playerHand).toUpperCase();
dealerCard = String(dealerCard).toUpperCase();
const row = strategyTable[playerHand];
if (!row) return null; // ligne inconnue
return row[dealerCard] || null; // action, ou null si la carte du croupier est inconnue
}
// exemples
console.log(getBlackjackAction("A7", "6")); // "D/S"
console.log(getBlackjackAction("16", "10")); // "SR"
console.log(getBlackjackAction("9-9", "7")); // "S"
Cette approche sépare la stratégie de la logique : le JSON contient les données, la fonction sert de recherche et d'adaptateur. Pour passer à une autre variante de règles (par ex. le croupier tire ou reste sur 17 souple, ou d'autres règles d'abandon), il suffit de charger un autre objet JSON.
Recherches instantanées
Une complexité en O(1) garantit des performances constantes, même avec des variantes de règles complexes.
Maintenance facile
Modifiez les règles de stratégie en changeant les données JSON, pas une logique conditionnelle complexe.
Une conception évolutive
Idéal pour des simulations qui jouent des milliers de mains par seconde.
Accepter de vraies cartes en entrée
En production, vous voudrez peut-être que la fonction accepte des cartes brutes (par ex. ['A','6']) au lieu de clés de ligne précalculées.
Écrivez un petit normaliseur qui :
- détecte les paires (deux rangs identiques) → ligne du type
"8-8" - détecte les totaux souples (un As compté pour 11) → ligne du type
"A6" - se rabat sinon sur les totaux durs (somme numérique) → ligne du type
"16"
// exemple de normaliseur (très simple)
function normalizeHand(cards) {
// cards : tableau de rangs, par ex. ['A','6'] ou ['9','9'] ou ['10','6']
const ranks = cards.map(c => String(c).toUpperCase());
if (ranks.length === 2 && ranks[0] === ranks[1]) {
// paire
return `${ranks[0]}-${ranks[1]}`;
}
const hasAce = ranks.includes('A');
const numeric = ranks.reduce((sum, r) => sum + (r === 'A' ? 11 : (r === 'J' || r === 'Q' || r === 'K' ? 10 : parseInt(r,10) || 0)), 0);
// détection naïve des mains souples à deux cartes
if (hasAce && ranks.length === 2) {
const other = ranks.find(r => r !== 'A');
return `A${other}`;
}
return String(numeric);
}
Combinez le normaliseur avec getBlackjackAction pour accepter soit des clés structurées, soit des tableaux de cartes brutes. Votre API devient ainsi plus souple et plus pratique à utiliser.
Pourquoi les développeurs devraient adopter ce modèle
Clarté
Une approche pilotée par les données garde la logique lisible et facile à maintenir. Fini le code spaghetti truffé de if imbriqués.
Performance
Une recherche en temps constant, adaptée aux simulations qui jouent des milliers de mains par minute.
Flexibilité
Changez de table pour une autre variante de règles ou ajoutez des modes d'entraînement sans toucher au cœur de votre logique.
Testabilité
Facile à tester unitairement avec différentes tables de stratégie et différents cas limites.
Modularité
Les données de stratégie peuvent être chargées indépendamment depuis des fichiers, des API ou des bases de données.
Internationalisation
Prenez en charge les variantes régionales du blackjack avec des fichiers JSON distincts.
Ressources et prochaines étapes
Prêt à mettre tout cela en pratique ? Essayez notre entraîneur interactif pour voir la stratégie de base en action :
21Count — Entraîneur interactif de stratégie de base
Télécharger le fichier JavaScript complet avec exemples
Comprend la table de stratégie complète, les fonctions de recherche, le normaliseur et des exemples d'utilisation prêts pour vos projets.