I added some comments to the code. There are some prerequisites to understanding it:
* How integers are represented in binary
* Bitwise operations
* Constants that start with a `0' in C/C++ are in octal
// This struct computes what categories match the dice in the constructor
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;
// Pass a pointer to an array of 5 dice, with values in 1..6
Classification(int *dice) {
// sum consists of 6 groups of 3 bits, which are counters for the values in the dice
int sum = 0;
// types marks which values appear at all, one bit per value
int types = 0;
for (int i=0; i<5; ++i) {
sum += 1 << ((dice-1)*3); // Increment the appropriate counter within sum
types |= 1 << (dice-1); // Mark the value
}
int n_types = __builtin_popcount(types); // This only works in gcc. You can find other ways of counting set bits for other compilers.
/*
// Alternative code to count bits:
static int const bitcount_table[64] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6
};
int n_types = bitcount_table[types];
*/
// I sorted the checks from easy to hard (somewhat subjectively)
// Chance: Every hand qualifies
is_chance = true;
// Yahtzee: Only one type
is_yahtzee = (n_types == 1);
// Large straight: Either 1-2-3-4-5 or 2-3-4-5-6, for which types
// is 31 or 62 respectively
is_large_straight = (types == 31 || types == 62);
// Small straight: types must contain four consecutive bits
is_small_straight = ((types & (types>>1) & (types>>2) & (types>>3)) != 0);
// Full house: Either only two values and none of them appear 4
// times (it can only be a pair and a trio), or is yahtzee
is_full_house = ((n_types == 2 && !is_four_of_a_kind) || n_types == 1);
// Four of a kind: check if any counter got to 4, by checking the
// bit whose value is 4
is_four_of_a_kind = ((sum & 0444444) != 0);
// To detect three of a kind, add 1 to each 3-bit counter and see
// if any of them trigger the bit whose value is 4
is_three_of_a_kind = (((sum + 0111111) & 0444444) != 0);
}
};
If you are a beginner and still don't understand it, it's OK. Maybe you can come back to this code after you have gained some experience with the things I listed at the beginning of this post.