Wie bereits angekündigt wird die nächste Version von Manager’s Life ein Casino in die Spielwelt integrieren. Dabei darf natürlich kein Multiplayer-Poker fehlen!
Poker mit PHP umzusetzen ist eigentlich eine relativ einfache Sache – der schwierigere Teil ist das erkennen der Poker-Hände beim Showdown (Flush, Straight, Pair, …). Natürlich kann man einfach alle möglichen Hände hardcoden und dann einfach eine nach der anderen Abarbeiten (siehe zB phppokerengine), das ist aber nicht besonderst elegant, performant oder erweiterbar. Außerdem ist es sehr unübersichtlich und fehleranfällig. Deshalb habe ich mir gedacht, man könnte alle möglichen Poker-Hände mit einer Abstraktions-Sprache definieren und diese dann mit entsprechendem Parser zu behandeln.
Zuerst zu meiner Sprache, die ich wie folgt definiert habe:
- Gleiche Zahlen stellen gleiche Karten-Werte dar
- Gleiche Buchstaben stellen gleiche Farben dar
- Ein Fragezeichen steht für eine beliebige Karte
- Ein > sagt, dass die nächste Karte direkt auf die vorherige folgen muss.
- Ein [ sagt, dass das nächste Zeichen kein Symbol, sondern kein expliziter Kartenwert ist
- {x} nach einem Symbol gibt an, wie oft es wiederholt wird
Um das ganze zu konkretisieren habe ich nun alle Poker-Hände in meine Sprache übersetzt:
// pair (zB ♥A - ♦A)
1{2}
// two pair (zB ♣A - ♦A - ♠3 - ♣3)
1{2}2{2}
// three of a kind (zB ♣A - ♦A - ♠A)
1{3}
// straight (zB ♣K - ♦Q - ♠J - ♣10 - ♣9)
?>?>?>?>?
// flush (zB ♣2 - ♣Q - ♣9 - ♣10 - ♣9)
a{5}
// full house (zB ♣K - ♦K - ♠Q - ♣Q - ♣Q)
1{3}2{2}
// four of a kind (zB ♣K - ♦K - ♠K - ♣K)
1{4}
// straight flush (zB ♣K - ♣Q - ♣J - ♣10 - ♣9)
a>a>a>a>a
// royal flush (zB ♣A - ♣K - ♣Q - ♣J - ♣10)
[a>a>a>a>a
Das Parsen und Verarbeiten ist zwar etwas trickreicher, aber machbar. Ich habe einen Quick-n-Dirty PHP-Prototypen gebaut – er funktioniert, ist allerdings nicht besonderst sauber geschrieben. Im Vergleich zu der Methode „alle-Möglichkeiten-hardcoren“ entsteht übrigens noch ein weiterer Vorteil: Meine Klasse ist 7kB groß, die oben verlinkte 0,5 MB…
Die Verwendung der Klasse erfolgt so:
a>a>a>a');
$hand = array(
array('color' => 'spades', 'card' => 'k'),
array('color' => 'spades', 'card' => 'q'),
array('color' => 'spades', 'card' => 'j'),
array('color' => 'spades', 'card' => '10'),
array('color' => 'spades', 'card' => '9')
);
if ($parser->check($hand)) {
echo "Deine Hand enthält ein Straight Flush!
n";
} else {
echo "Kein Straight Flush vorhanden.
n";
}
?>
Die Ausgabe sollte „Deine Hand enthält ein Straight Flush!“ sein.
Die Klasse findet sich dort: PokerParser.class.php