1

I'm making a Yahtzee game and I need a way to calculate a small straight (a sequence of 4 numbers in order). So valid ones would be: 1,2,3,4 | 2,3,4,5 | 3,4,5,6.

I have an array of 5 numbers and I need to figure out if one of those 3 combinations is in that array.

For those not familiar with Yahtzee, there are 5 dice (the five numbers in the array) that can be from 1-6.

2
  • do you have some of the state before hand? If so, you can get better results(speed). Commented May 12, 2009 at 2:35
  • What do you mean by state? I am just passing an array of 5 numbers to whatever function. Commented May 12, 2009 at 2:45

4 Answers 4

6
function isStraight($hand) {
    $straights = array(range(1, 4), range(2, 5), range(3, 6));
    foreach($straights as $solution) {
        if(array_intersect($solution, $hand) == $solution) {
            return $solution;
        }
    }
    return false;
}

$hand = array(1,5,2,4,3);

var_dump(isStraight($hand));

Not sure about the rules of the game, but that should do it.

The function is going to return the first solution it finds - in this case [1,2,3,4]. It is going to return the boolean false if it doesn't find any straights in the hand. Hope this helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Had to run off and have dinner before coming back to fix it. :)
1

Perhaps something like this: --- warning --- air coding

function findSequenceLength(array $array)
{
  // Filter duplicates out - and sort the array.
  $sorted = array_unique($array, SORT_NUMERIC);

  $lastValue = null;
  $thisSeq = 0;
  $longestSeq = 0;
  foreach ($sorted as $value)
  {
    if ( ( $lastValue !== null ) && $value == $lastValue + 1)
    {
      // our value is exactly one above the last entry
      // increase the counter
      $thisSeq++;
    } else {
      // sequence ended - save the value
      $longestSeq = max($longestSeq, $thisSeq);
      $thisSeq = 1;
    }
    $lastValue = $value;
  }
  return max($longestSeq, $thisSeq);
}

$sequence = array(1,2,4,5,4,6);
echo findSequenceLength($sequence);  // should return 3 [4,5,6]

You could then test that the "sequence length" is >= 4 to test for your "small straight"

Comments

0

More precisely:

  function array_match($array, $target_array) {
  $offset = 0;
  $maxoffset = sizeof($target_array) - sizeof($array);
  for($y=0;$y<$maxoffset;$y++) {
    $result = true;
    for($x=0;$x<sizeof($array);$x++) {
      if ($array[$x] != $target_array[$x+$y] ) {
         $result = false;
         continue;
      }
    }
    if ($result)
       return "true";
  }
  return "false";
}
echo array_match(array(1,2,3), array(1,2,3,4,5)); //true
echo array_match(array(1,2,3), array(4,1,2,3,5)); //true
echo array_match(array(1,2,3), array(4,2,2,1,2)); //false

Comments

0

Here's another idea, Use a generic isStraight() method and use it to test the two array slices.

$tests = array(
            array(1,2,3,4,5),
            array(1,1,2,3,4),
            array(4,3,2,1,4),
            array(3,4,5,6,1)
        );
foreach($tests as $test) {
    print_r($test);
    echo "Straight: "; 
    var_dump(isStraight($test));
    echo "Short Straight: "; 
    var_dump(isShortStraight($test));
    echo "\n";
}

function isShortStraight($hand) {
    return isStraight(array_slice($hand, 0, 4)) || 
           isStraight(array_slice($hand, 1, 4));
}

function isStraight($hand) {
    $unique = array_unique($hand);
    if (count($hand) != count($unique)) {
        /* Has Duplicates, not a straight */
        return false;
    }

    sort($unique);
    if ($unique != $hand) {
        /* Sort order changed, not a straight */
        return false;
    }
    return true;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.