Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a7a3dfb
Add skeleton for Haskell starter package
jparoz Nov 12, 2016
ebe8644
Haskell: Implement types and stub functions
jparoz Nov 12, 2016
2f16d1f
Implement rest of starter pack (untested!)
jparoz Nov 12, 2016
605683c
Complete Haskell starter package and examples
jparoz Nov 12, 2016
a017346
Haskell: Remove erroneous LICENSE file
jparoz Nov 12, 2016
ed339bc
Merge branch 'master' of https://github.com/HaliteChallenge/Halite
jparoz Nov 12, 2016
3bdcdd7
Merge branch 'master' of https://github.com/HaliteChallenge/Halite
jparoz Nov 12, 2016
ff2e04d
Merge pull request #189 from jparoz/master
truell20 Nov 12, 2016
15845d2
I have provided the src/ scripts with new interface, hopefuly more co…
Kesanov Nov 14, 2016
aad3cda
Merge pull request #216 from Josef-Vonasek/haskell-new-interface
truell20 Nov 14, 2016
36a3dac
Fix typos and simple copy-paste type errors
jparoz Nov 15, 2016
e66ad3d
Added manual instances for Effects and Test
jparoz Nov 15, 2016
8518f87
Improve showMove definition
jparoz Nov 15, 2016
e9a9d96
Fix bug, should start indexing from 0
jparoz Nov 15, 2016
bce63b1
Fixed typecheck errors.
Kesanov Nov 15, 2016
9327aa8
Fix incorrectly generating locations in algorithm
jparoz Nov 15, 2016
a0e2c81
Merge pull request #223 from jparoz/haskell
truell20 Nov 15, 2016
bdd1480
Few tweaks.
Kesanov Nov 16, 2016
fa8a99d
New module Halite.Logic
Kesanov Nov 16, 2016
2771e19
Resolved conflicts.
Kesanov Nov 16, 2016
d0131fc
Resolved merge conflicts.
Kesanov Nov 16, 2016
9a56aff
Merge pull request #233 from Josef-Vonasek/haskell
truell20 Nov 16, 2016
b8ec033
Merge branch 'master' into haskell
truell20 Nov 19, 2016
9d9a4f2
Add ghc to sandbox
truell20 Nov 19, 2016
022fda8
Add stack to sandbox
truell20 Nov 19, 2016
63ea5a2
Stack debugging
truell20 Nov 19, 2016
12f69b0
Add to website
truell20 Nov 19, 2016
802d89d
Merge branch 'master' into haskell
truell20 Nov 21, 2016
df5cdbf
Merge branch 'master' into haskell
truell20 Nov 21, 2016
75866a5
Add cabal
truell20 Nov 22, 2016
e5c35d3
Deleted two useless lines.
Kesanov Nov 24, 2016
1c9200b
Deleted two useless lines.
Kesanov Nov 24, 2016
2413217
Merge pull request #263 from Josef-Vonasek/haskell
truell20 Nov 24, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions airesources/Haskell/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.stack-work/
halite.exe
halite
2 changes: 2 additions & 0 deletions airesources/Haskell/Setup.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain
32 changes: 32 additions & 0 deletions airesources/Haskell/halite-haskell.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: halite-haskell
version: 0.1.0.0
synopsis: Halite starter pack for Haskell
author: Jesse Paroz
, Josef Vonasek
maintainer: [email protected]
, [email protected]
build-type: Simple
cabal-version: >=1.10

library
hs-source-dirs: lib
exposed-modules: Halite, Halite.Networking, Halite.Types, Halite.Classes, Halite.Logic
default-language: Haskell2010
build-depends: base >= 4.7 && < 5
, random

executable MyBot
hs-source-dirs: src
main-is: MyBot.hs
default-language: Haskell2010
build-depends: base >= 4.7 && < 5
, halite-haskell
, random

executable RandomBot
hs-source-dirs: src
main-is: RandomBot.hs
default-language: Haskell2010
build-depends: base >= 4.7 && < 5
, halite-haskell
, random
8 changes: 8 additions & 0 deletions airesources/Haskell/lib/Halite.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Halite
( module M
) where

import Halite.Networking as M
import Halite.Classes as M
import Halite.Types as M
import Halite.Logic as M
12 changes: 12 additions & 0 deletions airesources/Haskell/lib/Halite/Classes.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Halite.Classes
( RandomReader(..)
) where

-- use type classes to manage side effects for your algorithm function
-- if you want to add your custom side effect just create a new class
-- class Monad m => MyCustomSideEffect m where ...
-- and change type signature of your algorithm to
-- algorithm :: (MyCustomSideEffect m, RandomReader m) => .... -> m [Move]

class Monad m => RandomReader m where
rand :: Int -> m Int
47 changes: 47 additions & 0 deletions airesources/Haskell/lib/Halite/Logic.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module Halite.Logic
( toLocation
, distance
, angle
, moveToLocation
, site
) where

import Halite.Types

