package Ġapps . games . ser ious . Che at . logger Ċ Ċ import Ġapps . games . Game ExecutionException Ċ import Ġapps . games . ser ious . Che at . Bet Count Ċ import Ġapps . games . ser ious . Pip Ċ import Ġapps . games . ser ious . Sh uffled Deck Ċ import Ġentity . User Ċ import Ġorg . apache . commons . codec . digest . Digest Utils Ċ import Ġjava . math . BigInteger Ċ Ċ /** Ċ Ġ* ĠCreated Ġby Ġuser Ġon Ġ 8 / 2 / 1 6 . Ċ Ġ*/ Ċ Ċ class ĠRound Logger ( val ĠN : ĠInt , Ġval Ġdeck Size : ĠInt , Ġval Ġsh uffled Deck : ĠSh uffled Deck ) Ġ: ĠClone able Ġ{ ĊĠĠĠ Ġ// map : Ġposition Ġin Ġsh uffled ĠDeck Ġand Ġuser Ġ-> Ġkeys ĊĠĠĠ Ġprivate Ġval Ġkey Map Ġ= ĠArray ( N , Ġ{ Ġi Ġ-> ĊĠĠĠĠĠĠĠ ĠArray < BigInteger ? >( deck Size , Ġ{ Ġj Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ}) ĊĊĠĠĠ Ġprivate Ġval Ġstacks Ġ= Ġmutable ListOf < Play Stack >() ĊĠĠĠ Ġprivate Ġvar Ġcurrent Stack Ġ= ĠPlay Stack ( deck Size ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRegister Ġthat ĊĠĠĠĠ Ġ* Ġ@ param ĠuserID Ġ- ĠID Ġof Ġholder ĊĠĠĠĠ Ġ* Ġ@ param Ġcard ID Ġ- Ġposition Ġin Ġsh uffled Ġdeck ĊĠĠĠĠ Ġ* Ġ@ param Ġkey Ġ- Ġkey ĊĠĠĠĠ Ġ* Ġ@ return Ġposition Ġof Ġdecrypted Ġcard Ġin ĊĠĠĠĠ Ġ* Ġoriginal Ġdeck Ġ(- 1 Ġif Ġab sc ent ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġregister Card Key ( userID : ĠInt , Ġcard ID : ĠInt , Ġkey : ĠBigInteger ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( key Map [ userID ][ card ID ] Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsh uffled Deck . encrypted . deck . decrypt Card With Key ( card ID , Ġkey ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Map [ userID ][ card ID ] Ġ= Ġkey ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( key Ġ!= Ġkey Map [ userID ][ card ID ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠGame ExecutionException (" Attempt Ġto Ġoverride Ġcard Ġkey ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġsh uffled Deck . original Deck . cards . indexOf ( sh uffled Deck . encrypted . deck . cards [ card ID ]) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġif Ġcurrent Ġplayer Id Ġ- Ġf irs Ġplayer Id ĊĠĠĠĠ Ġ* Ġin Ġthe Ġnew Ġstack ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġis New Stack () Ġ= Ġcurrent Stack . isNew Stack () ĊĊĠĠĠ Ġfun Ġstack Finished () Ġ= Ġcurrent Stack . is Finished () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠStart Ġnext Ġstack ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġnext Stack () Ġ{ ĊĠĠĠĠĠĠĠ Ġstacks . add ( current Stack ) ĊĠĠĠĠĠĠĠ Ġcurrent Stack Ġ= ĠPlay Stack ( deck Size ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRegister Ġhash Ġpart Ġof Ġcommit ment Ġscheme ĊĠĠĠĠ Ġ* Ġused Ġfor Ġadding Ġcards . ĊĠĠĠĠ Ġ* Ġ@ param Ġuser Ġ- Ġactor , Ġthat Ġplayed Ġcards ĊĠĠĠĠ Ġ* Ġ@ param Ġcount Ġ- ĠBet Count Ġof Ġcards Ġplayed ĊĠĠĠĠ Ġ* Ġ@ param Ġclaim Ġ- Ġclaimed ĠP ip Ġof Ġall Ġcards ĊĠĠĠĠ Ġ* Ġ@ param Ġhashes Ġ- Ġhas he sh Ġof Ġcards Ġplayed ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġregister Add Play Hashes ( user : ĠUser , Ġcount : ĠBet Count , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclaim : ĠP ip Ġ= ĠP ip . UNKNOWN , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhashes : ĠList < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( hashes . size Ġ!= Ġcount . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠGame ExecutionException (" Number Ġof Ġhashes Ġin Ġcom it ment Ġdoesn 't " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġcorrespond Ġto Ġclaimed ĠBet Count ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( isNew Stack ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Stack . set Pip ( claim ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcurrent Stack . register Add Cards ( user , Ġcount , Ġhashes ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see Ġ[ Play Stack . register Verify ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġregister Verify ( user : ĠUser , Ġcard Pos : ĠInt , Ġche at : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent Stack . register Verify ( user , Ġcard Pos , Ġche at ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see Ġ[ Play Stack . register Verify Response ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġregister Verify Response ( user : ĠUser , Ġresponse : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent Stack . register Verify Response ( user , Ġresponse ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġsee Ġ[ Play Stack . check R sponse Card ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcheck Pip ( card Id : ĠInt ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcurrent Stack . check Response Card ( card Id ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see Ġ[ Play Stack . count User Card On Stack ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcount User Card On Stack ( user : ĠUser ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcurrent Stack . count User Card On Stack ( user ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see Ġ[ Play Stack . getLast User Bet Count Size ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun ĠgetLast User Bet Count Size ( user : ĠUser ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcurrent Stack . getLast User Bet Count Size ( user ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see Ġ[ Play Stack . next Player To Re veal ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġnext Player To Re veal (): ĠUser Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcurrent Stack . next Player To Re veal () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see Ġ[ Play Stack . next NumberOf Cards To Re veal ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġnext NumberOf Cards To Re veal (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcurrent Stack . next NumberOf Cards To Re veal () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see Ġ[ Play Stack . count Re ve aled Cards ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcount Re ve aled Cards ( user : ĠUser ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcurrent Stack . count Re ve aled Cards ( user ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRegister Ġencrypted Ġmessage Ġsent Ġby Ġuser ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġreg iser Encrypted Message ( user : ĠUser , Ġencrypt : ĠList < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( user Ġ!= Ġnext Player To Re veal ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠGame ExecutionException (" Unexpected Ġencrypted Ġmessage Ġencountered ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcurrent Stack . register Encrypt ( encrypt ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġformat Log (): ĠString Ġ= Ġ"" ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠVerify Ġthat Ġall Ġplays Ġof Ġthe Ġround Ġwere Ġconsistent ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġuser List Ġ- Ġlist Ġof Ġparticipants Ġin Ġthe Ġround ĊĠĠĠĠ Ġ* Ġ@ param Ġdecoder Ġ- Ġfunction Ġthat Ġtakes Ġuser Ġand Ġencrypted Ġmessage ĊĠĠĠĠ Ġ* Ġand Ġreturns Ġdecoded Ġmessage Ġfor Ġthat Ġuser ĊĠĠĠĠ Ġ* Ġ@ param Ġwin ners Ġ- Ġmaps ĠUser Ġto Ġthe Ġfact Ġwhether Ġhe Ġwon ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġverify Round ( user List : ĠList < User >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdecoder : Ġ( User , ĠString ) Ġ-> ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwin ners : ĠMap < User , ĠBoolean >): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Check , Ġthat Ġnobody Ġex changed Ġcards Ġbefore Ġthe Ġgame Ġstarted ĊĠĠĠĠĠĠĠ Ġfor Ġ( user Ġin Ġ 0 .. N Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( getUser Keys Hash ( user ) Ġ!= Ġsh uffled Deck . encrypted . hashes [ user List [ user ]]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// restore Ġplay Ġorder Ġto Ġsee , Ġthat Ġall Ġplays Ġwere Ġconsistent ĊĠĠĠĠĠĠĠ Ġval Ġcards Ġ= ĠArray ( N , Ġ{ Ġi Ġ-> Ġmutable Set Of < Int >() Ġ}) ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. deck Size Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġholder Ġ= Ġi Ġ% ĠN ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcards [ holder ]. add ( i ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( stack Ġin Ġstacks ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Stack ( user List , Ġstack , Ġcards , Ġdecoder ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġtmp Ġ= Ġwin ners . map Keys Ġ{ Ġx Ġ-> Ġuser List . indexOf ( x . key ) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtmp . all Ġ{ Ġx Ġ-> Ġx . value Ġ== Ġcards [ x . key ]. isEmpty () Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠVerify , Ġthat Ġall Ġplays Ġof Ġthis Ġstack Ġare Ġconsistent . ĊĠĠĠĠ Ġ* ĠOnly Ġhashes Ġand Ġcard Ġownership Ġis Ġchecked . ĠPlayer Ġorder ĊĠĠĠĠ Ġ* Ġis Ġen forced Ġby Ġdesign : Ġif Ġal Ġleast Ġone Ġplayer Id Ġis Ġnot Ġche ating ĊĠĠĠĠ Ġ* Ġhis Ġgame Ġwill Ġcr ush Ġdue Ġto Ġunexpected Ġmessage ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġuser List Ġ- Ġlist Ġof Ġall Ġusers , Ġwho Ġparticip ate Ġin Ġthe Ġgame ĊĠĠĠĠ Ġ* Ġ@ param Ġstack Ġ- Ġstack Ġto Ġbe Ġverified ĊĠĠĠĠ Ġ* Ġ@ param Ġuser Cards Ġ- Ġarray Ġof Ġmut al be Sets , Ġrepresents Ġcards Ġowned ĊĠĠĠĠ Ġ* Ġby Ġusers Ġat Ġthe Ġmoment ĊĠĠĠĠ Ġ* Ġ@ param Ġdecoder Ġ- Ġfunction Ġthat Ġtakes Ġuser Ġand Ġencrypted Ġmessage ĊĠĠĠĠ Ġ* Ġand Ġreturns Ġdecoded Ġmessage Ġfor Ġthat Ġuser ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġall Ġplay es Ġwere Ġconsistent . ĠOtherwise Ġ- Ġreturns Ġfalse ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcheck Stack ( user List : ĠList < User >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstack : ĠPlay Stack , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuser Cards : ĠArray < Mutable Set < Int >>, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdecoder : Ġ( User , ĠString ) Ġ-> Ġ( String )): ĠBoolean Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġcards Ġ= Ġmutable ListOf < Int >() ĊĠĠĠĠĠĠĠ Ġvar Ġreceiver Id : ĠInt Ġ= Ġuser List . indexOf ( stack . claims . last (). user ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! stack . g ues sed Correct ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreceiver Id Ġ= Ġ( receiver Id Ġ+ Ġ 1 ) Ġ% ĠN ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. stack . size Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠuserId Ġ= Ġuser List . indexOf ( stack . claims [ i ]. user ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( j Ġin Ġ 0 .. stack . claims [ i ]. count . size Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġs Ġ= Ġdecoder ( user List [ receiver Id ], Ġstack . encrypt s [ i ][ j ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Digest Utils . sha 2 5 6 Hex ( s ) Ġ!= Ġstack . claims [ i ]. hashes [ j ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcard Ġ= Ġs . split (" Ġ" )[ 0 ]. toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= ĠBigInteger ( s . split (" Ġ" )[ 1 ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( key Ġ!= Ġkey Map [ userId ][ card ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! user Cards [ userId ]. contains ( card )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuser Cards [ userId ]. remove ( card ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcards . add ( card ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġuser Cards [ receiver Id ]. addAll ( cards ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalculate Ġhash Ġfor Ġuser Ġkey Ġset Ġ- Ġused Ġto ĊĠĠĠĠ Ġ* Ġvalidate , Ġthat Ġno Ġcard ID Ġexchange Ġc oo peration Ġwas Ġpresent ĊĠĠĠĠ Ġ* Ġ@ param Ġplayer Ġ- Ġid Ġof Ġplayer Id , Ġwhose Ġkey Ġhash Ġis Ġbeing Ġcalculated ĊĠĠĠĠ Ġ* Ġ@ return ĠS ting Ġ- Ġresulting Ġhash . ĠNull Ġif Ġcurrent Ġinformation Ġis ĊĠĠĠĠ Ġ* Ġins uff it ient Ġto Ġcalculate Ġrequested Ġhash ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun ĠgetUser Keys Hash ( player : ĠInt ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( key Map [ player ]. contains ( null )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠDigest Utils . sha 2 5 6 Hex ( key Map [ player ]. join ToString (" Ġ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġpublic Ġfun Ġclone (): ĠRound Logger Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . clone () Ġas ĠRound Logger ĊĠĠĠ Ġ} Ċ }