『ポーカーの役判定』投稿

どう書く?orgに初めて投稿しました。

お題はポーカーの役判定です。

引数に手札を与えると、ポーカーの役を表示するプログラムを作ってください。

**条件:**

- スートはS,D,H,C、ランクはA,2~9,T,J,Q,Kのそれぞれ一文字で表します。
- 手札は S2D5H3CQS9 のように10文字で指定されます。特にソートはされていません。
- 手札にジョーカーは含まれません。
- ストレートで取りうるランクの種類はA2345, 23456 … 9TJQK, TJQKAの10種類で、JQKA2のようにK-A-2をまたぐものはストレートではありません。

以下、投稿したコード。選択した言語はPHP。自分でも気持ちの悪い箇所が幾つかあるが、勇気を出して投稿してみた。

function Poker($c)  
{  
    CSort($c);  
    if (IsFlush($c)) {  
        if (IsStraight($c)) {  
            if ($c[1] == 'A') {  
                return 'Royal flush';  
            }  
            return 'Straight flush';  
        }  
        return 'Flush';  
    } else {  
        if (IsStraight($c)) {  
            return 'Straight';  
        }  
        $wk = array();  
        $wk[$c[1]]++;  
        $wk[$c[3]]++;  
        $wk[$c[5]]++;  
        $wk[$c[7]]++;  
        $wk[$c[9]]++;  
        arsort($wk);  
        switch (array_shift($wk).array_shift($wk)) {  
        case '41':    return 'Four of a kind';  
        case '32':    return 'Full house';  
        case '31':    return 'Three of a kind';  
        case '22';    return 'Two pair';  
        case '21';    return 'One pair';  
        }  
    }  
    return 'No pair';  
}  
  
function IsFlush($c)  
{  
    if ($c[0] == $c[2] && $c[0] == $c[4] && $c[0] == $c[6] && $c[0] == $c[8]) {  
        return TRUE;  
    }  
    return FALSE;  
}  
  
function IsStraight($c)  
{  
    $rank = 'A23456789TJQK';  
    $num = $c[1].$c[3].$c[5].$c[7].$c[9];  
    if (strpos($rank, $num) !== FALSE || $num == 'ATJQK') {  
        return TRUE;  
    }  
    return FALSE;  
}  
  
function CSort(&$c)  
{  
    $rep = array('1'=>'A', '10'=>'T', '11'=>'J', '12'=>'Q', '13'=>'K');  
    $wk = array($c[0].$c[1] => $c[1], $c[2].$c[3] => $c[3],  
                $c[4].$c[5] => $c[5], $c[6].$c[7] => $c[7],  
                $c[8].$c[9] => $c[9]);  
    $wk = str_ireplace($rep, array_flip($rep), $wk);  
    asort($wk);  
    $c = '';  
    foreach ($wk as $key => $value) {  
        $c .= $key;  
    }  
}