ActionScript 3 Dice Poker Hand Evaluator
So, here is a class I wrote today. Jesse Freeman asked me to do this project, so I did. He showed me the approach that this class uses for being a singleton.
/**
* <p>Original Author: aidan coyne</p>
* <p>Class File: PokerLogic.as
*
* <p>Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:</p>
*
* <p>The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.</p>
*
* <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.</p>
*
* <p>Licensed under The MIT License</p>
* <p>Redistributions of files must retain the above copyright notice.</p>
*
* <p>Revisions<br/>
* 0.1 Initial version Aug 28, 2008</p>
*
*/
package //com.wordpress.raptros
{
/** written by (raptros-v76) Aidan Coyne while working at @radical.media.
*/
//import flash.display.Sprite; //this isn't actually a sprite.
/** Logic singleton for a simple poker dice game.
* At first I intended to do a lookup table system
* but I soon learned I would have to hand write every combination.
* No. Instead, I did this.
*/
public class PokerLogic //extends Sprite //not anymore!
{
private static var __instance:PokerLogic;
private static var __primes:Array = new Array(2, 3, 5, 7, 11, 13);
/** this is supposed to be a singleton
*
*/
public function PokerLogic(enforcer:SingletonEnforcer)
{
}
public static function get instance():PokerLogic //use this to get an`instance of PokerLogic.
{
if(PokerLogic.__instance == null)
{
PokerLogic.__instance = new PokerLogic(new SingletonEnforcer());
}
return PokerLogic.__instance;
}
/** @param hand1 array containing dice rolls
* @param hand2 array containing dice rolls
* @return 1 for hand1, 2 for hand 2, 0 if tied
*/
public function compareHands(hand1:Array, hand2:Array):int
{
var rank1:Object = rankHand(hand1);
var rank2:Object = rankHand(hand2);
if (rank1.rank == rank2.rank)
return 0;
else if (rank1.rank > rank2.rank)
return 1;
else
return 2;
}
/** @param hand array containing dice rolls
* @return an object ranking the hand.
* first number (object.rank) will be between 16 and 6 hundred million
* under 100:high card; 1000 to 7000: 1 pair
* 10,000 to 70,000: 2 pairs; 100,000 to 700,000; 3 of a kind
* 1,000,000 to 7,000,000: full house; 8,000,000 or 9,000,000: straight
* 10,000,000 to 70,000,000: 4 of a kind;
* 100,000,000 to 600,000,000: 5 of a kind.
* second number (object.type) see findHandType
*/
public function rankHand(hand:Array):Object
{
//count number of each type of card
var counts:Array = new Array(0, 0, 0, 0, 0, 0);
for each (var card:int in hand)
{
counts[card - 1]++;
}
var type:int=findHandType(counts);
var rank:int=0;
switch (type)
{
case 0: //high card
for (card=0; card < counts.length; card++)
{
//in high card, there are no repeats
if(counts[card] == 1)
rank+=card;
}
break;
case 1: //1 pair
rank=rankOnePair(counts);
break;
case 2: //2 pairs
rank=rankTwoPairs(counts);
break;
case 3: //3 of a kind
rank=rankThree(counts);
break;
case 4: //full house
rank=rankFullHouse(counts);
break;
case 5: //straight
rank=rankStraight(counts);
break;
case 6: //4 of a kind
rank=rankFour(counts);
break;
case 7: //5 of a kind
rank=rankFive(counts);
break;
}
return {rank:rank, type:type};
}
/** finds the type of the hand: (going from 0 to 7)
{high card, 1 pair, 2 pair, 3kind, fullhouse, straight, 4kind, 5kind}
*/
private function findHandType(counts:Array):int
{
var flags:Array= new Array(1, 0, 0, 0, 0, 0, 0, 0);
var ones:int=0;
for (var die:int = 1; die <= counts.length; die++)
{
var diceCount:int = counts[die-1];
switch(diceCount)
{
case 1:
ones++;
break;
case 2:
if (flags[1] > 0)
flags[2]++;
if (flags[3] > 0)
flags[4]++;
flags[1]++;
break;
case 3:
if (flags[1] > 0)
flags[4]++;
flags[3]++;
break;
case 4:
flags[6]++;
break;
case 5:
flags[7]++;
break;
}
}
//test for a straight
if (ones == 5)
{
if (counts[0] == 0 || counts[counts.length -1] == 0)
flags[5]++;
}
for (var flag:int = flags.length - 1; flag >= 0; flag--)
{
if (flags[flag] > 0)
{
return flag;
}
}
return -1; //should not be reached. might be a good idea to actually test for...
}
private function rankOnePair(counts:Array):int
{
var rank:int=0;
var multi:int=1;
//using the primes trick, plus knowledge that non-pair cards
// are unique in hand
for (var card:int=1; card<=counts.length; card++)
{
if (counts[card-1] == 1)
multi *= PokerLogic.__primes[card-1];
else if (counts[card-1] == 2)
rank = card * 1000;
}
rank += multi;
return rank;
}
private function rankTwoPairs(counts:Array):int
{
var rank:int=0;
var multi:int=0;
for (var card:int=1; card<=counts.length; card++)
{
if (counts[card-1] == 1)
multi = card;
else if (counts[card-1] == 2)
{
if (rank > 0)
rank += card*10000;
else
rank +=card*1000;
}
}
rank += multi;
return rank;
}
private function rankThree(counts:Array):int
{
var rank:int=0;
var multi:int=1;
for (var card:int=1; card<=counts.length; card++)
{
if (counts[card-1] == 1)
multi *= PokerLogic.__primes[card-1];
else if (counts[card-1] == 3)
rank = card * 100000;
}
rank += multi;
return rank;
}
private function rankFullHouse(counts:Array):int
{
var rank:int=0;
for (var card:int=1; card<=counts.length; card++)
{
if (counts[card-1] == 3)
rank+=card*1000000;
else if (counts[card-1] == 2)
rank+=card*100000;
}
return rank;
}
private function rankStraight(counts:Array):int
{
var rank:int=8000000;
if (counts[0] == 0)
rank=9000000;
return rank;
}
private function rankFour(counts:Array):int
{
var rank:int=0;
for (var card:int=1; card<=counts.length; card++)
{
if (counts[card-1] == 4)
rank+=card*10000000;
else if (counts[card-1] == 1)
rank+=card;
}
return rank;
}
private function rankFive(counts:Array):int
{
var rank:int=0;
for (var card:int=1; card<=counts.length; card++)
{
if (counts[card-1] == 5)
rank+=card*100000000;
}
return rank;
}
}
}
//singleton stuf borrowed from Jesse Freeman over at flashartofwar.com
internal class SingletonEnforcer { }
Here is a test class.
package
{
import flash.display.Sprite;
public class DicePokerTest extends Sprite
{
public function DicePokerTest()
{
var types:Array = new Array("High Card", "One Pair", "Two Pair", "Three of a Kind", "Full House", "Straight", "Four of a Kind", "Five of a Kind");
var logic:PokerLogic=PokerLogic.instance;
for (var run:Number=0; run < 5; run++)
{
trace("Test " + run);
var hand1:Array = makeRandomHand();
var hand2:Array = makeRandomHand();
var rank1:Object = logic.rankHand(hand1);
var rank2:Object = logic.rankHand(hand2);
trace("Hand 1: " + hand1 +" has value: " + rank1.rank + ", and is a " + types[rank1.type]);
trace("Hand 2: " + hand2 +" has value: " + rank2.rank + ", and is a " + types[rank2.type]);
var winner:Number=logic.compareHands(hand1, hand2);
trace("Winner is hand"+winner);
}
}
private function makeRandomHand():Array
{
var hand:Array = new Array(diceRoll(), diceRoll(), diceRoll(), diceRoll(), diceRoll());
return hand;
}
private function diceRoll():int
{
return ((Math.random()*1000)%6)+1;
}
}
}
Enjoy.
Categories: Uncategorized
actionscript, as3, class, code, flash, poker dice
Thanks for a great blog! Checkout my blog if you like. I log all my Poker Session there, give some feedback if you want/can. Keep up the blogging!
hi, are you the aidan coyne from kent school?
this is alex kim. do you remember me? u used to write a program
for me for stocks. email me back
This link has some great info on poker programming, hope it helps you guys here in your poker programming.
http://sumitghosh.co.in/category/online-gaming/multiplayer-poker/
This is some great code. Aidan please contact me i might have some work for you