functionPokerHand(hand){this.hand=hand}PokerHand.prototype.compareWith=function(hand){returncompareHands(this.hand,hand.hand||hand)}constorder="23456789TJQKA"functiongetHandDetails(hand){constcards=hand.split("")constfaces=cards.map(a=>String.fromCharCode([77-order.indexOf(a[0])])).sort()constsuits=cards.map(a=>a[1]).sort()constcounts=faces.reduce(count,{})constduplicates=Object.values(counts).reduce(count,{})constflush=suits[0]===suits[4]constfirst=faces[0].charCodeAt(0)//Also handle low straightconstlowStraight=faces.join("")==="AJKLM"conststraight=lowStraight||faces.every((f,index)=>f.charCodeAt(0)-first===index)letrank=(flush&&straight&&1)||(duplicates[4]&&2)||(duplicates[3]&&duplicates[2]&&3)||(flush&&4)||(straight&&5)||(duplicates[3]&&6)||(duplicates[2]>1&&7)||(duplicates[2]&&8)||9return{rank,value:faces.sort(byCountFirst).join("")}functionbyCountFirst(a,b){//Counts are in reverse order - bigger is betterconstcountDiff=counts[b]-counts[a]if(countDiff)returncountDiff// If counts don't match returnif(lowStraight){a=a==="A"?"N":ab=b==="A"?"N":b}returnb>a?-1:b===a?0:1}functioncount(c,a){c[a]=(c[a]||0)+1returnc}}functioncompareHands(h1,h2){letd1=getHandDetails(h1)letd2=getHandDetails(h2)if(d1.rank===d2.rank){if(d1.value<d2.value){return"WIN"}elseif(d1.value>d2.value){return"LOSE"}else{return"DRAW"}}returnd1.rank<d2.rank?"WIN":"LOSE"}
Real world Javascript map/reduce, solving the Poker Hand problem
Mike Talbot ・ Jun 16 ・ 6 min read