So you want to write a Haskell bot for the Robot Fruit Hunt. You came to the right place!
First, read about how the game works.
Then, make sure you have followed the instructions in the README to set up your coding environment.
Now, let's write our first bot.
Here's a Haskell bot that always goes EAST:
makeMove = return EAST
Here's a bot that always goes to the nearest fruit:
import Data.Maybe import Data.Ord (comparing) import Data.List (sortBy) -- manhattan distance dist (x1, y1) (x2, y2) = (abs $ x2 - x1) + (abs $ y2 - y1) -- positions myPos = (getMyX, getMyY) oppPos = (getOpponentX, getOpponentY) for = flip map -- get a list of all the positions with items allItems :: [(Int, Int)] allItems = catMaybes $ for positions $ \(x, y) -> if (isJust . hasItem $ getBoard !! x !! y) then Just (x, y) else Nothing -- all items, sorted by those closest to our bot nearestItems :: [(Int, Int)] nearestItems = sortBy (comparing $ dist myPos) allItems moveTo :: (Int, Int) -> Move moveTo (x, y) | getMyX < x = EAST | getMyX > x = WEST | getMyY < y = SOUTH | getMyY > y = NORTH | otherwise = TAKE makeMove :: State (Map String String) Move makeMove = return . moveTo . head $ nearestItems
You can use the trace function for debugging.
trace statement takes two values. It prints out the first and returns the second. Example:
makeMove = trace "I'm moving!" (return EAST)
You can only use
You may have noticed that
makeMove is a pure function. Your bot cannot do any IO. That includes
trace functions and random number generators as well. When you submit your bot, make sure it doesn't do any IO!
makeMove uses the State Monad. In this case the state is a
Map of Strings to Strings.
You can access the state with
get and modify it with
put. Here's a simple bot that keeps a counter of how many moves it's made:
makeMove = do let key = "move_num" state <- get case lookup key state of Just _ -> put $ adjust (\num -> (read num :: Int) + 1) key state Nothing -> put $ insert key (show 0) state return EAST
The complete API can be found here.