I have the following code (it looks long but it's not too bad):
function evaluate_cards(hand){
var hand_length = hand.length;
var num_of_sets = 0;
var num_of_runs = 0;
var cards_in_run = 0;
var suit = '';
var buckets = {
three_bucket: [],
four_bucket: [],
five_bucket: [],
six_bucket: [],
seven_bucket: [],
eight_bucket: [],
nine_bucket: [],
ten_bucket: [],
j_bucket: [],
q_bucket: [],
k_bucket: [],
w_bucket: [] //bucket for wilds
}
for(var i = 0; i < hand_length; i++){
if(hand[0].is_wild){
buckets.w_bucket.push(hand.splice(0, 1));
}else if(hand[0].value == 3){
buckets.three_bucket.push(hand.splice(0, 1));
}else if(hand[0].value == 4){
buckets.four_bucket.push(hand.splice(0, 1));
}else if(hand[0].value == 5){
buckets.five_bucket.push(hand.splice(0, 1));
}else if(hand[0].value == 6){
buckets.six_bucket.push(hand.splice(0, 1));
}else if(hand[0].value == 7){
buckets.seven_bucket.push(hand.splice(0, 1));
}else if(hand[0].value == 8){
buckets.eight_bucket.push(hand.splice(0, 1));
}else if(hand[0].value == 9){
buckets.nine_bucket.push(hand.splice(0, 1));
}else if(hand[0].value == 10){
buckets.ten_bucket.push(hand.splice(0, 1));
}else if(hand[0].value == 11){
buckets.j_bucket.push(hand.splice(0, 1));
}else if(hand[0].value == 12){
buckets.q_bucket.push(hand.splice(0, 1));
}else if(hand[0].value == 13){
buckets.k_bucket.push(hand.splice(0, 1));
}
}
for(var k in buckets){
if(buckets.hasOwnProperty(k)){
if(buckets[k].length >= 3 && buckets[k] != buckets.w_bucket){
num_of_sets++;
}else if(buckets.w_bucket.length > 0 && buckets[k].length == 2){
buckets[k].push(buckets.w_bucket.shift());
num_of_sets++;
}else if(buckets[k].length < 3 && buckets.w_bucket.length > 1){
for(var i = 0; i < buckets.w_bucket.length; i++){
buckets[k].push(buckets.w_bucket.shift());
}
if(buckets[k].length >= 3){
num_of_sets++;
}
}else if(num_of_sets == 0){
if(buckets[k].length > 0){
if(suit == ''){
suit = buckets[k][0].suit;
}else if(suit == buckets[k][0].suit){
cards_in_run++;
}else{
suit = '';
}
if(cards_in_run != 0 && cards_in_run < 3 && buckets.w_bucket.length != 0){
cards_in_run++;
}
}
if(cards_in_run >= 3){
num_of_runs++;
cards_in_run = 0;
}
}
}
}
return {'runs':num_of_runs, 'sets': num_of_sets};
}
It's based off of the second answer to this question on game-dev.se. There are two major differences, however.
- There are wilds in my game, which makes finding things like runs much more difficult.
- Most sets/runs are going to be 3 or four cards but could be up to 5 cards, obviously anything 6 and over can be divided (set or run has to be a minimum of 3 cards).
The following is passed a hand will determine almost all sets of three cards, but only a few runs.
My request is that it be reviewed for optimization and where my logic goes wrong with runs. I'm totally open to any suggestions.