1. module Main (main) where
  2.  
  3. import Game.Spacegoo
  4. import Data.List
  5.  
  6. import Control.Monad (msum)
  7.  
  8. main = client 6000 "spacegoo.gpn.entropia.de" "username" "password" myStrategy
  9.  
  10. exampleStrategy :: Strategy
  11. exampleStrategy s = do
  12.     me <- playerId `fmap` find itsme (players s)
  13.     let he = 3 - me
  14.     aPlanet <- find (\p -> planetOwner p == me) (planets s)
  15.     otherPlanet <- find (\p -> planetOwner p == he) (planets s)
  16.     return (planetId aPlanet, planetId otherPlanet, planetShips aPlanet)
  17.  
  18. planetCompareShips :: Planet -> Planet -> Ordering
  19. planetCompareShips p1 p2 = compare (numShips p1) (numShips p2)
  20.     where numShips Planet {planetShips = (a, b, c)} = a + b + c
  21.  
  22.  
  23. isUnattacked :: [Fleet] -> Planet -> Bool
  24. isUnattacked fleets Planet{planetId = pid} = notElem pid $ map target fleets
  25.  
  26. comparePlanetDistance :: Planet -> Planet -> Planet -> Ordering
  27. comparePlanetDistance p0 p1 p2 = compare (distance p0 p1) (distance p0 p2)
  28.  
  29. safeHead :: [a] -> Maybe a
  30. safeHead [] = Nothing
  31. safeHead (h:_) = Just h
  32.  
  33. safeMaximumBy f [] = Nothing
  34. safeMaximumBy f l = Just $ maximumBy f l
  35.  
  36. myId :: State -> Maybe Int
  37. myId s = playerId `fmap` find itsme (players s)
  38.  
  39. strongestPlanet :: [Planet] -> Maybe Planet
  40. strongestPlanet = safeMaximumBy planetCompareShips
  41.  
  42. fullForceStrategy :: Strategy
  43. fullForceStrategy s = do
  44.     me <- myId s
  45.     let ownPlanets = filter (\p -> planetOwner p == me) $ planets s
  46.     let unattacked = filter (isUnattacked $ fleets s) ownPlanets
  47.     strongest <- strongestPlanet unattacked
  48.     let hostilePlanets = sortBy (comparePlanetDistance strongest) $ filter (\p -> planetOwner p /= me && planetOwner p /= 0) $ planets s
  49.     let beatable = filter (\p -> planetCompareShips strongest p == GT) hostilePlanets
  50.     target <- safeHead beatable
  51.     return (planetId strongest, planetId target, (1000, 1000, 1000))
  52.  
  53. oneShip :: Strategy
  54. oneShip s = do
  55.     me <- myId s
  56.     let ownPlanets = filter (\p -> planetOwner p == me) $ planets s
  57.     strongest <- strongestPlanet ownPlanets
  58.     let otherPlanets = sortBy (comparePlanetDistance strongest) $ filter (\p -> planetOwner p /= me) $ planets s
  59.     target <- safeHead otherPlanets
  60.     return (planetId strongest, planetId target, (1, 1, 1))
  61.  
  62. myStrategy :: Strategy
  63. myStrategy s = msum [fullForceStrategy s, oneShip s]