toLocation :: Map -> (Int, Int) -> Location
toLocation (Map width height _) (x, y) =
Location (mod x width) (mod y height)

distance :: Map -> Location -> Location -> Int
distance (Map width height _) (Location x1 y1) (Location x2 y2) =
(x2 - x1) `mod` width + (y2 - y1) `mod` height

angle :: Map -> Location -> Location -> Double
angle (Map width height _) (Location x1 y1) (Location x2 y2) =
atan2 (fromIntegral $ foo dx width) (fromIntegral $ foo dy height)
where
dx = x2 - x1
dy = y2 - y1
foo a b
| a > b - a = a - b
| -a > b + a = a + b
| otherwise = a

moveToLocation :: Map -> Move -> Location
moveToLocation _ (Move location Still) = location
moveToLocation (Map width height _) (Move (Location x y) dir) = case dir of
North -> if y == 0
then Location x (height -1)
else Location x (y +1)
South -> if y == height -1
then Location x 0
else Location x (y -1)
West -> if x == 0
then Location (width -1) y
else Location (x +1) y
East -> if x == width -1
then Location 0 y
else Location (x +1) y

site :: Map -> Location -> Site
site (Map _ _ sites) (Location x y) = sites !! y !! x
75 changes: 75 additions & 0 deletions airesources/Haskell/lib/Halite/Networking.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
module Halite.Networking
( communicate
) where

import Halite.Types
import Data.List (zipWith4)
import System.Random (getStdGen)
import System.IO (hFlush, stdout)

communicate
:: Monad m
=> String
-> (ID -> Map -> m [Move])
-> (m [Move] -> a -> ([Move], a))
-> a
-> IO ()
communicate name algorithm runMonad input = do
(myID, gameMap) <- getInit
sendInit name
loop (algorithm myID) gameMap input runMonad

loop algorithm gameMap input runMonad = do
gameMap' <- getFrame gameMap
let (moves, input') = runMonad (algorithm gameMap') input
sendFrame moves
loop algorithm gameMap' input' runMonad

getInit :: IO (ID, Map)
getInit = do
userID <- read <$> getLine
[w, h] <- map read . words <$> getLine
prod <- map read . words <$> getLine
mapc <- parseMapContents (w, h) prod <$> getLine
return (userID, Map w h mapc)

sendInit :: String -> IO ()
sendInit s = putStrLn s >> hFlush stdout

getFrame :: Map -> IO Map
getFrame (Map w h cont) =
Map w h . parseMapContents (w, h) (getProds cont) <$> getLine

sendFrame' :: [Move] -> IO ()
sendFrame' = putStrLn . unwords . map showMove

sendFrame :: [Move] -> IO ()
sendFrame s = sendFrame' s >> hFlush stdout


