package Ġcom . paul meth f essel . cad . generator Ċ Ċ import Ġcom . paul meth f essel . cad . model .* Ċ import Ġcom . paul meth f essel . cad . util . Random Ċ Ċ class ĠRecursive Generator ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġwidth : ĠInt , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġheight : ĠInt , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġgrid : ĠGrid Ġ= ĠGrid ( width , Ġheight ) Ċ ) Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġamount Of Cast les Needed Min Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġval Ġopen Connections Ġ= Ġmutable ListOf < Connection >() ĊĠĠĠ Ġprivate Ġvar Ġplaced Dragon Red Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġplaced Dragon Blue Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġplaced Cast les Count Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġval Ġused Items Ġ= Ġmutable ListOf < Item >() ĊĊĠĠĠ Ġfun Ġgenerate (): ĠGrid Ġ{ ĊĠĠĠĠĠĠĠ Ġchoose Cast les () ĊĠĠĠĠĠĠĠ Ġval Ġhero Ġ= Ġchoose Hero Pos () ĊĠĠĠĠĠĠĠ Ġgrid . hero Pos Ġ= Ġhero ĊĠĠĠĠĠĠĠ Ġopen Connections . add ( Connection ( hero , Ġgrid . hero Start Pos ())) ĊĊĠĠĠĠĠĠĠ Ġ// Ġrecursively Ġchoose Ġitems Ġuntil Ġgrid Ġis Ġfinished ĊĠĠĠĠĠĠĠ Ġchoose Next Item () ĊĊĠĠĠĠĠĠĠ Ġremove St re ets From Grid () ĊĠĠĠĠĠĠĠ Ġreturn Ġgrid ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġchoose Next Item (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠSh uffle Ġso Ġdifferent Ġgrids Ġcan Ġbe Ġgenerated ĊĠĠĠĠĠĠĠ Ġval Ġpossib ilities Ġ= ĠRandom . shuffle ( getAll Connection Item Po ss ibilities ( open Connections )) ĊĠĠĠĠĠĠĠ Ġif Ġ( poss ibilities . isEmpty ()) Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( poss ibility Ġin Ġpossib ilities ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpos Ġ= Ġpossibility . connection . to ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplace Item ( pos , Ġpossibility . item Po ss ibility . item , Ġpossibility . item Po ss ibility . up ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( are Cast les And Drag ons In Grid () Ġ&& Ġopen Connections . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGrid Ġis Ġfinished ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( open Connections . isEmpty ()){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNo Ġopen Ġconnections , Ġbut Ġnot Ġall Ġnecessary Ġitems Ġare Ġplaced ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremove Item ( pos ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( choose Next Item ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGrid Ġis Ġfinished ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠPo ss ibility Ġis Ġnot Ġworking ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremove Item ( pos ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠNo Ġpossibility Ġwas Ġworking , Ġso Ġreturn Ġnot Ġfinished Ġ( prev Ġitem Ġwill Ġbe Ġremoved ) ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠgetAll Connection Item Po ss ibilities ( connections : ĠList < Connection >): ĠList < Connection Po ss ibility > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġconnections . flatMap Ġ{ ĠgetAll Valid Po ss ibilities For Connection ( it ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠgetAll Valid Po ss ibilities For Connection ( connection : ĠConnection ): ĠList < Connection Po ss ibility > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġitems Ġ= ĠItems . all . filter Ġ{ Ġit Ġ!= ĠItems . EMPTY Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġpossib ilities Ġ= Ġmutable ListOf < Connection Po ss ibility >() ĊĠĠĠĠĠĠĠ Ġfor Ġ( item Ġin Ġitems ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( orientation Ġin ĠOrientation . values ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Item Valid ( connection . to , Ġitem , Ġorientation ) Ġ&& Ġis Item Connected ( item , Ġorientation , Ġconnection )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpossib ilities . add ( Connection Po ss ibility ( connection , ĠItem Po ss ibility ( item , Ġorientation ))) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġpossib ilities ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġis Item Valid ( pos : ĠPos , Ġitem : ĠItem , Ġup : ĠOrientation ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( item Ġin Ġused Items ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġold State Ġ= Ġgrid [ pos ] ĊĠĠĠĠĠĠĠ Ġgrid . setItem ( pos , Ġitem , Ġup ) ĊĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġgrid [ pos ] ĊĠĠĠĠĠĠĠ Ġval Ġvalid Ġ= ĠOrientation . values (). all Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġneighbor Ġ= Ġgrid . neighbors Of ( state )[ it ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate . is Connection With Neighbor Valid ( it ) Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġneighbor . type Ġ== ĠNe ighbor Type . ITEM Ġ&& Ġneighbor . item State !!. item Ġ== ĠItems . EMPTY ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġgrid [ pos ] Ġ= Ġold State ĊĠĠĠĠĠĠĠ Ġreturn Ġvalid ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Item Connected ( item : ĠItem , Ġup : ĠOrientation , Ġconnection : ĠConnection ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstreet Dir Ġ= Ġconnection . direction . op pos ite (). to Local ( up ) ĊĠĠĠĠĠĠĠ Ġreturn Ġitem . stre ets [ street Dir ] Ġ!= ĠStreet Type . NONE ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġplace Item ( pos : ĠPos , Ġitem : ĠItem , Ġup : ĠOrientation ) Ġ{ ĊĠĠĠĠĠĠĠ Ġgrid . setItem ( pos , Ġitem , Ġup ) ĊĠĠĠĠĠĠĠ Ġif Ġ( item Ġ== ĠItems . DR AG ON _ ST ONE ) Ġplaced Dragon Blue Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġif Ġ( item Ġ== ĠItems . DR AG ON _ M UD ) Ġplaced Dragon Red Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġif Ġ( item . type Ġ== ĠItem Type . CAST LE ) Ġplaced Cast les Count ++ ĊĊĠĠĠĠĠĠĠ Ġopen Connections . remove If Ġ{ Ġit . to Ġ== Ġpos Ġ} ĊĠĠĠĠĠĠĠ Ġopen Connections . addAll ( get Open Connections From ( pos )) ĊĠĠĠĠĠĠĠ Ġused Items . add ( item ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġremove Item ( pos : ĠPos ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġgrid [ pos ] ĊĠĠĠĠĠĠĠ Ġval Ġitem Ġ= Ġstate . item ĊĠĠĠĠĠĠĠ Ġif Ġ( item Ġ== ĠItems . DR AG ON _ ST ONE ) Ġplaced Dragon Blue Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġif Ġ( item Ġ== ĠItems . DR AG ON _ M UD ) Ġplaced Dragon Red Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġif Ġ( item . type Ġ== ĠItem Type . CAST LE ) Ġplaced Cast les Count -- ĊĊĠĠĠĠĠĠĠ Ġopen Connections . removeAll ( get Open Connections From ( pos )) ĊĠĠĠĠĠĠĠ Ġopen Connections . addAll ( get Open Connections To ( pos )) ĊĊĠĠĠĠĠĠĠ Ġgrid . set Empty ( pos . x , Ġpos . y ) ĊĠĠĠĠĠĠĠ Ġused Items . remove ( item ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Open Connections To ( pos : ĠPos ): ĠList < Connection > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠOrientation . values (). filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfrom Ġ= Ġpos . move In Orientation ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠisOpen Connection From To ( from , Ġpos ) Ġ&& Ġgrid . in Grid ( from ) ĊĠĠĠĠĠĠĠ Ġ}. map Ġ{ ĠConnection ( pos . move In Orientation ( it ), Ġpos ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Open Connections From ( pos : ĠPos ): ĠList < Connection > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠOrientation . values (). filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Ġ= Ġpos . move In Orientation ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠisOpen Connection From To ( pos , Ġto ) Ġ&& Ġgrid . in Grid ( to ) ĊĠĠĠĠĠĠĠ Ġ}. map Ġ{ ĠConnection ( pos , Ġpos . move In Orientation ( it )) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠisOpen Connection From To ( from : ĠPos , Ġto : ĠPos ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( grid . in Grid ( from )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfrom State Ġ= Ġgrid [ from ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdir Ġ= Ġfrom . which Move Orientation ( to ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( from State . item Ġ== ĠItems . EMPTY Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfrom State . item . type Ġ== ĠItem Type . DR AG ON Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfrom State . street At ( dir ) Ġ== ĠStreet Type . NONE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( grid . in Grid ( to )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto State Ġ= Ġgrid [ to ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( to State . item Ġ!= ĠItems . EMPTY ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġremove St re ets From Grid () Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( element Ġin Ġgrid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġelement . item State . item . type ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( type Ġ!= ĠItem Type . DR AG ON Ġ&& Ġtype Ġ!= ĠItem Type . CAST LE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgrid . set Empty ( element . pos ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġare Cast les And Drag ons In Grid (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġplaced Dragon Blue Ġ&& Ġplaced Dragon Red Ġ&& Ġplaced Cast les Count Ġ>= Ġamount Of Cast les Needed Min ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġchoose Hero Pos (): ĠPos Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpositions Ġ= ĠMutable List ( width Ġ* Ġ 2 Ġ+ Ġheight Ġ* Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġ< Ġwidth Ġ-> ĠPos ( it , Ġ- 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġ< Ġwidth Ġ* Ġ 2 Ġ-> ĠPos ( it Ġ- Ġwidth , Ġheight ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġ< Ġwidth Ġ* Ġ 2 Ġ+ Ġheight Ġ-> ĠPos (- 1 , Ġit Ġ- Ġwidth Ġ* Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠPos ( width , Ġit Ġ- Ġ( width Ġ* Ġ 2 Ġ+ Ġheight )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠRandom . from ( positions ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġchoose Cast les () Ġ{ ĊĠĠĠĠĠĠĠ Ġamount Of Cast les Needed Min Ġ= ĠRandom . between ( 2 Ġ.. Ġ 4 ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠConnection Po ss ibility ( ĊĠĠĠĠĠĠĠ Ġval Ġconnection : ĠConnection , ĊĠĠĠĠĠĠĠ Ġval Ġitem Po ss ibility : ĠItem Po ss ibility ) Ċ Ċ data Ġclass ĠItem Po ss ibility ( ĊĠĠĠĠĠĠĠ Ġval Ġitem : ĠItem , ĊĠĠĠĠĠĠĠ Ġval Ġup : ĠOrientation ) Ċ Ċ data Ġclass ĠConnection ( ĊĠĠĠĠĠĠĠ Ġval Ġfrom : ĠPos , ĊĠĠĠĠĠĠĠ Ġval Ġto : ĠPos ) Ġ{ ĊĠĠĠ Ġval Ġdirection Ġ= Ġfrom . which Move Orientation ( to ) Ċ } Ċ Ċ infix Ġfun ĠPos . connect ( other : ĠPos ) Ġ= ĠConnection ( this , Ġother )