Writing a Haskell Bot for Scribd's fruit hunt
This project is maintained by egonSchiele
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.
The 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 trace
while testing locally. Output will be printed to the javascript console.
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.
Happy coding!