0

我正在尝试使用关联数组中的值来计算用户是否在扑克牌中拥有顺子。

每个玩家的手牌都在同一个数组中,其结构类似于:

<?php
// Note: the first 5 values of each player's hand are identical because those are
// the dealer's cards (the cards on the "board" that everyone can see).
// The last two values represent the player's "hole cards" that only they can see.

// Also note: 11 = Jack, 12 = Queen, 13 = King, 14 = Ace.
$hands = array(
  // Player 0
  0 => array(
    0 => array("value_num" => 6),
    1 => array("value_num" => 7),
    2 => array("value_num" => 8),
    3 => array("value_num" => 9),
    4 => array("value_num" => 14),
    5 => array("value_num" => 10),
    6 => array("value_num" => 8),
  ),
  // Player 1
  1 => array(
    0 => array("value_num" => 6),
    1 => array("value_num" => 7),
    2 => array("value_num" => 8),
    3 => array("value_num" => 9),
    4 => array("value_num" => 14),
    5 => array("value_num" => 10),
    6 => array("value_num" => 13),
  ),
  // Player 2
  2 => array(
    0 => array("value_num" => 6),
    1 => array("value_num" => 7),
    2 => array("value_num" => 8),
    3 => array("value_num" => 9),
    4 => array("value_num" => 14),
    5 => array("value_num" => 5),
    6 => array("value_num" => 12),
  ),
  // Player 3
  3 => array(
    0 => array("value_num" => 6),
    1 => array("value_num" => 7),
    2 => array("value_num" => 8),
    3 => array("value_num" => 9),
    4 => array("value_num" => 14),
    5 => array("value_num" => 5),
    6 => array("value_num" => 13),
  ),
);

我编写的用于确定玩家是否有顺子的函数如下所示:

<?php
/**
 * @return
 *   The highest card value of the player's straight, if they have a straight.
 *   Otherwise, 0.
 */
function has_straight($cards, $player_id, $required_consecutive_cards = 5) {
  // Extract the "value_num" values to calculate the straight.
  for ($i = 0; $i < count($cards[$player_id]); $i++) {
    $values[$player_id][$i] = $cards[$player_id][$i]['value_num'];
  }

  // Check to see if the player has an Ace within their hand.
  $has_ace[$player_id] = array_search(14, $values[$player_id]);

  // If the player has an Ace, push a 1 into their $value array in case they also
  // have 2, 3, 4, and 5 in their hand.
  if ($has_ace[$player_id] !== FALSE) {
    array_push($values[$player_id], 1);
  }

  // Only check the player's unique values. Right now we're not concerned with
  // pairs or anything else.
  $player_cards[$player_id] = array_unique($values[$player_id]);

  // Reverse sort the player's unique values to make counting sequences easier.
  rsort($player_cards[$player_id]);

  // Set a number to increment if one card is sequential to the other.
  $increment_value[$player_id] = 1;
  foreach ($player_cards[$player_id] as $key => $value) {
    $next_key = $key + 1;
    $next_value = $value - 1;
    if (!array_key_exists($next_key, $player_cards[$player_id])) {
      return 0;
    }
    if ($player_cards[$player_id][$next_key] == $next_value) {
      $increment_value[$player_id]++;
    }
    else {
      $increment_value[$player_id] = 1;
      unset($player_cards[$player_id][$key]);
    }
    if ($increment_value[$player_id] == $required_consecutive_cards) {
      // Reverse sort what's left of the values so that the first one can be
      // the value returned.
      rsort($player_cards[$player_id]);
      return $player_cards[$player_id][0];
    }
  }
  return 0;
}

因此,要确定玩家 0 是否有顺子,您可以运行以下命令:

<?php
$player_to_check = 0;
print has_straight($hands, $player_to_check);

...这应该导致10作为输出(10是玩家 0 顺子中的最高值 -- 6, 7, 8, 9, 10)。

我遇到的问题是,例如,当您检查玩家 1 的顺子(应该与玩家 0 的顺子相同)时,输出将1410.

发生这种情况的原因是因为玩家 113手中也有 a,并且由于13与 连续1414因此返回而不是10(即使14不在玩家 1 的顺子之内)。

比较玩家 3 和 4 时可以看到同样的问题。

我需要在函数内部做什么才能使其返回一组 5 个序列号中的最大值(而不是找到的第一组序列号的最大值)?

4

4 回答 4

1

顺子有 5 张连续的牌,总和始终遵循以下规则:(n*5)+10。其中 n 是起始卡。总和越高,起始卡越高。所以这可能是一个解决方案:

foreach($player_id as $id){
    //GET THE CARD VALUES FROM THIS PLAYER
    $cards=array();
    foreach($player_cards[$id] as $tmp){
        $cards[] = $tmp['value_num'];
        }
    //ONLY THE UNIQUE CARDS
    $cards=array_unique($cards);
    //SORT THEM LOW TO HIGH
    sort($cards);


    //Get the maximum amount of possabilities for a straight from 
      //the maximum 7 cards in a hand
    $max=count($cards)-4;
    //IF TOO LITTLE CARDS, CONTINUE WITH NEXT PLAYER
    if($max<=0)continue;

    //SET SUM and HIGHEST SUM
    $sum=0;
    $hsum=0;

    //LOOP THE POSSIBLE STRAIGHTS
    for($i=1;$i<$max+1;++$i){
        //GET 5 CONSECUTIVE CARDS
        $straight=array_slice($cards,$i-1,5);

        $sum_should_be=($straight[0]*5)+10;
        $sum = array_sum($straight);

        //IF SUM NOT CORRECT, CONTINUE WITH NEXT POSSIBLE STRAIGHT
        if($sum!=$sum_should_be)continue;
        //GET THE HIGHEST STRAIT FOR USER
        if($sum>$hsum)$hsum=$sum;
    //ADD STRAIGHT SCORE TO ARRAY FOR COMPARISON
    $straight_score[$id]=$straight[4];
    }
}

