Jump to content

  • Log In with Google      Sign In   
  • Create Account

Three of a kind numbers


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
34 replies to this topic

#1 nitishk   Members   -  Reputation: 161

Like
0Likes
Like

Posted 01 April 2013 - 10:57 AM

I am creating a method isThreeKind(int[] fiveNumbers) and it should return a boolean if 3 of the 5 are the same. I don't understand how I should go about doing this. I also need to make a similar method but instead do 4 of a kind. If someone could just help me out with understanding the logic that would be great.

 

Thanks



Sponsor:

#2 Paradigm Shifter   Crossbones+   -  Reputation: 5373

Like
6Likes
Like

Posted 01 April 2013 - 11:11 AM

Sort the array and count the largest number of consecutive equal values in the sorted array.

 

If it's for poker you need to check for 2 pairs as well and full houses so you need to keep the longest and 2nd longest run counts around.


"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#3 SiCrane   Moderators   -  Reputation: 9597

Like
4Likes
Like

Posted 01 April 2013 - 11:13 AM

One way would be look at the first number and then check the rest of the array for two or more of that number. If there aren't, look at the second number and check the rest of the array, and so on. Another way would be to sort the array first and then see if there or three or more in a row.

#4 SlamDrag   Members   -  Reputation: 111

Like
3Likes
Like

Posted 01 April 2013 - 11:13 AM

Well, you need to test if 3 of 5 numbers are the same.

 

What you could do is use a nested for loop to iterate through all the numbers and test which is the same with which then have an integer keep track of how many numbers are the same, then return true if it's greater than three. That's just one possible solution. There are probably others.



#5 EddieV223   Members   -  Reputation: 1406

Like
3Likes
Like

Posted 01 April 2013 - 11:18 AM

As you loop through the array, you don't have to go back wards, for example test the first one against the ones after it, then test the second one against the ones after it, but you don't have to retest the first one against the second since you already know the first one failed the test.  If you make it to the second to last one, ( only 2 left ) and you haven't found 3 matches yet, you don't have to test the last two since there is only 2 left there can't be 3 matches in 2 objects.


If this post or signature was helpful and/or constructive please give rep.

 

// C++ Video tutorials

http://www.youtube.com/watch?v=Wo60USYV9Ik

 

// Easy to learn 2D Game Library c++

SFML2.1 Download http://www.sfml-dev.org/download.php

SFML2.1 Tutorials http://www.sfml-dev.org/tutorials/2.1/

 

// SFML 2 book

http://www.amazon.com/gp/product/1849696845/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=1849696845&linkCode=as2&tag=gamer2creator-20

 


#6 Álvaro   Crossbones+   -  Reputation: 13317

Like
5Likes
Like

Posted 01 April 2013 - 11:44 AM

If your numbers are smaller than 21 (as they are in poker), you can use 64-bit arithmetic to do this really fast:
bool is_three_of_a_kind(int *a) {
  unsigned long long x = 0ull;
  for (int i=0; i<5; ++i)
    x += 1ull << (a[i]*3);
  return (x + 0111111111111111111111ull) & 0444444444444444444444ull;
  // return x & 0444444444444444444444ull; <-- four of a kind
}

Edited by Álvaro, 01 April 2013 - 11:45 AM.


#7 nitishk   Members   -  Reputation: 161

Like
0Likes
Like

Posted 01 April 2013 - 11:56 AM

ok i got it!
I sorted the array and simply checked for the number of consecutive numbers that are the same.


thanks for the help guys



#8 Paradigm Shifter   Crossbones+   -  Reputation: 5373

Like
5Likes
Like

Posted 01 April 2013 - 11:56 AM

Alvaro, please use capital L's instead of lower case l's when doing that ;) At least there is a u inbetween the digits and the l's though, nothing worse than seeing stuff like

 

long ll = 1l;
long l1 = 11;

Edited by Paradigm Shifter, 01 April 2013 - 11:57 AM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#9 alnite   Crossbones+   -  Reputation: 2108

Like
0Likes
Like

Posted 01 April 2013 - 11:58 AM

Why not just use a Hash?  Something like this (might be missing some corner cases):

 

int pair_count = 0;
bool three_of_a_kind = false;
bool four_of_a_kind = false;
for (int i=0; i<5; ++i) {
  hash[cards[i]]++;
  if (hash[cards[i]] == 2) pair_count++;
  three_of_a_kind ||= hash[cards[i]] == 3;
  four_of_a_kind ||= hash[cards[i]] == 4;
}
 
// now you can see if it has a two pair, a three of a kind, a four of a kind, or a full house.
 


#10 nitishk   Members   -  Reputation: 161

Like
0Likes
Like

Posted 01 April 2013 - 12:03 PM

i dont really understand what a hash is and I would like to keep this game simple. By the way this is for a game of yahtzee not poker

 

here is my code just so you guys could see what I did

Arrays.sort(player1.diceValues);		
for(int i = 0; i < 3; i++){
	if(player1.diceValues[i] == player1.diceValues[i + 1] && player1.diceValues[i] == player1.diceValues[i + 2]){
		player1.score =+ player1.diceValues[i] * 3;
	}
}

Edited by nitishk, 01 April 2013 - 12:12 PM.


#11 alnite   Crossbones+   -  Reputation: 2108

Like
0Likes
Like

Posted 01 April 2013 - 12:09 PM

i dont really understand what a hash is and I would like to keep this game simple. By the way this is for a game of yahtzee not poker

 

Hashtable.

 

In java, that'd be in java.util.Hashtable



#12 Paradigm Shifter   Crossbones+   -  Reputation: 5373

Like
1Likes
Like

