seperate haskell und purescript directories
This commit is contained in:
11
purescript/code_royal/.gitignore
vendored
Normal file
11
purescript/code_royal/.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/bower_components/
|
||||
/node_modules/
|
||||
/.pulp-cache/
|
||||
/output/
|
||||
/generated-docs/
|
||||
/.psc-package/
|
||||
/.psc*
|
||||
/.purs*
|
||||
/.psa*
|
||||
/.spago
|
||||
/index.js
|
||||
28
purescript/code_royal/.vscode/tasks.json
vendored
Normal file
28
purescript/code_royal/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build_purescript",
|
||||
"type": "shell",
|
||||
"command": "spago bundle-app && uglifyjs index.js --mangle --output index.min.js",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"focus": true,
|
||||
"reveal": "silent"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "build_purescript_old",
|
||||
"type": "shell",
|
||||
"command": "spago bundle-app && uglifyjs index.js --compress --mangle --output index.js",
|
||||
"group": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
1
purescript/code_royal/index.min.js
vendored
Normal file
1
purescript/code_royal/index.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
128
purescript/code_royal/packages.dhall
Normal file
128
purescript/code_royal/packages.dhall
Normal file
@@ -0,0 +1,128 @@
|
||||
{-
|
||||
Welcome to your new Dhall package-set!
|
||||
|
||||
Below are instructions for how to edit this file for most use
|
||||
cases, so that you don't need to know Dhall to use it.
|
||||
|
||||
## Warning: Don't Move This Top-Level Comment!
|
||||
|
||||
Due to how `dhall format` currently works, this comment's
|
||||
instructions cannot appear near corresponding sections below
|
||||
because `dhall format` will delete the comment. However,
|
||||
it will not delete a top-level comment like this one.
|
||||
|
||||
## Use Cases
|
||||
|
||||
Most will want to do one or both of these options:
|
||||
1. Override/Patch a package's dependency
|
||||
2. Add a package not already in the default package set
|
||||
|
||||
This file will continue to work whether you use one or both options.
|
||||
Instructions for each option are explained below.
|
||||
|
||||
### Overriding/Patching a package
|
||||
|
||||
Purpose:
|
||||
- Change a package's dependency to a newer/older release than the
|
||||
default package set's release
|
||||
- Use your own modified version of some dependency that may
|
||||
include new API, changed API, removed API by
|
||||
using your custom git repo of the library rather than
|
||||
the package set's repo
|
||||
|
||||
Syntax:
|
||||
Replace the overrides' "{=}" (an empty record) with the following idea
|
||||
The "//" or "⫽" means "merge these two records and
|
||||
when they have the same value, use the one on the right:"
|
||||
-------------------------------
|
||||
let overrides =
|
||||
{ packageName =
|
||||
upstream.packageName // { updateEntity1 = "new value", updateEntity2 = "new value" }
|
||||
, packageName =
|
||||
upstream.packageName // { version = "v4.0.0" }
|
||||
, packageName =
|
||||
upstream.packageName // { repo = "https://www.example.com/path/to/new/repo.git" }
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let overrides =
|
||||
{ halogen =
|
||||
upstream.halogen // { version = "master" }
|
||||
, halogen-vdom =
|
||||
upstream.halogen-vdom // { version = "v4.0.0" }
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
### Additions
|
||||
|
||||
Purpose:
|
||||
- Add packages that aren't already included in the default package set
|
||||
|
||||
Syntax:
|
||||
Replace the additions' "{=}" (an empty record) with the following idea:
|
||||
-------------------------------
|
||||
let additions =
|
||||
{ package-name =
|
||||
{ dependencies =
|
||||
[ "dependency1"
|
||||
, "dependency2"
|
||||
]
|
||||
, repo =
|
||||
"https://example.com/path/to/git/repo.git"
|
||||
, version =
|
||||
"tag ('v4.0.0') or branch ('master')"
|
||||
}
|
||||
, package-name =
|
||||
{ dependencies =
|
||||
[ "dependency1"
|
||||
, "dependency2"
|
||||
]
|
||||
, repo =
|
||||
"https://example.com/path/to/git/repo.git"
|
||||
, version =
|
||||
"tag ('v4.0.0') or branch ('master')"
|
||||
}
|
||||
, etc.
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let additions =
|
||||
{ benchotron =
|
||||
{ dependencies =
|
||||
[ "arrays"
|
||||
, "exists"
|
||||
, "profunctor"
|
||||
, "strings"
|
||||
, "quickcheck"
|
||||
, "lcg"
|
||||
, "transformers"
|
||||
, "foldable-traversable"
|
||||
, "exceptions"
|
||||
, "node-fs"
|
||||
, "node-buffer"
|
||||
, "node-readline"
|
||||
, "datetime"
|
||||
, "now"
|
||||
]
|
||||
, repo =
|
||||
"https://github.com/hdgarrood/purescript-benchotron.git"
|
||||
, version =
|
||||
"v7.0.0"
|
||||
}
|
||||
}
|
||||
-------------------------------
|
||||
-}
|
||||
|
||||
|
||||
let upstream =
|
||||
https://github.com/purescript/package-sets/releases/download/psc-0.13.6-20200404/packages.dhall sha256:f239f2e215d0cbd5c203307701748581938f74c4c78f4aeffa32c11c131ef7b6
|
||||
|
||||
let overrides = {=}
|
||||
|
||||
let additions = {=}
|
||||
|
||||
in upstream // overrides // additions
|
||||
17
purescript/code_royal/spago.dhall
Normal file
17
purescript/code_royal/spago.dhall
Normal file
@@ -0,0 +1,17 @@
|
||||
{-
|
||||
Welcome to a Spago project!
|
||||
You can edit this file as you like.
|
||||
-}
|
||||
{ name = "code_royal"
|
||||
, dependencies =
|
||||
[ "arrays"
|
||||
, "console"
|
||||
, "effect"
|
||||
, "integers"
|
||||
, "js-date"
|
||||
, "math"
|
||||
, "ordered-collections"
|
||||
]
|
||||
, packages = ./packages.dhall
|
||||
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
|
||||
}
|
||||
46
purescript/code_royal/src/Helpers.purs
Normal file
46
purescript/code_royal/src/Helpers.purs
Normal file
@@ -0,0 +1,46 @@
|
||||
module Lib where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Int (fromNumber, pow, toNumber)
|
||||
import Data.Maybe (Maybe(..), fromJust)
|
||||
import Math as M
|
||||
import Partial.Unsafe (unsafePartial)
|
||||
import Range (Area(..), Pos(..), Range(..))
|
||||
|
||||
maxPos :: Pos -> Int
|
||||
maxPos (Pos x y) = max x y
|
||||
|
||||
minPos :: Pos -> Int
|
||||
minPos (Pos x y) = min x y
|
||||
|
||||
getMiddlePos :: Area -> Pos
|
||||
getMiddlePos (Area (Range x1 x2) (Range y1 y2)) = Pos x y
|
||||
where
|
||||
x = abs (x1 + x2) / 2
|
||||
y = abs (y1 + y2) / 2
|
||||
|
||||
abs :: Int -> Int
|
||||
abs x = unsafePartial $ fromJust $ fromNumber $ M.abs $ toNumber x
|
||||
|
||||
sqrt :: Int -> Int
|
||||
sqrt x = unsafePartial $ fromJust $ fromNumber $ M.floor $ M.sqrt $ toNumber x
|
||||
|
||||
dist :: forall a b. { x :: Int, y :: Int | a } -> { x :: Int, y :: Int | b } -> Int
|
||||
dist p1 p2 = sqrt $ a2 + b2
|
||||
where
|
||||
a2 = abs (p2.x - p1.x) `pow` 2
|
||||
b2 = abs (p2.y - p1.y) `pow` 2
|
||||
|
||||
toPos :: forall e. { x :: Int, y :: Int | e } -> Pos
|
||||
toPos p = Pos p.x p.y
|
||||
|
||||
-- addNode :: forall k. Ord k => G.Graph k k -> k -> G.Graph k k
|
||||
-- addNode g v = G.insertVertex v v g
|
||||
-- infixl 5 addNode as <+>
|
||||
--
|
||||
-- addEdge :: forall k v. Ord k => Maybe (G.Graph k v) -> Array k -> Maybe (G.Graph k v)
|
||||
-- addEdge (Just g) [a,b] = case G.insertEdge a b g of
|
||||
-- Just g' -> Just g'
|
||||
-- Nothing -> Just g
|
||||
-- addEdge _ _ = Nothing
|
||||
346
purescript/code_royal/src/Main.purs
Normal file
346
purescript/code_royal/src/Main.purs
Normal file
@@ -0,0 +1,346 @@
|
||||
module Main where
|
||||
|
||||
-- mines only on side
|
||||
-- build giants
|
||||
-- Pattern match filed wei keine eigenes gebaeude
|
||||
-- letzte Mine wird nciht aufgelevelt?
|
||||
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.State (State, gets, modify_, runState)
|
||||
import Control.MonadZero (empty, guard)
|
||||
import Data.Array (any, concatMap, filter, foldl, head, length, sort, sortBy, (..))
|
||||
import Data.Maybe (Maybe(..), fromJust)
|
||||
import Data.Tuple (fst, snd)
|
||||
import Effect (Effect)
|
||||
import Effect.Console (error, log)
|
||||
import GameInput (Minion, Site, SiteInfo, ProtoSite, parseInitInput, parseInput)
|
||||
import Graph as G
|
||||
import Lib (dist)
|
||||
import Partial.Unsafe (unsafePartial)
|
||||
|
||||
type GameState =
|
||||
{ gold :: Int
|
||||
, numSites :: Int
|
||||
, touchedSite :: Int
|
||||
, sites :: Array Site
|
||||
, units :: Array Minion
|
||||
, leftSide :: Boolean
|
||||
}
|
||||
|
||||
main :: Effect Unit
|
||||
main = do
|
||||
initInput <- parseInitInput
|
||||
--error $ show $ concatMap nodeConnections nodes
|
||||
nextRound initInput.numSites initInput.sites Nothing G.empty
|
||||
where
|
||||
-- graph :: G.Graph String
|
||||
-- graph = unsafePartial $ fromJust $ foldl G.addNode graph' [ ["[1,1]", "[2,2]"], ["[3,4]", "[4,4]"], ["[2,2]", "[4,4]"] ]
|
||||
graph' = foldl G.addNode G.empty sNodes
|
||||
sNodes :: Array String
|
||||
sNodes = map (\n -> show n) nodes
|
||||
nodes = do
|
||||
x <- (1..4)
|
||||
y <- (1..4)
|
||||
pure $ [x, y]
|
||||
nodeConnections :: Array Int -> Array (Array String)
|
||||
nodeConnections [x, y] = [ [o, show [x-1,y]], [o, show [x+1,y]], [o, show [x,y-1]], [o, show [x,y+1]] ]
|
||||
where o = show [x, y]
|
||||
nodeConnections _ = []
|
||||
|
||||
nextRound :: Int -> Array SiteInfo -> Maybe GameState -> G.Graph String -> Effect Unit
|
||||
nextRound numSites siteInfo gameState graph = do
|
||||
input <- parseInput numSites
|
||||
-- error $ show $ G.shortestPath "[4,4]" "[1,1]" graph
|
||||
|
||||
-- do we start on the left side of the map?
|
||||
let leftSide' = case gameState of
|
||||
Just gs -> gs.leftSide
|
||||
Nothing -> (queen input.units).x < 500
|
||||
|
||||
let gameState' =
|
||||
{ gold: input.gold
|
||||
, numSites
|
||||
, touchedSite: input.touchedSite
|
||||
, sites: combinedSites input.sites
|
||||
, units: input.units
|
||||
, leftSide: leftSide'
|
||||
}
|
||||
|
||||
let res = runState loop gameState'
|
||||
let state = snd res
|
||||
let val = fst res
|
||||
log $ val
|
||||
nextRound state.numSites (toSiteInfo <$> state.sites) (Just state) graph
|
||||
|
||||
where
|
||||
-- combine sites with siteInfo and old state
|
||||
combinedSites :: Array ProtoSite -> Array Site
|
||||
combinedSites sites = do
|
||||
protoS <- sites
|
||||
infoS <- siteInfo
|
||||
guard $ protoS.id == infoS.id
|
||||
let prevSite = case gameState of
|
||||
Just gs -> head $ filter (\s -> s.id == infoS.id) gs.sites
|
||||
Nothing -> Nothing
|
||||
let lvl = case prevSite of
|
||||
Just pSite -> if protoS.owner /= 0
|
||||
then 0 -- reset level of all buildings, which are not (any longer) ours
|
||||
else pSite.lvl
|
||||
Nothing -> 0
|
||||
pure { id: protoS.id
|
||||
, gold: protoS.gold
|
||||
, maxMineSize: protoS.maxMineSize
|
||||
, structureType: protoS.structureType
|
||||
, owner: protoS.owner
|
||||
, param1: protoS.param1
|
||||
, param2: protoS.param2
|
||||
, x: infoS.x
|
||||
, y: infoS.y
|
||||
, radius: infoS.radius
|
||||
, lvl
|
||||
}
|
||||
|
||||
loop :: State GameState String
|
||||
loop = do
|
||||
ba <- buildAll
|
||||
ta <- trainAll
|
||||
pure $ ba <> "\n" <> ta
|
||||
|
||||
buildAll :: State GameState String
|
||||
buildAll = do
|
||||
sites <- gets _.sites
|
||||
let buildingsCnt = length $ friendlySites sites
|
||||
let noTowerBuildingsCnt = length $ filter (not isTower) $ friendlySites sites
|
||||
let mines = length $ maxLvlFriendlyMines sites
|
||||
if mines < 4 -- TODO: letzte Mine muss auch ganz ausgebaut werden
|
||||
then buildMines
|
||||
else if noTowerBuildingsCnt < 5
|
||||
then buildBarracks
|
||||
else if buildingsCnt < 8 || (minTowerRange sites) < 300
|
||||
then if buildingsCnt < 8 then buildTowers
|
||||
else refreshTowers
|
||||
else if noTowerBuildingsCnt < 6
|
||||
then buildBarracks
|
||||
else refreshTowers
|
||||
where
|
||||
minTowerRange sites = case head $ sort $ map (\t -> t.param2) $ filter (isTower) $ friendlySites sites of
|
||||
Just t -> t
|
||||
Nothing -> 0
|
||||
|
||||
buildBarracks :: State GameState String
|
||||
buildBarracks = do
|
||||
sites <- gets _.sites
|
||||
units <- gets _.units
|
||||
case head $ nearFreeSites (queen units) sites of
|
||||
Just site -> do
|
||||
let typ = --if not $ hasArcherBarrack sites then 1
|
||||
if not $ hasKnightsBarrack sites then 0
|
||||
else 2
|
||||
pure $ build site typ
|
||||
Nothing -> refreshTowers
|
||||
|
||||
buildTowers :: State GameState String
|
||||
buildTowers = do
|
||||
leftSide <- gets _.leftSide
|
||||
units <- gets _.units
|
||||
sites <- gets _.sites
|
||||
case head $ nearFreeSites (queen units) sites of
|
||||
Just site -> pure $ "BUILD " <> show site.id <> " TOWER"
|
||||
Nothing -> refreshTowers
|
||||
|
||||
refreshTowers :: State GameState String
|
||||
refreshTowers = do
|
||||
towers <-friendlyTowersByAttraction
|
||||
case head towers of
|
||||
Just site -> do
|
||||
touched <- gets _.touchedSite
|
||||
if touched == -1 || touched /= site.id
|
||||
then pure unit
|
||||
else modify_ (\s -> s { sites = map (incLvl site.id) s.sites })
|
||||
pure $ "BUILD " <> show site.id <> " TOWER"
|
||||
Nothing -> avoid
|
||||
where
|
||||
incLvl :: Int -> Site -> Site
|
||||
incLvl sId site
|
||||
| sId == site.id = site { lvl = site.lvl + 1 }
|
||||
| otherwise = site
|
||||
|
||||
|
||||
buildMines :: State GameState String
|
||||
buildMines = do
|
||||
units <- gets _.units
|
||||
sites <- gets _.sites
|
||||
leftSide <- gets _.leftSide
|
||||
case head $ nearNonEmptyMines (queen units) sites of
|
||||
Just site -> do
|
||||
touched <- gets _.touchedSite
|
||||
if touched == -1 || touched /= site.id
|
||||
then pure unit
|
||||
else modify_ (\s -> s { sites = map (incMineLvl site.id) s.sites })
|
||||
pure $ "BUILD " <> show site.id <> " MINE"
|
||||
Nothing -> avoid
|
||||
where
|
||||
incMineLvl :: Int -> Site -> Site
|
||||
incMineLvl sId site
|
||||
| sId == site.id = site { lvl = site.lvl + 1 }
|
||||
| otherwise = site
|
||||
|
||||
avoid :: State GameState String
|
||||
avoid = do
|
||||
sites <- gets _.sites
|
||||
nEnemy <- nearestEnemy
|
||||
case nEnemy of
|
||||
Just enemy -> do
|
||||
let site = unsafePartial $ fromJust $ head $
|
||||
sortBy (\s1 s2 -> compare (dist enemy s2) (dist enemy s1)) (friendlySites sites)
|
||||
pure $ moveToPos site
|
||||
Nothing -> pure $ "MOVE 0 0"
|
||||
|
||||
-- nearest non-queen enemy
|
||||
nearestEnemy :: State GameState (Maybe Minion)
|
||||
nearestEnemy = do
|
||||
units <- gets _.units
|
||||
pure $ head $ filter (\u -> isEnemy u) units
|
||||
|
||||
trainAll :: State GameState String
|
||||
trainAll = do
|
||||
gold <- gets _.gold
|
||||
sites <- gets _.sites
|
||||
units <- gets _.units
|
||||
|
||||
let ownGiants = filter isGiant $ ownMinions units
|
||||
let trainGiants = length (enemyTowers sites) > 2 && length ownGiants < 3
|
||||
let barrack = if not trainGiants
|
||||
then knightBarracks sites
|
||||
else if gold > 140 then
|
||||
--knightBarracks sites
|
||||
|
||||
-- if length ownArchers < 4 && length (enemyKnights units) /= 0
|
||||
-- then archerBarrack sites
|
||||
giantBarrack sites
|
||||
else []
|
||||
pure $ foldl siteToIds "TRAIN" barrack
|
||||
where
|
||||
siteToIds acc site = acc <> " " <> show site.id
|
||||
knightBarrack sites = case head $ knightBarracks sites of
|
||||
Just barrack -> [barrack]
|
||||
Nothing -> []
|
||||
archerBarrack sites = case head $ archerBarracks sites of
|
||||
Just barrack -> [barrack]
|
||||
Nothing -> []
|
||||
giantBarrack sites = case head $ giantBarracks sites of
|
||||
Just barrack -> [barrack]
|
||||
Nothing -> knightBarracks sites
|
||||
|
||||
build :: forall e. { id :: Int | e } -> Int -> String
|
||||
build s typ = "BUILD " <> show s.id <> " BARRACKS-" <> t
|
||||
where t | typ == 0 = "KNIGHT"
|
||||
| typ == 1 = "ARCHER"
|
||||
| otherwise = "GIANT"
|
||||
|
||||
queen :: Array Minion -> Minion
|
||||
queen units = unsafePartial $ fromJust $ head $ filter (\u -> u.unitType == -1 && u.owner == 0) units
|
||||
|
||||
enemyQueen :: Array Minion -> Minion
|
||||
enemyQueen units = unsafePartial $ fromJust $ head $ filter (\u -> u.unitType == -1 && u.owner == 1) units
|
||||
|
||||
ownMinions :: Array Minion -> Array Minion
|
||||
ownMinions = filter isOwn
|
||||
|
||||
enemyKnights :: Array Minion -> Array Minion
|
||||
enemyKnights = filter isEnemy <<< filter isKnight
|
||||
|
||||
freeSites :: Array Site -> Array Site
|
||||
freeSites = filter (\s -> s.owner == -1)
|
||||
|
||||
friendlySites :: Array Site -> Array Site
|
||||
friendlySites = filter (\s -> s.owner == 0)
|
||||
|
||||
friendlyMines :: Array Site -> Array Site
|
||||
friendlyMines sites = filter (\s -> s.structureType == 0) $ friendlySites sites
|
||||
|
||||
maxLvlFriendlyMines :: Array Site -> Array Site
|
||||
maxLvlFriendlyMines sites = filter (\s -> s.lvl >= s.maxMineSize) $ friendlyMines sites
|
||||
|
||||
enemyTowers :: Array Site -> Array Site
|
||||
enemyTowers = filter isEnemy <<< filter isTower
|
||||
|
||||
friendlyTowers :: Array Site -> Array Site
|
||||
friendlyTowers = filter isOwn <<< filter isTower
|
||||
|
||||
friendlyTowersByLvl :: Array Site -> Array Site
|
||||
friendlyTowersByLvl sites = sortBy (\s1 s2 -> compare s1.lvl s2.lvl) (friendlyTowers sites)
|
||||
|
||||
-- TODO: Queen should use state -> easier
|
||||
-- less distant towers and towers with less hp are preferred
|
||||
friendlyTowersByAttraction :: State GameState (Array Site)
|
||||
friendlyTowersByAttraction = do
|
||||
sites <- gets _.sites
|
||||
units <- gets _.units
|
||||
let q = queen units
|
||||
pure $ sortBy (\t1 t2 -> compare (attraction t1 q) (attraction t2 q)) (friendlyTowers sites)
|
||||
where attraction t q = t.param1 + dist t q
|
||||
|
||||
nearSites :: forall a. { x :: Int, y :: Int | a } -> Array Site -> Array Site
|
||||
nearSites minion sites = sortBy (compareSiteDist minion) sites
|
||||
|
||||
nearFreeSites :: forall a. { x :: Int, y :: Int | a } -> Array Site -> Array Site
|
||||
nearFreeSites minion sites = sortBy (compareSiteDist minion) (freeSites sites)
|
||||
|
||||
nearNonEmptyMines :: forall x. { x :: Int, y :: Int | x } -> Array Site -> Array Site
|
||||
nearNonEmptyMines minion sites = filter (\s -> (s.gold > 20 || s.gold == -1) && s.lvl < 3 && s.owner /= 1) $ nearSites minion sites
|
||||
|
||||
hasKnightsBarrack :: Array Site -> Boolean
|
||||
hasKnightsBarrack sites = any (\s -> s.param2 == 0) (friendlySites sites)
|
||||
|
||||
hasArcherBarrack :: Array Site -> Boolean
|
||||
hasArcherBarrack sites = any (\s -> s.param2 == 1) (friendlySites sites)
|
||||
|
||||
hasGiantsBarrack :: Array Site -> Boolean
|
||||
hasGiantsBarrack sites = any (\s -> s.param2 == 2) (friendlySites sites)
|
||||
|
||||
knightBarracks :: Array Site -> Array Site
|
||||
knightBarracks sites = filter (\s -> s.param2 == 0) (friendlySites sites)
|
||||
|
||||
archerBarracks :: Array Site -> Array Site
|
||||
archerBarracks sites = filter (\s -> s.param2 == 1) (friendlySites sites)
|
||||
|
||||
giantBarracks :: Array Site -> Array Site
|
||||
giantBarracks sites = filter (\s -> s.param2 == 2) (friendlySites sites)
|
||||
|
||||
toSiteInfo :: Site -> SiteInfo
|
||||
toSiteInfo s = { id: s.id, x: s.x, y: s.y, radius: s.radius }
|
||||
|
||||
compareSiteDist :: forall x. { x :: Int, y :: Int | x } -> Site -> Site -> Ordering
|
||||
compareSiteDist u s1 s2 = compare (dist s1 u) (dist s2 u)
|
||||
|
||||
corner :: Boolean -> { x :: Int, y :: Int }
|
||||
corner leftSide = if leftSide then { x: 0, y: 0 } else { x: 1920, y: 1000 }
|
||||
|
||||
isOwn :: forall a. { owner :: Int | a } -> Boolean
|
||||
isOwn = owner 0
|
||||
|
||||
isEnemy :: forall a. { owner :: Int | a } -> Boolean
|
||||
isEnemy = owner 1
|
||||
|
||||
owner :: Int -> forall a. { owner :: Int | a } -> Boolean
|
||||
owner oId r = r.owner == oId
|
||||
|
||||
isKnight :: Minion -> Boolean
|
||||
isKnight minion = minion.unitType == 0
|
||||
|
||||
isArcher :: Minion -> Boolean
|
||||
isArcher minion = minion.unitType == 1
|
||||
|
||||
isGiant :: Minion -> Boolean
|
||||
isGiant minion = minion.unitType == 2
|
||||
|
||||
isTower :: forall a. { structureType :: Int | a } -> Boolean
|
||||
isTower s = s.structureType == 1
|
||||
|
||||
barracks :: Array Site -> Array Site
|
||||
barracks sites = filter (\b -> b.structureType == 2) sites
|
||||
|
||||
moveToPos :: forall e. { x :: Int, y :: Int | e } -> String
|
||||
moveToPos p = "MOVE " <> show p.x <> " " <> show p.y
|
||||
26
purescript/code_royal/src/Ruler.purs
Normal file
26
purescript/code_royal/src/Ruler.purs
Normal file
@@ -0,0 +1,26 @@
|
||||
module Range
|
||||
( Area(..)
|
||||
, Pos(..)
|
||||
, Range(..)
|
||||
, range
|
||||
) where
|
||||
|
||||
import Prelude
|
||||
|
||||
-- data Building = Building Int Int
|
||||
data Pos = Pos Int Int
|
||||
data Area = Area Range Range
|
||||
|
||||
instance showPos :: Show Pos where
|
||||
show (Pos x y) = show x <> " " <> show y
|
||||
|
||||
instance showRange :: Show Range where
|
||||
show (Range x y) = show x <> "-" <> show y
|
||||
|
||||
instance showArea :: Show Area where
|
||||
show (Area r1 r2) = show r1 <> " / " <> show r2
|
||||
|
||||
data Range = Range Int Int
|
||||
|
||||
range :: Int -> Int -> Range
|
||||
range x y = Range (min x y) (max x y)
|
||||
77
purescript/code_royal/src/ffi/GameInput.js
Normal file
77
purescript/code_royal/src/ffi/GameInput.js
Normal file
@@ -0,0 +1,77 @@
|
||||
"use strict";
|
||||
|
||||
exports.readline = readline
|
||||
|
||||
exports.parseInitInput = function() {
|
||||
var sites = []
|
||||
var numSites = parseInt(readline());
|
||||
for (var i = 0; i < numSites; i++) {
|
||||
var inputs = readline().split(' ');
|
||||
var siteId = parseInt(inputs[0]);
|
||||
var x = parseInt(inputs[1]);
|
||||
var y = parseInt(inputs[2]);
|
||||
var radius = parseInt(inputs[3]);
|
||||
sites.push({
|
||||
id: siteId,
|
||||
x: x,
|
||||
y: y,
|
||||
radius: radius,
|
||||
})
|
||||
}
|
||||
return {
|
||||
numSites: numSites,
|
||||
sites: sites,
|
||||
}
|
||||
};
|
||||
|
||||
exports.parseInput = function(numSites) {
|
||||
return function() {
|
||||
var inputs = readline().split(' ');
|
||||
var gold = parseInt(inputs[0]);
|
||||
var touchedSite = parseInt(inputs[1]); // -1 if none
|
||||
var sites = []
|
||||
for (var i = 0; i < numSites; i++) {
|
||||
var inputs = readline().split(' ');
|
||||
var siteId = parseInt(inputs[0]);
|
||||
var mineGold = parseInt(inputs[1]); // The total number of gold remaining to be mined from this site (-1 if unknown)
|
||||
var maxMineSize = parseInt(inputs[2]); // The maximum rate that a mine can extract gold from this site (-1 if unknown)
|
||||
var structureType = parseInt(inputs[3]); // -1 = No structure, 2 = Barracks
|
||||
var owner = parseInt(inputs[4]); // -1 = No structure, 0 = Friendly, 1 = Enemy
|
||||
var param1 = parseInt(inputs[5]);
|
||||
var param2 = parseInt(inputs[6]);
|
||||
sites.push({
|
||||
id: siteId,
|
||||
gold: mineGold,
|
||||
maxMineSize: maxMineSize,
|
||||
structureType: structureType,
|
||||
owner: owner,
|
||||
param1: param1,
|
||||
param2: param2,
|
||||
})
|
||||
}
|
||||
var numUnits = parseInt(readline());
|
||||
var units = []
|
||||
for (var i = 0; i < numUnits; i++) {
|
||||
var inputs = readline().split(' ');
|
||||
var x = parseInt(inputs[0]);
|
||||
var y = parseInt(inputs[1]);
|
||||
var owner = parseInt(inputs[2]);
|
||||
var unitType = parseInt(inputs[3]); // -1 = QUEEN, 0 = KNIGHT, 1 = ARCHER
|
||||
var health = parseInt(inputs[4]);
|
||||
units.push({
|
||||
x: x,
|
||||
y: y,
|
||||
owner: owner,
|
||||
unitType: unitType,
|
||||
health: health
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
gold: gold,
|
||||
touchedSite: touchedSite,
|
||||
sites: sites,
|
||||
units: units
|
||||
}
|
||||
}
|
||||
};
|
||||
60
purescript/code_royal/src/ffi/GameInput.purs
Normal file
60
purescript/code_royal/src/ffi/GameInput.purs
Normal file
@@ -0,0 +1,60 @@
|
||||
module GameInput where
|
||||
|
||||
import Effect (Effect)
|
||||
|
||||
type GameInitInput =
|
||||
{ numSites :: Int
|
||||
, sites :: Array SiteInfo
|
||||
}
|
||||
|
||||
type GameInput =
|
||||
{ gold :: Int
|
||||
, touchedSite :: Int -- -1 if none
|
||||
, sites :: Array ProtoSite
|
||||
, units :: Array Minion
|
||||
}
|
||||
|
||||
type SiteInfo =
|
||||
{ id :: Int
|
||||
, x :: Int
|
||||
, y :: Int
|
||||
, radius :: Int
|
||||
}
|
||||
|
||||
type ProtoSite =
|
||||
{ id :: Int
|
||||
, gold :: Int
|
||||
, maxMineSize :: Int
|
||||
, structureType :: Int
|
||||
, owner :: Int
|
||||
, param1 :: Int
|
||||
, param2 :: Int
|
||||
}
|
||||
|
||||
type Site =
|
||||
{ id :: Int
|
||||
, x :: Int
|
||||
, y :: Int
|
||||
, radius :: Int
|
||||
, gold :: Int -- The total number of gold remaining to be mined from this site (-1 if unknown)
|
||||
, maxMineSize :: Int -- The maximum rate that a mine can extract gold from this site (-1 if unknown)
|
||||
, structureType :: Int -- -1 No structure, 0 Goldmine, 1 Tower, 2 Barracks
|
||||
, owner :: Int -- -1 No structure, 0 friendly, 1 enemy
|
||||
, param1 :: Int -- -1 No structure, else turns till training
|
||||
, param2 :: Int -- -1 No structure, barracks: 0 knight 1 archer 2 giant
|
||||
, lvl :: Int -- -1 whatever, otherwise curr. mine/tower lvl
|
||||
}
|
||||
|
||||
type Minion =
|
||||
{ x :: Int
|
||||
, y :: Int
|
||||
, owner :: Int -- 0 = Friendly; 1 = Enemy
|
||||
, unitType :: Int -- -1 = QUEEN, 0 = KNIGHT, 1 = ARCHER, 2 = GIANT
|
||||
, health :: Int
|
||||
}
|
||||
|
||||
foreign import parseInitInput :: Effect GameInitInput
|
||||
|
||||
foreign import parseInput :: Int -> Effect GameInput
|
||||
|
||||
foreign import readline :: Effect String
|
||||
84
purescript/code_royal/test/Main.purs
Normal file
84
purescript/code_royal/test/Main.purs
Normal file
@@ -0,0 +1,84 @@
|
||||
module Test.Main where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Array (concatMap, (..))
|
||||
import Data.Foldable (foldl)
|
||||
import Data.Int (fromNumber)
|
||||
import Data.JSDate (JSDate, getTime, now)
|
||||
import Data.Map (Map, showTree)
|
||||
import Data.Maybe (fromJust)
|
||||
import Effect (Effect)
|
||||
import Effect.Console (log)
|
||||
import Graph (Graph(..), addEdge, addNode, dfs, empty, pathExists, shortestPath, shortestPathList, toMap, (<+>))
|
||||
import Partial.Unsafe (unsafePartial)
|
||||
|
||||
|
||||
main :: Effect Unit
|
||||
main = do
|
||||
let graph = foldl addEdge' graph' $ concatMap nodeConnections nodes
|
||||
|
||||
d0 <- now
|
||||
-- log $ show $ shortestPathList graph "[1,1]" "[7,7]"
|
||||
-- log $ show $ shortestPathList graph "[1,1]" "[7,7]"
|
||||
-- log $ show $ shortestPathList graph "[1,1]" "[7,7]"
|
||||
-- d1 <- now
|
||||
-- test "list search" d0 d1
|
||||
|
||||
-- log ""
|
||||
|
||||
-- d2 <- now
|
||||
-- log $ show $ shortestPath graph "[1,1]" "[7,7]"
|
||||
-- log $ show $ shortestPath graph "[1,1]" "[7,7]"
|
||||
-- log $ show $ shortestPath graph "[1,1]" "[7,7]"
|
||||
-- d3 <- now
|
||||
-- test "set search" d2 d3
|
||||
|
||||
-- log ""
|
||||
|
||||
-- d4 <- now
|
||||
-- log $ show $ pathExists graph "[1,1]" "[7,7]"
|
||||
-- log $ show $ pathExists graph "[1,1]" "[7,7]"
|
||||
-- log $ show $ pathExists graph "[1,1]" "[7,7]"
|
||||
-- d5 <- now
|
||||
-- test "exists test" d4 d5
|
||||
|
||||
-- log ""
|
||||
|
||||
d6 <- now
|
||||
log $ show $ dfs graph "[1,1]" "[1,2]"
|
||||
log $ show $ dfs graph "[1,1]" "[1,2]"
|
||||
log $ show $ dfs graph "[1,1]" "[1,2]"
|
||||
d7 <- now
|
||||
test "dfs test" d6 d7
|
||||
|
||||
log ""
|
||||
|
||||
log $ "execution time of ALL: " <> (show $ (getTime d7 - getTime d0) / 3000.0) <> "s"
|
||||
|
||||
test :: String -> JSDate -> JSDate -> Effect Unit
|
||||
test tName d0 d1 = do
|
||||
let t0 = getTime d0
|
||||
let t1 = getTime d1
|
||||
log $ "execution time of " <> tName <> ": " <> (show $ (t1 - t0) / 3000.0) <> "s"
|
||||
|
||||
addEdge' :: forall v. Ord v => Graph v -> Array v -> Graph v
|
||||
addEdge' g v = unsafePartial $ addEdge'' v
|
||||
where
|
||||
addEdge'' :: Partial => Array v -> Graph v
|
||||
addEdge'' [a,b] = addEdge g a b
|
||||
|
||||
graph' = foldl addNode empty sNodes
|
||||
|
||||
sNodes :: Array String
|
||||
sNodes = map (\n -> show n) nodes
|
||||
|
||||
nodes = do
|
||||
x <- (1..9)
|
||||
y <- (1..9)
|
||||
pure $ [x, y]
|
||||
|
||||
nodeConnections :: Array Int -> Array (Array String)
|
||||
nodeConnections [x, y] = [ [o, show [x-1,y]], [o, show [x+1,y]], [o, show [x,y-1]], [o, show [x,y+1]] ]
|
||||
where o = show [x, y]
|
||||
nodeConnections _ = []
|
||||
7
purescript/code_royal/workspace.code-workspace
Normal file
7
purescript/code_royal/workspace.code-workspace
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
10
purescript/code_vs_zombies/.gitignore
vendored
Normal file
10
purescript/code_vs_zombies/.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/bower_components/
|
||||
/node_modules/
|
||||
/.pulp-cache/
|
||||
/output/
|
||||
/generated-docs/
|
||||
/.psc-package/
|
||||
/.psc*
|
||||
/.purs*
|
||||
/.psa*
|
||||
/.spago
|
||||
27
purescript/code_vs_zombies/.vscode/tasks.json
vendored
Normal file
27
purescript/code_vs_zombies/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build_purescript",
|
||||
"type": "shell",
|
||||
"command": "spago bundle-app",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"focus": true,
|
||||
"reveal": "silent"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "build_purescript_old",
|
||||
"type": "shell",
|
||||
"command": "spago bundle-app && sed -i \"$ d\" index.js && uglifyjs index.js --compress --mangle --output index.js",
|
||||
"group": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
128
purescript/code_vs_zombies/packages.dhall
Normal file
128
purescript/code_vs_zombies/packages.dhall
Normal file
@@ -0,0 +1,128 @@
|
||||
{-
|
||||
Welcome to your new Dhall package-set!
|
||||
|
||||
Below are instructions for how to edit this file for most use
|
||||
cases, so that you don't need to know Dhall to use it.
|
||||
|
||||
## Warning: Don't Move This Top-Level Comment!
|
||||
|
||||
Due to how `dhall format` currently works, this comment's
|
||||
instructions cannot appear near corresponding sections below
|
||||
because `dhall format` will delete the comment. However,
|
||||
it will not delete a top-level comment like this one.
|
||||
|
||||
## Use Cases
|
||||
|
||||
Most will want to do one or both of these options:
|
||||
1. Override/Patch a package's dependency
|
||||
2. Add a package not already in the default package set
|
||||
|
||||
This file will continue to work whether you use one or both options.
|
||||
Instructions for each option are explained below.
|
||||
|
||||
### Overriding/Patching a package
|
||||
|
||||
Purpose:
|
||||
- Change a package's dependency to a newer/older release than the
|
||||
default package set's release
|
||||
- Use your own modified version of some dependency that may
|
||||
include new API, changed API, removed API by
|
||||
using your custom git repo of the library rather than
|
||||
the package set's repo
|
||||
|
||||
Syntax:
|
||||
Replace the overrides' "{=}" (an empty record) with the following idea
|
||||
The "//" or "⫽" means "merge these two records and
|
||||
when they have the same value, use the one on the right:"
|
||||
-------------------------------
|
||||
let overrides =
|
||||
{ packageName =
|
||||
upstream.packageName // { updateEntity1 = "new value", updateEntity2 = "new value" }
|
||||
, packageName =
|
||||
upstream.packageName // { version = "v4.0.0" }
|
||||
, packageName =
|
||||
upstream.packageName // { repo = "https://www.example.com/path/to/new/repo.git" }
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let overrides =
|
||||
{ halogen =
|
||||
upstream.halogen // { version = "master" }
|
||||
, halogen-vdom =
|
||||
upstream.halogen-vdom // { version = "v4.0.0" }
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
### Additions
|
||||
|
||||
Purpose:
|
||||
- Add packages that aren't already included in the default package set
|
||||
|
||||
Syntax:
|
||||
Replace the additions' "{=}" (an empty record) with the following idea:
|
||||
-------------------------------
|
||||
let additions =
|
||||
{ package-name =
|
||||
{ dependencies =
|
||||
[ "dependency1"
|
||||
, "dependency2"
|
||||
]
|
||||
, repo =
|
||||
"https://example.com/path/to/git/repo.git"
|
||||
, version =
|
||||
"tag ('v4.0.0') or branch ('master')"
|
||||
}
|
||||
, package-name =
|
||||
{ dependencies =
|
||||
[ "dependency1"
|
||||
, "dependency2"
|
||||
]
|
||||
, repo =
|
||||
"https://example.com/path/to/git/repo.git"
|
||||
, version =
|
||||
"tag ('v4.0.0') or branch ('master')"
|
||||
}
|
||||
, etc.
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let additions =
|
||||
{ benchotron =
|
||||
{ dependencies =
|
||||
[ "arrays"
|
||||
, "exists"
|
||||
, "profunctor"
|
||||
, "strings"
|
||||
, "quickcheck"
|
||||
, "lcg"
|
||||
, "transformers"
|
||||
, "foldable-traversable"
|
||||
, "exceptions"
|
||||
, "node-fs"
|
||||
, "node-buffer"
|
||||
, "node-readline"
|
||||
, "datetime"
|
||||
, "now"
|
||||
]
|
||||
, repo =
|
||||
"https://github.com/hdgarrood/purescript-benchotron.git"
|
||||
, version =
|
||||
"v7.0.0"
|
||||
}
|
||||
}
|
||||
-------------------------------
|
||||
-}
|
||||
|
||||
|
||||
let upstream =
|
||||
https://github.com/purescript/package-sets/releases/download/psc-0.13.6-20200404/packages.dhall sha256:f239f2e215d0cbd5c203307701748581938f74c4c78f4aeffa32c11c131ef7b6
|
||||
|
||||
let overrides = {=}
|
||||
|
||||
let additions = {=}
|
||||
|
||||
in upstream // overrides // additions
|
||||
17
purescript/code_vs_zombies/spago.dhall
Normal file
17
purescript/code_vs_zombies/spago.dhall
Normal file
@@ -0,0 +1,17 @@
|
||||
{-
|
||||
Welcome to a Spago project!
|
||||
You can edit this file as you like.
|
||||
-}
|
||||
{ name = "shadown_of_the_knight"
|
||||
, dependencies =
|
||||
[ "arrays"
|
||||
, "console"
|
||||
, "effect"
|
||||
, "integers"
|
||||
, "math"
|
||||
, "psci-support"
|
||||
, "random"
|
||||
]
|
||||
, packages = ./packages.dhall
|
||||
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
|
||||
}
|
||||
35
purescript/code_vs_zombies/src/Lib.purs
Normal file
35
purescript/code_vs_zombies/src/Lib.purs
Normal file
@@ -0,0 +1,35 @@
|
||||
module Lib where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Int (fromNumber, pow, toNumber)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Math as M
|
||||
import Range (Area(..), Pos(..), Range(..))
|
||||
|
||||
maxPos :: Pos -> Int
|
||||
maxPos (Pos x y) = max x y
|
||||
|
||||
minPos :: Pos -> Int
|
||||
minPos (Pos x y) = min x y
|
||||
|
||||
getMiddlePos :: Area -> Pos
|
||||
getMiddlePos (Area (Range x1 x2) (Range y1 y2)) = Pos x y
|
||||
where
|
||||
x = abs (x1 + x2) / 2
|
||||
y = abs (y1 + y2) / 2
|
||||
|
||||
abs :: Int -> Int
|
||||
abs x = fromMaybe 0 $ fromNumber $ M.abs $ toNumber x
|
||||
|
||||
sqrt :: Int -> Int
|
||||
sqrt x = fromMaybe 0 $ fromNumber $ M.sqrt $ toNumber x
|
||||
|
||||
dist :: Pos -> Pos -> Int
|
||||
dist (Pos x1 y1) (Pos x2 y2) = sqrt $ a2 + b2
|
||||
where
|
||||
a2 = abs (x2 - x1) `pow` 2
|
||||
b2 = abs (y2 - y1) `pow` 2
|
||||
|
||||
toPos :: forall e. { x :: Int, y :: Int | e } -> Pos
|
||||
toPos p = Pos p.x p.y
|
||||
47
purescript/code_vs_zombies/src/Main.purs
Normal file
47
purescript/code_vs_zombies/src/Main.purs
Normal file
@@ -0,0 +1,47 @@
|
||||
module Main where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Array (any, drop, head, length, sortBy)
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Effect (Effect)
|
||||
import Effect.Console (log)
|
||||
import Lib (dist, toPos)
|
||||
import Range (Pos(..))
|
||||
import Reader (Player, Human, parseInput)
|
||||
|
||||
main :: Effect Unit
|
||||
main = do
|
||||
loop Nothing
|
||||
|
||||
loop :: Maybe Pos -> Effect Unit
|
||||
loop target = do
|
||||
input <- parseInput
|
||||
loop' input.player input.humans target
|
||||
|
||||
loop' :: Player -> Array Human -> Maybe Pos -> Effect Unit
|
||||
loop' player humans target = do
|
||||
let nearestHuman = sortBy (\h1 h2 -> compare (dist (toPos h1) playerPos) (dist (toPos h2) playerPos)) humans
|
||||
let sndHuman = if length nearestHuman > 1 then drop 1 nearestHuman else nearestHuman
|
||||
|
||||
let target' = case target of
|
||||
Just t -> if targetAlive then [t] else map toPos sndHuman
|
||||
Nothing -> if length nearestHuman == 2 then map toPos sndHuman else map toPos nearestHuman
|
||||
|
||||
let pos = case head target' of
|
||||
Just p -> p
|
||||
Nothing -> Pos 6000 6000
|
||||
|
||||
log $ show pos
|
||||
|
||||
loop $ Just pos
|
||||
|
||||
where
|
||||
playerPos :: Pos
|
||||
playerPos = toPos player
|
||||
|
||||
targetAlive :: Boolean
|
||||
targetAlive = case target of
|
||||
Just (Pos tx ty) -> any (\h -> h.x == tx && h.y == ty) humans
|
||||
Nothing -> false
|
||||
|
||||
26
purescript/code_vs_zombies/src/Ruler.purs
Normal file
26
purescript/code_vs_zombies/src/Ruler.purs
Normal file
@@ -0,0 +1,26 @@
|
||||
module Range
|
||||
( Area(..)
|
||||
, Pos(..)
|
||||
, Range(..)
|
||||
, range
|
||||
) where
|
||||
|
||||
import Prelude
|
||||
|
||||
-- data Building = Building Int Int
|
||||
data Pos = Pos Int Int
|
||||
data Area = Area Range Range
|
||||
|
||||
instance showPos :: Show Pos where
|
||||
show (Pos x y) = show x <> " " <> show y
|
||||
|
||||
instance showRange :: Show Range where
|
||||
show (Range x y) = show x <> "-" <> show y
|
||||
|
||||
instance showArea :: Show Area where
|
||||
show (Area r1 r2) = show r1 <> " / " <> show r2
|
||||
|
||||
data Range = Range Int Int
|
||||
|
||||
range :: Int -> Int -> Range
|
||||
range x y = Range (min x y) (max x y)
|
||||
47
purescript/code_vs_zombies/src/ffi/Reader.js
Normal file
47
purescript/code_vs_zombies/src/ffi/Reader.js
Normal file
@@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
|
||||
exports.readline = readline
|
||||
|
||||
exports.parseInput = function() {
|
||||
var inputs = readline().split(' ');
|
||||
var x = parseInt(inputs[0]);
|
||||
var y = parseInt(inputs[1]);
|
||||
var humanCount = parseInt(readline());
|
||||
var humans = []
|
||||
for (let i = 0; i < humanCount; i++) {
|
||||
var inputs = readline().split(' ');
|
||||
var humanId = parseInt(inputs[0]);
|
||||
var humanX = parseInt(inputs[1]);
|
||||
var humanY = parseInt(inputs[2]);
|
||||
humans.push({
|
||||
id: humanId,
|
||||
x: humanX,
|
||||
y: humanY,
|
||||
})
|
||||
}
|
||||
var zombieCount = parseInt(readline());
|
||||
var zombies = []
|
||||
for (let i = 0; i < zombieCount; i++) {
|
||||
var inputs = readline().split(' ');
|
||||
var zombieId = parseInt(inputs[0]);
|
||||
var zombieX = parseInt(inputs[1]);
|
||||
var zombieY = parseInt(inputs[2]);
|
||||
var zombieXNext = parseInt(inputs[3]);
|
||||
var zombieYNext = parseInt(inputs[4]);
|
||||
zombies.push({
|
||||
id: zombieId,
|
||||
x: zombieX,
|
||||
y: zombieY,
|
||||
nextX: zombieXNext,
|
||||
nextY: zombieYNext,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
player: { x, y },
|
||||
humanCount,
|
||||
zombieCount,
|
||||
humans,
|
||||
zombies,
|
||||
}
|
||||
};
|
||||
34
purescript/code_vs_zombies/src/ffi/Reader.purs
Normal file
34
purescript/code_vs_zombies/src/ffi/Reader.purs
Normal file
@@ -0,0 +1,34 @@
|
||||
module Reader where
|
||||
|
||||
import Effect (Effect)
|
||||
|
||||
type Player =
|
||||
{ x :: Int
|
||||
, y :: Int
|
||||
}
|
||||
|
||||
type Human =
|
||||
{ id :: Int
|
||||
, x :: Int
|
||||
, y :: Int
|
||||
}
|
||||
|
||||
type Zombie =
|
||||
{ id :: Int
|
||||
, x :: Int
|
||||
, y :: Int
|
||||
, nextX :: Int
|
||||
, nextY :: Int
|
||||
}
|
||||
|
||||
type GameInput =
|
||||
{ player :: Player
|
||||
, humanCount :: Int
|
||||
, zombieCount :: Int
|
||||
, humans :: Array Human
|
||||
, zombies :: Array Zombie
|
||||
}
|
||||
|
||||
foreign import parseInput :: Effect GameInput
|
||||
|
||||
foreign import readline :: Effect String
|
||||
19
purescript/code_vs_zombies/test/Main.purs
Normal file
19
purescript/code_vs_zombies/test/Main.purs
Normal file
@@ -0,0 +1,19 @@
|
||||
module Test.Main where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Effect (Effect)
|
||||
import Effect.Console (log)
|
||||
|
||||
|
||||
main :: Effect Unit
|
||||
main = do
|
||||
let input = {
|
||||
x: 20,
|
||||
y: 20,
|
||||
width: 100,
|
||||
height: 100,
|
||||
turns: 50
|
||||
}
|
||||
-- loop input $ calcWindows input
|
||||
log "hi"
|
||||
7
purescript/code_vs_zombies/workspace.code-workspace
Normal file
7
purescript/code_vs_zombies/workspace.code-workspace
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
1
purescript/graphtest/.gitignore
vendored
Normal file
1
purescript/graphtest/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/index.js
|
||||
29
purescript/graphtest/package-lock.json
generated
Normal file
29
purescript/graphtest/package-lock.json
generated
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "graphtest",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@dagrejs/graphlib": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-2.1.4.tgz",
|
||||
"integrity": "sha512-QCg9sL4uhjn468FDEsb/S9hS2xUZSrv/+dApb1Ze5VKO96pTXKNJZ6MGhIpgWkc1TVhbVGH9/7rq/Mf8/jWicw==",
|
||||
"requires": {
|
||||
"lodash": "^4.11.1"
|
||||
}
|
||||
},
|
||||
"graphlib": {
|
||||
"version": "2.1.8",
|
||||
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
|
||||
"integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.15"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
15
purescript/graphtest/package.json
Normal file
15
purescript/graphtest/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "graphtest",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@dagrejs/graphlib": "^2.1.4",
|
||||
"graphlib": "^2.1.8"
|
||||
}
|
||||
}
|
||||
96
purescript/lib/Graph.purs
Normal file
96
purescript/lib/Graph.purs
Normal file
@@ -0,0 +1,96 @@
|
||||
module Graph where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.List (List(..), any, drop, foldl, fromFoldable, head, reverse, union, (:), (\\))
|
||||
import Data.Map as M
|
||||
import Data.Maybe (Maybe(..), fromMaybe)
|
||||
import Data.Set as S
|
||||
import Data.Tuple (Tuple(..), fst, snd)
|
||||
|
||||
newtype Graph v = Graph (M.Map v (List v))
|
||||
|
||||
empty :: forall v. Graph v
|
||||
empty = Graph M.empty
|
||||
|
||||
addNode :: forall v. Ord v => Graph v -> v -> Graph v
|
||||
addNode (Graph m) v = Graph $ M.insert v Nil m
|
||||
infixl 5 addNode as <+>
|
||||
|
||||
-- adds an Edge from Node "from" to Node "to"
|
||||
-- returns the graph unmodified if "to" does not exist
|
||||
addEdge :: forall v. Ord v => Graph v -> v -> v -> Graph v
|
||||
addEdge g@(Graph m) from to = Graph $ M.update updateVal from m
|
||||
where
|
||||
updateVal :: List v -> Maybe (List v)
|
||||
updateVal nodes
|
||||
| g `contains` to = Just $ to : nodes
|
||||
| otherwise = Just nodes
|
||||
|
||||
toMap :: forall v. Graph v -> M.Map v (List v)
|
||||
toMap (Graph m) = m
|
||||
|
||||
adjacentEdges :: forall v. Ord v => Graph v -> v -> List v
|
||||
adjacentEdges (Graph m) nodeId = fromMaybe Nil $ M.lookup nodeId m
|
||||
|
||||
contains :: forall v. Ord v => Graph v -> v -> Boolean
|
||||
contains (Graph m) key = case M.lookup key m of
|
||||
Just _ -> true
|
||||
Nothing -> false
|
||||
|
||||
shortestPath :: forall v. Ord v => Graph v -> v -> v -> List v
|
||||
shortestPath g@(Graph m) from to = reverse $ shortestPath' (Tuple from Nil) Nil S.empty
|
||||
where
|
||||
shortestPath' :: (Tuple v (List v)) -> List (Tuple v (List v)) -> S.Set v-> List v
|
||||
shortestPath' from queue visited
|
||||
| fst from == to = snd from
|
||||
| otherwise = case head $ newQueue of
|
||||
Just n -> shortestPath' n newQueue (S.insert (fst from) visited)
|
||||
Nothing -> Nil
|
||||
where
|
||||
adjacent :: S.Set v
|
||||
adjacent = S.fromFoldable $ adjacentEdges g (fst from)
|
||||
newQueue :: List (Tuple v (List v))
|
||||
newQueue = drop 1 queue <> ( map (\x -> Tuple x $ fst from : snd from) (fromFoldable $ S.difference adjacent visited) )
|
||||
|
||||
shortestPathList :: forall v. Ord v => Graph v -> v -> v -> List v
|
||||
shortestPathList g@(Graph m) from to = reverse $ shortestPath' (Tuple from Nil) Nil Nil
|
||||
where
|
||||
shortestPath' :: (Tuple v (List v)) -> List (Tuple v (List v)) -> List v-> List v
|
||||
shortestPath' from queue visited
|
||||
| fst from == to = snd from
|
||||
| otherwise = case head $ newQueue of
|
||||
Just n -> shortestPath' n newQueue (fst from : visited)
|
||||
Nothing -> Nil
|
||||
where
|
||||
adjacent :: List v
|
||||
adjacent = adjacentEdges g (fst from)
|
||||
newQueue :: List (Tuple v (List v))
|
||||
newQueue = drop 1 queue <> ( map (\x -> Tuple x $ fst from : snd from) (adjacent \\ visited) )
|
||||
|
||||
pathExists :: forall v. Ord v => Graph v -> v -> v -> Boolean
|
||||
pathExists g@(Graph m) from to = shortestPath' from Nil Nil
|
||||
where
|
||||
shortestPath' :: v -> List v -> List v -> Boolean
|
||||
shortestPath' from queue visited
|
||||
| from == to = true
|
||||
| otherwise = case head $ newQueue of
|
||||
Just n -> shortestPath' n newQueue (from : visited)
|
||||
Nothing -> false
|
||||
where
|
||||
adjacent :: List v
|
||||
adjacent = adjacentEdges g from
|
||||
newQueue :: List v
|
||||
newQueue = drop 1 queue <> (adjacent \\ visited)
|
||||
|
||||
dfs :: forall v. Ord v => Graph v -> v -> v -> Boolean
|
||||
dfs g@(Graph m) from to = dfs' g from to Nil
|
||||
|
||||
dfs' :: forall v. Ord v => Graph v -> v -> v -> List v -> Boolean
|
||||
dfs' g@(Graph m) from to visited
|
||||
| from == to = true
|
||||
| otherwise = any ((==) true) $ subcalls (adjacent \\ visited)
|
||||
where
|
||||
subcalls = map (\f -> dfs' g f to visited')
|
||||
visited' = union visited adjacent
|
||||
adjacent = adjacentEdges g from
|
||||
11
purescript/shawdows_of_the_knight_episode_1/.gitignore
vendored
Normal file
11
purescript/shawdows_of_the_knight_episode_1/.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/bower_components/
|
||||
/node_modules/
|
||||
/.pulp-cache/
|
||||
/output/
|
||||
/generated-docs/
|
||||
/.psc-package/
|
||||
/.psc*
|
||||
/.purs*
|
||||
/.psa*
|
||||
/.spago
|
||||
/index.js
|
||||
22
purescript/shawdows_of_the_knight_episode_1/.vscode/tasks.json
vendored
Normal file
22
purescript/shawdows_of_the_knight_episode_1/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build_purescript",
|
||||
"type": "shell",
|
||||
"command": "spago bundle-app && uglifyj s index.js --compress --mangle --output index.js",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "build_purescript_old",
|
||||
"type": "shell",
|
||||
"command": "spago bundle-app && sed -i \"$ d\" index.js && uglifyjs index.js --compress --mangle --output index.js",
|
||||
"group": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
128
purescript/shawdows_of_the_knight_episode_1/packages.dhall
Normal file
128
purescript/shawdows_of_the_knight_episode_1/packages.dhall
Normal file
@@ -0,0 +1,128 @@
|
||||
{-
|
||||
Welcome to your new Dhall package-set!
|
||||
|
||||
Below are instructions for how to edit this file for most use
|
||||
cases, so that you don't need to know Dhall to use it.
|
||||
|
||||
## Warning: Don't Move This Top-Level Comment!
|
||||
|
||||
Due to how `dhall format` currently works, this comment's
|
||||
instructions cannot appear near corresponding sections below
|
||||
because `dhall format` will delete the comment. However,
|
||||
it will not delete a top-level comment like this one.
|
||||
|
||||
## Use Cases
|
||||
|
||||
Most will want to do one or both of these options:
|
||||
1. Override/Patch a package's dependency
|
||||
2. Add a package not already in the default package set
|
||||
|
||||
This file will continue to work whether you use one or both options.
|
||||
Instructions for each option are explained below.
|
||||
|
||||
### Overriding/Patching a package
|
||||
|
||||
Purpose:
|
||||
- Change a package's dependency to a newer/older release than the
|
||||
default package set's release
|
||||
- Use your own modified version of some dependency that may
|
||||
include new API, changed API, removed API by
|
||||
using your custom git repo of the library rather than
|
||||
the package set's repo
|
||||
|
||||
Syntax:
|
||||
Replace the overrides' "{=}" (an empty record) with the following idea
|
||||
The "//" or "⫽" means "merge these two records and
|
||||
when they have the same value, use the one on the right:"
|
||||
-------------------------------
|
||||
let overrides =
|
||||
{ packageName =
|
||||
upstream.packageName // { updateEntity1 = "new value", updateEntity2 = "new value" }
|
||||
, packageName =
|
||||
upstream.packageName // { version = "v4.0.0" }
|
||||
, packageName =
|
||||
upstream.packageName // { repo = "https://www.example.com/path/to/new/repo.git" }
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let overrides =
|
||||
{ halogen =
|
||||
upstream.halogen // { version = "master" }
|
||||
, halogen-vdom =
|
||||
upstream.halogen-vdom // { version = "v4.0.0" }
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
### Additions
|
||||
|
||||
Purpose:
|
||||
- Add packages that aren't already included in the default package set
|
||||
|
||||
Syntax:
|
||||
Replace the additions' "{=}" (an empty record) with the following idea:
|
||||
-------------------------------
|
||||
let additions =
|
||||
{ package-name =
|
||||
{ dependencies =
|
||||
[ "dependency1"
|
||||
, "dependency2"
|
||||
]
|
||||
, repo =
|
||||
"https://example.com/path/to/git/repo.git"
|
||||
, version =
|
||||
"tag ('v4.0.0') or branch ('master')"
|
||||
}
|
||||
, package-name =
|
||||
{ dependencies =
|
||||
[ "dependency1"
|
||||
, "dependency2"
|
||||
]
|
||||
, repo =
|
||||
"https://example.com/path/to/git/repo.git"
|
||||
, version =
|
||||
"tag ('v4.0.0') or branch ('master')"
|
||||
}
|
||||
, etc.
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let additions =
|
||||
{ benchotron =
|
||||
{ dependencies =
|
||||
[ "arrays"
|
||||
, "exists"
|
||||
, "profunctor"
|
||||
, "strings"
|
||||
, "quickcheck"
|
||||
, "lcg"
|
||||
, "transformers"
|
||||
, "foldable-traversable"
|
||||
, "exceptions"
|
||||
, "node-fs"
|
||||
, "node-buffer"
|
||||
, "node-readline"
|
||||
, "datetime"
|
||||
, "now"
|
||||
]
|
||||
, repo =
|
||||
"https://github.com/hdgarrood/purescript-benchotron.git"
|
||||
, version =
|
||||
"v7.0.0"
|
||||
}
|
||||
}
|
||||
-------------------------------
|
||||
-}
|
||||
|
||||
|
||||
let upstream =
|
||||
https://github.com/purescript/package-sets/releases/download/psc-0.13.6-20200404/packages.dhall sha256:f239f2e215d0cbd5c203307701748581938f74c4c78f4aeffa32c11c131ef7b6
|
||||
|
||||
let overrides = {=}
|
||||
|
||||
let additions = {=}
|
||||
|
||||
in upstream // overrides // additions
|
||||
17
purescript/shawdows_of_the_knight_episode_1/spago.dhall
Normal file
17
purescript/shawdows_of_the_knight_episode_1/spago.dhall
Normal file
@@ -0,0 +1,17 @@
|
||||
{-
|
||||
Welcome to a Spago project!
|
||||
You can edit this file as you like.
|
||||
-}
|
||||
{ name = "shadown_of_the_knight"
|
||||
, dependencies =
|
||||
[ "arrays"
|
||||
, "console"
|
||||
, "effect"
|
||||
, "integers"
|
||||
, "math"
|
||||
, "psci-support"
|
||||
, "random"
|
||||
]
|
||||
, packages = ./packages.dhall
|
||||
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
|
||||
}
|
||||
71
purescript/shawdows_of_the_knight_episode_1/src/Main.purs
Normal file
71
purescript/shawdows_of_the_knight_episode_1/src/Main.purs
Normal file
@@ -0,0 +1,71 @@
|
||||
module Main where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Array (filter, head, length, reverse, sort, sortBy, (!!), (..))
|
||||
import Data.Int (fromNumber, toNumber)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Effect (Effect)
|
||||
import Effect.Console (error, log)
|
||||
import Math as M
|
||||
import Range (Range(..), Area(..), Pos(..), range)
|
||||
import Reader (GameInput, parseInput, readline)
|
||||
|
||||
main :: Effect Unit
|
||||
main = do
|
||||
input <- parseInput
|
||||
error $ show input
|
||||
loop input (calcArea input)
|
||||
|
||||
calcArea :: GameInput -> Area
|
||||
calcArea input = Area rX rY
|
||||
where
|
||||
rX = range 0 $ input.width - 1
|
||||
rY = range 0 $ input.height - 1
|
||||
|
||||
loop :: GameInput -> Area -> Effect Unit
|
||||
loop input area = do
|
||||
dir <- readline
|
||||
|
||||
let pos = Pos input.x input.y
|
||||
|
||||
let area' = shrinkArea dir area pos
|
||||
error $ show area
|
||||
error $ show area'
|
||||
let (Pos x y) = getMiddlePos area'
|
||||
let input' = input { x = x, y = y }
|
||||
|
||||
log $ show x <> " " <> show y
|
||||
|
||||
loop input' area'
|
||||
|
||||
where
|
||||
shrinkArea :: String -> Area -> Pos -> Area
|
||||
shrinkArea "U" a (Pos x y) = Area (range x x) (yUp a y)
|
||||
shrinkArea "D" a (Pos x y) = Area (range x x) (yDown a y)
|
||||
shrinkArea "R" a (Pos x y) = Area (xRight a x) (range y y)
|
||||
shrinkArea "L" a (Pos x y) = Area (xLeft a x) (range y y)
|
||||
shrinkArea "UR" a (Pos x y) = Area (xRight a x) (yUp a y)
|
||||
shrinkArea "DR" a (Pos x y) = Area (xRight a x) (yDown a y)
|
||||
shrinkArea "DL" a (Pos x y) = Area (xLeft a x) (yDown a y)
|
||||
shrinkArea "UL" a (Pos x y) = Area (xLeft a x) (yUp a y)
|
||||
shrinkArea _ _ _ = Area (range 9999 9999) (range 9999 9999)
|
||||
xRight (Area (Range xL xR) _) x = range (x+1) xR
|
||||
xLeft (Area (Range xL xR) _) x = range xL (x-1)
|
||||
yUp (Area _ (Range yU yL)) y = range yU (y-1)
|
||||
yDown (Area _ (Range yU yL)) y = range (y+1) yL
|
||||
|
||||
maxPos :: Pos -> Int
|
||||
maxPos (Pos x y) = max x y
|
||||
|
||||
minPos :: Pos -> Int
|
||||
minPos (Pos x y) = min x y
|
||||
|
||||
getMiddlePos :: Area -> Pos
|
||||
getMiddlePos (Area (Range x1 x2) (Range y1 y2)) = Pos x y
|
||||
where
|
||||
x = abs (x1 + x2) / 2
|
||||
y = abs (y1 + y2) / 2
|
||||
|
||||
abs :: Int -> Int
|
||||
abs x = fromMaybe (-1) $ fromNumber $ M.abs $ toNumber x
|
||||
26
purescript/shawdows_of_the_knight_episode_1/src/Ruler.purs
Normal file
26
purescript/shawdows_of_the_knight_episode_1/src/Ruler.purs
Normal file
@@ -0,0 +1,26 @@
|
||||
module Range
|
||||
( Area(..)
|
||||
, Pos(..)
|
||||
, Range(..)
|
||||
, range
|
||||
) where
|
||||
|
||||
import Prelude
|
||||
|
||||
-- data Building = Building Int Int
|
||||
data Pos = Pos Int Int
|
||||
data Area = Area Range Range
|
||||
|
||||
instance showPos :: Show Pos where
|
||||
show (Pos x y) = show x <> " " <> show y
|
||||
|
||||
instance showRange :: Show Range where
|
||||
show (Range x y) = show x <> "-" <> show y
|
||||
|
||||
instance showArea :: Show Area where
|
||||
show (Area r1 r2) = show r1 <> " / " <> show r2
|
||||
|
||||
data Range = Range Int Int
|
||||
|
||||
range :: Int -> Int -> Range
|
||||
range x y = Range (min x y) (max x y)
|
||||
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
exports.readline = readline
|
||||
|
||||
exports.parseInput = function() {
|
||||
var inputs = readline().split(' ');
|
||||
var W = parseInt(inputs[0]); // width of the building.
|
||||
var H = parseInt(inputs[1]); // height of the building.
|
||||
var N = parseInt(readline()); // maximum number of turns before game over.
|
||||
var inputs = readline().split(' ');
|
||||
var X0 = parseInt(inputs[0]);
|
||||
var Y0 = parseInt(inputs[1]);
|
||||
return {
|
||||
width: W,
|
||||
height: H,
|
||||
turns: N,
|
||||
x: X0,
|
||||
y: Y0,
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
module Reader where
|
||||
|
||||
import Effect (Effect)
|
||||
|
||||
type GameInput =
|
||||
{ width :: Int
|
||||
, height :: Int
|
||||
, turns :: Int
|
||||
, x :: Int
|
||||
, y :: Int
|
||||
}
|
||||
|
||||
foreign import parseInput :: Effect GameInput
|
||||
|
||||
foreign import readline :: Effect String
|
||||
19
purescript/shawdows_of_the_knight_episode_1/test/Main.purs
Normal file
19
purescript/shawdows_of_the_knight_episode_1/test/Main.purs
Normal file
@@ -0,0 +1,19 @@
|
||||
module Test.Main where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Effect (Effect)
|
||||
import Effect.Console (log)
|
||||
|
||||
|
||||
main :: Effect Unit
|
||||
main = do
|
||||
let input = {
|
||||
x: 20,
|
||||
y: 20,
|
||||
width: 100,
|
||||
height: 100,
|
||||
turns: 50
|
||||
}
|
||||
-- loop input $ calcWindows input
|
||||
log "hi"
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
11
purescript/vindinium/.gitignore
vendored
Normal file
11
purescript/vindinium/.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/bower_components/
|
||||
/node_modules/
|
||||
/.pulp-cache/
|
||||
/output/
|
||||
/generated-docs/
|
||||
/.psc-package/
|
||||
/.psc*
|
||||
/.purs*
|
||||
/.psa*
|
||||
/.spago
|
||||
/index.js
|
||||
28
purescript/vindinium/.vscode/tasks.json
vendored
Normal file
28
purescript/vindinium/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build_purescript",
|
||||
"type": "shell",
|
||||
"command": "spago bundle-app && uglifyjs index.js --mangle --output index.min.js",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"focus": true,
|
||||
"reveal": "silent"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "build_purescript_old",
|
||||
"type": "shell",
|
||||
"command": "spago bundle-app && uglifyjs index.js --compress --mangle --output index.js",
|
||||
"group": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
1
purescript/vindinium/index.min.js
vendored
Normal file
1
purescript/vindinium/index.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
128
purescript/vindinium/packages.dhall
Normal file
128
purescript/vindinium/packages.dhall
Normal file
@@ -0,0 +1,128 @@
|
||||
{-
|
||||
Welcome to your new Dhall package-set!
|
||||
|
||||
Below are instructions for how to edit this file for most use
|
||||
cases, so that you don't need to know Dhall to use it.
|
||||
|
||||
## Warning: Don't Move This Top-Level Comment!
|
||||
|
||||
Due to how `dhall format` currently works, this comment's
|
||||
instructions cannot appear near corresponding sections below
|
||||
because `dhall format` will delete the comment. However,
|
||||
it will not delete a top-level comment like this one.
|
||||
|
||||
## Use Cases
|
||||
|
||||
Most will want to do one or both of these options:
|
||||
1. Override/Patch a package's dependency
|
||||
2. Add a package not already in the default package set
|
||||
|
||||
This file will continue to work whether you use one or both options.
|
||||
Instructions for each option are explained below.
|
||||
|
||||
### Overriding/Patching a package
|
||||
|
||||
Purpose:
|
||||
- Change a package's dependency to a newer/older release than the
|
||||
default package set's release
|
||||
- Use your own modified version of some dependency that may
|
||||
include new API, changed API, removed API by
|
||||
using your custom git repo of the library rather than
|
||||
the package set's repo
|
||||
|
||||
Syntax:
|
||||
Replace the overrides' "{=}" (an empty record) with the following idea
|
||||
The "//" or "⫽" means "merge these two records and
|
||||
when they have the same value, use the one on the right:"
|
||||
-------------------------------
|
||||
let overrides =
|
||||
{ packageName =
|
||||
upstream.packageName // { updateEntity1 = "new value", updateEntity2 = "new value" }
|
||||
, packageName =
|
||||
upstream.packageName // { version = "v4.0.0" }
|
||||
, packageName =
|
||||
upstream.packageName // { repo = "https://www.example.com/path/to/new/repo.git" }
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let overrides =
|
||||
{ halogen =
|
||||
upstream.halogen // { version = "master" }
|
||||
, halogen-vdom =
|
||||
upstream.halogen-vdom // { version = "v4.0.0" }
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
### Additions
|
||||
|
||||
Purpose:
|
||||
- Add packages that aren't already included in the default package set
|
||||
|
||||
Syntax:
|
||||
Replace the additions' "{=}" (an empty record) with the following idea:
|
||||
-------------------------------
|
||||
let additions =
|
||||
{ package-name =
|
||||
{ dependencies =
|
||||
[ "dependency1"
|
||||
, "dependency2"
|
||||
]
|
||||
, repo =
|
||||
"https://example.com/path/to/git/repo.git"
|
||||
, version =
|
||||
"tag ('v4.0.0') or branch ('master')"
|
||||
}
|
||||
, package-name =
|
||||
{ dependencies =
|
||||
[ "dependency1"
|
||||
, "dependency2"
|
||||
]
|
||||
, repo =
|
||||
"https://example.com/path/to/git/repo.git"
|
||||
, version =
|
||||
"tag ('v4.0.0') or branch ('master')"
|
||||
}
|
||||
, etc.
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let additions =
|
||||
{ benchotron =
|
||||
{ dependencies =
|
||||
[ "arrays"
|
||||
, "exists"
|
||||
, "profunctor"
|
||||
, "strings"
|
||||
, "quickcheck"
|
||||
, "lcg"
|
||||
, "transformers"
|
||||
, "foldable-traversable"
|
||||
, "exceptions"
|
||||
, "node-fs"
|
||||
, "node-buffer"
|
||||
, "node-readline"
|
||||
, "datetime"
|
||||
, "now"
|
||||
]
|
||||
, repo =
|
||||
"https://github.com/hdgarrood/purescript-benchotron.git"
|
||||
, version =
|
||||
"v7.0.0"
|
||||
}
|
||||
}
|
||||
-------------------------------
|
||||
-}
|
||||
|
||||
|
||||
let upstream =
|
||||
https://github.com/purescript/package-sets/releases/download/psc-0.13.6-20200404/packages.dhall sha256:f239f2e215d0cbd5c203307701748581938f74c4c78f4aeffa32c11c131ef7b6
|
||||
|
||||
let overrides = {=}
|
||||
|
||||
let additions = {=}
|
||||
|
||||
in upstream // overrides // additions
|
||||
18
purescript/vindinium/spago.dhall
Normal file
18
purescript/vindinium/spago.dhall
Normal file
@@ -0,0 +1,18 @@
|
||||
{-
|
||||
Welcome to a Spago project!
|
||||
You can edit this file as you like.
|
||||
-}
|
||||
{ name = "vinidium"
|
||||
, dependencies =
|
||||
[ "arrays"
|
||||
, "console"
|
||||
, "effect"
|
||||
, "integers"
|
||||
, "js-date"
|
||||
, "math"
|
||||
, "ordered-collections"
|
||||
, "random"
|
||||
]
|
||||
, packages = ./packages.dhall
|
||||
, sources = [ "src/**/*.purs", "test/**/*.purs", "../lib/**/*.purs" ]
|
||||
}
|
||||
55
purescript/vindinium/src/Main.purs
Normal file
55
purescript/vindinium/src/Main.purs
Normal file
@@ -0,0 +1,55 @@
|
||||
module Main where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.State (State, gets, modify_, runState)
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Data.Tuple (fst, snd)
|
||||
import Effect (Effect)
|
||||
import Effect.Console (log, error)
|
||||
import Effect.Random (randomInt)
|
||||
import GameInput (parseInitInput, parseInput, GameInitInput, Board, Entity)
|
||||
import Graph
|
||||
|
||||
type GameState =
|
||||
{ boardSize :: Int
|
||||
, heroId :: Int
|
||||
, board :: Board
|
||||
, entityCount :: Int
|
||||
, entities :: Array Entity
|
||||
}
|
||||
|
||||
main :: Effect Unit
|
||||
main = do
|
||||
initInput <- parseInitInput
|
||||
error $ show $ initInput.board
|
||||
nextRound initInput Nothing
|
||||
|
||||
nextRound :: GameInitInput -> Maybe GameState -> Effect Unit
|
||||
nextRound initInput gameState = do
|
||||
input <- parseInput
|
||||
-- error $ show $ G.shortestPath "[4,4]" "[1,1]" graph
|
||||
|
||||
-- do we start on the left side of the map?
|
||||
|
||||
let gameState' =
|
||||
{ boardSize: initInput.boardSize
|
||||
, heroId: initInput.heroId
|
||||
, board: initInput.board
|
||||
, entityCount: input.entityCount
|
||||
, entities: input.entities
|
||||
}
|
||||
rand <- randomInt 0 3
|
||||
|
||||
let res = runState (loop rand) gameState'
|
||||
let state = snd res
|
||||
let val = fst res
|
||||
log $ val
|
||||
nextRound initInput (Just state)
|
||||
|
||||
loop :: Int -> State GameState String
|
||||
loop rand
|
||||
| rand == 0 = pure "NORTH"
|
||||
| rand == 1 = pure "EAST"
|
||||
| rand == 2 = pure "SOUTH"
|
||||
| otherwise = pure "WEST"
|
||||
26
purescript/vindinium/src/Ruler.purs
Normal file
26
purescript/vindinium/src/Ruler.purs
Normal file
@@ -0,0 +1,26 @@
|
||||
module Range
|
||||
( Area(..)
|
||||
, Pos(..)
|
||||
, Range(..)
|
||||
, range
|
||||
) where
|
||||
|
||||
import Prelude
|
||||
|
||||
-- data Building = Building Int Int
|
||||
data Pos = Pos Int Int
|
||||
data Area = Area Range Range
|
||||
|
||||
instance showPos :: Show Pos where
|
||||
show (Pos x y) = show x <> " " <> show y
|
||||
|
||||
instance showRange :: Show Range where
|
||||
show (Range x y) = show x <> "-" <> show y
|
||||
|
||||
instance showArea :: Show Area where
|
||||
show (Area r1 r2) = show r1 <> " / " <> show r2
|
||||
|
||||
data Range = Range Int Int
|
||||
|
||||
range :: Int -> Int -> Range
|
||||
range x y = Range (min x y) (max x y)
|
||||
52
purescript/vindinium/src/ffi/GameInput.js
Normal file
52
purescript/vindinium/src/ffi/GameInput.js
Normal file
@@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
|
||||
exports.readline = readline
|
||||
|
||||
exports.parseInitInput = function() {
|
||||
var size = parseInt(readline());
|
||||
var board = []
|
||||
for (var i = 0; i < size; i++) {
|
||||
var inner = []
|
||||
var line = readline();
|
||||
for (var l=0; l < line.length; l++) {
|
||||
inner.push(line[l])
|
||||
}
|
||||
board.push(inner)
|
||||
}
|
||||
var myId = parseInt(readline()); // ID of your hero
|
||||
|
||||
return {
|
||||
boardSize: size,
|
||||
heroId: myId,
|
||||
board: board
|
||||
}
|
||||
};
|
||||
|
||||
exports.parseInput = function(numSites) {
|
||||
return function() {
|
||||
var entityCount = parseInt(readline()); // the number of entities
|
||||
var entities = []
|
||||
for (var i = 0; i < entityCount; i++) {
|
||||
var inputs = readline().split(' ');
|
||||
var entityType = inputs[0]; // HERO or MINE
|
||||
var id = parseInt(inputs[1]); // the ID of a hero or the owner of a mine
|
||||
var x = parseInt(inputs[2]); // the x position of the entity
|
||||
var y = parseInt(inputs[3]); // the y position of the entity
|
||||
var life = parseInt(inputs[4]); // the life of a hero (-1 for mines)
|
||||
var gold = parseInt(inputs[5]); // the gold of a hero (-1 for mines)
|
||||
entities.push({
|
||||
entityType: entityType,
|
||||
id: id,
|
||||
x: x,
|
||||
y: y,
|
||||
life: life,
|
||||
gold: gold,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
entityCount: entityCount,
|
||||
entities: entities
|
||||
}
|
||||
}
|
||||
};
|
||||
34
purescript/vindinium/src/ffi/GameInput.purs
Normal file
34
purescript/vindinium/src/ffi/GameInput.purs
Normal file
@@ -0,0 +1,34 @@
|
||||
module GameInput where
|
||||
|
||||
import Effect (Effect)
|
||||
|
||||
-- TODO: Convert to proper types
|
||||
|
||||
data BoardElement = Spawn Int | Wall | Tavern | Mine | Empty
|
||||
type Board = Array (Array String)
|
||||
|
||||
type GameInitInput =
|
||||
{ boardSize :: Int
|
||||
, heroId :: Int
|
||||
, board :: Board
|
||||
}
|
||||
|
||||
type Entity =
|
||||
{ type :: String
|
||||
, id :: Int
|
||||
, x :: Int
|
||||
, y :: Int
|
||||
, life :: Int
|
||||
, gold :: Int
|
||||
}
|
||||
|
||||
type GameInput =
|
||||
{ entityCount :: Int
|
||||
, entities :: Array Entity
|
||||
}
|
||||
|
||||
foreign import parseInitInput :: Effect GameInitInput
|
||||
|
||||
foreign import parseInput :: Effect GameInput
|
||||
|
||||
foreign import readline :: Effect String
|
||||
57
purescript/vindinium/test/Main.purs
Normal file
57
purescript/vindinium/test/Main.purs
Normal file
@@ -0,0 +1,57 @@
|
||||
module Test.Main where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Array (concatMap, (..))
|
||||
import Data.Foldable (foldl)
|
||||
import Data.Int (fromNumber)
|
||||
import Data.JSDate (JSDate, getTime, now)
|
||||
import Data.Map (Map, showTree)
|
||||
import Data.Maybe (fromJust)
|
||||
import Effect (Effect)
|
||||
import Effect.Console (log)
|
||||
import Graph (Graph(..), addEdge, addNode, empty, pathExists, shortestPath)
|
||||
import Partial.Unsafe (unsafePartial)
|
||||
|
||||
|
||||
main :: Effect Unit
|
||||
main = do
|
||||
let graph = foldl addEdge' graph' $ concatMap nodeConnections nodes
|
||||
|
||||
d0 <- now
|
||||
log $ show $ shortestPath graph "[2,2]" "[9,9]"
|
||||
log $ show $ shortestPath graph "[2,2]" "[9,9]"
|
||||
log $ show $ shortestPath graph "[2,2]" "[9,9]"
|
||||
d1 <- now
|
||||
test "exists test" d0 d1
|
||||
|
||||
log ""
|
||||
|
||||
-- log $ "execution time of ALL: " <> (show $ (getTime d7 - getTime d0) / 3000.0) <> "s"
|
||||
|
||||
test :: String -> JSDate -> JSDate -> Effect Unit
|
||||
test tName d0 d1 = do
|
||||
let t0 = getTime d0
|
||||
let t1 = getTime d1
|
||||
log $ "execution time of " <> tName <> ": " <> (show $ (t1 - t0) / 3.0) <> "ms"
|
||||
|
||||
addEdge' :: forall v. Ord v => Graph v -> Array v -> Graph v
|
||||
addEdge' g v = unsafePartial $ addEdge'' v
|
||||
where
|
||||
addEdge'' :: Partial => Array v -> Graph v
|
||||
addEdge'' [a,b] = addEdge g a b
|
||||
|
||||
graph' = foldl addNode empty sNodes
|
||||
|
||||
sNodes :: Array String
|
||||
sNodes = map (\n -> show n) nodes
|
||||
|
||||
nodes = do
|
||||
x <- (1..10)
|
||||
y <- (1..10)
|
||||
pure $ [x, y]
|
||||
|
||||
nodeConnections :: Array Int -> Array (Array String)
|
||||
nodeConnections [x, y] = [ [o, show [x-1,y]], [o, show [x+1,y]], [o, show [x,y-1]], [o, show [x,y+1]] ]
|
||||
where o = show [x, y]
|
||||
nodeConnections _ = []
|
||||
10
purescript/vindinium/workspace.code-workspace
Normal file
10
purescript/vindinium/workspace.code-workspace
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
},
|
||||
{
|
||||
"path": "..\\lib"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user