package Ġfoo . bar . clean . domain . t ict act oe Ċ Ċ import Ġfoo . bar . clean . domain . t ict act oe . Player .* Ċ import Ġfoo . bar . clean . domain . Domain Error Ċ import Ġkotlinx . serialization . Serializable Ċ import Ġkotlinx . serialization . Transient Ċ Ċ /** Ċ Ġ* ĠThis Ġimmutable Ġgame Ġstate Ġis Ġworking Ġquite Ġhard Ġfor Ġus , Ġfrom Ġthe Ċ Ġ* Ġbasic Ġstructure Ġwe Ġare Ġable Ġto Ġtell Ġnot Ġjust Ġthe Ġstate Ġof Ġthe Ġboard , Ċ Ġ* Ġbut Ġalso Ġwhose Ġturn Ġit Ġis , Ġand Ġhow Ġmany Ġturns Ġhave Ġbeen Ġplayed . Ċ Ġ* Ċ Ġ* ĠCode Ġhere Ġis Ġreally Ġeasy Ġto Ġtest : Ġit 's Ġnot Ġth readed , Ġit 's Ġall Ġbased Ċ Ġ* Ġon Ġimmutable Ġstate . Ċ Ġ* Ċ Ġ* ĠThe Ġdown side Ġis Ġperformance : Ġnotice Ġhow Ġeach Ġtime Ġwe Ġask Ġwho 's Ċ Ġ* Ġturn Ġit Ġis , Ġthe Ġboard Ġstate Ġis Ġcounted Ġup Ġ( the ĠUI Ġlayer Ġmight Ġask Ċ Ġ* Ġthis Ġquestion Ġa Ġlot Ġas Ġit Ġre Ġdraw s Ġitself ). Ċ Ġ* Ċ Ġ* ĠFor Ġthis Ġreason , Ġjust Ġto Ġdemonstrate Ġthe Ġtrade off , Ġwe Ġwill Ġdecide Ġto Ċ Ġ* Ġkeep Ġthe Ġ" who Ġwon " Ġcalculation Ġin Ġthe Ġgame Ġmodel Ġwhere Ġit Ġwon 't Ġbe Ġrun Ċ Ġ* Ġas Ġoften Ġ( only Ġwhen Ġa Ġplayer Ġtakes Ġa Ġturn ) Ġand Ġwhere Ġwe Ġcan Ġeasily Ġrun Ċ Ġ* Ġit Ġusing Ġcor outines Ġas Ġwe Ġdo Ġwith Ġthe Ġnetwork Ġconnection Ġwork . ĠHere Ġwe Ċ Ġ* Ġjust Ġkeep Ġthe Ġresults Ġof Ġthat Ġcalculation Ġin Ġthe Ġwinner Ġvalue . Ċ Ġ* Ċ Ġ* ĠIt 's Ġsomewhat Ġrelated Ġto Ġthis Ġadvice Ġto Ġkeep ĠU Is Ġsn appy : Ċ Ġ* Ġhttps :// er do . github . io / android - fore / 0 5 - extras . html # slow - get ters Ċ Ġ*/ Ċ @ Serializable Ċ data Ġclass ĠGameState ( ĊĠĠĠ Ġval Ġfirst Player : ĠPlayer , ĊĠĠĠ Ġval Ġwinner : ĠPlayer Ġ= ĠN obody , ĊĠĠĠ Ġval Ġboard : ĠList < List < Player >> Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠ ĠlistOf ( N obody , ĠN obody , ĠN obody ), ĊĠĠĠĠĠĠĠ ĠlistOf ( N obody , ĠN obody , ĠN obody ), ĊĠĠĠĠĠĠĠ ĠlistOf ( N obody , ĠN obody , ĠN obody ) ĊĠĠĠ Ġ), ĊĠĠĠ Ġ@ Transient ĊĠĠĠ Ġval ĠisLoading : ĠBoolean Ġ= Ġfalse , ĊĠĠĠ Ġ@ Transient ĊĠĠĠ Ġval Ġerror : ĠDomain Error Ġ= ĠDomain Error . NO _ ERROR , Ċ ) Ġ{ ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( board . size Ġ== Ġboard Size ) Ġ{" game Ġboard Ġmust Ġhave Ġ$ board Size Ġrows "} ĊĠĠĠĠĠĠĠ Ġboard . forEach Indexed Ġ{ Ġindex , Ġlist Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( list . size Ġ== Ġboard Size ) Ġ{" game Ġboard Ġrow [$ index ] Ġmust Ġhave Ġ$ board Size Ġcolumns "} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġrequire ( first Player Ġ!= ĠN obody ) Ġ{" some body Ġmust Ġbe Ġthe Ġfirst Ġplayer "} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġwhose Turn () Ġ= Ġif Ġ( turn s Taken () % 2 Ġ== Ġ 0 ) Ġfirst Player Ġelse Ġopposite Player ( first Player ) ĊĠĠĠ Ġfun Ġgame Finished (): ĠBoolean Ġ= Ġ( winner Ġ!= ĠN obody Ġ|| Ġboard Complete ()) ĊĊĠĠĠ Ġprivate Ġfun Ġboard Complete (): ĠBoolean Ġ= Ġ( turn s Taken () Ġ== Ġboard Size Ġ* Ġboard Size ) ĊĠĠĠ Ġprivate Ġfun Ġturns Taken (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġboard . sum Of Ġ{ Ġrow Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrow . count Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġ!= ĠN obody ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Serializable Ċ sealed Ġclass ĠPlayer Ġ{ ĊĠĠĠ Ġ@ Serializable ĊĠĠĠ Ġobject ĠX Ġ: ĠPlayer () ĊĠĠĠ Ġ@ Serializable ĊĠĠĠ Ġobject ĠO Ġ: ĠPlayer () ĊĠĠĠ Ġ@ Serializable ĊĠĠĠ Ġobject ĠN obody Ġ: ĠPlayer () Ċ } Ċ Ċ @ Serializable Ċ data Ġclass ĠNext Turn ( var Ġx Pos : ĠInt , Ġvar Ġy Pos : ĠInt ) Ċ Ċ fun Ġopposite Player ( player : ĠPlayer ): ĠPlayer Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( player ) Ġ{ ĊĠĠĠĠĠĠĠ ĠX Ġ-> ĠO ĊĠĠĠĠĠĠĠ ĠO Ġ-> ĠX ĊĠĠĠĠĠĠĠ Ġelse Ġ-> ĠN obody ĊĠĠĠ Ġ} Ċ } Ċ