0

I am trying to find four of kind in a 5 poker hand. I don't know where I went wrong, but the JUnit is reporting it's wrong.

public boolean hasFourOfaKind(String hand) {
    int counter = 0;
    char x = 0;

    for (int i = 0; i < hand.length(); i++) {
        for (int j = 0; j < hand.length(); j++) {
            if (i == 0) {
                x = hand.charAt(0);
                counter++;
            } else if (x == hand.charAt(i)) {
                counter++;

            }
        }
    }
    if (counter >= 4) {
        return true;
    } else {
        return false;
    }
}
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Heniam
  • 68
  • 16
  • 1
    What is the format of String which `hand` will hold? BTW `if (condition){ return true; }else{ return false;}` is same as `return condition;`. – Pshemo Oct 08 '16 at 17:36
  • how do you use `i` in line `if(i==0)` without definition... – coolstoner Oct 08 '16 at 17:39
  • All of your cards are represented as single chars ? How do you represent 10 for example? – Dimitar Spasovski Oct 08 '16 at 17:39
  • Please help yourself to some [complementary debugging techniques](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). If you still have issues afterwards, please feel free to come back with more details. – Joe C Oct 08 '16 at 17:41
  • Please note that Java and JavaScript are completely different languages. @coolstoner `i` is defined and declared in the outer `for` loop. – Sebastian Simon Oct 08 '16 at 17:41
  • i saw the edit made now....it wasnt there when i was adding my comment.... – coolstoner Oct 08 '16 at 17:43
  • then what should i do to make this program work. Newbie and confused – Heniam Oct 08 '16 at 17:43
  • Not sure what you're trying to do, but having a loop variable `j` that is never used is not a good sign. – Alain Oct 08 '16 at 17:44
  • I don't understand the code. How do you distinguish the "kinds"? It seems that x is the counted kind, but x is always the same, the first kind of hand. Additionally, it seems strange to me that j is not used. – mm759 Oct 08 '16 at 17:44
  • am trying to find four of a kind. – Heniam Oct 08 '16 at 17:45
  • Do change if (counter >= 4) for if (counter >= 3) you are not counting when i=0. – HaroldSer Oct 08 '16 at 17:55
  • Four of kind means four or more cards can be same right?? "JJJJJ" or "JJKJJ" will return true in this case?? – cody123 Oct 08 '16 at 18:05
  • You don't seem to be using `j` for anything. Was that intentional? – Dawood ibn Kareem Oct 08 '16 at 18:11
  • Incidentally, if this happened to me, I would step through the failing unit test with a debugger. If I did this, I'd be able to see immediately what was going wrong. – Dawood ibn Kareem Oct 08 '16 at 18:12

3 Answers3

1

Your loop logic is wrong. It is incrementing counter for the same card again. That's why it is failing. In below mentioned code I am considering card only once.

public static boolean hasFourOfaKind(String hand) {
    int counter = 0;
    for (int i = 0; i < hand.length(); i++) {
        counter = 0;
        for (int j = 0; j < hand.length(); j++) {
            if (hand.charAt(j) == hand.charAt(i)) {
                counter++;
            }
        }
        if (counter >= 4) {
            return true;
        }
    }
    return false;
}
cody123
  • 2,040
  • 24
  • 29
  • 1
    Yea i have tried that before too but the Junit is reporting it wrong idk why. Even to this code above it reported it wrong – Heniam Oct 08 '16 at 18:20
  • Code you posted above was giving wrong output for some cases but I think above code is passing all the cases. Can you paste your junit code? – cody123 Oct 08 '16 at 18:26
  • i will put it as part of the question because its too long to paste it here. – Heniam Oct 08 '16 at 18:28
  • You can separate your junit test case for this specific case?? You will be using some assert statements. Or you can use syso before and after you calling above method and tell me what you got? – cody123 Oct 08 '16 at 18:29
  • `public void testFourOfAKind() { java.util.Random rng = new java.util.Random(SEED); Adler32 check = new Adler32(); for(int i = 0; i < RUNS; i++) { String hand = createHand(rng, 5); check.update(cp.hasFourOfAKind(hand) ? i : ~i); } assertEquals(check.getValue(), 3699029383L); }` – Heniam Oct 08 '16 at 18:32
  • assertEquals(cp.hasFourOfAKind(hand), true); ? Can you test something like that. – cody123 Oct 08 '16 at 18:40
0

a real quickie on this since you wanted to test your hand assuming its a string of characters and below code is rewritten in javascript since i see the JS tag for the question too.....

function hasFourOfaKind(hand) {
    var counter = 0;
    var set_of_four = [];

    for (i = 0; i < hand.length; i++) {
        if (i == 0) {
            x = hand.charAt(0);
            set_of_four.push(x);
            counter++;
        } else {
            x = hand.charAt(i);
            if(set_of_four.indexOf(x) != '-1'){
                counter++;
            } else {
                set_of_four = set_of_four.splice(-1,1);
                set_of_four.push(x);
                counter = 0;
            }
        }
    }
    return (counter >= 3);
}

var poker_hand = 'BAAAAA';
var result = hasFourOfaKind(poker_hand);
console.log(result);

@Dmitry: thanks for the correction earlier...i was in too much haste then......

coolstoner
  • 719
  • 2
  • 9
  • 20
0

I assume your hand is represented as something like "ABCDE". Your code is wrong. Let's take a look at the inner loop body:

for (int i = 0; i < hand.length(); i++) {
    for (int j = 0; j < hand.length(); j++) {
        if (i == 0) {  // take a look at this line
            x = hand.charAt(0);
            counter++;
        } else if (x == hand.charAt(i)) {
            counter++;

        }
    }
}

I've commented the line you should look at. The i will be always be 0 at first outer loop iteration so you'll increase your counter hand.length() times (that's how many times inner loop will execute while i == 0). If your hand length is 4 or more your method will always return true. Moreover even if you'll fix this part it won't help as you're always comparing chars to the first char of the string.

As a suggestion you can get a char array from your string, sort it and look how many identical chars are going one by one:

private boolean hasFourOfaKind(String hand) {
    if (hand == null || hand.length() == 0) {
        return false;
    }
    char[] chars = hand.toCharArray();
    Arrays.sort(chars);
    char current = chars[0];
    int count = 1;
    for (int i = 1; i < chars.length; i++) {
        char next = chars[i];
        if (current != next) {
            current = next;
            count = 1;
        } else {
            count++;
            if (count == 4) {
                return true;
            }
        }
    }
    return false;
}
Dmitry Smorzhok
  • 635
  • 11
  • 21