它会给你:

Player 0. Straight score: 10
Player 1. Straight score: 10
Player 2. Straight score: 9
Player 3. Straight score: 9
于 2014-07-25T09:52:43.490 回答
0

那这个呢?不确定我是否理解这些问题并且我没有测试它,但也许它会有所帮助。

$increment_value[$player_id] = 1;
  foreach ($player_cards[$player_id] as $key => $value) {
    $next_key = $key + 1;
    $next_value = $value - 1;
    if (!array_key_exists($next_key, $player_cards[$player_id])) {
      return 0;
    }
    if ($player_cards[$player_id][$next_key] == $next_value) {
      if($increment_value[$player_id] == 1) {
          $top_card_key = $player_cards[$player_id][key]
          $top_card[$top_card_key] = 1;
      }
      $increment_value[$player_id]++;
      if(isset($top_card[$top_card_key])) {
          $top_card[$top_card_key]++;
      }
    }
    else {
      $increment_value[$player_id] = 1;
      unset($player_cards[$player_id][$key]);
    }
    if ($increment_value[$player_id] == $required_consecutive_cards) {
      // Reverse sort what's left of the values so that the first one can be
      // the value returned.
      rsort($player_cards[$player_id]);

      // Foreach on top_card, check which one == 5  and display it 
      // return the top_card;
    }
于 2014-07-25T09:20:29.620 回答
0

这是你的答案,我尽我所能评论它。请注意,其中有一部分是同花不需要的,这是真的,但我也冒昧地将牌分组。您将在输出中看到这一点。顶部数组的键是卡片值,该项目的数组计数是多张卡片的数量,我想你可以弄清楚如何处理这些。

    foreach( $hands as $cards ){
        rsort($cards);
        //holding array for sequential cards
        $seq = array();
        $_cards = array();
        foreach( $cards as $key => $card){
            $c_value = $card['value_num'];
            // < start --- not needed for flush  - need these without the nested array 
            if( !isset( $_cards[$c_value] ) ){
                $_cards[$c_value] = array($c_value);
            }else{
                $_cards[$c_value][] = $c_value;
            }
            //end --- not needed for flush >
            //expect last item from seq - 1 ( initially -1 )
            $expected = end($seq) - 1;
            if(count($seq) < 5 && !in_array( $c_value, $seq )){
                if( $c_value ==  $expected){
                    //match add to sequence
                    $seq[] = $c_value;
                }else{
                    //fail, reset sequence to start at this card
                    $seq = array($c_value);
                }
            }
        }
        print_r( $seq );
        echo '<br>';
        print_r( max($seq));
        echo '<br>';
        print_r($_cards);
        echo '<br>------------<br>';
    }

输出

Array
(
    [0] => 10
    [1] => 9
    [2] => 8
    [3] => 7
    [4] => 6
)

10
Array
(
    [14] => Array
        (
            [0] => 14
        )

    [10] => Array
        (
            [0] => 10
        )

    [9] => Array
        (
            [0] => 9
        )

    [8] => Array
        (
            [0] => 8
            [1] => 8
        )

    [7] => Array
        (
            [0] => 7
        )

    [6] => Array
        (
            [0] => 6
        )

)

------------
Array
(
    [0] => 10
    [1] => 9
    [2] => 8
    [3] => 7
    [4] => 6
)

10
Array
(
    [14] => Array
        (
            [0] => 14
        )

    [13] => Array
        (
            [0] => 13
        )

    [10] => Array
        (
            [0] => 10
        )

    [9] => Array
        (
            [0] => 9
        )

    [8] => Array
        (
            [0] => 8
        )

    [7] => Array
        (
            [0] => 7
        )

    [6] => Array
        (
            [0] => 6
        )

)

------------
Array
(
    [0] => 9
    [1] => 8
    [2] => 7
    [3] => 6
    [4] => 5
)

9
Array
(
    [14] => Array
        (
            [0] => 14
        )

    [12] => Array
        (
            [0] => 12
        )

    [9] => Array
        (
            [0] => 9
        )

    [8] => Array
        (
            [0] => 8
        )

    [7] => Array
        (
            [0] => 7
        )

    [6] => Array
        (
            [0] => 6
        )

    [5] => Array
        (
            [0] => 5
        )

)

------------
Array
(
    [0] => 9
    [1] => 8
    [2] => 7
    [3] => 6
    [4] => 5
)

9
Array
(
    [14] => Array
        (
            [0] => 14
        )

    [13] => Array
        (
            [0] => 13
        )

    [9] => Array
        (
            [0] => 9
        )

    [8] => Array
        (
            [0] => 8
        )

    [7] => Array
        (
            [0] => 7
        )

    [6] => Array
        (
            [0] => 6
        )

    [5] => Array
        (
            [0] => 5
        )

)

作为旁注,比较之前和之后的卡数可以预测您是否需要检查对等,因为没有对没有删除任何项目。

$cards = array_unique( $cards );
于 2014-07-25T09:34:44.660 回答
0

看看 php 的 max 函数。

http://php.net/manual/en/function.max.php

于 2014-07-25T08:47:28.213 回答