package Ġnet . z om is . games . impl Ċ Ċ import Ġnet . z om is . games . Player Elimin ations Write Ċ import Ġnet . z om is . games . Win Result Ċ import Ġnet . z om is . games . api . Games Ċ import Ġnet . z om is . games . common . Direction 8 Ċ import Ġnet . z om is . games . common . Point Ċ import Ġnet . z om is . games . common . Point Move Ċ import Ġnet . z om is . games . components . Grid Point Ċ import Ġnet . z om is . games . dsl .* Ċ import Ġkotlin . math . abs Ċ import Ġkotlin . math . max Ċ Ċ class ĠTT Art ax ( private Ġval Ġelim ination Callback : ĠPlayer Elimin ations Write , ĊĠĠĠĠĠĠĠĠĠ Ġplayer Count : ĠInt , Ġsize X : ĠInt , Ġsize Y : ĠInt ) Ġ{ ĊĠĠĠ Ġval Ġboard Ġ= ĠGames . components . grid < Int ? >( size X , Ġsize Y ) Ġ{ Ġ_, Ġ_ Ġ-> Ġnull Ġ} ĊĠĠĠ Ġvar Ġcurrent Player : ĠInt Ġ= Ġ 0 ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġboard . all (). forEach Ġ{ Ġit . value Ġ= Ġnull Ġ} ĊĠĠĠĠĠĠĠ Ġboard . point ( 0 , Ġ 0 ). value Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġboard . point ( board . size X Ġ- Ġ 1 , Ġ 0 ). value Ġ= Ġ 1 ĊĊĠĠĠĠĠĠĠ Ġif Ġ( player Count Ġ== Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġboard . point ( 0 , Ġboard . size Y Ġ- Ġ 1 ). value Ġ= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġboard . point ( board . size X Ġ- Ġ 1 , Ġboard . size Y Ġ- Ġ 1 ). value Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( player Count Ġ>= Ġ 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġboard . point ( 0 , Ġboard . size Y Ġ- Ġ 1 ). value Ġ= Ġ 2 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( player Count Ġ== Ġ 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġboard . point ( board . size X Ġ- Ġ 1 , Ġboard . size Y Ġ- Ġ 1 ). value Ġ= Ġ 3 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdistance ( a : ĠGrid Point < Int ? >, Ġb : ĠGrid Point < Int ?> ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġmax ( abs ( a . x Ġ- Ġb . x ), Ġabs ( a . y Ġ- Ġb . y )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġallowed Source ( tile : ĠGrid Point < Int ?> ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtile . value OrNull () Ġ== Ġthis . current Player ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġallowed Destination ( source : ĠGrid Point < Int ? >, Ġtile : ĠGrid Point < Int ?> ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( tile . value OrNull () Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtile Distance Ġ= Ġdistance ( tile , Ġsource ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtile Distance Ġin Ġ 1 .. 2 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġperform ( source : ĠGrid Point < Int ? >, Ġdestination : ĠGrid Point < Int ?> ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! allowed Source ( source ) Ġ|| Ġ! allowed Destination ( source , Ġdestination )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġtile Distance Ġ= Ġdistance ( destination , Ġsource ) ĊĠĠĠĠĠĠĠ Ġdestination . value Ġ= Ġthis . current Player ĊĠĠĠĠĠĠĠ Ġif Ġ( tile Distance Ġ== Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsource . value Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġpotential Winner Ġ= Ġthis . current Player ĊĠĠĠĠĠĠĠ ĠDirection 8 . values (). map Ġ{ Ġdir Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġboard . point ( destination . x Ġ+ Ġdir . delta X , Ġdestination . y Ġ+ Ġdir . delta Y ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. range Check ( board ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . take If Ġ{ Ġit . value OrNull () Ġ!= Ġnull Ġ} ?. value Ġ= Ġpotential Winner ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġthis . elim inate Players Without Tiles () ĊĊĠĠĠĠĠĠĠ Ġthis . current Player Ġ= Ġelim ination Callback . next Player ( this . current Player ) !! ĊĊĠĠĠĠĠĠĠ Ġif Ġ( elim ination Callback . remaining Players (). size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelim ination Callback . elim inate Remaining ( Win Result . WIN ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġplayers That Can Move Ġ= Ġelim ination Callback . remaining Players (). filter Ġ{ player Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġplayer Tiles Ġ= Ġthis . board . all (). filter Ġ{ Ġit . value OrNull () Ġ== Ġplayer Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ filter Ġthis . board . all (). any Ġ{ Ġtile Ġ-> Ġtile . value OrNull () Ġ== Ġnull Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplayer Tiles . any Ġ{ Ġdistance ( tile , Ġit ) Ġ<= Ġ 2 Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( players That Can Move . size Ġ<= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġno Ġmoves Ġare Ġpossible ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounts Ġ= Ġthis . board . all (). filter Ġ{ Ġit . value OrNull () Ġ!= Ġnull Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. groupBy Ġ{ Ġit . value Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Keys Ġ{ Ġit . key !! Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Values Ġ{ Ġit . value . size Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. entries . sorted By Descending Ġ{ Ġit . value Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . key Ġto Ġit . value Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġelim ination Callback . elim inate By ( counts , Ġcompare By Ġ{ Ġit Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwhile Ġ(! players That Can Move . contains ( this . current Player )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . current Player Ġ= Ġelim ination Callback . next Player ( this . current Player ) Ġ?: Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġeliminate Players Without Tiles () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlo sing Players Ġ= Ġelim ination Callback . remaining Players (). filter Ġ{ Ġplayer Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . board . all (). none Ġ{ Ġit . value OrNull () Ġ== Ġplayer Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelim ination Callback . elim inate Many ( lo sing Players , ĠWin Result . LO SS ) ĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ object ĠArt ax Game Ġ{ ĊĊĠĠĠ Ġval Ġfactory Ġ= ĠGame Creator ( TT Art ax :: class ) ĊĠĠĠ Ġval Ġmove Action Ġ= Ġfactory . action (" move ", ĠPoint Move :: class ) ĊĠĠĠ Ġval Ġgame Art ax Ġ= Ġfactory . game (" Art ax ") Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsize X Ġ= Ġconfig (" x ") Ġ{ Ġ 7 Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġsize Y Ġ= Ġconfig (" y ") Ġ{ Ġ 7 Ġ} ĊĠĠĠĠĠĠĠ Ġsetup Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplayers ( 2 .. 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTT Art ax ( elim ination Callback , Ġplayer Count , Ġconfig ( size X ), Ġconfig ( size Y )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġaction Rules Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġaction ( move Action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpre condition Ġ{ Ġgame . current Player Ġ== Ġplayer Index Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchoose Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions ({ Ġgame . board . points (). filter Ġ{ Ġgame . allowed Source ( game . board . point ( it )) Ġ} Ġ}) Ġ{ source Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions ({ Ġgame . board . points (). filter Ġ{ Ġgame . allowed Destination ( game . board . point ( source ), Ġgame . board . point ( it )) Ġ} Ġ}) Ġ{ destination Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameter ( Point Move ( Point ( source . x , Ġsource . y ), ĠPoint ( destination . x , Ġdestination . y ))) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequires Ġ{ Ġgame . allowed Source ( game . board . point ( action . parameter . source )) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequires Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgame . allowed Destination ( game . board . point ( action . parameter . source ), Ġgame . board . point ( action . parameter . destination )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġeffect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgame . perform ( game . board . point ( action . parameter . source ), Ġgame . board . point ( action . parameter . destination )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġview (" action Name ") Ġ{ Ġmove Action . name Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġview (" current Player ") Ġ{ Ġgame . current Player Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġview (" board ") Ġ{ Ġgame . board . view Ġ{ Ġmap Of (" owner " Ġto Ġit ) Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ } Ċ