package Ġboard Ċ Ċ import Ġboard . Direction .* Ċ Ċ fun Ġcreate Square Board ( width : ĠInt ): ĠSquare Board Ġ= ĠSquare Board Impl ( width ) Ċ Ċ fun Ġ< T > Ġcreate Game Board ( width : ĠInt ): ĠGame Board < T > Ġ= ĠGame Board Impl ( width ) Ċ Ċ open Ġclass ĠSquare Board Impl ( final Ġoverride Ġval Ġwidth : ĠInt ) Ġ: ĠSquare Board Ġ{ ĊĠĠĠ Ġprivate Ġval Ġcells : ĠArray < Array < Cell >> Ġ= ĠArray ( width ) Ġ{ Ġi Ġ-> ĠArray ( width ) Ġ{ Ġj Ġ-> ĠCell ( i Ġ+ Ġ 1 , Ġj Ġ+ Ġ 1 ) Ġ} Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Cell OrNull ( i : ĠInt , Ġj : ĠInt ): ĠCell ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ(( i Ġ! in Ġ 1 .. width ) Ġ|| Ġ( j Ġ! in Ġ 1 .. width )) Ġnull Ġelse Ġcells [ i Ġ- Ġ 1 ][ j Ġ- Ġ 1 ] ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Cell ( i : ĠInt , Ġj : ĠInt ): ĠCell Ġ{ ĊĠĠĠĠĠĠĠ Ġfun ĠInt . require Index Within Range () Ġ= Ġrequire (( i Ġin Ġ 1 .. width )) Ġ{ Ġ"$ this Ġshould Ġbe Ġbetween Ġ 1 Ġand Ġ$ width " Ġ} ĊĠĠĠĠĠĠĠ Ġi . require Index Within Range () ĊĠĠĠĠĠĠĠ Ġj . require Index Within Range () ĊĠĠĠĠĠĠĠ Ġreturn Ġcells [ i Ġ- Ġ 1 ][ j Ġ- Ġ 1 ] ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠgetAll Cells (): ĠCollection < Cell > Ġ= Ġcells . flatMap Ġ{ Ġit . toList () Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Row ( i : ĠInt , Ġj Range : ĠInt Progress ion ): ĠList < Cell > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĠArrayList < Cell >() ĊĠĠĠĠĠĠĠ Ġfor Ġ( j Ġin Ġj Range . get Normalized Range ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add ( cells [ i . get Within Range Index () ][ j ]) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Column ( i Range : ĠInt Progress ion , Ġj : ĠInt ): ĠList < Cell > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĠArrayList < Cell >() ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġi Range . get Normalized Range ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add ( cells [ i ][ j . get Within Range Index ()]) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠInt Progress ion . get Normalized Range () Ġ= ĠInt Progress ion . from Closed Range ( first . get Within Range Index (), Ġlast . get Within Range Index (), Ġstep ) ĊĠĠĠ Ġprivate Ġfun ĠInt . get Within Range Index () Ġ= Ġif Ġ( this Ġ< Ġ 0 ) Ġ 0 Ġelse Ġif Ġ( this Ġ> Ġwidth ) Ġwidth Ġ- Ġ 1 Ġelse Ġthis Ġ- Ġ 1 ĊĊĠĠĠ Ġoverride Ġfun ĠCell . get Ne ighbour ( direction : ĠDirection ) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUP Ġ-> Ġget Cell OrNull ( i Ġ- Ġ 1 , Ġj ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDOWN Ġ-> Ġget Cell OrNull ( i Ġ+ Ġ 1 , Ġj ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRIGHT Ġ-> Ġget Cell OrNull ( i , Ġj Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLEFT Ġ-> Ġget Cell OrNull ( i , Ġj Ġ- Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ Ċ } Ċ Ċ class ĠGame Board Impl < T >( board Width : ĠInt ) Ġ: ĠGame Board < T >, ĠSquare Board Impl ( board Width ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġcells Map : ĠMutable Map < Cell , ĠT ?> Ġ= ĠHashMap () ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ ĠgetAll Cells (). forEach Ġ{ Ġcells Map [ it ] Ġ= Ġnull Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget ( cell : ĠCell ) Ġ= Ġcells Map [ cell ] ĊĊĠĠĠ Ġoverride Ġfun Ġset ( cell : ĠCell , Ġvalue : ĠT ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġcells Map [ cell ] Ġ= Ġvalue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġfilter ( predicate : Ġ( T ?) Ġ-> ĠBoolean ): ĠCollection < Cell > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcells Map . filter Values ( predicate ). keys ĊĊĠĠĠ Ġoverride Ġfun Ġfind ( predicate : Ġ( T ?) Ġ-> ĠBoolean ): ĠCell ? Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ(( key , Ġvalue ) Ġin Ġcells Map ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( predicate ( value )) Ġreturn Ġkey ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġany ( predicate : Ġ( T ?) Ġ-> ĠBoolean ) Ġ= Ġcells Map . any Ġ{ Ġ(_, Ġvalue ) Ġ-> Ġpredicate ( value ) Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġall ( predicate : Ġ( T ?) Ġ-> ĠBoolean ): ĠBoolean Ġ= Ġcells Map . all Ġ{ Ġ(_, Ġvalue ) Ġ-> Ġpredicate ( value ) Ġ} Ċ Ċ }