PhpSnip.com

User Stats

Poker Player

This script will automatically play the game of poker. It is the winner of a Codewalkers.com PHP Coding Contest.

Info

 Download  View Source (print view)
 Rating : 4.7  Views : 341

Source Code ( 346 lines )

<?php
/**********************************************************
* Nicholas Clark
* 9/12/02
* Poker Contest
**********************************************************/
    define('TWO_KIND',2);
    define('TWO_PAIR',5);
    define('THREE_KIND',8);
    define('STRAIGHT',10);
    define('FLUSH',15);
    define('FULL_HOUSE',17);
    define('FOUR_KIND',20);
    define('STRAIGHT_FLUSH',25);
    main();
    function main() {
    global $deck_values,$deck_suits,$hand_values,$hand_suits,$total_odds_value,$deck,$final_points;
    get_deck_file();
    while (sizeof($deck) > 8) {
        $total_odds_value = $newhand_value = $newhand_suits = $test_suits = $test_value = $hand_suits = $hand_values = array();
        $deck_keys = array_keys($deck);
        for ($i = 0; $i < 5; $i++) {
        $hand_suits[] = $deck_suits[$deck_keys[$i]];
        $hand_values[] = $deck_values[$deck_keys[$i]];
        unset($deck_suits[$deck_keys[$i]]);unset($deck_values[$deck_keys[$i]]);unset($deck[$deck_keys[$i]]);
        }
        $hand = array_join($hand_suits,$hand_values,',');
        for ($i = 0; $i < 32; $i++) {
        for ($j = 0; $j < 5; $j++) {
            if ($i & pow(2,$j)) {
            $test_suits[$i][] = $hand_suits[$j];
            $test_value[$i][] = $hand_values[$j];
            }
            else {
            $test_suits[$i][] = '*';
            $test_value[$i][] = '*';
            }
        }
        get_odds($test_value[$i],$test_suits[$i]);
        }
        arsort($total_odds_value);
        $keys = array_keys($total_odds_value);

        $count = 0;
        $deck_keys = array_keys($deck);
        for ($i = 0; $i < 5; $i++) {
        if ($test_value[$keys[0]][$i]) {
            $newhand_value[$i] = $test_value[$keys[0]][$i];
            $newhand_suits[$i] = $test_suits[$keys[0]][$i];
        }
        else {
            $newhand_suits[$i] = $deck_suits[$deck_keys[$count]];
            $newhand_value[$i] = $deck_values[$deck_keys[$count]];
            unset($deck_suits[$deck_keys[$count]]);unset($deck_values[$deck_keys[$count]]);unset($deck[$deck_keys[$count]]);
            $count++;
        }
        }
        $final_points += $final_hands[] = get_points($newhand_value,$newhand_suits);
    }
    $keys = array_keys($deck);

    $file = fopen("output.txt",'w');
    $final_hands = array_count_values($final_hands);
    $total_hands = 0;
    $total_points = 0;
    foreach (array(
        //0 => 'ZERO_HAND',
        TWO_KIND => 'TWO_KIND',
        TWO_PAIR => 'TWO_PAIR',
        THREE_KIND => 'THREE_KIND',
        STRAIGHT => 'STRAIGHT',
        FLUSH => 'FLUSH',
        FULL_HOUSE => 'FULL_HOUSE',
        FOUR_KIND => 'FOUR_KIND',
        STRAIGHT_FLUSH => 'STRAIGHT_FLUSH',
        ) as $id => $name) {
        $final_hands[$id] += 1-1;
        fwrite($file,$name.': '.$final_hands[$id]."n");
        $total_hands += $final_hands[$id];
        $total_points += $final_hands[$id]*$id;
    }
    fwrite($file,$total_hands."n".($total_points/$total_hands)."n".$total_points);
    fclose($file);
    }
    function get_deck_file() {
    global $suits,$cards,$deck_suits,$deck_values,$deck;
    $suits = array('d','c','s','h');
    $cards = array(2,3,4,5,6,7,8,9,10,11,12,13,14);
    $file = file("input.txt");
    foreach ($file as $card) {
        $deck_values[] = str_replace(array('T','J','Q','K','A'),array(10,11,12,13,14),substr($card,0,1));
        $deck_suits[]  = strtolower(substr($card,1,1));
    }

    $deck = array_join($deck_suits,$deck_values,'');
    }
    function get_odds(&$values,&$suits) {
    global $deck,$total_odds_value,$total_odds;
    for ($i = 0; $i < 5; $i++) if ($values[$i] == '*') { unset($values[$i]);unset($suits[$i]); }
    if (sizeof($values) < 2 && !in_array(14,$values)) {$total_odds_value[] = ''; return false;}
    // odds for a straight-flush
    $odds += get_odds_straightflush($values,$suits) * STRAIGHT_FLUSH;
    // odds for a flush
    $odds += get_odds_flush($suits) * FLUSH;
    // odds for a straight
    $odds += get_odds_straight($values) * STRAIGHT;
    // odds for 4-kind
    $odds += get_odds_xkind($values,4) * FOUR_KIND;
    // odds for full house
    $odds += get_odds_fullhouse($values) * FULL_HOUSE;
    // odds for 3-kind
    $odds += get_odds_xkind($values,3) * THREE_KIND;
    // odds for 2-pair
    $odds += get_odds_twopair($values) * TWO_PAIR;
    // odds for 2-kind
    $odds += get_odds_xkind($values,2) * TWO_KIND;
    $total_odds_value[] = $odds;
    return $odds;
    }
    function get_points(&$values,&$suits) {
    // points for a straight-flush
    if     (get_points_straightflush($values,$suits)) return STRAIGHT_FLUSH;
    // points for a flush
    elseif (get_points_flush($suits)) return FLUSH;
    // points for a straight
    elseif (get_odds_straight($values)) return STRAIGHT;
    // points for 4-kind
    elseif (get_points_xkind($values,4)) return FOUR_KIND;
    // points for full house
    elseif (get_points_fullhouse($values)) return FULL_HOUSE;
    // points for 3-kind
    elseif (get_points_xkind($values,3)) return THREE_KIND;
    // points for 2-pair
    elseif (get_points_twopair($values)) return TWO_PAIR;
    // points for 2-kind
    elseif (get_points_xkind($values,2)) return TWO_KIND;
    else return 0;
    }
    function get_odds_straightflush($values,$suits) {
    global $deck,$deck_values,$total_odds;
    if (array_max($values,0) > 1 || array_max($suits,0) != sizeof($suits)) return 0;
    asort($values);
    $keys = array_keys($values);
    $lo = $values[$keys[0]];
    $hi = $values[$keys[sizeof($values)-1]];
    
    if ($hi - $lo >= 5) return 0;
    if (sizeof($hand) == 5) return 1;

    $deck_count = array_count_values($deck);
    for ($i = $lo-4; $i <= $lo; $i++) {
        if ($i < $hi-4 || $i < 2 || $i+4 > 14) continue;
        $temp = 1;
        for ($j = 0; $j < 5; $j++) {
        if (in_array($j+$i,$values)) continue;
        $temp *= $deck_count[$suits[$keys[0]].($j+$i)]/(sizeof($deck)-$count);
        }
        $odds += $temp*factorial(5-sizeof($values));
    }
    return $odds;
    }
    function get_odds_xkind($values,$amount) {
    global $deck_values,$deck,$total_odds;

    $left = array_count_values($deck_values);
    $numleft = array_count_values($left);
    // odds of getting x of a kind using one of the cards already in hand

    foreach (array_count_values($values) as $key => $count) {
        $numleft[4-$count]--;
        if        ($amount == $count) return 1;
        elseif    ($amount < $count) return 0;
        elseif    ($amount - $count > 5 - sizeof($values)) continue;
        $temp = choose($left[$key],$amount-$count)*choose(sizeof($deck_values)-$left[$key],5-sizeof($values)-($amount-$count));
        $odds += $temp;
    }
    // odds of getting x of a kind with a card not currently in your hand
    if ($amount <= 5-sizeof($values)) {
        for ($i = 4; $i >= $amount; $i--) {
        $odds += choose($numleft[$i],1)*choose($i,$amount);
        }
    }
    return $odds / choose(sizeof($deck),5-sizeof($values));
    }
    function get_odds_fullhouse($values) {
    global $deck_values,$deck,$total_odds;
    $cards = array_count_values($values);
    if (sizeof($cards) > 2) return 0;
    $keys = array_keys($cards);
    $left = array_count_values($deck_values);
    foreach ($left as $key => $value) {
        if ($cards[$key]) continue;
        $numleft[$value]++;
    }
    if (sizeof($cards) == 1) {
        for ($j = 4; $j > 1; $j--) {
        if (!$numleft[$j]) continue;
        $odds += choose($left[$keys[0]],3-$cards[$keys[0]])*choose($numleft[$j],1)*choose($j,2) +
                 choose($left[$keys[0]],2-$cards[$keys[0]])*choose($numleft[$j],1)*choose($j,3);
        }
    }
    else {
        $odds = choose($left[$keys[0]],3-$cards[$keys[0]])*choose(1,1)*choose($cards[$keys[1]],2)+
            choose($left[$keys[1]],3-$cards[$keys[1]])*choose(1,1)*choose($cards[$keys[0]],2);
    }
    return $odds / choose(sizeof($deck),5-sizeof($values));
    }
    function get_odds_twopair($values) {
    global $deck_values,$deck,$total_odds;
    $cards = array_count_values($values);
    if (sizeof($cards) > 3) return 0;
    arsort($cards);
    $keys = array_keys($cards);
    if (array_max($values,0) == 2 && array_max($values,1) == 2) return 1;
    $left = array_count_values($deck_values);

    foreach ($left as $key => $value) {
        if ($cards[$key]) continue;
        $numleft[$value]++;
    }
    if ($cards[$keys[0]] == 2) {
        for ($i = 1; $i < sizeof($cards); $i++) {
        $odds += choose($left[$keys[$i]],1)*choose(sizeof($deck)-$left[$keys[0]]-$left[$keys[$i]],5-sizeof($values)-1);
        }
        if (2 <= 5-sizeof($values)) {
        for ($i = 4; $i >= 2; $i--) {
            $odds += choose($numleft[$i],1)*choose($i,2)*choose(sizeof($deck)-$left[$keys[0]]-$i,5-sizeof($values)-2);
        }
        }
    }
    else {
        for ($i = 0; $i < sizeof($cards); $i++) {
        for ($j = 4; $j >= 2; $j--) {
            $odds += choose($left[$keys[$i]],1)*choose($numleft[$j],1)*choose($j,2)*choose(sizeof($deck)-$left[$keys[$i]]-$j,5-sizeof($values)-3);
        }
        foreach ($values as $key => $value) {
            if ($values[$keys[$i]] == $value) continue;
            $odds += choose($left[$keys[$j]],1)*choose($left[$keys[$j]],1)*choose(sizeof($deck)-$left[$keys[$j]]-$left[$key],5-sizeof($values)-2);
        }
        }
    }
    return $odds / choose(sizeof($deck),5-sizeof($values));
    }
    function get_odds_flush($values) {
    global $deck_suits,$total_odds;
    if (sizeof(array_count_values($values)) != 1) return 0;
    if (sizeof($values) == 5) return 1;
    $left = array_count_values($deck_suits);
    $keys = array_keys($values);
    return choose($left[$values[$keys[0]]],5-sizeof($values))/choose(sizeof($deck_suits),5-sizeof($values));
    }
    function get_odds_straight($values) {
    global $deck,$deck_values;
    if (sizeof(array_count_values($values)) != sizeof($values)) return 0;
    asort($values);
    $keys = array_keys($values);

    $lo = $values[$keys[0]];
    $hi = $values[$keys[sizeof($values)-1]];
    
    if ($hi - $lo >= 5) return 0;
    if (sizeof($values) == 5) return 1;
    $deck_count = array_count_values($deck_values);

    for ($i = $lo-4; $i <= $lo; $i++) {
        if ($i < $hi-4 || $i < 2 || $i+4 > 14) continue;
        $temp = 1;
        for ($j = 0; $j < 5; $j++) {
        if (in_array($j+$i,$values)) continue;
        $temp *= $deck_count[$j+$i]/(sizeof($deck)-$count);
        }
        $odds += $temp*factorial(5-sizeof($values));
    }
    return $odds;
    }

    function get_points_straightflush(&$values,&$suits) {
    if (array_max($values,0) == 1 && array_max($suits,0) == 5) {
        arsort($values);
        $keys = array_keys($values);
        if ($values[$keys[0]] - $values[$keys[4]] == 4) return true;
    }
    return false;
    }
    
    function get_points_flush(&$suits) {
    if (array_max($suits,0) == 5) return true;
    return false;
    }
    
    function get_points_straight(&$values) {
    if (array_max($values,0) == 1) {
        arsort($values);
        $keys = array_keys($values);
        if ($values[$keys[0]] - $values[$keys[4]] == 4) return true;
    }
    return false;
    }
    
    function get_points_xkind($values,$amount) {
    if (array_max($values,0) == $amount) return true;
    return false;
    }
    
    function get_points_fullhouse(&$values) {
    if (array_max($values,0) == 3 && array_max($values,1) == 2) return true;
    return false;
    }
    
    function get_points_twopair(&$values) {
    if (array_max($values,0) == 2 && array_max($values,1) == 2) return true;
    return false;
    }

    function choose($a=0,$b=0) {
    if ($b > $a || $a < 0 || $b < 0) return 0;
    $temp = 1;
    for ($i = $a; $i > $a - $b; $i--) $temp *= $i;
    return $temp / factorial($b);
    }
    function factorial($start) {
    global $cache;
    if ($start < 1) return 1;
    if ($cache[$start]) return $cache[$start];
    $output = 1;
    for ($i = 1; $i <= $start; $i++) $output *= $i;
    $cache[$start] = $output;
    return $output;
    }
    function array_join($one,$two,$join) {
    if (sizeof($one) != sizeof($two)) return false;
    foreach ($one as $id => $key) $new[$id] = $one[$id].$join.$two[$id];
    return $new;
    }
    function array_max($array,$offset = 0) {
    $count = array_count_values($array);
    arsort($count);
    $keys = array_keys($count);
    return $count[$keys[$offset]];
    }
    function array_multiply($keys) {
    $output = 1;
    foreach ($keys as $val) $output *= $val;
    return $output;
    }
?>

Search

Subscribe

  Rss Feeds

Sponsors

Advertise