Posted 01 April 2013 - 02:05 PM

With Yahtzee you might be better having an array of size 6 and store a count of how many dice are rolled of each number. That makes checking the combinations and scoring them really easy.

 

Can't you still have a full house and 2 pairs in Yahtzee too?

 

Ten Thousand/Farkle/Dix Mille is a much better dice game though I reckon, especially with the 4 or more 2's = disaster lose all your banked points rule.


Edited by Paradigm Shifter, 01 April 2013 - 02:10 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#13 jms bc   Members   -  Reputation: 428

Like
2Likes
Like

Posted 01 April 2013 - 02:11 PM

I think this is the easiest way if you have no need to sort:

 

int same=0;

for(int i=0;i<4;++i)

    for(int j=i+1;j<5;++j)

        if(a[i] == a[j])

              same++;

 

same = 1 is a pair

same = 3 is a three of a kind

same = 6 is a quad

same = 10 is 5 of a kind

 

added:

same = 2 is two pair

same = 4 is a full house


Edited by jms bc, 01 April 2013 - 02:20 PM.

The Four Horsemen of Happiness have left.


#14 NightCreature83   Crossbones+   -  Reputation: 2826

Like
0Likes
Like

Posted 01 April 2013 - 02:15 PM

You could also use histograms as they allow you to check all of the other constraints on placing a roll really quickly. 3 of a kind one histogram bar is at least 3, with 4 it goes to 4, with a large straight all of them are 1, small straight at least four connecting number bars are 1 or more.
Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#15 Paradigm Shifter   Crossbones+   -  Reputation: 5373

Like
0Likes
Like

Posted 01 April 2013 - 02:19 PM

Yeah that's what I was suggesting with the array of 6 entries, use it as a histogram.

 

I thought a small straight was 1-2-3-4-5 and a large straight was 2-3-4-5-6?


"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#16 nimrodson   Members   -  Reputation: 275

Like
1Likes
Like

Posted 01 April 2013 - 02:20 PM

Just for fun, a (beginner) Haskell implementation:

 

unique :: (Eq a) => [a] -> [a]
unique []     = []
unique (x:xs) = x : unique (filter (\y -> not (x==y)) xs)

nOcurrences :: (Eq a) => a -> [a] -> Int
nOcurrences elem list = length (filter (==elem) list)

isThreeKind :: (Eq a) => [a] -> Bool
isThreeKind list = elem 3 [nOcurrences i list | i <- (unique list)]

You could parametrize the 3 number in "isThreeKind" function and have a "fourKind", a "fiveKind", or whatever...

Cheers.


Edited by nimrodson, 01 April 2013 - 02:40 PM.


#17 NightCreature83   Crossbones+   -  Reputation: 2826

Like
0Likes
Like

Posted 01 April 2013 - 02:22 PM

Yeah that's what I was suggesting with the array of 6 entries, use it as a histogram.
 
I thought a small straight was 1-2-3-4-5 and a large straight was 2-3-4-5-6?

Not according to wikipedia: http://en.wikipedia.org/wiki/Yahtzee
Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#18 Paradigm Shifter   Crossbones+   -  Reputation: 5373

Like
0Likes
Like

Posted 01 April 2013 - 02:28 PM

Looks like I've been playing a weird Yacht/Yahtzee hybrid then ;) I also thought Yacht was the same game as Yahtzee, you learn something new every day ;)

 

Since I mentioned 10,000 someone should do a physics based simulation of the remarkably similar game "Pass the Pigs" http://en.wikipedia.org/wiki/Pass_the_pigs

 

EDIT: And I've never heard of the Kissin' Bacon (both snouts touching) rule before. It's not in my ruleset!


Edited by Paradigm Shifter, 01 April 2013 - 02:30 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#19 Álvaro   Crossbones+   -  Reputation: 13317

Like
4Likes
Like

Posted 01 April 2013 - 05:02 PM

This should be blazing fast:
struct Classification {
  bool is_three_of_a_kind;
  bool is_four_of_a_kind;
  bool is_full_house;
  bool is_small_straight;
  bool is_large_straight;
  bool is_yahtzee;
  bool is_chance;

  Classification(int *dice) {
    int sum = 0;
    int types = 0;

    for (int i=0; i<5; ++i) {
      sum += 1 << ((dice[i]-1)*3);
      types |= 1 << (dice[i]-1);
    }
    int n_types = __builtin_popcount(types); // This only works in gcc. You can find other ways of counting set bits for other compilers.

    is_three_of_a_kind = (((sum + 0111111) & 0444444) != 0);
    is_four_of_a_kind = ((sum & 0444444) != 0);
    is_full_house = ((n_types == 2) && !is_four_of_a_kind);
    is_small_straight = ((types & (types>>1) & (types>>2) & (types>>3)) != 0);
    is_large_straight = (types == 31 || types == 62);
    is_yahtzee = ((types & (types-1)) == 0);
    is_chance = true;
  }
};
Another alternative is to encode all the bools in a single byte and make a table that maps a 5-digit base-6 number to its classification. That table is smaller than 8KB.

Edited by Álvaro, 01 April 2013 - 05:05 PM.


#20 Paradigm Shifter   Crossbones+   -  Reputation: 5373

Like
2Likes
Like

Posted 01 April 2013 - 05:08 PM

*reads Alvaro's post* *checks name of forum*

 

OK, it's "For Beginners" ;) Probably a tad too advanced for a simple Yahtzee game...

 

I suggested a sort and count consecutive approach (since it is scalable for more complex problems) until I found out it was Yahtzee where I feel a histogram based approach is going to be simplest to implement and understand.


Edited by Paradigm Shifter, 01 April 2013 - 05:08 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS