Online-Poker automatisieren mit C#.NET

KartenDetektor mit GewinnwahrscheinlichkeitKommen wir heute zum dritten Teil der C#-Casino-Reihe. Wer gerade erst in die Serie einsteigt, sollte sich zuvor die ersten beiden Teile durchlesen. In Teil 1 ging es um die Berechnung der Gewinnwahrscheinlichkeit einer Pokerhand in C# und in Teil 2 ging es um das Erkennen von Spielkarten und deren Werten mittels maschinellem Sehen mit Hilfe der AForge-Bibliothek. Wir haben bisher also auf spielerische Art und Weise sowohl das Feld der Statistik, die Verwendung von externen Bibliotheken als auch die Grundlagen der Bildverarbeitung mittels C# bearbeitet.

Im heutigen, dritten Teil, soll es um die Verknüpfung der Ergebnisse der ersten beiden Artikel gehen. Wir wollen also für die analysierten Karten aus Teil 2 direkt die Gewinnwahrscheinlichkeit (wie in Teil 1) berechnen.

Vorbereitungen

Bevor es losgeht, solltet ihr euch das Ergebnis des zweiten Artikels herunterladen. Den Downloadlink für das Visual Studio Projekt findet ihr am Ende des Artikels. Um ein wenig “Kanonenfutter” zu haben, sprich Ausgangsmaterial, braucht ihr noch Screenshots aus einem beliebigen Online-Casino. Zum Testen reicht definitiv auch ein kostenloser Account!

Solltet ihr mit den gleichen Screenshots wie ich arbeiten wollen, damit ihr die Bilderkennung aus Teil 2 nicht anpassen müsst, so müsstet ihr euch einen kostenlosen Account bei Full Tilt Casino oder Mr. Green machen. (Alternativ hilft z.B. ein Blick auf serioeseonlinecasinos.org – dort sind, neben Mr. Green und Full Tilt Poker, noch weitere Alternativen gelistet.)

Habt ihr das Visual Studio Projekt geladen, kann es losgehen. Wir nehmen bewusst das Projekt des zweiten Artikels als Ausgangslage, da sich der Code aus Teil 1 leichter in Teil 2 “verpflanzen” lässt, als es andersrum der Fall wäre.

Using-Direktiven und eine weitere Bibliothek

Zuerst übertragen wir die externen Referenzen und Hilfsklassen aus Teil 1 in unser aktuelles Projekt. Hierzu kopieren wir die HandEvaluator.dll aus dem Projektordner von Teil 1 in den aktuellen Projektordner. Danach klicken wir im Verweis-Bereich des Visual Studios auf “Verweis hinzufügen”, wählen die DLL-Datei aus und schreiben schlussendlich die using-Anweisung (“HoldemHand”) in den Kopf der Form1.cs-Datei.


//...
using AForge.Math.Geometry;
using System.Drawing.Imaging;
using HoldemHand;

Nun haben wir die Grundlage geschaffen, um auch in unserem aktuellen Projekt die Gewinnwahrscheinlichkeit zu berechnen. Um nun auch in der Praxis die Wahrscheinlichkeit zu berechnen, brauchen wir natürlich die ausgeteilten Karten – ohne diese kann eine Berechnung logischerweise nicht stattfinden. Wer Teil 2 noch im Kopf hat, weiß, dass die Erkennung der Karten in der analyzeCards()-Methode stattgefunden hat. Zum Ende der Methode haben wir also die nötigen Informationen, sodass wir uns an dieser Stelle einklinken und die Funktion erweitern.

Arbeiten mit dem HandEvaluator

Nun geht es also darum, mittels des HandEvaluators die Gewinnwahrscheinlichkeit der bereits ermittelten Karten zu bestimmen. Die Aufgabe lautet also die erkannten Kartenwerte in die Form zu bringen, die der Handevaluator als Eingabe benötigt. Unsere Kartenwerte haben wir bisher in der Liste List<Card> cards abgelegt, wobei die Indizes 0-2 die Karten im Deck und die Indizes 3 und 4 die beiden Handkarten enthalten.  Jeder Index der cards-Liste besitzt wiederum die Eigenschaften suit (= Kartenfarbe) und value (=Kartenwert).

Da der HandEvaluator jedoch die englischen Kurzformen für die Kartenfarben benötigt, legen wir zuvor noch ein Dictionary an, mit dem wir gleich die deutschen Kartenfarbennamen (aus Teil 2) in die englische Kurzform überführen können.


