implementation module wormstate import StdBool, StdEnum, StdList import StdIOCommon, StdSystem import Highscore, Random // The worm data types. :: State = { gamelevel :: Level , food :: Food , foodsupply :: [Food] , grow :: Grow , points :: Points , dir :: SpecialKey , worm :: Worm , best :: HiScores , lives :: Lives } :: Level = { fix :: Int , speed :: Int , level :: Int , obstacles :: [Obstacle] } :: Food = { value :: Int , pos :: Point2 } :: Grow :== Int :: Obstacle :== Rectangle :: Segment :== Point2 :: Worm :== [Segment] :: Points :== Int :: Lives :== Int SizeX :== 45 SizeY :== 26 NrOfWorms :== 4 NrOfLevels :== 8 PointsPerLevel :== 500 StartLevel :== 0 EasySpeed :== ticksPerSecond/6 MediumSpeed :== ticksPerSecond/9 HardSpeed :== ticksPerSecond/18 Accelation :== ticksPerSecond/18 // Initial State. InitState :: HiScores -> State InitState best = { gamelevel = initlevel , food = initfood , foodsupply = [] , grow = 0 , points = 0 , dir = rightKey , worm = initworm , best = best , lives = NrOfWorms } where initfood = {value=0,pos={x=(-10),y=(-10)}} initlevel = InitLevel EasySpeed initworm = NewWorm initlevel // Make a new initial worm. NewWorm :: Level -> Worm NewWorm {Level | level} = [{x=x,y=y}\\x<-[5,4..1]] where y = StartHeights!!(level rem NrOfLevels) StartHeights :: [Int] StartHeights =: [13,5,13,13,13,1,1,14] // Construct the next level. InitLevel :: Int -> Level InitLevel fix = {fix=fix,speed=fix,level=StartLevel,obstacles=Obstacles!!StartLevel} DecreaseLevel :: Level -> Level DecreaseLevel curlevel=:{speed,level} # level = level-1 speed = if (level rem NrOfLevels==0 && level<>0) (speed+Accelation) speed = { curlevel & fix = speed , speed = speed , level = level , obstacles = Obstacles!!(level rem NrOfLevels) } IncreaseLevel :: Level -> Level IncreaseLevel curlevel=:{speed,level} # speed = if (level rem NrOfLevels==0 && level<>0) (speed-Accelation) speed level = level+1 = { curlevel & fix = speed , speed = speed , level = level , obstacles = Obstacles!!(level rem NrOfLevels) } Obstacles :: [[Obstacle]] Obstacles =: [ [] , [{corner1={x=12,y=11},corner2={x=34,y=16}}] , [{corner1={x=12,y= 1},corner2={x=34,y= 3}}, {corner1={x=12,y=24},corner2={x=34,y=26}}] , [{corner1={x= 7,y= 7},corner2={x=38,y= 9}}, {corner1={x= 7,y=17},corner2={x=38,y=19}}] , [{corner1={x= 1,y= 1},corner2={x=18,y=10}}, {corner1={x=28,y=17},corner2={x=45,y=26}}] , [{corner1={x=14,y= 3},corner2={x=15,y=24}}, {corner1={x=30,y= 3},corner2={x=31,y=24}}] , [{corner1={x= 3,y=13},corner2={x=43,y=14}}, {corner1={x=22,y= 3},corner2={x=24,y=24}}] , [{corner1={x= 3,y= 3},corner2={x=20,y=12}}, {corner1={x=26,y=15},corner2={x=43,y=24}}] ] // Generate a food supply. FoodSupply :: RandomSeed -> [Food] FoodSupply seed = [{value=value,pos=pos}:FoodSupply seed3] where (random1,seed1) = random seed (random2,seed2) = random seed1 (random3,seed3) = random seed2 foodx = (IncMod random2 (SizeX-2))+1 foody = (IncMod random3 (SizeY-2))+1 pos = {x=foodx,y=foody} value = IncMod random1 9 IncMod a b = (a rem b)+1 // Think of some new random food. NewFood :: Worm Level [Food] -> (Food, [Food]) NewFood worm level=:{obstacles} [food=:{pos}:foods] | isMember pos worm || any (InRectangle pos) obstacles = NewFood worm level foods | otherwise = (food, foods) where InRectangle :: Point2 Obstacle -> Bool InRectangle {x,y} {corner1={x=lx,y=ty},corner2={x=rx,y=by}} = x>=lx && x<=rx && y>=ty && y<=by