package Ġkat as . kotlin . snake . v 0 _ ref actored Ċ Ċ import Ġdat sok . should Equal Ċ import Ġdat sok . should NotEqual Ċ import Ġorg . junit . Test ĊĊ Ċ class ĠPoint Tests Ġ{ ĊĠĠĠ Ġ@ Test Ġfun Ġ` point Ġhas Ġequality Ġand Ġcan Ġbe Ġconverted Ġto Ġstring `() Ġ{ ĊĠĠĠĠĠĠĠ ĠPoint ( 1 , Ġ 1 ) Ġshould Equal ĠPoint ( 1 , Ġ 1 ) ĊĠĠĠĠĠĠĠ ĠPoint ( 1 , Ġ 1 ) Ġshould NotEqual ĠPoint ( 1 , Ġ 2 ) ĊĠĠĠĠĠĠĠ ĠPoint ( 2 , Ġ 3 ). toString () Ġshould Equal Ġ"( 2 , 3 )" ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠPoint ( val Ġx : ĠInt , Ġval Ġy : ĠInt ) Ġ{ ĊĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġ" ($ x ,$ y )" Ċ } Ċ Ċ enum Ġclass ĠDirection Ġ{ ĊĠĠĠ ĠLeft , ĠUp , ĠRight , ĠDown Ċ } ĊĊ Ċ class ĠSn ake Tests Ġ{ ĊĊĠĠĠ Ġ@ Test Ġfun Ġ` snake Ġis Ġconstructed Ġwith Ġbody Ġas Ġlist Ġor Ġvar arg Ġof Ġpoints `() Ġ{ ĊĠĠĠĠĠĠĠ ĠSn ake ( listOf ( Point ( 1 , Ġ 1 ), ĠPoint ( 1 , Ġ 2 ))) Ġshould Equal ĠSn ake ( Point ( 1 , Ġ 1 ), ĠPoint ( 1 , Ġ 2 )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġ` snake Ġknows Ġits Ġdirection `() Ġ{ ĊĠĠĠĠĠĠĠ ĠSn ake ( Point ( 1 , Ġ 1 ), ĠPoint ( 1 , Ġ 2 )). direction Ġshould Equal ĠDirection . Up ĊĠĠĠĠĠĠĠ ĠSn ake ( Point ( 1 , Ġ 2 ), ĠPoint ( 1 , Ġ 1 )). direction Ġshould Equal ĠDirection . Down ĊĠĠĠĠĠĠĠ ĠSn ake ( Point ( 1 , Ġ 1 ), ĠPoint ( 2 , Ġ 1 )). direction Ġshould Equal ĠDirection . Left ĊĠĠĠĠĠĠĠ ĠSn ake ( Point ( 2 , Ġ 1 ), ĠPoint ( 1 , Ġ 1 )). direction Ġshould Equal ĠDirection . Right ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġ` snake Ġknows Ġwhen Ġit Ġbit Ġitself `() Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠX x ĊĠĠĠĠĠĠĠ ĠSn ake ( Point ( 1 , Ġ 1 ), ĠPoint ( 2 , Ġ 1 )). bit It self Ġshould Equal Ġfalse ĊĠĠĠĠĠĠĠ Ġ// ĠX x ĊĠĠĠĠĠĠĠ Ġ// Ġ Ġx ĊĠĠĠĠĠĠĠ ĠSn ake ( Point ( 1 , Ġ 1 ), ĠPoint ( 1 , Ġ 2 ), ĠPoint ( 2 , Ġ 2 )). bit It self Ġshould Equal Ġfalse ĊĠĠĠĠĠĠĠ Ġ// ĠX x ĊĠĠĠĠĠĠĠ Ġ// Ġxx ĊĠĠĠĠĠĠĠ ĠSn ake ( Point ( 1 , Ġ 1 ), ĠPoint ( 2 , Ġ 1 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 1 , Ġ 2 )). bit It self Ġshould Equal Ġfalse ĊĠĠĠĠĠĠĠ Ġ// Ġ* x ĊĠĠĠĠĠĠĠ Ġ// Ġxx ĊĠĠĠĠĠĠĠ ĠSn ake ( Point ( 1 , Ġ 1 ), ĠPoint ( 2 , Ġ 1 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 1 , Ġ 2 ), ĠPoint ( 1 , Ġ 1 )). bit It self Ġshould Equal Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġ` moves Ġof Ġhorizontal Ġsnake `() Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠX xx ĊĠĠĠĠĠĠĠ Ġval Ġsnake Ġ= ĠSn ake ( Point ( 2 , Ġ 2 ), ĠPoint ( 3 , Ġ 2 ), ĠPoint ( 4 , Ġ 2 )) ĊĊĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Left ) Ġshould Equal ĠSn ake ( Point ( 1 , Ġ 2 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 3 , Ġ 2 )) ĊĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Right ) Ġshould Equal ĠSn ake ( Point ( 5 , Ġ 2 ), ĠPoint ( 4 , Ġ 2 ), ĠPoint ( 3 , Ġ 2 )) ĊĊĠĠĠĠĠĠĠ Ġ// Ġxx ĊĠĠĠĠĠĠĠ Ġ// ĠX ĊĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Down ) Ġshould Equal ĠSn ake ( Point ( 2 , Ġ 3 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 3 , Ġ 2 )) ĊĠĠĠĠĠĠĠ Ġ// ĠX ĊĠĠĠĠĠĠĠ Ġ// Ġxx ĊĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Up ) Ġshould Equal ĠSn ake ( Point ( 2 , Ġ 1 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 3 , Ġ 2 )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġ` moves Ġof Ġvertical Ġsnake `() Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠX ĊĠĠĠĠĠĠĠ Ġ// Ġx ĊĠĠĠĠĠĠĠ Ġ// Ġx ĊĠĠĠĠĠĠĠ Ġval Ġsnake Ġ= ĠSn ake ( Point ( 2 , Ġ 2 ), ĠPoint ( 2 , Ġ 3 ), ĠPoint ( 2 , Ġ 4 )) ĊĊĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Up ) Ġshould Equal ĠSn ake ( Point ( 2 , Ġ 1 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 2 , Ġ 3 )) ĊĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Down ) Ġshould Equal ĠSn ake ( Point ( 2 , Ġ 5 ), ĠPoint ( 2 , Ġ 4 ), ĠPoint ( 2 , Ġ 3 )) ĊĠĠĠĠĠĠĠ Ġ// ĠX x ĊĠĠĠĠĠĠĠ Ġ// Ġ Ġx ĊĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Left ) Ġshould Equal ĠSn ake ( Point ( 1 , Ġ 2 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 2 , Ġ 3 )) ĊĠĠĠĠĠĠĠ Ġ// Ġx X ĊĠĠĠĠĠĠĠ Ġ// Ġx ĊĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Right ) Ġshould Equal ĠSn ake ( Point ( 3 , Ġ 2 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 2 , Ġ 3 )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġ` reverse Ġmoves Ġof Ġsh aped Ġsnake `() Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠX ĊĠĠĠĠĠĠĠ Ġ// Ġxx ĊĠĠĠĠĠĠĠ Ġ// Ġ Ġx ĊĠĠĠĠĠĠĠ ĠSn ake ( Point ( 1 , Ġ 1 ), ĠPoint ( 1 , Ġ 2 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 2 , Ġ 3 )). let Ġ{ Ġsnake Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠX ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġx ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġxx ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Up ) Ġshould Equal ĠSn ake ( Point ( 1 , Ġ 0 ), ĠPoint ( 1 , Ġ 1 ), ĠPoint ( 1 , Ġ 2 ), ĠPoint ( 2 , Ġ 2 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġxx ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ Ġx ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ ĠX ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Down ) Ġshould Equal ĠSn ake ( Point ( 2 , Ġ 4 ), ĠPoint ( 2 , Ġ 3 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 1 , Ġ 2 )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠX x ĊĠĠĠĠĠĠĠ Ġ// Ġxx ĊĠĠĠĠĠĠĠ ĠSn ake ( Point ( 1 , Ġ 1 ), ĠPoint ( 1 , Ġ 2 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 2 , Ġ 1 )). let Ġ{ Ġsnake Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠX ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġx ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġxx ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Up ) Ġshould Equal ĠSn ake ( Point ( 1 , Ġ 0 ), ĠPoint ( 1 , Ġ 1 ), ĠPoint ( 1 , Ġ 2 ), ĠPoint ( 2 , Ġ 2 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ ĠX ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ Ġx ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġxx ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsnake . move ( Direction . Down ) Ġshould Equal ĠSn ake ( Point ( 2 , Ġ 0 ), ĠPoint ( 2 , Ġ 1 ), ĠPoint ( 2 , Ġ 2 ), ĠPoint ( 1 , Ġ 2 )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠSn ake ( val Ġbody : ĠList < Point >) Ġ{ ĊĠĠĠ Ġconstructor ( var arg Ġbody : ĠPoint ) Ġ: Ġthis ( body . toList ()) ĊĊĠĠĠ Ġval Ġdirection Ġ= Ġbody . direction ĊĊĠĠĠ Ġval Ġbit It self Ġ= Ġbody . distinct (). size Ġ!= Ġbody . size ĊĊĠĠĠ Ġfun Ġmove ( direction : ĠDirection ): ĠSn ake Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġreversed Ġ= Ġdirection . is Opp osite To ( body . direction ) ĊĠĠĠĠĠĠĠ Ġval Ġupdated Body Ġ= Ġif Ġ( reversed ) Ġbody . reversed () Ġelse Ġbody ĊĠĠĠĠĠĠĠ Ġval Ġactual Direction Ġ= Ġif Ġ( reversed ) Ġupdated Body . direction Ġelse Ġdirection ĊĠĠĠĠĠĠĠ Ġreturn ĠSn ake ( updated Body . move In ( actual Direction )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠList < Point >. move In ( direction : ĠDirection ) Ġ= ĠlistOf ( first (). move In ( direction )) Ġ+ Ġdrop Last ( 1 ) ĊĊĠĠĠ Ġprivate Ġfun ĠPoint . move In ( direction : ĠDirection ) Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠ ĠDirection . Left Ġ-> ĠPoint ( x Ġ- Ġ 1 , Ġy ) ĊĠĠĠĠĠĠĠ ĠDirection . Up Ġ-> ĠPoint ( x , Ġy Ġ- Ġ 1 ) ĊĠĠĠĠĠĠĠ ĠDirection . Right Ġ-> ĠPoint ( x Ġ+ Ġ 1 , Ġy ) ĊĠĠĠĠĠĠĠ ĠDirection . Down Ġ-> ĠPoint ( x , Ġy Ġ+ Ġ 1 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval ĠList < Point >. direction Ġget (): ĠDirection Ġ= Ġthis . let Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( it [ 0 ]. x Ġ== Ġit [ 1 ]. x Ġ- Ġ 1 ) ĠDirection . Left ĊĠĠĠĠĠĠĠ Ġelse Ġif Ġ( it [ 0 ]. x Ġ== Ġit [ 1 ]. x Ġ+ Ġ 1 ) ĠDirection . Right ĊĠĠĠĠĠĠĠ Ġelse Ġif Ġ( it [ 0 ]. y Ġ== Ġit [ 1 ]. y Ġ- Ġ 1 ) ĠDirection . Up ĊĠĠĠĠĠĠĠ Ġelse Ġif Ġ( it [ 0 ]. y Ġ== Ġit [ 1 ]. y Ġ+ Ġ 1 ) ĠDirection . Down ĊĠĠĠĠĠĠĠ Ġelse Ġerror ("") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠDirection . is Opp osite To ( direction : ĠDirection ): ĠBoolean Ġ= Ġwhen Ġ( this ) Ġ{ ĊĠĠĠĠĠĠĠ ĠDirection . Left Ġ-> Ġdirection Ġ== ĠDirection . Right ĊĠĠĠĠĠĠĠ ĠDirection . Up Ġ-> Ġdirection Ġ== ĠDirection . Down ĊĠĠĠĠĠĠĠ ĠDirection . Right Ġ-> Ġdirection Ġ== ĠDirection . Left ĊĠĠĠĠĠĠĠ ĠDirection . Down Ġ-> Ġdirection Ġ== ĠDirection . Up ĊĠĠĠ Ġ} Ċ } Ċ