# Proposed Hint/Solution suggestion - Poker Hands

After solving this problem I was curious to see if it differed much from the solution in the hint, to find there was no solution there. So I thought I would share mine in case someone would like to put it there.

What is your hint or solution suggestion?

Problem Explanation:

• In this challenge you need to supply a function that accepts an array of poker card hands, and returns a sum of how many of those hands player 1 wins
• The array contains strings, each string containing 10 playing card indicators, the first 5 for Player 1, the next 5 for Player 2
• The function needs to analyze those hands, and determine if Player 1 is the winner, and tally how many of the hands supplied in the array were won by Player 1

Proposed Solution:

Summary
``````function pokerHands(arr) {

// Initialize Variables
let cardValues = {2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8, 9:9, T:10, J:11, Q:12, K:13, A:14}
let winsP1 = 0;
let handP1, handP2;
let scoreP1, scoreP2;

// For each hands in the provided array input, analyze winner
for (let hands of arr) {

// Split input into two separate hands
handP1 = hands.split(" ");
handP2 = handP1.splice(5,5);

// Calculate score for each players hand
scoreP1 = calcHand(handP1);
scoreP2 = calcHand(handP2);

// Check values of the score array to check for player 1 win
for (let x in scoreP1) {
if (scoreP1[x] > scoreP2[x]) {
winsP1++;
break;
} else if (scoreP2[x] > scoreP1[x]) {
break;
}
}
}

// Return sum of all the games player one won
return winsP1;

//---- function calcHand - Analyizes supplied card hand and return score array ------------------------
function calcHand (theHand) {
// Will hold counts of suits and cards in the hand Ex: {14: 4, 11: 1} = 4 aces and 1 jack
let suits = {}, cards = {};

// Score [hand score, major high card, minor high card, next highest, next highest, next highest]
let score = [0,0,0,0,0,0]

// Count card types and suit types in the hand, convert card type to integer
for (let card of theHand) {
cards[cardValues[card]] = (cards[cardValues[card]] + 1) || 1;
suits[card] = (suits[card] + 1) || 1;
}

// Get the length of card and suit objects
let cardLen = Object.keys(cards).length;
let suitLen = Object.keys(suits).length;

// If 5 different cards present - its a straight or high card, and possible flush
if (cardLen == 5) {

// Sort card types in descending order
let cardNums = Object.keys(cards).map(item => parseInt(item));
cardNums.sort( (a,b) => b-a );

//If straight detected (highest - lowest cards = 4), return score of 5, with card values attached, or 1 for high card
if (cardNums - cardNums == 4) {
score = .concat(cardNums);
} else {
score = .concat(cardNums);
}

// If flush (only one suit present), adjust score accordingly
if (suitLen == 1) {
score += 5;  //( so 6 for flush, 10 for straight flush)
}
}

// If 2 different card types - its a four of a kind or full house
if (cardLen == 2) {

let twoCards = Object.keys(cards);
switch(cards[twoCards]) {
// if card counts are 1 or 4, its 4 of a kind, put the 4 card as major, 1 card as minor
case 1: score = [8, twoCards, twoCards, 0, 0, 0];break;
case 4: score = [8, twoCards, twoCards, 0, 0, 0];break;

// if card counts are 2 or 3, its full house, put the 3 card as major, 2 card as minor
case 2: score = [7, twoCards, twoCards, 0, 0, 0];break;
case 3: score = [7, twoCards, twoCards, 0, 0, 0];break;
}
}

// If 3 different card types - its a three of a kind or two pair
if (cardLen == 3) {

// If there is a card count of 3 present, its 3 of a kind
if (Object.values(cards).includes(3)) {
score = 4;

// Go through cards, if count is 3, set it as Major, and set others as minor in decending order
let leftovers = [];
for (let card3 in cards) {
if (cards[card3] == 3) {
score = parseInt(card3);
} else {
leftovers.push(parseInt(card3));
}
score = Math.max(...leftovers);
score = Math.min(...leftovers);
}

// If no 3 count, its 2 pair, assign pairs as major/minor based on value, and then extra card
} else {
score = 3;
let majors = [];
for (let card22 in cards) {
if (cards[card22] == 2) {
majors.push(parseInt(card22));
} else {
score = parseInt(card22);
}
score = Math.max(...majors);
score = Math.min(...majors);
}
}
}

// If 4 different card types - Its a single pair
if (cardLen == 4) {
score = 2;
let minors = [];

// Check cards, the pair is the Major, all other cards minors in decending order
for (let card2 in cards) {
if (cards[card2] == 2) {
score = parseInt(card2);
} else {
minors.push(parseInt(card2));
}
minors.sort((a,b) => b-a);
score = minors;
score = minors;
score = minors;
}
}

// Return the score array
return score;
}
}

const testArr = [
'8C TS KC 9H 4S 7D 2S 5D 3S AC',
'5C AD 5D AC 9C 7C 5H 8D TD KS',
'3H 7H 6S KC JS QH TD JC 2D 8S',
'TH 8H 5C QS TC 9H 4D JC KS JS',
'7C 5H KC QH JD AS KH 4C AD 4S'
];

console.log(pokerHands(testArr));
``````

Code Explanation
For this problem, there are two major design decisions that need to be addressed.

1. How to determine what type of hand a player has (straight, flush, etc)
2. How to compare two hands to determine which player wins

For this solution, the first issue was resolved by simply counting the cards and suits found in a hand, and putting them into an object with the card type as the keys, and the count as the value:

EX: ` { 7: 3, 13: 2 }` - This indicates three 7’s, and two Kings => full house

Once you compile the counts, you can then categorize the hands by either the counts (if suit count values contains 5, its a flush, if card count values contains 4, its a 4 of a kind) or by checking the length of keys (if suit length is 1, its a flush, if card count length is 2, its a 4 of a kind or full house). This solution uses the length.

For the second issue on how to compare hands for a winner, this solution uses an array it calls score. The score’s first value is the “hand score” which is determines by the type of hand… a full house scores a 7, two pair scores a 3 etc. Then when comparing two scores the winner is whoever has the highest value. The remainder of the score array is used to store the values of the cards at play, so if the hand score is a tie, you then can check card values to determine the winner. The score array looks like this:

`[ hand score, major card value, minor card value, extra card value, extra card value, extra card value]`

In this case, major card value is the value of the card related to the hand score… for a three of a kind, its the card you have three of. The minor card is for hands that have two, like the full house, where first check the three cards value, then check the two cards value. The remainer are the additional cards in decending order. If no remainders they are just 0.

With that score array, now to determine who wins, all you’d have to do is check the first value, if it ties, check the second value, if it ties, third, and so on.

With this design layout, the function just then needs to go through each value in the array, split the hands string into two separate hands, calculate the score of the first, the score of the second, and then compare those two for a winner. If Player 1 wins, you increment a counter.

Challenge: Problem 54: Poker hands