//Kartenwerte und dazugehörige Bezeichnungen für die Poker-Library
private Dictionary<string, string> cardsTranslator = new Dictionary<string, string>()
{
{"2", "2"}, {"3", "3"}, {"4", "4"}, {"5", "5"}, {"6", "6"}, {"7", "7"},
{"8", "8"}, {"9", "9"}, {"10", "10"}, {"Bube", "J"}, {"Dame", "Q"},
{"König", "K"}, { "Ass", "A" }, {"Pik", "s"}, {"Herz", "h"}, {"Karo", "d"}, {"Kreuz", "c"}
};

Nun sind wir bereit, um die Gewinnwahrscheinlichkeit auszurechnen. Hierzu iterieren wir über alle Karten, übersetzen die Kartenfarben und übergeben dann den String, der alle Karten enthält an den HandEvaluator. Wem das jetzt zu schnell ging, der schaut sich am besten die Kommentare im nachfolgenden Code an oder hängt einfach mal einen Breakpoint in den Debugger. Folgenden Code fügen wir, wie eben besprochen, am Ende der analyzeCards()-Methode ein.


//Gewinnwahrscheinlichkeit berechnen - Teil 3

//Fasse alle Hand-Karten als string in der Poker-Library-Syntax zusammen
string handCards = "";
//Durchlaufe alle erkannten Karten
for (int i = 3; i < 5; i++)
{
handCards += cardsTranslator[cards[i].value] + cardsTranslator[cards[i].suit] + " ";
}
handCards = handCards.Trim();

//Fasse alle Deck-Karten als string in der Poker-Library-Syntax zusammen
string deckCards = "";
for (int i = 0; i < 3; i++)
{
deckCards += cardsTranslator[cards[i].value] + cardsTranslator[cards[i].suit] + " ";
}
deckCards = deckCards.Trim();

//Initialisiere Hilfsvariablen für die Poker-Library
double[] self = new double[9];
double[] opponent = new double[9];
double selfWin = 0.0;

//Berechne Poker-Hände und Wahrscheinlichkeiten
Hand.HandPlayerOpponentOdds(handCards, deckCards, ref self, ref opponent);

//Berechne Sieg-/Split-Wahrscheinlichkeit
for (int i = 0; i < 9; i++)
{
selfWin += self[i] * 100.0;
}

//Gebe Sieg-/Split-Wahrscheinlichkeit aus
var siegWahrscheinlichkeit = string.Format("{0:##0.0}%", selfWin);

KartenDetektor Label in WinFormsNun sind wir auch schon fast fertig. Das Ergebnis unserer Berechnung sollte sich nun in der String-Variable siegWahrscheinlichkeit befinden. Um diese auch an geeigneter Stelle anzuzeigen, fügen wir im WinForms-Designer noch ein Label ein. (Ich habe es labelWahrscheinlichkeit genannt und neben dem “nächster Screenshot”-Button platziert.)

Um die Wahrscheinlichkeit auszugeben, fügen wir nun noch eine letzte Zeile in unsere analyzeCards()-Methode ein.


labelWahrscheinlichkeit.Text = "Wahrscheinlichkeit für\r\nSieg oder Split:\r\n\r\n" + siegWahrscheinlichkeit;

Nun sind die Arbeiten abgeschlossen und wir neigen uns dem Ende des dritten Teils unserer Serie.

Fazit & Download

Das fertige Projekt könnt ihr natürlich wie immer herunterladen:

Download: KartenDetektor V2 – Visual Studio Project

Mit wenigen “Handgriffen” lassen sich die Ergebnisse der ersten beiden Artikel miteinander verschmelzen und somit ein Mehrwert kreieren. Solltet ihr Fragen oder Probleme haben, schreibt mir einen Kommentar. Selbiges gilt natürlich auch für Ideen, Wünsche oder Vorschläge für weitere Teile in der Serie! Was wollt ihr als nächstes sehen/lernen? Ich freue mich auf euer Feedback.

Raffi

Seit 2011 blogge ich hier über Programmierung, meine Software, schreibe Tutorials und versuche mein Wissen, so gut es geht, mit meinen Lesern zu teilen.

Hinterlasse einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Sie dient nur dem Spamschutz.