package Ġcom . iteration . king dom ino . game Ċ Ċ import Ġtim ber . log . Tim ber Ċ Ċ public Ġclass ĠField Ġ{ ĊĠĠĠ Ġ// ĠFIXME Ġ: Ġshould Ġcast le Ġhave Ġvalue Ġ 0 Ġor Ġ 1 ? ĊĠĠĠ Ġval Ġfield Ġ: ĠMutable List < Mutable List < Tile >> Ġ= ĠMutable List ( 9 ) Ġ{ ĠMutable List ( 9 ) Ġ{ ĠTile ( Tile . Terrain . NULL , ĠTile . C rown . ZERO ) Ġ} Ġ} ĊĠĠĠ Ġprivate Ġvar Ġdomains Ġ= ĠHashMap < HashSet < Int >, ĠTile . Terrain >() Ċ // ĠĠĠ Ġprivate Ġvar Ġdomains Ġ: ĠMap < HashSet < Int >, ĠTile . Terrain > Ġ= ĠHashMap < HashSet < Int >, ĠTile . Terrain >() ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġfield [ 4 ][ 4 ] Ġ= ĠTile ( Tile . Terrain . CAST LE , ĠTile . C rown . ZERO ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġcalculate Score () Ġ: ĠInt ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġscore Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ ĠTim ber . d ( domains . toString ()) ĊĊĠĠĠĠĠĠĠ Ġfor ( domain Ġin Ġdomains . keys ) ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġc row ns Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor ( tile Id Ġin Ġdomain ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġy Ġ= Ġtile Id Ġ% Ġ 1 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġx Ġ= Ġ( tile Id Ġ- Ġy )/ 1 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġc row ns Ġ+= Ġfield [ x ][ y ]. c rown . value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscore Ġ+= Ġc row ns Ġ* Ġdomain . size ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġscore ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Tile ( t Ġ: ĠTile , Ġpos XY Ġ: ĠPair < Int , ĠInt >) ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġx Ġ= Ġpos XY . first ; Ġval Ġy Ġ= Ġpos XY . second ĊĊĠĠĠĠĠĠĠ Ġif ( x Ġ< Ġ 0 Ġ|| Ġx Ġ> Ġ 8 ){ Ġthrow ĠPlayer Field Exception (" Imp ossible Ġto Ġadd Ġthis Ġtile Ġto Ġthe Ġplayer Ġfield : Ġgiven Ġx Ġindex Ġwas Ġ$ x ; Ġshould Ġbe Ġbetween Ġ 0 Ġand Ġ 8 ") Ġ} ĊĠĠĠĠĠĠĠ Ġif ( y Ġ< Ġ 0 Ġ|| Ġy Ġ> Ġ 8 ){ Ġthrow ĠPlayer Field Exception (" Imp ossible Ġto Ġadd Ġthis Ġtile Ġto Ġthe Ġplayer Ġfield : Ġgiven Ġy Ġindex Ġwas Ġ$ y ; Ġshould Ġbe Ġbetween Ġ 0 Ġand Ġ 8 ") Ġ} ĊĠĠĠĠĠĠĠ Ġif ( field [ x ][ y ]. type Ġ!= ĠTile . Terrain . NULL ) Ġthrow ĠPlayer Field Exception (" Imp ossible Ġto Ġadd Ġthis Ġtile : Ġtarget Ġis Ġnot Ġan Ġempty Ġtile ") ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( field Small En ough ( x , Ġy )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( valid Ne ighbour ( x , Ġy , Ġt . type )) Ġ{// Ġat Ġleast Ġone Ġneighbour Ġof ĠXY Ġis Ġvalid ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield [ x ][ y ] Ġ= Ġt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠaddTo Domains ( x , Ġy , Ġt ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Success Ġplaying Ġtile Ġ$ t Ġat Ġ$ pos XY ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ Ġthrow ĠPlayer Field Exception (" Invalid Ġmovement : Ġno Ġvalid Ġneighbour Ġhas Ġbeen Ġfound Ġnear Ġthis Ġposition .") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ Ġthrow ĠPlayer Field Exception (" Invalid Ġmovement : Ġfield Ġalready Ġreaches Ġlimits Ġof Ġsize Ġfor Ġa Ġfield .") Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠaddTo Domains ( x : ĠInt , Ġy : ĠInt , Ġt : ĠTile ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠChecking Ġwhich Ġdomain Ġto Ġadd Ġto ... ĊĠĠĠĠĠĠĠ Ġval Ġne ighbours Id Ġ= Ġget Ne ighbours Id ( x , Ġy ) ĊĠĠĠĠĠĠĠ Ġ// ĠNo Ġsimilar Ġterrain , Ġmeans Ġonly Ġa Ġcast le Ġis Ġnearby ĊĠĠĠĠĠĠĠ Ġif ( ne ighbours Id . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Set Ġ= ĠHashSet < Int >(); Ġnew Set . add ( x * 1 0 Ġ+ Ġy ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdomains [ new Set ] Ġ= Ġfield [ x ][ y ]. type ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠSimilar Ġterrain Ġfound , Ġadding Ġto Ġthe Ġfirst Ġdomain ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor ( ne ighbour Id Ġin Ġne ighbours Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdomains . forEach Ġ{ Ġentry Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( entry . key . contains ( ne ighbour Id )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry . key . add ( x * 1 0 Ġ+ Ġy ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠChecking Ġif Ġtwo Ġdomains Ġshould Ġbe Ġmerged ĊĊĠĠĠĠĠĠĠ Ġval Ġdomains Containing XY Ġ= Ġdomains . filter Ġ{ Ġentry Ġ-> Ġentry . key . contains ( x * 1 0 Ġ+ Ġy ) Ġ} ĊĠĠĠĠĠĠĠ Ġif ( domains Containing XY . size Ġ> Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor ( i Ġin Ġ 1 Ġuntil Ġdomains Containing XY . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( domains . keys . find Ġ{ Ġdomain Ġ-> Ġdomain Ġ== Ġdomains Containing XY . keys . elementAt ( 0 ) Ġ} Ġas ĠHashSet ). addAll ( domains Containing XY . keys . elementAt ( i )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdomains Ġ= Ġdomains . filter Ġ{ Ġentry Ġ-> Ġentry . key Ġ!= Ġdomains Containing XY . keys . elementAt ( i ) Ġ} Ġas ĠHashMap ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġtrimmed Field ( field Ġ: ĠMutable List < Mutable List < Tile >>) Ġ: ĠMutable List < Mutable List < Tile >> ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtrimmed Field Ġ= Ġfield Clone () Ġ// Ġclone Ġthe Ġfield ĊĠĠĠĠĠĠĠ Ġfor ( i Ġin Ġ 8 Ġdown To Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( field [ i ]. all Ġ{ Ġtile Ġ-> Ġtile . type Ġ== ĠTile . Terrain . NULL Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrimmed Field . remove At ( i ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( field . all Ġ{ Ġrow Ġ-> Ġrow [ i ]. type Ġ== ĠTile . Terrain . NULL Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrimmed Field . forEach Ġ{ Ġrow Ġ-> Ġrow . remove At ( i ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtrimmed Field ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtrimmed Field () Ġ= Ġtrimmed Field ( field ) ĊĊĠĠĠ Ġprivate Ġfun Ġfield Clone (): ĠMutable List < Mutable List < Tile >> Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfield . map Ġ{ Ġit . map Ġ{ tile Ġ-> Ġtile . copy () Ġ}. to Mutable List ()}. to Mutable List () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfield Small En ough ( x Ġ: ĠInt , Ġy Ġ: ĠInt ) Ġ: ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfuture Field Ġ= Ġfield Clone () ĊĠĠĠĠĠĠĠ Ġfuture Field [ x ][ y ] Ġ= ĠTile ( Tile . Terrain . CAST LE , ĠTile . C rown . TH REE ) ĊĠĠĠĠĠĠĠ Ġval Ġtrimmed Ġ= Ġtrimmed Field ( future Field ) ĊĠĠĠĠĠĠĠ Ġreturn Ġ( trimmed . size Ġ< Ġ 6 ) Ġand Ġ( trimmed [ 0 ]. size Ġ< Ġ 6 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġvalid Ne ighbour ( x Ġ: ĠInt , Ġy Ġ: ĠInt , Ġtype Ġ: ĠTile . Terrain ) Ġ: ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġget Ne ighbours Types ( x , Ġy ). any Ġ{ Ġterrain Type Ġ-> Ġterrain Type Ġ== Ġtype Ġ|| Ġterrain Type Ġ== ĠTile . Terrain . CAST LE Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Ne ighbours Id ( x : ĠInt , Ġy : ĠInt ): ĠList < Int > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġne ighbours Ġ= Ġmutable ListOf < Int >() ĊĠĠĠĠĠĠĠ Ġif ( field [ x ][ y ]. type Ġ!= ĠTile . Terrain . NULL ) ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( y Ġ> Ġ 0 Ġ&& Ġfield [ x ][ y - 1 ]. type Ġ== Ġfield [ x ][ y ]. type ) Ġne ighbours . add ( x * 1 0 +( y - 1 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( y Ġ< Ġ 8 Ġ&& Ġfield [ x ][ y + 1 ]. type Ġ== Ġfield [ x ][ y ]. type ) Ġne ighbours . add ( x * 1 0 +( y + 1 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( x Ġ> Ġ 0 Ġ&& Ġfield [ x - 1 ][ y ]. type Ġ== Ġfield [ x ][ y ]. type ) Ġne ighbours . add (( x - 1 )* 1 0 + y ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( x Ġ< Ġ 8 Ġ&& Ġfield [ x + 1 ][ y ]. type Ġ== Ġfield [ x ][ y ]. type ) Ġne ighbours . add (( x + 1 )* 1 0 + y ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġne ighbours ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Ne ighbours Types ( x Ġ: ĠInt , Ġy Ġ: ĠInt ) Ġ: ĠSet < Tile . Terrain > ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġne ighbours Ġ= ĠHashSet < Tile . Terrain >() ĊĠĠĠĠĠĠĠ Ġif ( y Ġ> Ġ 0 ) Ġne ighbours . add ( field [ x ][ y - 1 ]. type ) ĊĠĠĠĠĠĠĠ Ġif ( y Ġ< Ġ 8 ) Ġne ighbours . add ( field [ x ][ y + 1 ]. type ) ĊĠĠĠĠĠĠĠ Ġif ( x Ġ> Ġ 0 ) Ġne ighbours . add ( field [ x - 1 ][ y ]. type ) ĊĠĠĠĠĠĠĠ Ġif ( x Ġ< Ġ 8 ) Ġne ighbours . add ( field [ x + 1 ][ y ]. type ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġne ighbours ĊĠĠĠ Ġ} ĊĊĊĊĊĠĠĠ Ġprivate Ġfun Ġmap AsString ( field Ġ: ĠMutable List < Mutable List < Tile >>) Ġ: ĠString ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġmap Representation Ġ= Ġ"" ĊĠĠĠĠĠĠĠ Ġfor ( row Ġin Ġ 0 Ġuntil Ġfield . size ) ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor ( col Ġin Ġ 0 Ġuntil Ġfield [ row ]. size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmap Representation Ġ+= Ġfield [ row ][ col ]. type . toString (). elementAt ( 0 ). toUpperCase () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmap Representation Ġ+= Ġ'\ n ' ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġmap Representation ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġmap AsString ( trimmed Field ( field )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠPlayer Field Exception ( message Ġ: ĠString ) Ġ: ĠException ( message ) Ċ }