Bot de poker avec détection de cartes, OCR, et automatisation en 3 phases.
- Installer les dépendances Python:
pip install -r requirements.txt- Installer Tesseract OCR:
- Télécharger depuis: https://github.com/UB-Mannheim/tesseract/wiki
- Ajouter au PATH ou configurer le chemin dans
config.py
- Configurer un provider dans
providers/(exemple:pokerstars.json) - Ajuster les paramètres dans
config.pyou créerconfig.json - Configurer les zones de détection dans le fichier du provider
python main.pypython main.py --debug --test-allpython main.py --provider PokerStars# Afficher les 10 dernières sessions
python view_database.py
# Afficher les 20 dernières sessions
python view_database.py --sessions 20
# Afficher les détails d'une session
python view_database.py --session 1
# Afficher les statistiques globales
python view_database.py --statsLes zones définissent les régions de l'écran à analyser pour extraire des informations (texte, cartes, couleurs, boutons).
Sélectionnez manuellement des zones dans une image et créez un fichier de configuration :
# Sélectionner des zones interactivement
python zone_selector.py zone.jpg
# Spécifier le fichier de sortie
python zone_selector.py zone.jpg --output zones_config.jsonRaccourcis clavier dans zone_selector.py :
- Sélection : Cliquez et glissez pour sélectionner une zone
- Édition : Cliquez sur une zone existante et glissez pour la redimensionner
- Zoom : Molette de souris pour zoomer/dézoomer
- Navigation : Molette appuyée + glisser pour déplacer l'image
s: Sauvegarder le fichier JSONi: Sauvegarder l'image annotéed: Supprimer la dernière zoner: Supprimer une zone spécifique (par nom)l: Lister toutes les zoneszou0: Réinitialiser le zoomqouESC: Quitter (sauvegarde automatique)
Chaque zone est définie par un objet JSON avec les propriétés suivantes :
{
"name": "nom_de_la_zone",
"x": 100,
"y": 200,
"width": 150,
"height": 30,
"type": "ocr",
"description": "Description de la zone"
}Propriétés communes (toutes les zones) :
name(string, requis) : Nom unique de la zonex(int, requis) : Position X (pixels depuis la gauche)y(int, requis) : Position Y (pixels depuis le haut)width(int, requis) : Largeur de la zone (pixels)height(int, requis) : Hauteur de la zone (pixels)type(string, requis) : Type de zone (ocr,card_detection,color_detection,button)description(string, optionnel) : Description de la zone
Zone pour la lecture de texte avec Tesseract OCR.
Options spécifiques :
-
psm_modes(array, optionnel) : Modes PSM (Page Segmentation Mode) à essayer, dans l'ordre"8": Un seul mot"7": Une seule ligne de texte"13": Ligne brute (pas de segmentation)"6": Bloc uniforme de texte"11": Texte clairsemé"3": Automatique (sans OSD)- Exemple :
["7", "8", "6"]- essaiera d'abord le mode 7, puis 8, puis 6
-
languageoulang(string, optionnel) : Langue pour Tesseract"fra": Français"eng": Anglais"fra+eng": Multilingue (français + anglais)"spa": Espagnol"deu": Allemand- Liste complète : https://tesseract-ocr.github.io/tessdoc/Data-Files-in-different-versions.html
-
char_whitelist(string, optionnel) : Liste des caractères autorisés"0123456789": Uniquement chiffres"ABCDEFGHIJKLMNOPQRSTUVWXYZ": Uniquement lettres majuscules"abcdefghijklmnopqrstuvwxyz": Uniquement lettres minuscules"0123456789ABCDEF": Chiffres et lettres hexadécimales"0123456789€,.": Chiffres, euro, virgule, point
-
preprocess(boolean, optionnel) : Activer le pré-traitement d'image (amélioration du contraste, etc.)true: Active le pré-traitementfalse: Désactivé par défaut
-
color_filter(string ou object, optionnel) : Filtre couleur à appliquer avant l'OCR -
transform(object, optionnel) : Transformation à appliquer au résultat OCR
Exemple de zone OCR :
{
"name": "prize_pool",
"x": 362,
"y": 125,
"width": 318,
"height": 25,
"type": "ocr",
"description": "Zone prize_pool",
"language": "fra",
"char_whitelist": "0123456789€,.",
"color_filter": {
"type": "color",
"rgb": [245, 118, 3],
"tolerance": 60
},
"psm_modes": ["7"],
"transform": {
"function": "extract_number",
"params": {}
}
}Zone pour détecter les cartes à jouer.
Options spécifiques :
-
num_slots(int, optionnel, défaut: 5) : Nombre de cartes à détecter2: Pour une main de 2 cartes5: Pour le flop/turn/river (5 cartes communes)
-
crop_width(int, optionnel) : Largeur de crop pour chaque carte (en pixels)- Utile si les cartes sont très proches les unes des autres
-
save_crops(boolean, optionnel, défaut: false) : Sauvegarder les images découpées de chaque cartetrue: Sauvegarde les crops pour debugfalse: Ne sauvegarde pas
Exemple de zone card_detection :
{
"name": "my_card",
"x": 444,
"y": 493,
"width": 135,
"height": 44,
"type": "card_detection",
"description": "Zone my_card",
"num_slots": 2,
"save_crops": false
}Zone pour détecter la présence d'une couleur spécifique.
Options spécifiques :
-
target_color(array, requis) : Couleur cible en RGB[R, G, B]- Exemple :
[255, 0, 0]pour rouge
- Exemple :
-
color_space(string, optionnel, défaut: "RGB") : Espace colorimétrique"RGB": Rouge, Vert, Bleu
-
tolerance(int, optionnel, défaut: 30) : Tolérance de couleur (0-255)- Plus la valeur est élevée, plus la détection est permissive
-
min_percentage(int, optionnel, défaut: 50) : Pourcentage minimum de pixels de la couleur cible- Si moins de X% de pixels correspondent, la couleur n'est pas détectée
Exemple de zone color_detection :
{
"name": "button_active",
"x": 500,
"y": 600,
"width": 100,
"height": 50,
"type": "color_detection",
"description": "Détecter si le bouton est actif (vert)",
"target_color": [0, 255, 0],
"color_space": "RGB",
"tolerance": 30,
"min_percentage": 50
}Zone représentant un bouton cliquable.
Options spécifiques :
button_action(string, requis) : Action du bouton"Fold","Call","Raise","All-in","Check", ou une action personnalisée
Exemple de zone button :
{
"name": "button_fold",
"x": 665,
"y": 668,
"width": 106,
"height": 49,
"type": "button",
"description": "Zone button_fold",
"button_action": "Fold"
}Les filtres de couleur améliorent la détection OCR en isolant le texte d'une couleur spécifique.
Format simple (string) :
"color_filter": "bright" // ou "dark", "white", "yellow", "red", "green", "cyan", "blue"Filtres prédéfinis disponibles :
"bright": Texte lumineux (blanc/jaune) sur fond sombre (seuil: 200)"dark": Texte sombre (noir) sur fond clair (seuil: 80)"white": Couleur blanche (RGB: 255,255,255, tolérance: 60)"yellow": Couleur jaune (RGB: 255,255,0, tolérance: 80)"red": Couleur rouge (filtre par teinte)"green": Couleur verte (filtre par teinte)"cyan": Couleur cyan (RGB: 0,255,255, tolérance: 80)"blue": Couleur bleue (filtre par teinte)
Format avancé (object) :
- Filtre par luminosité :
"color_filter": {
"type": "bright", // ou "dark"
"threshold": 200 // Seuil de luminosité (0-255)
}- Filtre par couleur RGB :
"color_filter": {
"type": "color",
"rgb": [245, 118, 3], // Couleur cible [R, G, B]
"tolerance": 60 // Tolérance (0-255)
}- Filtre par saturation :
"color_filter": {
"type": "saturation",
"keep_saturated": false, // true = garder couleurs vives, false = garder gris/blanc
"saturation_threshold": 30 // Seuil de saturation (0-255)
}- Filtre par teinte (HSV) :
"color_filter": {
"type": "hue",
"hue_min": 0, // Teinte minimale (0-360)
"hue_max": 30, // Teinte maximale (0-360)
"saturation_min": 50 // Saturation minimale (0-255)
}Exemples :
// Texte lumineux avec seuil personnalisé
"color_filter": {
"type": "bright",
"threshold": 180
}
// Couleur orange spécifique
"color_filter": {
"type": "color",
"rgb": [245, 118, 3],
"tolerance": 60
}Les transformations permettent de nettoyer et convertir les résultats OCR.
Structure :
"transform": {
"function": "nom_fonction",
"params": {
// Paramètres spécifiques à la fonction
}
}Fonctions disponibles :
-
extract_number: Extrait uniquement le nombre (gère les virgules comme séparateurs décimaux)"transform": { "function": "extract_number", "params": {} }
- Exemple :
"0,506"→0.506,"24%"→24.0
- Exemple :
-
remove_percent: Enlève le signe % et retourne le nombre"transform": { "function": "remove_percent", "params": {} }
- Exemple :
"24%"→24.0
- Exemple :
-
remove_symbol: Enlève un symbole spécifique"transform": { "function": "remove_symbol", "params": { "symbol": "$" // ou "€", "%", etc. } }
-
replace: Remplace un texte par un autre"transform": { "function": "replace", "params": { "old": "ancien_texte", "new": "nouveau_texte" } }
-
round_up: Arrondit à la valeur supérieure"transform": { "function": "round_up", "params": {} }
- Exemple :
24.3→25,24.7→25
- Exemple :
-
round_down: Arrondit à la valeur inférieure"transform": { "function": "round_down", "params": {} }
- Exemple :
24.3→24,24.7→24
- Exemple :
-
round_nearest: Arrondit à la valeur la plus proche"transform": { "function": "round_nearest", "params": {} }
- Exemple :
24.3→24,24.7→25
- Exemple :
-
multiply: Multiplie par un facteur"transform": { "function": "multiply", "params": { "factor": 1.5 } }
- Exemple :
10×1.5→15.0
- Exemple :
-
add: Ajoute une valeur"transform": { "function": "add", "params": { "amount": 1 } }
- Exemple :
24+1→25.0
- Exemple :
-
subtract: Soustrait une valeur"transform": { "function": "subtract", "params": { "amount": 1 } }
- Exemple :
24-1→23.0
- Exemple :
Note importante : La fonction extract_number convertit automatiquement les virgules en points pour les nombres (format français/européen). Par exemple, "0,506" sera converti en 0.506.
Teste les zones configurées pour vérifier qu'elles fonctionnent correctement :
# Tester toutes les zones
python test_zones.py zones_config.json zone.jpg
# Tester toutes les zones et sauvegarder les images extraites
python test_zones.py zones_config.json zone.jpg --save-images
# Tester une zone spécifique
python test_zones.py zones_config.json zone.jpg --zone "nom_zone"Le script affiche :
- Le statut de chaque zone (OK ou erreur)
- Les résultats bruts (avant transformation)
- Les résultats transformés (après transformation)
- Un résumé avec le nombre de zones OK/erreur
- Les images extraites et filtrées (si
--save-imagesest utilisé)
{
"name": "prize_pool",
"x": 362,
"y": 125,
"width": 318,
"height": 25,
"type": "ocr",
"description": "Zone pour lire le prize pool",
"language": "fra",
"char_whitelist": "0123456789€,.",
"psm_modes": ["7", "8"],
"color_filter": {
"type": "color",
"rgb": [245, 118, 3],
"tolerance": 60
},
"preprocess": false,
"transform": {
"function": "extract_number",
"params": {}
}
}Cette zone :
- Lit le texte dans la région (362, 125) de taille 318×25
- Utilise la langue française pour l'OCR
- Autorise uniquement les chiffres, le symbole €, la virgule et le point
- Essaie d'abord le mode PSM 7 (une ligne), puis 8 (un mot)
- Filtre pour garder uniquement les pixels proches de la couleur orange (245, 118, 3)
- Extrait le nombre du résultat (convertit "0,506" en 0.506)
# Initialiser la base de données (applique les migrations automatiquement)
python init_database.py
# Ou appliquer les migrations manuellement
python run_migrations.py upgrade head
# Créer une nouvelle migration après modification des modèles
python run_migrations.py "revision --autogenerate -m 'Description'"
# Revenir en arrière
python run_migrations.py "downgrade -1"- Phase 1 (par défaut): Collecte et affichage des informations
- Phase 2: Analyse et suggestions de coups
- Phase 3: Automatisation avec clics
Activer les phases dans config.py ou config.json.
main.py: Point d'entrée principalconfig.py: Configuration centraliséedatabase.py: Gestionnaire de base de données SQLite avec ORMview_database.py: Script pour consulter les données stockéesproviders/: Configurations par providerscreenshots/: Screenshots sauvegardéserror_captures/: Captures d'erreurtest_screenshots/: Screenshots de test (mode debug)playtime_data/: Données de temps de jeuopponent_data/: Statistiques des adversairespoker_bot.db: Base de données SQLite (créée automatiquement)
Le bot stocke automatiquement toutes les informations des parties dans une base de données SQLite (poker_bot.db) :
- Sessions de jeu : Chaque partie est enregistrée avec ses métadonnées
- États de jeu : Tous les screenshots et données extraites sont sauvegardés
- Actions : Toutes les actions effectuées (Fold, Call, Raise, etc.) avec leur contexte
- Adversaires : Statistiques et informations sur chaque adversaire rencontré
Utilisez view_database.py pour consulter les données stockées.
- Le bot fonctionne uniquement sur Windows (win32gui)
- Les screenshots sont pris uniquement de la fenêtre de poker
- Le bot s'arrête automatiquement après 11-12h de jeu par provider
- Pauses aléatoires de 2-5 minutes entre les parties
- Toutes les données sont automatiquement sauvegardées dans la base de données SQLite