Finding an EVEN STRAIGHT in a poker hand

481 views Asked by At

So my professor decided to be clever and made up a hand called an EVEN STRAIGHT for my Poker project. It's just like a straight except the cards need to be consecutive even numbers. For example- 8,6,2,4,10 is an even straight. Also, an ace (value of 1) can either be used as a "high end" or a "low end," meaning if it can either be 1 or 14 depending on the other cards. I'm having trouble sorting the value of the cards in an array in ascending order because we can't use the .sort method in this project. Can someone help me? Also it's an introductory Java class so please try to make it as simple as possible. Thanks. This is what I have so far....

//can assume only 5 cards are being passed in as parameter.

public static boolean hasEvenStraight(Card [] cards) {  
        boolean evenCard = false;
        int [] value = new int[cards.length];
        for(int i = 0; i<cards.length; i++){
            Card myCard = cards[i];
            value[i] = myCard.getValue();
            if(value[i]%2 == 0){
                evenCard = true;
            }
            else
                evenCard = false;
        }
        if(evenCard){
            //This is where I am stuck
        }
        return false; 
    }
1

There are 1 answers

5
RealSkeptic On BEST ANSWER

First, there is a logical error in your code. In your for loop, you are checking whether the current card is even or odd. But when the loop finishes, what you are left with is whether the last card you looked at. You need to check whether they are all even.

    for(int i = 0; i<cards.length; i++){
        Card myCard = cards[i];
        value[i] = myCard.getValue();
        if ( value[i] == 1 ) {
           value[i] = 14;
        }
        if(value[i]%2 != 0)
            return false
        }
    }

This loop, if it finds a card that's not even, it immediately returns false, because even one odd card means you don't have an even straight. So after it finishes you know that you have all evens.

But this, of course, is not enough. You want to know whether the cards are consecutive. Now here is the trick: You don't actually have to save all the cards values in that value array. You need to keep only the highest one and the lowest one. After you finish the loop, if you know that they were all even, and that your highest - your lowest = 8, it means you have consecutive evens, that is, an even straight.

Why? Because if they weren't consecutive, then there's a missing even in the middle, right? But if the lowest is 8 less than the top, there is no way you can push 3 cards between them so that they would all be even.

But we need to be watchful for cards of the same number, such as 2 of spades and 2 of hearts. They will ruin this principle. And if they exist, it's not an even straight anyway.

To check this, we have to keep a flag for each card value that we processed, saying "did we already process this card value"? We could use something like a Set for this. Upon examining each number, we ask: "Is this number in the set of numbers we have already checked?". If so, then of course, this is not an even straight. If not, we add the current number to the set, so that the following numbers can be checked against it.

For a range of small integers, we can do this without an actual Java Set. We use an array of booleans called alreadyThere or something like that. The element at index i means "Have we checked the card whose value is i". It's a bit wasteful of space because we'll never use the odd indexes or the zero and one indexes, but it's very easy to implement. Just check if alreadyThere[cardValue] is true. And of course, after we checked and it is a unique number, we set alreadyThere[cardValue] to true for the next iterations's check.

So let's modify your method:

public static boolean hasEvenStraight(Card [] cards) {  

    int low = 20; // There is no 20 card.
    int high = 0; // There is no 0 card.

    // This array is a bit wasteful as it won't all be used,
    // but it's straightforward this way.

    boolean[] alreadyThere = new boolean[15];

    for(int i = 0; i<cards.length; i++){
        Card myCard = cards[i];
        int currValue = myCard.getValue();

        // Handle ace. If it's 1 it's not an
        // even hand anyway, so assume it's 14.
        if ( currValue == 1 ) {
           currValue = 14;
        }

        // If any card is not even, this is not an Even Straight.
        if(currValue%2 != 0){
            return false;
        }

        // We have two cards of the same number
        // (E.g. 2 of spades and 2 of hearts). So
        // not a straight.
        if ( alreadyThere[currValue] ) {
           return false;
        }
        alreadyThere[currValue] = true;

        // To get the lowest and highest, compare each value to
        // existing lowest and highest and change them accordingly.
        if ( currValue > high ) {
           high = currValue;
        }
        if ( currValue < low ) {
           low = currValue;
        }
    }

    // Loop finished. All the numbers are even, now check if they
    // are consecutive.
    return ( high - low ) == 8;
}