Code Royal - initial commit

This commit is contained in:
weiss
2020-04-09 08:06:50 +02:00
parent 7fe78eaf40
commit 80038b3883
13 changed files with 453 additions and 2 deletions

2
.gitignore vendored
View File

@@ -6,4 +6,4 @@ node_modules
# Generated files # Generated files
.psci .psci
output output
/shawdows_of_the_knight_episode_1/index.js /*/index.js

10
code_royal/.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
/bower_components/
/node_modules/
/.pulp-cache/
/output/
/generated-docs/
/.psc-package/
/.psc*
/.purs*
/.psa*
/.spago

27
code_royal/.vscode/tasks.json vendored Normal file
View 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
code_royal/packages.dhall Normal file
View 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

15
code_royal/spago.dhall Normal file
View File

@@ -0,0 +1,15 @@
{-
Welcome to a Spago project!
You can edit this file as you like.
-}
{ name = "code_royal"
, dependencies =
[ "arrays"
, "console"
, "effect"
, "integers"
, "math"
]
, packages = ./packages.dhall
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
}

35
code_royal/src/Lib.purs Normal file
View 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 :: 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

67
code_royal/src/Main.purs Normal file
View File

@@ -0,0 +1,67 @@
module Main where
import Prelude
import Data.Array (any, drop, filter, head, length, sortBy)
import Data.Maybe (Maybe(..), fromJust)
import Effect (Effect)
import Effect.Console (log, error)
import GameInput (Site, Minion, SiteInfo, parseInitInput, parseInput)
import Lib (dist, toPos)
import Partial.Unsafe (unsafePartial)
import Range (Pos(..))
main :: Effect Unit
main = do
initInput <- parseInitInput
error $ show initInput
loop initInput.numSites initInput.sites
loop :: Int -> Array SiteInfo -> Effect Unit
loop numSites siteInfo = do
input <- parseInput numSites
let touchedSite = if input.touchedSite == -1
then Nothing
else Just input.touchedSite
loop' numSites input.gold touchedSite siteInfo input.sites input.units
loop' :: Int -> Int -> Maybe Int -> Array SiteInfo -> Array Site -> Array Minion -> Effect Unit
loop' numSites gold touchedSite siteInfo sites units = do
error $ "Sites: " <> show sites
error $ "SiteI: " <> show siteInfo
let queen = unsafePartial $ fromJust $ head $ filter (\u -> u.unitType == -1 && u.owner == 0) units
let siteInfo' = sortBy (compareSiteInfoDist queen) siteInfo
case head siteInfo' of
Just sInfo -> do
log $ build sInfo
log $ "TRAIN " <> show sInfo.id
Nothing -> do
log $ "WAIT"
log $ "TRAIN"
loop numSites siteInfo
compareSiteInfoDist :: Minion -> SiteInfo -> SiteInfo -> Ordering
compareSiteInfoDist u s1 s2 = compare (dist s1 u) (dist s2 u)
build :: forall e. { id :: Int | e } -> String
build s = "BUILD " <> show s.id <> " BARRACKS-ARCHER"
moveToPos :: forall e. { x :: Int, y :: Int | e } -> String
moveToPos p = "MOVE " <> show p.x <> " " <> show p.y
-- Phase 1
-- Queen takes as much buildings as possible
-- Build Archers only
-- Phase 2
-- Queen destroys enemy buildings
-- Build Archers only
-- Phase 3
-- Queen avoids Knights
-- All Buildings but one train Archers
-- nearestBuilding :: Pos

26
code_royal/src/Ruler.purs Normal file
View 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)

View File

@@ -0,0 +1,73 @@
"use strict";
exports.readline = readline
exports.parseInitInput = function() {
var sites = []
var numSites = parseInt(readline());
for (let 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, y,
radius,
})
}
return {
numSites,
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 (let i = 0; i < numSites; i++) {
var inputs = readline().split(' ');
var siteId = parseInt(inputs[0]);
var ignore1 = parseInt(inputs[1]); // used in future leagues
var ignore2 = parseInt(inputs[2]); // used in future leagues
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,
structureType,
owner,
param1,
param2,
})
}
var numUnits = parseInt(readline());
var units = []
for (let 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, y,
owner,
unitType,
health
})
}
return {
gold,
touchedSite,
sites,
units,
}
}
};

View File

@@ -0,0 +1,44 @@
module GameInput where
import Effect (Effect)
type GameInitInput =
{ numSites :: Int
, sites :: Array SiteInfo
}
type GameInput =
{ gold :: Int
, touchedSite :: Int -- -1 if none
, sites :: Array Site
, units :: Array Minion
}
type SiteInfo =
{ id :: Int
, x :: Int
, y :: Int
, radius :: Int
}
type Site =
{ id :: Int
, structureType :: Int -- -1 No structure, 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
}
type Minion =
{ x :: Int
, y :: Int
, owner :: Int -- 0 = Friendly; 1 = Enemy
, unitType :: Int -- -1 = QUEEN, 0 = KNIGHT, 1 = ARCHER
, health :: Int
}
foreign import parseInitInput :: Effect GameInitInput
foreign import parseInput :: Int -> Effect GameInput
foreign import readline :: Effect String

19
code_royal/test/Main.purs Normal file
View 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"

View File

@@ -0,0 +1,7 @@
{
"folders": [
{
"path": "."
}
]
}