parseMapContents :: (Int, Int) -> [Int] -> String -> [[Site]]
parseMapContents (w, h) productions s =
splitEvery w $ zipWith4 Site owners strengths productions locations
where
(owners', strengths) = splitMapContents (read <$> words s) (w * h)
owners = stretch owners'
stretch (a:b:bs) = replicate a b ++ stretch bs
stretch [] = []
xs = concat $ replicate h [0 .. w - 1]
ys = concatMap (replicate w) [0 .. h - 1]
locations = zipWith Location xs ys

splitMapContents :: [Int] -> Int -> ([Int], [Int])
splitMapContents xs area = splitAt (length xs - area) xs

splitEvery :: Int -> [a] -> [[a]]
splitEvery _ [] = []
splitEvery n xs = first : splitEvery n rest
where
(first, rest) = splitAt n xs

getProds :: [[Site]] -> [Int]
getProds = map siteProduction . concat

showMove :: Move -> String
showMove (Move (Location x y) d) = unwords $ map show [x, y, fromEnum d]
82 changes: 82 additions & 0 deletions airesources/Haskell/lib/Halite/Types.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{-# LANGUAGE DeriveFunctor #-}

module Halite.Types
( Direction(..)
, Location(..)
, Map(..)
, Site(..)
, Move(..)
, ID
, Effects(runEffects) -- you don't want to export constructor
, Test(runTest)
) where


import Control.Monad (ap)
import System.Random (StdGen, randomR)
import Halite.Classes

data Direction
= Still
| North
| East
| South
| West
deriving (Show, Eq, Ord, Enum)

data Location = Location
{ posX :: Int
, posY :: Int
} deriving (Show, Eq)

data Site = Site
{ siteOwner :: Int
, siteStrength :: Int
, siteProduction :: Int
, siteLocation :: Location
} deriving (Show, Eq)

data Move = Move
{ movelocation :: Location
, moveDirection :: Direction
} deriving (Show, Eq)

data Map = Map
{ mapWidth :: Int
, mapHeight :: Int
, mapContents :: [[Site]]
} deriving (Show, Eq)

type ID = Int

-- these two monads allow you to use side effects in your algorithm

data Effects a = Effects {runEffects :: StdGen -> (a, StdGen)}
deriving (Functor)

instance Applicative Effects where
pure x = Effects (\y -> (x, y))
(<*>) = ap

instance Monad Effects where
m >>= k = Effects $ \s ->
let (a, s') = runEffects m s
in runEffects (k a) s'

instance RandomReader Effects where
rand i = Effects $ randomR (0, i-1)

data Test a = Test {runTest :: [Int] -> (a, [Int])}
deriving (Functor)

instance Applicative Test where
pure x = Test (\y -> (x, y))
(<*>) = ap

instance Monad Test where
m >>= k = Test $ \s ->
let (a, s') = runTest m s
in runTest (k a) s'

instance RandomReader Test where
rand i = Test $ \(x:xs) -> (mod x i, xs)
3 changes: 3 additions & 0 deletions airesources/Haskell/runGame.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cabal configure
cabal build
.\halite.exe -d "30 30" "dist/build/MyBot/MyBot" "dist/build/RandomBot/RandomBot"
12 changes: 12 additions & 0 deletions airesources/Haskell/runGame.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

if hash stack 2>/dev/null; then
stack build
build="$(stack path --dist-dir)/build"
else
cabal configure
cabal build
build="./dist/build"
fi

./halite -d "30 30" "$build/MyBot/MyBot" "$build/RandomBot/RandomBot"
21 changes: 21 additions & 0 deletions airesources/Haskell/src/MyBot.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Main where

import System.Random (getStdGen)
import Halite

main :: IO ()
main = getStdGen >>= communicate name algorithm runEffects

name = "Awesome Haskell Bot"

algorithm :: RandomReader m => ID -> Map -> m [Move]
algorithm me g@(Map width height sites) =
randomMoves $ filter ((== me) . siteOwner) (concat sites)

randomMoves :: RandomReader m => [Site] -> m [Move]
randomMoves = traverse $ randMove . siteLocation
where
randMove location = do
direction <- toEnum <$> rand 5
return $ Move location direction

20 changes: 20 additions & 0 deletions airesources/Haskell/src/RandomBot.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module Main where

import System.Random (getStdGen)
import Halite

main :: IO ()
main = getStdGen >>= communicate name algorithm runEffects

name = "Random Haskell Bot"

algorithm :: RandomReader m => ID -> Map -> m [Move]
algorithm me g@(Map width height sites) =
randomMoves $ filter ((== me) . siteOwner) (concat sites)

randomMoves :: RandomReader m => [Site] -> m [Move]
randomMoves = traverse $ randMove . siteLocation
where
randMove location = do
direction <- toEnum <$> rand 5
return $ Move location direction
35 changes: 35 additions & 0 deletions airesources/Haskell/stack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# This file was automatically generated by stack init
# For more information, see: http://docs.haskellstack.org/en/stable/yaml_configuration/

# Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2)
resolver: lts-7.8

# Local packages, usually specified by relative directory name
packages:
- '.'
# Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3)
extra-deps: []

# Override default flag values for local packages and extra-deps
flags: {}

# Extra package databases containing global packages
extra-package-dbs: []

# Control whether we use the GHC we find on the path
# system-ghc: true

# Require a specific version of stack, using version ranges
# require-stack-version: -any # Default
# require-stack-version: >= 1.0.0

# Override the architecture used by stack, especially useful on Windows
# arch: i386
# arch: x86_64

# Extra directories used by stack for building
# extra-include-dirs: [/path/to/dir]
# extra-lib-dirs: [/path/to/dir]

# Allow a newer minor version of GHC than the snapshot specifies
# compiler-check: newer-minor
6 changes: 6 additions & 0 deletions website/advanced_game_server.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
<li>Python - .py</li>
<li>C++ - .cpp and .h(pp)</li>
<li>C# - .cs</li>
<li>Go - .go</li>
<li>Haskell - .hs</li>
<li>Rust - .toml (for your Cargo.toml) and .rs (for your Rust source)</li>
<li>Scala - .scala</li>
<li>Ruby - .rb</li>
Expand All @@ -55,6 +57,7 @@
<li>Java - javac 1.8.0_111</li>
<li>C++ - g++ 4.84</li>
<li>C# - mcs 4.6.1.0</li>
<li>Haskell - ghc 8.0.1</li>
<li>Rust - rustc 1.10.0</li>
<li>Scala - scalac 2.10.4</li>
</ul>
Expand All @@ -63,6 +66,7 @@
<p>
The following build automators are used:
<ul>
<li>Haskell - stack 1.2.0</li>
<li>Rust - cargo 0.11.0</li>
</ul>
</p>
Expand All @@ -74,6 +78,8 @@
<li>Python 3.4.3</li>
<li>C++ 11</li>
<li>C# 6.0</li>
<li>Go 1.6</li>
<li>Haskell 8.0.1</li>
<li>Rust 1.10</li>
<li>Scala 2.10.4</li>
<li>Ruby 2.3.1</li>
Expand Down
Loading