/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 ĠJul ian ĠK och Ġand Ġcontributors Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġshared Ċ Ċ import Ġeval . Rank Poker Hand Public Ċ import Ġkotlinx . serialization . Serializable Ċ import Ġkotlin . random . Random Ċ Ċ @ Serializable Ċ class ĠConcrete Card ( val Ġcard : ĠCard , Ġval Ġis Community Card : ĠBoolean ) Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġequals ( other : ĠAny ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this Ġ=== Ġother ) Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġif Ġ( other Ġ! is ĠConcrete Card ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġreturn Ġcard Ġ== Ġother . card ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠhashCode (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcard . hashCode () ĊĠĠĠ Ġ} Ċ } Ċ Ċ // TODO Ġmake Ġimmutable Ċ @ Serializable Ċ class ĠHand ( val Ġcards : ĠList < Concrete Card >) Ġ: ĠComparable < Hand > Ġ{ ĊĊĠĠĠ Ġ// ĠTODO : ĠAdd Ġsome Ġauto Ġsort ers Ġ( by Ġvalue , Ġby Ġf action , Ġetc .) ĊĠĠĠ Ġfun Ġreorder Man ually ( new Indices : ĠList < Int >): ĠHand Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( new Indices . size Ġ!= Ġcards . size ) Ġthrow ĠIllegalArgumentException () ĊĊĠĠĠĠĠĠĠ Ġval Ġnew Ġ= ĠArray ( cards . size ) Ġ{ Ġi Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcards [ new Indices [ i ]] ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠHand ( new . asList ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġevaluate (): ĠInt Ġ= Ġwhen Ġ( cards . size ) Ġ{ ĊĠĠĠĠĠĠĠĠ 5 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnr Ġ= ĠInt Array ( 5 ) Ġ{ Ġi Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcard Ġ= Ġcards [ i ]. card ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( card . typeName ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" jack " Ġ-> ĠRank Poker Hand Public . J ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" queen " Ġ-> ĠRank Poker Hand Public . Q ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" king " Ġ-> ĠRank Poker Hand Public . K ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ace " Ġ-> ĠRank Poker Hand Public . A ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġcard . typeName . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsu its Ġ= ĠInt Array ( 5 ) Ġ{ Ġi Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcard Ġ= Ġcards [ i ]. card ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( card . suit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCard . Suit . SPA DES Ġ-> Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCard . Suit . CL UB S Ġ-> Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCard . Suit . HE ART S Ġ-> Ġ 4 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCard . Suit . DI AM ON DS Ġ-> Ġ 8 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRank Poker Hand Public . rank Poker Hand 5 ( nr , Ġsu its ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠ 7 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO Ġuse Ġfaster Ġalgorithm Ġfrom ĠRank Poker Hand Public ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnr Ġ= ĠInt Array ( 7 ) Ġ{ Ġi Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcard Ġ= Ġcards [ i ]. card ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( card . typeName ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" jack " Ġ-> ĠRank Poker Hand Public . J ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" queen " Ġ-> ĠRank Poker Hand Public . Q ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" king " Ġ-> ĠRank Poker Hand Public . K ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ace " Ġ-> ĠRank Poker Hand Public . A ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġcard . typeName . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsu its Ġ= ĠInt Array ( 7 ) Ġ{ Ġi Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcard Ġ= Ġcards [ i ]. card ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( card . suit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCard . Suit . SPA DES Ġ-> Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCard . Suit . CL UB S Ġ-> Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCard . Suit . HE ART S Ġ-> Ġ 4 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCard . Suit . DI AM ON DS Ġ-> Ġ 8 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTry Ġall Ġcombinations Ġand Ġchoose Ġbest Ġone ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( 0 Ġuntil Ġ 7 ). toList (). sub sets Of Size ( 5 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġindices Ġ-> Ġnr . slice Array ( indices ) Ġto Ġsu its . slice Array ( indices ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġ( nr Sub , Ġsu its Sub ) Ġ-> ĠRank Poker Hand Public . rank Poker Hand 5 ( nr Sub , Ġsu its Sub ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. max () !! ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Evalu ating Ġhands Ġwith Ġ${ cards . size } Ġcards Ġis Ġnot Ġsupported ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġevaluate Rank (): ĠRank Poker Hand Public . Combination Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠRank Poker Hand Public . Combination . from Rank ( evaluate () Ġshr Ġ 2 6 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġcompare To ( other : ĠHand ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( cards . size Ġ!= Ġother . cards . size ) Ġthrow ĠIllegalArgumentException (" Cannot Ġcompare Ġhands Ġwith Ġdifferent Ġnumber Ġof Ġcards ") ĊĠĠĠĠĠĠĠ Ġreturn Ġevaluate (). compareTo ( other . evaluate ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Deprecated (" use less ") ĊĠĠĠĠĠĠĠ Ġfun Ġgenerate H ands ( num : ĠInt , Ġhand Size : ĠInt , Ġrandom : ĠRandom Ġ= ĠRandom ): ĠList < Hand > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( num Ġ< Ġ 1 ) Ġthrow ĠIllegalArgumentException (" players Ġshould Ġbe Ġat Ġleast Ġ 1 Ġbut Ġis Ġ$ num ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( hand Size Ġ< Ġ 1 ) Ġthrow ĠIllegalArgumentException (" hand Size Ġshould Ġbe Ġat Ġleast Ġ 1 Ġbut Ġis Ġ$ hand Size ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠCard . draw Card Sequence ( random ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠConcrete Card ( it , Ġfalse ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. chunk ed ( hand Size ) Ġ{ ĠHand ( it . to Mutable List ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. take ( num ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toList () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* val Ġsh uffled Deck Ġ= ĠCard . STANDARD _ DE CK . sh uffled ( random ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhands Ġ= ĠArrayList < Hand >( num ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrepeat ( num ) Ġ{ Ġi Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhands Ġ+= ĠHand ( sh uffled Deck . sub List ( i Ġ* Ġhand Size , Ġ( i Ġ+ Ġ 1 ) Ġ* Ġhand Size ). to Mutable List ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġhands */ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ fun ĠDraw Cards . take Hand ( size : ĠInt ) Ġ= ĠHand ( ĊĠĠĠ Ġtake ( size ) ĊĠĠĠĠĠĠĠ Ġ. map To ( ArrayList ( size )) Ġ{ ĠConcrete Card ( it , Ġfalse ) Ġ} Ċ ) Ċ Ċ @ Deprecated (" not Ġthe Ġway Ġwe Ġwent ") Ċ fun ĠDraw Cards . take Hand ( individual Cards : ĠInt , Ġcommunity Cards : ĠList < Card >): ĠHand Ġ{ ĊĠĠĠ Ġval Ġhand Ġ= ĠArrayList < Concrete Card >() ĊĠĠĠ Ġtake ( individual Cards ). map To ( hand ) Ġ{ ĠConcrete Card ( it , Ġfalse ) Ġ} ĊĠĠĠ Ġcommunity Cards . map To ( hand ) Ġ{ ĠConcrete Card ( it , Ġtrue ) Ġ} ĊĠĠĠ Ġreturn ĠHand ( hand ) Ċ } Ċ Ċ private Ġtail rec Ġfun Ġpower set ( a : ĠList < Int >, Ġacc : ĠList < List < Int >>) Ġ{ ĊĠĠĠ Ġif Ġ( a . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġpower set ( a . drop ( 1 ), Ġacc Ġ+ Ġacc . map Ġ{ Ġit Ġ+ Ġa . first () Ġ}) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠList < Int >. sub sets Of Size ( k : ĠInt ) Ġ= Ġsub sets Of Size ( this , Ġk ) Ċ Ċ private Ġfun Ġsub sets Of Size ( set : ĠList < Int >, Ġk : ĠInt ): ĠList < List < Int >> Ġ{ ĊĠĠĠ Ġif Ġ( set . size Ġ< Ġk ) Ġreturn Ġempty List () ĊĠĠĠ Ġif Ġ( set . size Ġ== Ġk ) Ġreturn ĠlistOf ( set ) ĊĠĠĠ Ġif Ġ( set . isEmpty ()) Ġreturn Ġempty List () ĊĠĠĠ Ġval Ġx Ġ= Ġset . first () ĊĠĠĠ Ġval Ġset Without X Ġ= Ġset . drop ( 1 ) ĊĠĠĠ Ġreturn Ġsub sets Of Size ( set Without X , Ġk ) Ġ+ Ġsub sets Of Size ( set Without X , Ġk Ġ- Ġ 1 ). map Ġ{ Ġit Ġ+ Ġx Ġ} Ċ } ĊĊ Ċ operator Ġfun ĠHand . plus ( more Cards : ĠIterable < Concrete Card >) Ġ= ĠHand ( cards Ġ+ Ġmore Cards ) Ċ