type alias ĠSymbol Ġ= ĠString Ċ type alias ĠCard Id Ġ= ĠString Ċ type alias ĠCell Coords Ġ= ĠPair < Int , ĠInt > Ċ Ċ data Ġclass ĠGame Card ( ĊĠĠĠĠĠĠĠ Ġval Ġplacement : ĠCell Coords , ĊĠĠĠĠĠĠĠ Ġval Ġsymbol : ĠSymbol , ĊĠĠĠĠĠĠĠ Ġval Ġcard Id : ĠCard Id Ċ ) Ġ{ ĊĠĠĠ Ġfun ĠisEmpty () Ġ= Ġsymbol Ġ== ĠConstants . EMPTY _ CELL _ SYMBOL ĊĊĠĠĠ Ġfun Ġwith New Placement ( new Placement : ĠCell Coords ) Ġ= ĠGame Card ( new Placement , Ġsymbol , Ġcard Id ) Ċ } Ċ Ċ data Ġclass ĠCard Move ( ĊĠĠĠĠĠĠĠ Ġval Ġcard : ĠGame Card , ĊĠĠĠĠĠĠĠ Ġval Ġnew Placement : ĠCell Coords Ċ ) Ċ Ċ data Ġclass ĠSh uffle Result ( ĊĠĠĠĠĠĠĠ Ġval Ġsh uffled : ĠPair < Game Card , ĠGame Card >, ĊĠĠĠĠĠĠĠ Ġval Ġnew Cards : ĠList < Game Card > Ċ ) Ġ{ ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( sh uffled . first . card Id Ġ!= Ġsh uffled . second . card Id ) Ġ{ Ġ" Expected Ġdifferent Ġcards Ġbut Ġgot Ġ${ sh uffled . first . card Id }" Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠGame Round ( ĊĠĠĠĠĠĠĠ Ġval Ġmoves : ĠInt Ċ ) Ċ Ċ data Ġclass ĠGame Level ( ĊĠĠĠĠĠĠĠ Ġval Ġdifficulty : ĠInt , ĊĠĠĠĠĠĠĠ Ġval Ġrounds : ĠInt Ċ ) Ċ Ċ class ĠSh uff les State ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġcards Count : ĠInt Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġcounter Ġ= Ġ 0 ĊĊĠĠĠ Ġprivate Ġval Ġshuffle History : ĠMutable List < Shuffle Result > Ġ= Ġmutable ListOf () ĊĊĠĠĠ Ġfun Ġget Shuffle Results () Ġ= Ġshuffle History . toList () ĊĊĠĠĠ Ġfun Ġadd Shuffle Result ( shuffle Result : ĠSh uffle Result ) Ġ{ ĊĠĠĠĠĠĠĠ Ġshuffle History . add ( shuffle Result ) ĊĠĠĠĠĠĠĠ Ġcounter Ġ= Ġif Ġ( cards Count Ġ- Ġcounter Ġ* Ġ 2 Ġ> Ġ 0 ) Ġcounter Ġ+ Ġ 1 Ġelse Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġreset Counter () Ġ{ ĊĠĠĠĠĠĠĠ Ġcounter Ġ= Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġcards Already Sh uffled (): ĠSet < Card Id > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshuffle History ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. take Last ( counter ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ ĠlistOf ( it . sh uffled . first . card Id , Ġit . sh uffled . second . card Id ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toSet () Ċ Ċ } Ċ Ċ class ĠCell s Field ( ĊĠĠĠĠĠĠĠ Ġval Ġrows : ĠInt , ĊĠĠĠĠĠĠĠ Ġval Ġcols : ĠInt , ĊĠĠĠĠĠĠĠ Ġvar arg Ġvalues : ĠInt ) Ġ{ ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( cols Ġ> Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġrequire ( rows Ġ> Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġrequire ( values . size Ġ== Ġcols Ġ* Ġrows ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġcell Coords : ĠList < Cell Coords > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalues ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. as Iterable () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. chunk ed ( cols ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. with Index () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġ( index , Ġvalue ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue . with Index (). filter Ġ{ Ġit . value Ġ> Ġ 0 Ġ}. map Ġ{ ĠCell Coords ( index , Ġit . index ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġplay able Cells Count Ġ= Ġcell Coords . size Ċ }