From a7a3dfbfc2a9dae3b779fbf3cee8000a36d7ab35 Mon Sep 17 00:00:00 2001 From: Jesse Paroz Date: Sat, 12 Nov 2016 21:15:14 +1000 Subject: [PATCH 01/22] Add skeleton for Haskell starter package runGame.bat is rather simplified compared to runGame.sh, mostly as I have no real knowledge of batch scripting, and no Windows machine on which to test. I don't think it should be too complicated to port for someone more knowledgeable though. --- airesources/Haskell/LICENSE | 30 +++++++++++++++++ airesources/Haskell/Setup.hs | 2 ++ airesources/Haskell/halite-haskell.cabal | 25 ++++++++++++++ airesources/Haskell/lib/Halite.hs | 1 + airesources/Haskell/lib/Halite/Networking.hs | 1 + airesources/Haskell/runGame.bat | 3 ++ airesources/Haskell/runGame.sh | 12 +++++++ airesources/Haskell/src/MyBot.hs | 3 ++ airesources/Haskell/src/RandomBot.hs | 3 ++ airesources/Haskell/stack.yaml | 35 ++++++++++++++++++++ 10 files changed, 115 insertions(+) create mode 100644 airesources/Haskell/LICENSE create mode 100644 airesources/Haskell/Setup.hs create mode 100644 airesources/Haskell/halite-haskell.cabal create mode 100644 airesources/Haskell/lib/Halite.hs create mode 100644 airesources/Haskell/lib/Halite/Networking.hs create mode 100644 airesources/Haskell/runGame.bat create mode 100755 airesources/Haskell/runGame.sh create mode 100644 airesources/Haskell/src/MyBot.hs create mode 100644 airesources/Haskell/src/RandomBot.hs create mode 100644 airesources/Haskell/stack.yaml diff --git a/airesources/Haskell/LICENSE b/airesources/Haskell/LICENSE new file mode 100644 index 000000000..3cd48fe71 --- /dev/null +++ b/airesources/Haskell/LICENSE @@ -0,0 +1,30 @@ +Copyright Jesse Paroz (c) 2016 + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Jesse Paroz nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/airesources/Haskell/Setup.hs b/airesources/Haskell/Setup.hs new file mode 100644 index 000000000..9a994af67 --- /dev/null +++ b/airesources/Haskell/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/airesources/Haskell/halite-haskell.cabal b/airesources/Haskell/halite-haskell.cabal new file mode 100644 index 000000000..09b20b37f --- /dev/null +++ b/airesources/Haskell/halite-haskell.cabal @@ -0,0 +1,25 @@ +name: halite-haskell +version: 0.1.0.0 +synopsis: Halite starter pack for Haskell +author: Jesse Paroz +maintainer: jesse.paroz@gmail.com +build-type: Simple +cabal-version: >=1.10 + +library + hs-source-dirs: lib + exposed-modules: Halite, Halite.Networking + default-language: Haskell2010 + build-depends: base >= 4.7 && < 5 + +executable MyBot + hs-source-dirs: src + main-is: MyBot.hs + default-language: Haskell2010 + build-depends: base >= 4.7 && < 5 + +executable RandomBot + hs-source-dirs: src + main-is: RandomBot.hs + default-language: Haskell2010 + build-depends: base >= 4.7 && < 5 diff --git a/airesources/Haskell/lib/Halite.hs b/airesources/Haskell/lib/Halite.hs new file mode 100644 index 000000000..96835ffab --- /dev/null +++ b/airesources/Haskell/lib/Halite.hs @@ -0,0 +1 @@ +module Halite where diff --git a/airesources/Haskell/lib/Halite/Networking.hs b/airesources/Haskell/lib/Halite/Networking.hs new file mode 100644 index 000000000..939b2cece --- /dev/null +++ b/airesources/Haskell/lib/Halite/Networking.hs @@ -0,0 +1 @@ +module Halite.Networking where diff --git a/airesources/Haskell/runGame.bat b/airesources/Haskell/runGame.bat new file mode 100644 index 000000000..d3df1b1ea --- /dev/null +++ b/airesources/Haskell/runGame.bat @@ -0,0 +1,3 @@ +cabal configure +cabal build +.\halite.exe -d "30 30" "dist/build/MyBot/MyBot" "dist/build/RandomBot/RandomBot" diff --git a/airesources/Haskell/runGame.sh b/airesources/Haskell/runGame.sh new file mode 100755 index 000000000..396e2aa8e --- /dev/null +++ b/airesources/Haskell/runGame.sh @@ -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" diff --git a/airesources/Haskell/src/MyBot.hs b/airesources/Haskell/src/MyBot.hs new file mode 100644 index 000000000..a4531e1a4 --- /dev/null +++ b/airesources/Haskell/src/MyBot.hs @@ -0,0 +1,3 @@ +module Main where + +main = putStrLn "hullo from MyBot" diff --git a/airesources/Haskell/src/RandomBot.hs b/airesources/Haskell/src/RandomBot.hs new file mode 100644 index 000000000..300cc63cf --- /dev/null +++ b/airesources/Haskell/src/RandomBot.hs @@ -0,0 +1,3 @@ +module Main where + +main = main diff --git a/airesources/Haskell/stack.yaml b/airesources/Haskell/stack.yaml new file mode 100644 index 000000000..7a275c54c --- /dev/null +++ b/airesources/Haskell/stack.yaml @@ -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 From ebe864417cb424fdd500870fb0f47cbc2a750711 Mon Sep 17 00:00:00 2001 From: Jesse Paroz Date: Sat, 12 Nov 2016 23:12:26 +1000 Subject: [PATCH 02/22] Haskell: Implement types and stub functions --- airesources/Haskell/halite-haskell.cabal | 2 +- airesources/Haskell/lib/Halite.hs | 3 ++ airesources/Haskell/lib/Halite/Networking.hs | 32 +++++++++++++++- airesources/Haskell/lib/Halite/Types.hs | 40 ++++++++++++++++++++ 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 airesources/Haskell/lib/Halite/Types.hs diff --git a/airesources/Haskell/halite-haskell.cabal b/airesources/Haskell/halite-haskell.cabal index 09b20b37f..6a865f605 100644 --- a/airesources/Haskell/halite-haskell.cabal +++ b/airesources/Haskell/halite-haskell.cabal @@ -8,7 +8,7 @@ cabal-version: >=1.10 library hs-source-dirs: lib - exposed-modules: Halite, Halite.Networking + exposed-modules: Halite, Halite.Networking, Halite.Types default-language: Haskell2010 build-depends: base >= 4.7 && < 5 diff --git a/airesources/Haskell/lib/Halite.hs b/airesources/Haskell/lib/Halite.hs index 96835ffab..ed601c1ed 100644 --- a/airesources/Haskell/lib/Halite.hs +++ b/airesources/Haskell/lib/Halite.hs @@ -1 +1,4 @@ module Halite where + +import Halite.Types +import Halite.Networking diff --git a/airesources/Haskell/lib/Halite/Networking.hs b/airesources/Haskell/lib/Halite/Networking.hs index 939b2cece..ebf331162 100644 --- a/airesources/Haskell/lib/Halite/Networking.hs +++ b/airesources/Haskell/lib/Halite/Networking.hs @@ -1 +1,31 @@ -module Halite.Networking where +module Halite.Networking + ( getInit + , sendInit + , getFrame + , sendMoves + ) where + +import Halite.Types + +getInit :: IO (ID, Map) +getInit = do + userID <- read <$> getLine + [w, h] <- map read . words <$> getLine + prod <- parseProductionMap (w, h) <$> getLine + mapc <- parseMapContents (w, h) prod <$> getLine + return (userID, Map w h mapc) + +sendInit :: String -> IO () +sendInit = undefined + +getFrame :: IO Map +getFrame = undefined + +sendMoves :: [Move] -> IO () +sendMoves = undefined + +parseProductionMap :: (Int, Int) -> String -> [[Int]] +parseProductionMap = undefined + +parseMapContents :: (Int, Int) -> [[Int]] -> String -> [[Site]] +parseMapContents = undefined diff --git a/airesources/Haskell/lib/Halite/Types.hs b/airesources/Haskell/lib/Halite/Types.hs new file mode 100644 index 000000000..d5492df47 --- /dev/null +++ b/airesources/Haskell/lib/Halite/Types.hs @@ -0,0 +1,40 @@ +module Halite.Types + ( Direction(..) + , Map(..) + , Location(..) + , Site(..) + , Move(..) + , ID + ) where + +data Direction + = Still + | North + | East + | South + | West + deriving (Show, Eq, Ord, Enum) + +data Location = Location + { locX :: Int + , locY :: Int + } deriving (Show, Eq) + +data Site = Site + { siteOwner :: Int + , siteStrength :: Int + , siteProduction :: Int + } 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 From 2f16d1f2203b8da997dc840b8016cb504f6525c4 Mon Sep 17 00:00:00 2001 From: Jesse Paroz Date: Sun, 13 Nov 2016 01:21:06 +1000 Subject: [PATCH 03/22] Implement rest of starter pack (untested!) --- airesources/Haskell/lib/Halite/Networking.hs | 42 +++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/airesources/Haskell/lib/Halite/Networking.hs b/airesources/Haskell/lib/Halite/Networking.hs index ebf331162..6d9a92b0d 100644 --- a/airesources/Haskell/lib/Halite/Networking.hs +++ b/airesources/Haskell/lib/Halite/Networking.hs @@ -2,7 +2,7 @@ module Halite.Networking ( getInit , sendInit , getFrame - , sendMoves + , sendFrame ) where import Halite.Types @@ -11,21 +11,41 @@ getInit :: IO (ID, Map) getInit = do userID <- read <$> getLine [w, h] <- map read . words <$> getLine - prod <- parseProductionMap (w, h) <$> getLine + prod <- map read . words <$> getLine mapc <- parseMapContents (w, h) prod <$> getLine return (userID, Map w h mapc) sendInit :: String -> IO () -sendInit = undefined +sendInit = putStrLn -getFrame :: IO Map -getFrame = undefined +getFrame :: Map -> IO Map +getFrame (Map w h cont) = + Map w h . parseMapContents (w, h) (getProds cont) <$> getLine -sendMoves :: [Move] -> IO () -sendMoves = undefined +sendFrame :: [Move] -> IO () +sendFrame = putStrLn . unwords . map showMove -parseProductionMap :: (Int, Int) -> String -> [[Int]] -parseProductionMap = undefined -parseMapContents :: (Int, Int) -> [[Int]] -> String -> [[Site]] -parseMapContents = undefined +parseMapContents :: (Int, Int) -> [Int] -> String -> [[Site]] +parseMapContents (w, h) pds s = splitEvery w $ zipWith3 Site ons sts pds + where + (owners, sts) = splitMapContents (read <$> words s) (w * h) + ons = stretch owners + stretch (x:y:ys) = replicate x y ++ stretch ys + stretch [] = [] + +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) = + show x ++ " " ++ show y ++ " " ++ show (fromEnum d) From 605683c5a470d8dbe3342bbf1319a9cb8c95cc34 Mon Sep 17 00:00:00 2001 From: Jesse Paroz Date: Sun, 13 Nov 2016 03:51:51 +1000 Subject: [PATCH 04/22] Complete Haskell starter package and examples --- airesources/Haskell/halite-haskell.cabal | 4 +++ airesources/Haskell/lib/Halite.hs | 5 +++- airesources/Haskell/lib/Halite/Networking.hs | 17 ++++++++---- airesources/Haskell/lib/Halite/Types.hs | 11 +++----- airesources/Haskell/src/MyBot.hs | 27 +++++++++++++++++++- airesources/Haskell/src/RandomBot.hs | 27 +++++++++++++++++++- 6 files changed, 76 insertions(+), 15 deletions(-) diff --git a/airesources/Haskell/halite-haskell.cabal b/airesources/Haskell/halite-haskell.cabal index 6a865f605..d970e681e 100644 --- a/airesources/Haskell/halite-haskell.cabal +++ b/airesources/Haskell/halite-haskell.cabal @@ -17,9 +17,13 @@ executable MyBot 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 diff --git a/airesources/Haskell/lib/Halite.hs b/airesources/Haskell/lib/Halite.hs index ed601c1ed..02655875d 100644 --- a/airesources/Haskell/lib/Halite.hs +++ b/airesources/Haskell/lib/Halite.hs @@ -1,4 +1,7 @@ -module Halite where +module Halite + ( module Halite.Types + , module Halite.Networking + ) where import Halite.Types import Halite.Networking diff --git a/airesources/Haskell/lib/Halite/Networking.hs b/airesources/Haskell/lib/Halite/Networking.hs index 6d9a92b0d..beb56e32e 100644 --- a/airesources/Haskell/lib/Halite/Networking.hs +++ b/airesources/Haskell/lib/Halite/Networking.hs @@ -6,6 +6,8 @@ module Halite.Networking ) where import Halite.Types +import Data.List (zipWith5) +import System.IO (hFlush, stdout) getInit :: IO (ID, Map) getInit = do @@ -16,23 +18,28 @@ getInit = do return (userID, Map w h mapc) sendInit :: String -> IO () -sendInit = putStrLn +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 = putStrLn . unwords . map showMove +sendFrame s = sendFrame' s >> hFlush stdout parseMapContents :: (Int, Int) -> [Int] -> String -> [[Site]] -parseMapContents (w, h) pds s = splitEvery w $ zipWith3 Site ons sts pds +parseMapContents (w, h) pds s = splitEvery w $ zipWith5 Site ons sts pds xs ys where (owners, sts) = splitMapContents (read <$> words s) (w * h) ons = stretch owners - stretch (x:y:ys) = replicate x y ++ stretch ys + stretch (a:b:bs) = replicate a b ++ stretch bs stretch [] = [] + xs = concat $ replicate h [0..w - 1] + ys = concatMap (replicate w) [0..h - 1] splitMapContents :: [Int] -> Int -> ([Int], [Int]) splitMapContents xs area = splitAt (length xs - area) xs @@ -47,5 +54,5 @@ getProds :: [[Site]] -> [Int] getProds = map siteProduction . concat showMove :: Move -> String -showMove (Move (Location x y) d) = +showMove (Move x y d) = show x ++ " " ++ show y ++ " " ++ show (fromEnum d) diff --git a/airesources/Haskell/lib/Halite/Types.hs b/airesources/Haskell/lib/Halite/Types.hs index d5492df47..9c1a2033c 100644 --- a/airesources/Haskell/lib/Halite/Types.hs +++ b/airesources/Haskell/lib/Halite/Types.hs @@ -1,7 +1,6 @@ module Halite.Types ( Direction(..) , Map(..) - , Location(..) , Site(..) , Move(..) , ID @@ -15,19 +14,17 @@ data Direction | West deriving (Show, Eq, Ord, Enum) -data Location = Location - { locX :: Int - , locY :: Int - } deriving (Show, Eq) - data Site = Site { siteOwner :: Int , siteStrength :: Int , siteProduction :: Int + , siteX :: Int + , siteY :: Int } deriving (Show, Eq) data Move = Move - { moveLocation :: Location + { moveX :: Int + , moveY :: Int , moveDirection :: Direction } deriving (Show, Eq) diff --git a/airesources/Haskell/src/MyBot.hs b/airesources/Haskell/src/MyBot.hs index a4531e1a4..5a48eaad5 100644 --- a/airesources/Haskell/src/MyBot.hs +++ b/airesources/Haskell/src/MyBot.hs @@ -1,3 +1,28 @@ module Main where -main = putStrLn "hullo from MyBot" +import Halite +import System.Random (randomRs, getStdGen, StdGen) + +main :: IO () +main = do + (myID, gameMap) <- getInit + sendInit "MyHaskellBot" + dirs <- randomDirections <$> getStdGen + loop myID gameMap dirs + +loop :: ID -> Map -> [Direction] -> IO () +loop myID gameMap dirs = do + gameMap' <- getFrame gameMap + let sites = concat $ mapContents gameMap' + moves = assignMoves myID sites dirs + dirs' = drop (length moves) dirs + sendFrame moves + loop myID gameMap' dirs' + +assignMoves :: ID -> [Site] -> [Direction] -> [Move] +assignMoves myID sites = zipWith3 Move (map siteX sites') (map siteY sites') + where + sites' = filter (\s -> siteOwner s == myID) sites + +randomDirections :: StdGen -> [Direction] +randomDirections g = toEnum <$> randomRs (0, 4) g diff --git a/airesources/Haskell/src/RandomBot.hs b/airesources/Haskell/src/RandomBot.hs index 300cc63cf..a76d0bd1e 100644 --- a/airesources/Haskell/src/RandomBot.hs +++ b/airesources/Haskell/src/RandomBot.hs @@ -1,3 +1,28 @@ module Main where -main = main +import Halite +import System.Random (randomRs, getStdGen, StdGen) + +main :: IO () +main = do + (myID, gameMap) <- getInit + sendInit "RandomHaskellBot" + dirs <- randomDirections <$> getStdGen + loop myID gameMap dirs + +loop :: ID -> Map -> [Direction] -> IO () +loop myID gameMap dirs = do + gameMap' <- getFrame gameMap + let sites = concat $ mapContents gameMap' + moves = assignMoves myID sites dirs + dirs' = drop (length moves) dirs + sendFrame moves + loop myID gameMap' dirs' + +assignMoves :: ID -> [Site] -> [Direction] -> [Move] +assignMoves myID sites = zipWith3 Move (map siteX sites') (map siteY sites') + where + sites' = filter (\s -> siteOwner s == myID) sites + +randomDirections :: StdGen -> [Direction] +randomDirections g = toEnum <$> randomRs (0, 4) g From a017346f3812ce7770366361030b93ae32d191e3 Mon Sep 17 00:00:00 2001 From: Jesse Paroz Date: Sun, 13 Nov 2016 03:57:28 +1000 Subject: [PATCH 05/22] Haskell: Remove erroneous LICENSE file --- airesources/Haskell/LICENSE | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 airesources/Haskell/LICENSE diff --git a/airesources/Haskell/LICENSE b/airesources/Haskell/LICENSE deleted file mode 100644 index 3cd48fe71..000000000 --- a/airesources/Haskell/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ -Copyright Jesse Paroz (c) 2016 - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of Jesse Paroz nor the names of other - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file From 15845d29b813dd0d95b35af321704da7fcbe2d60 Mon Sep 17 00:00:00 2001 From: Josef Vonasek Date: Mon, 14 Nov 2016 13:52:21 -0500 Subject: [PATCH 06/22] I have provided the src/ scripts with new interface, hopefuly more convenient for the user. --- .gitignore | 3 ++ airesources/Haskell/halite-haskell.cabal | 5 ++- airesources/Haskell/lib/Halite.hs | 8 ++-- airesources/Haskell/lib/Halite/Classes.hs | 12 ++++++ airesources/Haskell/lib/Halite/Networking.hs | 28 +++++++++++--- airesources/Haskell/lib/Halite/Types.hs | 33 +++++++++++++++-- airesources/Haskell/src/MyBot.hs | 39 ++++++++++---------- airesources/Haskell/src/RandomBot.hs | 39 ++++++++++---------- 8 files changed, 112 insertions(+), 55 deletions(-) create mode 100644 airesources/Haskell/lib/Halite/Classes.hs diff --git a/.gitignore b/.gitignore index 189a8098c..9680c76bf 100644 --- a/.gitignore +++ b/.gitignore @@ -372,3 +372,6 @@ google*.html screenlog.* *.dll + +node_modules +/dist diff --git a/airesources/Haskell/halite-haskell.cabal b/airesources/Haskell/halite-haskell.cabal index d970e681e..17743ff1b 100644 --- a/airesources/Haskell/halite-haskell.cabal +++ b/airesources/Haskell/halite-haskell.cabal @@ -2,15 +2,18 @@ name: halite-haskell version: 0.1.0.0 synopsis: Halite starter pack for Haskell author: Jesse Paroz + , Josef Vonasek maintainer: jesse.paroz@gmail.com + , j.f.vonasek@gmail.com build-type: Simple cabal-version: >=1.10 library hs-source-dirs: lib - exposed-modules: Halite, Halite.Networking, Halite.Types + exposed-modules: Halite, Halite.Networking, Halite.Types, Halite.Classes default-language: Haskell2010 build-depends: base >= 4.7 && < 5 + , random executable MyBot hs-source-dirs: src diff --git a/airesources/Haskell/lib/Halite.hs b/airesources/Haskell/lib/Halite.hs index 02655875d..4aa9ae102 100644 --- a/airesources/Haskell/lib/Halite.hs +++ b/airesources/Haskell/lib/Halite.hs @@ -1,7 +1,7 @@ module Halite - ( module Halite.Types - , module Halite.Networking + ( module M ) where -import Halite.Types -import Halite.Networking +import Halite.Networking as M +import Halite.Classes as M +import Halite.Types as M diff --git a/airesources/Haskell/lib/Halite/Classes.hs b/airesources/Haskell/lib/Halite/Classes.hs new file mode 100644 index 000000000..1ec68aebd --- /dev/null +++ b/airesources/Haskell/lib/Halite/Classes.hs @@ -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 diff --git a/airesources/Haskell/lib/Halite/Networking.hs b/airesources/Haskell/lib/Halite/Networking.hs index beb56e32e..faf619bd4 100644 --- a/airesources/Haskell/lib/Halite/Networking.hs +++ b/airesources/Haskell/lib/Halite/Networking.hs @@ -1,14 +1,29 @@ module Halite.Networking - ( getInit - , sendInit - , getFrame - , sendFrame + ( communicate ) where import Halite.Types import Data.List (zipWith5) +import System.Random (getStdGen) import System.IO (hFlush, stdout) +communicate + :: Monad m + => String + -> (ID -> Map -> m [Move]) + -> a -> (m [Move] -> a -> ([Move], a)) + -> IO () +communicate name algorithm input runMonad = 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 @@ -32,7 +47,7 @@ sendFrame s = sendFrame' s >> hFlush stdout parseMapContents :: (Int, Int) -> [Int] -> String -> [[Site]] -parseMapContents (w, h) pds s = splitEvery w $ zipWith5 Site ons sts pds xs ys +parseMapContents (w, h) pds s = splitEvery w $ zipWith5 Site ons sts pds locations where (owners, sts) = splitMapContents (read <$> words s) (w * h) ons = stretch owners @@ -40,6 +55,7 @@ parseMapContents (w, h) pds s = splitEvery w $ zipWith5 Site ons sts pds xs ys 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 @@ -54,5 +70,5 @@ getProds :: [[Site]] -> [Int] getProds = map siteProduction . concat showMove :: Move -> String -showMove (Move x y d) = +showMove (Move (Location x y) d) = show x ++ " " ++ show y ++ " " ++ show (fromEnum d) diff --git a/airesources/Haskell/lib/Halite/Types.hs b/airesources/Haskell/lib/Halite/Types.hs index 9c1a2033c..dca6313cd 100644 --- a/airesources/Haskell/lib/Halite/Types.hs +++ b/airesources/Haskell/lib/Halite/Types.hs @@ -1,11 +1,19 @@ +{-# LANGUAGE DeriveFunctor, DeriveAnyClass #-} + module Halite.Types ( Direction(..) + , Location(..) , Map(..) , Site(..) , Move(..) , ID + , Effects(runEffects) + , Test(runTest) ) where +import System.Random (StdGen, randomR) +import Halite.Classes + data Direction = Still | North @@ -14,17 +22,20 @@ data Direction | 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 - , siteX :: Int - , siteY :: Int + , siteLocation :: Location } deriving (Show, Eq) data Move = Move - { moveX :: Int - , moveY :: Int + { movelocation :: Location , moveDirection :: Direction } deriving (Show, Eq) @@ -35,3 +46,17 @@ data Map = Map } 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, Applicative, Monad) + +instance RandomReader Effects where + rand i = Effects $ randomR (0, i) + +data Test a = Test {runTest :: [Int] -> (a, [Int])} + deriving (Functor, Applicative, Monad) + +instance RandomReader Test where + rand i = Test $ \(x:xs) -> (mod x i, xs) diff --git a/airesources/Haskell/src/MyBot.hs b/airesources/Haskell/src/MyBot.hs index 5a48eaad5..feef45f65 100644 --- a/airesources/Haskell/src/MyBot.hs +++ b/airesources/Haskell/src/MyBot.hs @@ -1,28 +1,27 @@ module Main where +import System.Random (getStdGen) import Halite -import System.Random (randomRs, getStdGen, StdGen) main :: IO () -main = do - (myID, gameMap) <- getInit - sendInit "MyHaskellBot" - dirs <- randomDirections <$> getStdGen - loop myID gameMap dirs +main = communicate name algorithm runEffects <$> getStdGen -loop :: ID -> Map -> [Direction] -> IO () -loop myID gameMap dirs = do - gameMap' <- getFrame gameMap - let sites = concat $ mapContents gameMap' - moves = assignMoves myID sites dirs - dirs' = drop (length moves) dirs - sendFrame moves - loop myID gameMap' dirs' +name = "Awesome Haskell Bot" -assignMoves :: ID -> [Site] -> [Direction] -> [Move] -assignMoves myID sites = zipWith3 Move (map siteX sites') (map siteY sites') - where - sites' = filter (\s -> siteOwner s == myID) sites +algorithm :: RandomReader m => ID -> Map -> m [Move] +algorithm me g@(GameMap width height sites) = + randomMoves + [Location x y | x <- [1..width], y <- [1..height]] $ + fmap (isMy me) sites -randomDirections :: StdGen -> [Direction] -randomDirections g = toEnum <$> randomRs (0, 4) g +randomMoves :: RandomReader m => [Location] -> [Bool] -> m [Move] +randomMoves l = traverse randMove . filter' l + where + filter' :: [a] -> [Bool] -> [a] + filter' [] [] = [] + filter' (a:as) (True:bs) = a : filter' as bs + filter' (_:as) (False:bs) = filter' as bs + randMove :: RandomReader r => Location -> r Move + randMove location = do + direction <- toEnum <$> randR 5 + return $ Move location direction diff --git a/airesources/Haskell/src/RandomBot.hs b/airesources/Haskell/src/RandomBot.hs index a76d0bd1e..feef45f65 100644 --- a/airesources/Haskell/src/RandomBot.hs +++ b/airesources/Haskell/src/RandomBot.hs @@ -1,28 +1,27 @@ module Main where +import System.Random (getStdGen) import Halite -import System.Random (randomRs, getStdGen, StdGen) main :: IO () -main = do - (myID, gameMap) <- getInit - sendInit "RandomHaskellBot" - dirs <- randomDirections <$> getStdGen - loop myID gameMap dirs +main = communicate name algorithm runEffects <$> getStdGen -loop :: ID -> Map -> [Direction] -> IO () -loop myID gameMap dirs = do - gameMap' <- getFrame gameMap - let sites = concat $ mapContents gameMap' - moves = assignMoves myID sites dirs - dirs' = drop (length moves) dirs - sendFrame moves - loop myID gameMap' dirs' +name = "Awesome Haskell Bot" -assignMoves :: ID -> [Site] -> [Direction] -> [Move] -assignMoves myID sites = zipWith3 Move (map siteX sites') (map siteY sites') - where - sites' = filter (\s -> siteOwner s == myID) sites +algorithm :: RandomReader m => ID -> Map -> m [Move] +algorithm me g@(GameMap width height sites) = + randomMoves + [Location x y | x <- [1..width], y <- [1..height]] $ + fmap (isMy me) sites -randomDirections :: StdGen -> [Direction] -randomDirections g = toEnum <$> randomRs (0, 4) g +randomMoves :: RandomReader m => [Location] -> [Bool] -> m [Move] +randomMoves l = traverse randMove . filter' l + where + filter' :: [a] -> [Bool] -> [a] + filter' [] [] = [] + filter' (a:as) (True:bs) = a : filter' as bs + filter' (_:as) (False:bs) = filter' as bs + randMove :: RandomReader r => Location -> r Move + randMove location = do + direction <- toEnum <$> randR 5 + return $ Move location direction From 36a3dacc5b2219dabed0540fb98b454f72a2ed28 Mon Sep 17 00:00:00 2001 From: Jesse Paroz Date: Tue, 15 Nov 2016 13:45:23 +1000 Subject: [PATCH 07/22] Fix typos and simple copy-paste type errors --- airesources/Haskell/lib/Halite/Networking.hs | 4 ++-- airesources/Haskell/src/MyBot.hs | 13 +++++++++---- airesources/Haskell/src/RandomBot.hs | 13 +++++++++---- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/airesources/Haskell/lib/Halite/Networking.hs b/airesources/Haskell/lib/Halite/Networking.hs index faf619bd4..07685883e 100644 --- a/airesources/Haskell/lib/Halite/Networking.hs +++ b/airesources/Haskell/lib/Halite/Networking.hs @@ -3,7 +3,7 @@ module Halite.Networking ) where import Halite.Types -import Data.List (zipWith5) +import Data.List (zipWith4) import System.Random (getStdGen) import System.IO (hFlush, stdout) @@ -47,7 +47,7 @@ sendFrame s = sendFrame' s >> hFlush stdout parseMapContents :: (Int, Int) -> [Int] -> String -> [[Site]] -parseMapContents (w, h) pds s = splitEvery w $ zipWith5 Site ons sts pds locations +parseMapContents (w, h) pds s = splitEvery w $ zipWith4 Site ons sts pds locations where (owners, sts) = splitMapContents (read <$> words s) (w * h) ons = stretch owners diff --git a/airesources/Haskell/src/MyBot.hs b/airesources/Haskell/src/MyBot.hs index feef45f65..879349f38 100644 --- a/airesources/Haskell/src/MyBot.hs +++ b/airesources/Haskell/src/MyBot.hs @@ -4,15 +4,17 @@ import System.Random (getStdGen) import Halite main :: IO () -main = communicate name algorithm runEffects <$> getStdGen +main = do + input <- getStdGen + communicate name algorithm input runEffects name = "Awesome Haskell Bot" algorithm :: RandomReader m => ID -> Map -> m [Move] -algorithm me g@(GameMap width height sites) = +algorithm me (Map width height sites) = randomMoves [Location x y | x <- [1..width], y <- [1..height]] $ - fmap (isMy me) sites + fmap (ownedBy me) (concat sites) randomMoves :: RandomReader m => [Location] -> [Bool] -> m [Move] randomMoves l = traverse randMove . filter' l @@ -23,5 +25,8 @@ randomMoves l = traverse randMove . filter' l filter' (_:as) (False:bs) = filter' as bs randMove :: RandomReader r => Location -> r Move randMove location = do - direction <- toEnum <$> randR 5 + direction <- toEnum <$> rand 5 return $ Move location direction + +ownedBy :: ID -> Site -> Bool +ownedBy userID site = siteOwner site == userID diff --git a/airesources/Haskell/src/RandomBot.hs b/airesources/Haskell/src/RandomBot.hs index feef45f65..879349f38 100644 --- a/airesources/Haskell/src/RandomBot.hs +++ b/airesources/Haskell/src/RandomBot.hs @@ -4,15 +4,17 @@ import System.Random (getStdGen) import Halite main :: IO () -main = communicate name algorithm runEffects <$> getStdGen +main = do + input <- getStdGen + communicate name algorithm input runEffects name = "Awesome Haskell Bot" algorithm :: RandomReader m => ID -> Map -> m [Move] -algorithm me g@(GameMap width height sites) = +algorithm me (Map width height sites) = randomMoves [Location x y | x <- [1..width], y <- [1..height]] $ - fmap (isMy me) sites + fmap (ownedBy me) (concat sites) randomMoves :: RandomReader m => [Location] -> [Bool] -> m [Move] randomMoves l = traverse randMove . filter' l @@ -23,5 +25,8 @@ randomMoves l = traverse randMove . filter' l filter' (_:as) (False:bs) = filter' as bs randMove :: RandomReader r => Location -> r Move randMove location = do - direction <- toEnum <$> randR 5 + direction <- toEnum <$> rand 5 return $ Move location direction + +ownedBy :: ID -> Site -> Bool +ownedBy userID site = siteOwner site == userID From e66ad3dbef700abbc1478c9ecf27abd8b04809b4 Mon Sep 17 00:00:00 2001 From: Jesse Paroz Date: Tue, 15 Nov 2016 14:58:00 +1000 Subject: [PATCH 08/22] Added manual instances for Effects and Test --- airesources/Haskell/lib/Halite/Types.hs | 30 ++++++++++++++++++++----- airesources/Haskell/src/MyBot.hs | 2 +- airesources/Haskell/src/RandomBot.hs | 2 +- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/airesources/Haskell/lib/Halite/Types.hs b/airesources/Haskell/lib/Halite/Types.hs index dca6313cd..67a74ff67 100644 --- a/airesources/Haskell/lib/Halite/Types.hs +++ b/airesources/Haskell/lib/Halite/Types.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE DeriveFunctor, DeriveAnyClass #-} +{-# LANGUAGE DeriveFunctor #-} module Halite.Types ( Direction(..) @@ -7,10 +7,12 @@ module Halite.Types , Site(..) , Move(..) , ID - , Effects(runEffects) - , Test(runTest) + , Effects(..) + , Test(..) ) where + +import Control.Monad (ap) import System.Random (StdGen, randomR) import Halite.Classes @@ -50,13 +52,31 @@ 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, Applicative, Monad) + 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) data Test a = Test {runTest :: [Int] -> (a, [Int])} - deriving (Functor, Applicative, Monad) + 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) diff --git a/airesources/Haskell/src/MyBot.hs b/airesources/Haskell/src/MyBot.hs index 879349f38..0d3a5d3b9 100644 --- a/airesources/Haskell/src/MyBot.hs +++ b/airesources/Haskell/src/MyBot.hs @@ -25,7 +25,7 @@ randomMoves l = traverse randMove . filter' l filter' (_:as) (False:bs) = filter' as bs randMove :: RandomReader r => Location -> r Move randMove location = do - direction <- toEnum <$> rand 5 + direction <- toEnum <$> rand 4 return $ Move location direction ownedBy :: ID -> Site -> Bool diff --git a/airesources/Haskell/src/RandomBot.hs b/airesources/Haskell/src/RandomBot.hs index 879349f38..0d3a5d3b9 100644 --- a/airesources/Haskell/src/RandomBot.hs +++ b/airesources/Haskell/src/RandomBot.hs @@ -25,7 +25,7 @@ randomMoves l = traverse randMove . filter' l filter' (_:as) (False:bs) = filter' as bs randMove :: RandomReader r => Location -> r Move randMove location = do - direction <- toEnum <$> rand 5 + direction <- toEnum <$> rand 4 return $ Move location direction ownedBy :: ID -> Site -> Bool From 8518f87b7fdc3fa0fa98394d7599571ebe68f813 Mon Sep 17 00:00:00 2001 From: Jesse Paroz Date: Tue, 15 Nov 2016 15:02:50 +1000 Subject: [PATCH 09/22] Improve showMove definition --- airesources/Haskell/lib/Halite/Networking.hs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/airesources/Haskell/lib/Halite/Networking.hs b/airesources/Haskell/lib/Halite/Networking.hs index 07685883e..b9b3213d8 100644 --- a/airesources/Haskell/lib/Halite/Networking.hs +++ b/airesources/Haskell/lib/Halite/Networking.hs @@ -70,5 +70,4 @@ getProds :: [[Site]] -> [Int] getProds = map siteProduction . concat showMove :: Move -> String -showMove (Move (Location x y) d) = - show x ++ " " ++ show y ++ " " ++ show (fromEnum d) +showMove (Move (Location x y) d) = unwords $ map show [x, y, fromEnum d] From e9a9d96a31fd0a17af92348d0e7516260f1fcc33 Mon Sep 17 00:00:00 2001 From: Jesse Paroz Date: Tue, 15 Nov 2016 15:31:15 +1000 Subject: [PATCH 10/22] Fix bug, should start indexing from 0 Also renamed variables in parseMapContents to aid readability --- airesources/Haskell/lib/Halite/Networking.hs | 11 ++++++----- airesources/Haskell/src/MyBot.hs | 2 +- airesources/Haskell/src/RandomBot.hs | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/airesources/Haskell/lib/Halite/Networking.hs b/airesources/Haskell/lib/Halite/Networking.hs index b9b3213d8..418172f65 100644 --- a/airesources/Haskell/lib/Halite/Networking.hs +++ b/airesources/Haskell/lib/Halite/Networking.hs @@ -47,14 +47,15 @@ sendFrame s = sendFrame' s >> hFlush stdout parseMapContents :: (Int, Int) -> [Int] -> String -> [[Site]] -parseMapContents (w, h) pds s = splitEvery w $ zipWith4 Site ons sts pds locations +parseMapContents (w, h) productions s = + splitEvery w $ zipWith4 Site owners strengths productions locations where - (owners, sts) = splitMapContents (read <$> words s) (w * h) - ons = stretch owners + (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] + xs = concat $ replicate h [0 .. w - 1] + ys = concatMap (replicate w) [0 .. h - 1] locations = zipWith Location xs ys splitMapContents :: [Int] -> Int -> ([Int], [Int]) diff --git a/airesources/Haskell/src/MyBot.hs b/airesources/Haskell/src/MyBot.hs index 0d3a5d3b9..bc7c0d770 100644 --- a/airesources/Haskell/src/MyBot.hs +++ b/airesources/Haskell/src/MyBot.hs @@ -13,7 +13,7 @@ name = "Awesome Haskell Bot" algorithm :: RandomReader m => ID -> Map -> m [Move] algorithm me (Map width height sites) = randomMoves - [Location x y | x <- [1..width], y <- [1..height]] $ + [Location x y | x <- [0..width-1], y <- [0..height-1]] $ fmap (ownedBy me) (concat sites) randomMoves :: RandomReader m => [Location] -> [Bool] -> m [Move] diff --git a/airesources/Haskell/src/RandomBot.hs b/airesources/Haskell/src/RandomBot.hs index 0d3a5d3b9..bc7c0d770 100644 --- a/airesources/Haskell/src/RandomBot.hs +++ b/airesources/Haskell/src/RandomBot.hs @@ -13,7 +13,7 @@ name = "Awesome Haskell Bot" algorithm :: RandomReader m => ID -> Map -> m [Move] algorithm me (Map width height sites) = randomMoves - [Location x y | x <- [1..width], y <- [1..height]] $ + [Location x y | x <- [0..width-1], y <- [0..height-1]] $ fmap (ownedBy me) (concat sites) randomMoves :: RandomReader m => [Location] -> [Bool] -> m [Move] From bce63b1a254dd17e6f97e5c3cc38f6cd1eda300b Mon Sep 17 00:00:00 2001 From: Josef Vonasek Date: Tue, 15 Nov 2016 01:33:09 -0500 Subject: [PATCH 11/22] Fixed typecheck errors. --- airesources/Haskell/.gitignore | 1 + airesources/Haskell/lib/Halite/Networking.hs | 9 +++++---- airesources/Haskell/src/MyBot.hs | 19 ++++++------------- airesources/Haskell/src/RandomBot.hs | 19 ++++++------------- 4 files changed, 18 insertions(+), 30 deletions(-) create mode 100644 airesources/Haskell/.gitignore diff --git a/airesources/Haskell/.gitignore b/airesources/Haskell/.gitignore new file mode 100644 index 000000000..3a5b47571 --- /dev/null +++ b/airesources/Haskell/.gitignore @@ -0,0 +1 @@ +.stack-work/ diff --git a/airesources/Haskell/lib/Halite/Networking.hs b/airesources/Haskell/lib/Halite/Networking.hs index faf619bd4..8287cdb30 100644 --- a/airesources/Haskell/lib/Halite/Networking.hs +++ b/airesources/Haskell/lib/Halite/Networking.hs @@ -3,7 +3,7 @@ module Halite.Networking ) where import Halite.Types -import Data.List (zipWith5) +import Data.List (zipWith4) import System.Random (getStdGen) import System.IO (hFlush, stdout) @@ -11,9 +11,10 @@ communicate :: Monad m => String -> (ID -> Map -> m [Move]) - -> a -> (m [Move] -> a -> ([Move], a)) + -> (m [Move] -> a -> ([Move], a)) + -> a -> IO () -communicate name algorithm input runMonad = do +communicate name algorithm runMonad input = do (myID, gameMap) <- getInit sendInit name loop (algorithm myID) gameMap input runMonad @@ -47,7 +48,7 @@ sendFrame s = sendFrame' s >> hFlush stdout parseMapContents :: (Int, Int) -> [Int] -> String -> [[Site]] -parseMapContents (w, h) pds s = splitEvery w $ zipWith5 Site ons sts pds locations +parseMapContents (w, h) pds s = splitEvery w $ zipWith4 Site ons sts pds locations where (owners, sts) = splitMapContents (read <$> words s) (w * h) ons = stretch owners diff --git a/airesources/Haskell/src/MyBot.hs b/airesources/Haskell/src/MyBot.hs index feef45f65..534983b14 100644 --- a/airesources/Haskell/src/MyBot.hs +++ b/airesources/Haskell/src/MyBot.hs @@ -4,24 +4,17 @@ import System.Random (getStdGen) import Halite main :: IO () -main = communicate name algorithm runEffects <$> getStdGen +main = getStdGen >>= communicate name algorithm runEffects name = "Awesome Haskell Bot" algorithm :: RandomReader m => ID -> Map -> m [Move] -algorithm me g@(GameMap width height sites) = - randomMoves - [Location x y | x <- [1..width], y <- [1..height]] $ - fmap (isMy me) sites +algorithm me g@(Map width height sites) = + randomMoves $ filter ( \s -> siteOwner s == me ) (concat sites) -randomMoves :: RandomReader m => [Location] -> [Bool] -> m [Move] -randomMoves l = traverse randMove . filter' l +randomMoves :: RandomReader m => [Site] -> m [Move] +randomMoves = traverse $ randMove . siteLocation where - filter' :: [a] -> [Bool] -> [a] - filter' [] [] = [] - filter' (a:as) (True:bs) = a : filter' as bs - filter' (_:as) (False:bs) = filter' as bs - randMove :: RandomReader r => Location -> r Move randMove location = do - direction <- toEnum <$> randR 5 + direction <- toEnum <$> rand 5 return $ Move location direction diff --git a/airesources/Haskell/src/RandomBot.hs b/airesources/Haskell/src/RandomBot.hs index feef45f65..534983b14 100644 --- a/airesources/Haskell/src/RandomBot.hs +++ b/airesources/Haskell/src/RandomBot.hs @@ -4,24 +4,17 @@ import System.Random (getStdGen) import Halite main :: IO () -main = communicate name algorithm runEffects <$> getStdGen +main = getStdGen >>= communicate name algorithm runEffects name = "Awesome Haskell Bot" algorithm :: RandomReader m => ID -> Map -> m [Move] -algorithm me g@(GameMap width height sites) = - randomMoves - [Location x y | x <- [1..width], y <- [1..height]] $ - fmap (isMy me) sites +algorithm me g@(Map width height sites) = + randomMoves $ filter ( \s -> siteOwner s == me ) (concat sites) -randomMoves :: RandomReader m => [Location] -> [Bool] -> m [Move] -randomMoves l = traverse randMove . filter' l +randomMoves :: RandomReader m => [Site] -> m [Move] +randomMoves = traverse $ randMove . siteLocation where - filter' :: [a] -> [Bool] -> [a] - filter' [] [] = [] - filter' (a:as) (True:bs) = a : filter' as bs - filter' (_:as) (False:bs) = filter' as bs - randMove :: RandomReader r => Location -> r Move randMove location = do - direction <- toEnum <$> randR 5 + direction <- toEnum <$> rand 5 return $ Move location direction From 9327aa8c45c4bfa5c000b5d24aed96cb16d91125 Mon Sep 17 00:00:00 2001 From: Jesse Paroz Date: Tue, 15 Nov 2016 16:32:08 +1000 Subject: [PATCH 12/22] Fix incorrectly generating locations in algorithm A list comprehension generates almost the right list, but in the wrong order. The way the list was used, the order must correspond to the order of Bools in the second list, or else you end up with nonsense moves, sending requests for unowned sites to move. I changed it to use the more precise method used in the library function, but probably a neater way to do things would be to simply filter the list of sites based on owner, then map `siteLocation` over the resulting list. --- airesources/Haskell/src/MyBot.hs | 6 +++++- airesources/Haskell/src/RandomBot.hs | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/airesources/Haskell/src/MyBot.hs b/airesources/Haskell/src/MyBot.hs index bc7c0d770..7a4db05f8 100644 --- a/airesources/Haskell/src/MyBot.hs +++ b/airesources/Haskell/src/MyBot.hs @@ -13,8 +13,12 @@ name = "Awesome Haskell Bot" algorithm :: RandomReader m => ID -> Map -> m [Move] algorithm me (Map width height sites) = randomMoves - [Location x y | x <- [0..width-1], y <- [0..height-1]] $ + locations $ fmap (ownedBy me) (concat sites) + where + xs = concat $ replicate height [0 .. width - 1] + ys = concatMap (replicate width) [0 .. height - 1] + locations = zipWith Location xs ys randomMoves :: RandomReader m => [Location] -> [Bool] -> m [Move] randomMoves l = traverse randMove . filter' l diff --git a/airesources/Haskell/src/RandomBot.hs b/airesources/Haskell/src/RandomBot.hs index bc7c0d770..7a4db05f8 100644 --- a/airesources/Haskell/src/RandomBot.hs +++ b/airesources/Haskell/src/RandomBot.hs @@ -13,8 +13,12 @@ name = "Awesome Haskell Bot" algorithm :: RandomReader m => ID -> Map -> m [Move] algorithm me (Map width height sites) = randomMoves - [Location x y | x <- [0..width-1], y <- [0..height-1]] $ + locations $ fmap (ownedBy me) (concat sites) + where + xs = concat $ replicate height [0 .. width - 1] + ys = concatMap (replicate width) [0 .. height - 1] + locations = zipWith Location xs ys randomMoves :: RandomReader m => [Location] -> [Bool] -> m [Move] randomMoves l = traverse randMove . filter' l From bdd1480ee6acf78970475880f9059f2e48e9f9d7 Mon Sep 17 00:00:00 2001 From: Josef Vonasek Date: Wed, 16 Nov 2016 05:03:13 -0500 Subject: [PATCH 13/22] Few tweaks. --- airesources/Haskell/.gitignore | 2 ++ airesources/Haskell/lib/Halite/Networking.hs | 14 ++++----- airesources/Haskell/lib/Halite/Types.hs | 30 ++++++++++++++++---- airesources/Haskell/src/MyBot.hs | 2 +- airesources/Haskell/src/RandomBot.hs | 4 +-- 5 files changed, 37 insertions(+), 15 deletions(-) diff --git a/airesources/Haskell/.gitignore b/airesources/Haskell/.gitignore index 3a5b47571..24047bee7 100644 --- a/airesources/Haskell/.gitignore +++ b/airesources/Haskell/.gitignore @@ -1 +1,3 @@ .stack-work/ +halite.exe +halite diff --git a/airesources/Haskell/lib/Halite/Networking.hs b/airesources/Haskell/lib/Halite/Networking.hs index 8287cdb30..6e409896d 100644 --- a/airesources/Haskell/lib/Halite/Networking.hs +++ b/airesources/Haskell/lib/Halite/Networking.hs @@ -48,14 +48,15 @@ sendFrame s = sendFrame' s >> hFlush stdout parseMapContents :: (Int, Int) -> [Int] -> String -> [[Site]] -parseMapContents (w, h) pds s = splitEvery w $ zipWith4 Site ons sts pds locations +parseMapContents (w, h) productions s = + splitEvery w $ zipWith4 Site owners strengths productions locations where - (owners, sts) = splitMapContents (read <$> words s) (w * h) - ons = stretch owners + (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] + xs = concat $ replicate h [0 .. w - 1] + ys = concatMap (replicate w) [0 .. h - 1] locations = zipWith Location xs ys splitMapContents :: [Int] -> Int -> ([Int], [Int]) @@ -71,5 +72,4 @@ getProds :: [[Site]] -> [Int] getProds = map siteProduction . concat showMove :: Move -> String -showMove (Move (Location x y) d) = - show x ++ " " ++ show y ++ " " ++ show (fromEnum d) +showMove (Move (Location x y) d) = unwords $ map show [x, y, fromEnum d] diff --git a/airesources/Haskell/lib/Halite/Types.hs b/airesources/Haskell/lib/Halite/Types.hs index dca6313cd..b4cf10224 100644 --- a/airesources/Haskell/lib/Halite/Types.hs +++ b/airesources/Haskell/lib/Halite/Types.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE DeriveFunctor, DeriveAnyClass #-} +{-# LANGUAGE DeriveFunctor #-} module Halite.Types ( Direction(..) @@ -7,10 +7,12 @@ module Halite.Types , Site(..) , Move(..) , ID - , Effects(runEffects) + , Effects(runEffects) -- you don't want to export constructor , Test(runTest) ) where + +import Control.Monad (ap) import System.Random (StdGen, randomR) import Halite.Classes @@ -50,13 +52,31 @@ 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, Applicative, Monad) + 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) + rand i = Effects $ randomR (0, i-1) data Test a = Test {runTest :: [Int] -> (a, [Int])} - deriving (Functor, Applicative, Monad) + 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) diff --git a/airesources/Haskell/src/MyBot.hs b/airesources/Haskell/src/MyBot.hs index 534983b14..035661b8e 100644 --- a/airesources/Haskell/src/MyBot.hs +++ b/airesources/Haskell/src/MyBot.hs @@ -10,7 +10,7 @@ name = "Awesome Haskell Bot" algorithm :: RandomReader m => ID -> Map -> m [Move] algorithm me g@(Map width height sites) = - randomMoves $ filter ( \s -> siteOwner s == me ) (concat sites) + randomMoves $ filter ((== me) . siteOwner) (concat sites) randomMoves :: RandomReader m => [Site] -> m [Move] randomMoves = traverse $ randMove . siteLocation diff --git a/airesources/Haskell/src/RandomBot.hs b/airesources/Haskell/src/RandomBot.hs index 534983b14..ddb2546ca 100644 --- a/airesources/Haskell/src/RandomBot.hs +++ b/airesources/Haskell/src/RandomBot.hs @@ -6,11 +6,11 @@ import Halite main :: IO () main = getStdGen >>= communicate name algorithm runEffects -name = "Awesome Haskell Bot" +name = "Random Haskell Bot" algorithm :: RandomReader m => ID -> Map -> m [Move] algorithm me g@(Map width height sites) = - randomMoves $ filter ( \s -> siteOwner s == me ) (concat sites) + randomMoves $ filter ((== me) . siteOwner) (concat sites) randomMoves :: RandomReader m => [Site] -> m [Move] randomMoves = traverse $ randMove . siteLocation From fa8a99db83b4966112a42e74604ad85230431f5c Mon Sep 17 00:00:00 2001 From: Josef Vonasek Date: Wed, 16 Nov 2016 05:05:34 -0500 Subject: [PATCH 14/22] New module Halite.Logic --- airesources/Haskell/halite-haskell.cabal | 2 +- airesources/Haskell/lib/Halite.hs | 1 + airesources/Haskell/lib/Halite/Logic.hs | 47 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 airesources/Haskell/lib/Halite/Logic.hs diff --git a/airesources/Haskell/halite-haskell.cabal b/airesources/Haskell/halite-haskell.cabal index 17743ff1b..6bf201a6f 100644 --- a/airesources/Haskell/halite-haskell.cabal +++ b/airesources/Haskell/halite-haskell.cabal @@ -10,7 +10,7 @@ cabal-version: >=1.10 library hs-source-dirs: lib - exposed-modules: Halite, Halite.Networking, Halite.Types, Halite.Classes + exposed-modules: Halite, Halite.Networking, Halite.Types, Halite.Classes, Halite.Logic default-language: Haskell2010 build-depends: base >= 4.7 && < 5 , random diff --git a/airesources/Haskell/lib/Halite.hs b/airesources/Haskell/lib/Halite.hs index 4aa9ae102..8259c46e9 100644 --- a/airesources/Haskell/lib/Halite.hs +++ b/airesources/Haskell/lib/Halite.hs @@ -5,3 +5,4 @@ module Halite import Halite.Networking as M import Halite.Classes as M import Halite.Types as M +import Halite.Logic as M diff --git a/airesources/Haskell/lib/Halite/Logic.hs b/airesources/Haskell/lib/Halite/Logic.hs new file mode 100644 index 000000000..9346df261 --- /dev/null +++ b/airesources/Haskell/lib/Halite/Logic.hs @@ -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 From 2771e19d9c9f902e137dc16f5723ce1c1c3ec1bc Mon Sep 17 00:00:00 2001 From: Josef Vonasek Date: Wed, 16 Nov 2016 07:10:22 -0500 Subject: [PATCH 15/22] Resolved conflicts. --- airesources/Haskell/src/MyBot.hs | 3 +++ airesources/Haskell/src/RandomBot.hs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/airesources/Haskell/src/MyBot.hs b/airesources/Haskell/src/MyBot.hs index 035661b8e..73465149a 100644 --- a/airesources/Haskell/src/MyBot.hs +++ b/airesources/Haskell/src/MyBot.hs @@ -18,3 +18,6 @@ randomMoves = traverse $ randMove . siteLocation randMove location = do direction <- toEnum <$> rand 5 return $ Move location direction + +ownedBy :: ID -> Site -> Bool +ownedBy userID site = siteOwner site == userID diff --git a/airesources/Haskell/src/RandomBot.hs b/airesources/Haskell/src/RandomBot.hs index ddb2546ca..6937f260b 100644 --- a/airesources/Haskell/src/RandomBot.hs +++ b/airesources/Haskell/src/RandomBot.hs @@ -18,3 +18,6 @@ randomMoves = traverse $ randMove . siteLocation randMove location = do direction <- toEnum <$> rand 5 return $ Move location direction + +ownedBy :: ID -> Site -> Bool +ownedBy userID site = siteOwner site == userID From 9d9a4f2a9f87cf88795f64ff128eb6074c7d805c Mon Sep 17 00:00:00 2001 From: Michael Truell Date: Sat, 19 Nov 2016 12:05:36 -0500 Subject: [PATCH 16/22] Add ghc to sandbox --- worker/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/worker/Dockerfile b/worker/Dockerfile index d2e2b2bfc..3fe35283a 100644 --- a/worker/Dockerfile +++ b/worker/Dockerfile @@ -8,12 +8,16 @@ RUN apt-get install -y curl RUN apt-get install -y libstdc++6 RUN apt-get install -y gcc RUN apt-get install -y g++ + RUN apt-get install -y python3 python3-pip python3-dev python3-numpy + RUN curl -sSf https://static.rust-lang.org/rustup.sh | sh + RUN apt-get install -y python-software-properties RUN apt-get install -y software-properties-common RUN apt-get install -y openjdk-8-jdk + RUN apt-get install -y scala RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF @@ -25,3 +29,5 @@ RUN apt-get install -y ruby RUN gem install bundler RUN apt-get install -y golang + +RUN apt-get install -y ghc From 022fda8bac00e511fab7d43a99b7aba80eb143d9 Mon Sep 17 00:00:00 2001 From: Michael Truell Date: Sat, 19 Nov 2016 12:17:12 -0500 Subject: [PATCH 17/22] Add stack to sandbox --- worker/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worker/Dockerfile b/worker/Dockerfile index 3fe35283a..9720aaf81 100644 --- a/worker/Dockerfile +++ b/worker/Dockerfile @@ -30,4 +30,5 @@ RUN gem install bundler RUN apt-get install -y golang -RUN apt-get install -y ghc +RUN curl -sSL https://get.haskellstack.org/ | sh +RUN stack setup From 63ea5a2e9347d1a297adf27ee71a2bb446b05dd8 Mon Sep 17 00:00:00 2001 From: Michael Truell Date: Sat, 19 Nov 2016 12:24:24 -0500 Subject: [PATCH 18/22] Stack debugging --- worker/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/worker/Dockerfile b/worker/Dockerfile index 9720aaf81..3aa4ac262 100644 --- a/worker/Dockerfile +++ b/worker/Dockerfile @@ -31,4 +31,6 @@ RUN gem install bundler RUN apt-get install -y golang RUN curl -sSL https://get.haskellstack.org/ | sh +RUN stack update +RUN stack upgrade RUN stack setup From 12f69b06ac545ff9f5c8d4e8c6f4d4de2eb39011 Mon Sep 17 00:00:00 2001 From: Michael Truell Date: Sat, 19 Nov 2016 12:27:41 -0500 Subject: [PATCH 19/22] Add to website --- website/advanced_game_server.php | 8 ++++++-- website/archiveStarterPackages.sh | 4 +++- website/downloads.php | 3 ++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/website/advanced_game_server.php b/website/advanced_game_server.php index 2d5ddd42f..275ac101f 100644 --- a/website/advanced_game_server.php +++ b/website/advanced_game_server.php @@ -39,10 +39,11 @@
  • Python - .py
  • C++ - .cpp and .h(pp)
  • C# - .cs
  • +
  • Go - .go
  • +
  • Haskell - .hs
  • Rust - .toml (for your Cargo.toml) and .rs (for your Rust source)
  • Scala - .scala
  • Ruby - .rb
  • -
  • Go - .go
  • @@ -52,6 +53,7 @@
  • Java - javac 1.8.0_111
  • C++ - g++ 4.84
  • C# - mcs 4.6.1.0
  • +
  • Haskell - ghc 8.0.1
  • Rust - rustc 1.10.0
  • Scala - scalac 2.10.4
  • @@ -60,6 +62,7 @@

    The following build automators are used:

      +
    • Haskell - stack 1.2.0
    • Rust - cargo 0.11.0

    @@ -71,10 +74,11 @@
  • Python 3.4.3
  • C++ 11
  • C# 6.0
  • +
  • Go 1.6
  • +
  • Haskell 8.0.1
  • Rust 1.10
  • Scala 2.10.4
  • Ruby 2.3.1
  • -
  • Go 1.6
  • diff --git a/website/archiveStarterPackages.sh b/website/archiveStarterPackages.sh index 624bf5461..daa383956 100755 --- a/website/archiveStarterPackages.sh +++ b/website/archiveStarterPackages.sh @@ -4,7 +4,7 @@ cd ../airesources/ rm -r *-Starter-Package -mkdir Halite-Python-Starter-Package Halite-Java-Starter-Package Halite-C++-Starter-Package Halite-Rust-Starter-Package Halite-C#-Starter-Package Halite-Scala-Starter-Package Halite-Ruby-Starter-Package Halite-Go-Starter-Package +mkdir Halite-Python-Starter-Package Halite-Java-Starter-Package Halite-C++-Starter-Package Halite-Rust-Starter-Package Halite-C#-Starter-Package Halite-Scala-Starter-Package Halite-Ruby-Starter-Package Halite-Go-Starter-Package Halite-Haskell-Starter-Package cp -r Python/* Halite-Python-Starter-Package/ cp -r Java/* Halite-Java-Starter-Package/ @@ -14,6 +14,7 @@ cp -r Java/* Halite-Scala-Starter-Package/ cp -r CSharp/* Halite-C#-Starter-Package/ cp -r Ruby/* Halite-Ruby-Starter-Package/ cp -r Go/* Halite-Go-Starter-Package/ +cp -r Haskell/* Halite-Haskell-Starter-Package/ cp -r Scala/* Halite-Scala-Starter-Package/ rm Halite-Scala-Starter-Package/MyBot.java @@ -26,6 +27,7 @@ zip -r Halite-C#-Starter-Package.zip Halite-C#-Starter-Package/ zip -r Halite-Scala-Starter-Package.zip Halite-Scala-Starter-Package/ zip -r Halite-Ruby-Starter-Package.zip Halite-Ruby-Starter-Package/ zip -r Halite-Go-Starter-Package.zip Halite-Go-Starter-Package/ +zip -r Halite-Haskell-Starter-Package.zip Halite-Haskell-Starter-Package/ mkdir -p ../website/downloads/starterpackages mv *.zip ../website/downloads/starterpackages diff --git a/website/downloads.php b/website/downloads.php index b92d80982..e472d09fc 100644 --- a/website/downloads.php +++ b/website/downloads.php @@ -27,10 +27,11 @@

    Community Packages

    From 75866a52b6b629a879ef34d66cc3f4e62b2922fe Mon Sep 17 00:00:00 2001 From: Michael Truell Date: Mon, 21 Nov 2016 19:20:59 -0500 Subject: [PATCH 20/22] Add cabal --- worker/Dockerfile | 14 ++++++++++++++ worker/compiler.py | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/worker/Dockerfile b/worker/Dockerfile index 1ebd43ad0..759e1fba2 100644 --- a/worker/Dockerfile +++ b/worker/Dockerfile @@ -37,3 +37,17 @@ RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - RUN apt-get install -y nodejs RUN apt-get install -y ocaml + +RUN echo 'deb http://ppa.launchpad.net/hvr/ghc/ubuntu trusty main' > /etc/apt/sources.list.d/ghc.list && \ + echo 'deb http://download.fpcomplete.com/debian/jessie stable main'| tee /etc/apt/sources.list.d/fpco.list && \ + # hvr keys + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F6F88286 && \ + # fpco keys + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C5705533DA4F78D8664B5DC0575159689BEFB442 && \ + apt-get update && \ + apt-get install -y --no-install-recommends cabal-install-1.24 ghc-8.0.1 happy-1.19.5 alex-3.1.7 \ + stack zlib1g-dev libtinfo-dev libsqlite3-0 libsqlite3-dev ca-certificates g++ git && \ + rm -rf /var/lib/apt/lists/* + +ENV PATH /root/.cabal/bin:/root/.local/bin:/opt/cabal/1.24/bin:/opt/ghc/8.0.1/bin:/opt/happy/1.19.5/bin:/opt/alex/3.1.7/bin:$PATH + diff --git a/worker/compiler.py b/worker/compiler.py index c4291abc3..75a1acbdb 100644 --- a/worker/compiler.py +++ b/worker/compiler.py @@ -254,7 +254,7 @@ def compile(self, bot_dir, globs, errors, timelimit): "D" : [["dmd", "-O", "-inline", "-release", "-noboundscheck", "-of" + BOT]], "Groovy" : [["groovyc"], ["jar", "cfe", BOT + ".jar", BOT]], - "Haskell" : [["ghc", "--make", BOT + ".hs", "-O", "-v0"]], + "Haskell" : [["cabal", "configure"], ["cabal", "build"]], "Java" : [["javac", "-encoding", "UTF-8", "-J-Xmx%sm" % (MEMORY_LIMIT)]], "Lisp" : [['sbcl', '--dynamic-space-size', str(MEMORY_LIMIT), '--script', BOT + '.lisp']], "OCaml" : [["ocamlbuild -lib unix", BOT + ".native"]], @@ -342,7 +342,7 @@ def compile(self, bot_dir, globs, errors, timelimit): [(["*.groovy"], ExternalCompiler(comp_args["Groovy"][0])), (["*.class"], ExternalCompiler(comp_args["Groovy"][1]))] ), - Language("Haskell", BOT, "MyBot.hs", + Language("Haskell", "src/"+BOT, "src/MyBot.hs", "./MyBot +RTS -M" + str(MEMORY_LIMIT) + "m", [BOT], [([""], ExternalCompiler(comp_args["Haskell"][0]))] From e5c35d37b1d01c64fbdf5c2aa4e3902bd7cecc55 Mon Sep 17 00:00:00 2001 From: Josef Date: Thu, 24 Nov 2016 02:09:20 -0500 Subject: [PATCH 21/22] Deleted two useless lines. --- airesources/Haskell/src/MyBot.hs | 2 -- 1 file changed, 2 deletions(-) diff --git a/airesources/Haskell/src/MyBot.hs b/airesources/Haskell/src/MyBot.hs index 73465149a..18819a812 100644 --- a/airesources/Haskell/src/MyBot.hs +++ b/airesources/Haskell/src/MyBot.hs @@ -19,5 +19,3 @@ randomMoves = traverse $ randMove . siteLocation direction <- toEnum <$> rand 5 return $ Move location direction -ownedBy :: ID -> Site -> Bool -ownedBy userID site = siteOwner site == userID From 1c9200b5aca4187e87a80d2505c782786ee87f81 Mon Sep 17 00:00:00 2001 From: Josef Date: Thu, 24 Nov 2016 02:10:21 -0500 Subject: [PATCH 22/22] Deleted two useless lines. --- airesources/Haskell/src/RandomBot.hs | 3 --- 1 file changed, 3 deletions(-) diff --git a/airesources/Haskell/src/RandomBot.hs b/airesources/Haskell/src/RandomBot.hs index 6937f260b..ddb2546ca 100644 --- a/airesources/Haskell/src/RandomBot.hs +++ b/airesources/Haskell/src/RandomBot.hs @@ -18,6 +18,3 @@ randomMoves = traverse $ randMove . siteLocation randMove location = do direction <- toEnum <$> rand 5 return $ Move location direction - -ownedBy :: ID -> Site -> Bool -ownedBy userID site = siteOwner site == userID