enhanced train&build logic
This commit is contained in:
@@ -3,13 +3,15 @@ module Main where
|
|||||||
-- mines only on side
|
-- mines only on side
|
||||||
-- build giants
|
-- build giants
|
||||||
-- Pattern match filed wei keine eigenes gebaeude
|
-- Pattern match filed wei keine eigenes gebaeude
|
||||||
-- aber warum nur 2 minen und dann stopp?
|
-- letzte Mine wird nciht aufgelevelt?
|
||||||
|
|
||||||
import Prelude
|
import Prelude
|
||||||
|
|
||||||
import Control.Monad.State (State, gets, modify_, runState)
|
import Control.Monad.State (State, gets, modify_, runState)
|
||||||
import Control.MonadZero (guard)
|
import Control.MonadZero (guard)
|
||||||
import Data.Array (any, filter, foldl, head, length, reverse, sortBy)
|
import Data.Array (any, filter, foldl, head, length, reverse, sort, sortBy)
|
||||||
|
import Data.DateTime (time)
|
||||||
|
import Data.Foldable (sum)
|
||||||
import Data.Maybe (Maybe(..), fromJust)
|
import Data.Maybe (Maybe(..), fromJust)
|
||||||
import Data.Tuple (fst, snd)
|
import Data.Tuple (fst, snd)
|
||||||
import Effect (Effect)
|
import Effect (Effect)
|
||||||
@@ -94,22 +96,35 @@ loop' = do
|
|||||||
buildAll :: State GameState String
|
buildAll :: State GameState String
|
||||||
buildAll = do
|
buildAll = do
|
||||||
sites <- gets _.sites
|
sites <- gets _.sites
|
||||||
units <- gets _.units
|
|
||||||
let buildingsCnt = length $ friendlySites sites
|
let buildingsCnt = length $ friendlySites sites
|
||||||
let minesCnt = length $ friendlyMines sites
|
let noTowerBuildingsCnt = length $ filter (not isTower) $ friendlySites sites
|
||||||
if minesCnt < 3
|
let mines = length $ maxLvlFriendlyMines sites
|
||||||
|
if mines < 4 -- TODO: letzte Mine muss auch ganz ausgebaut werden
|
||||||
then buildMines
|
then buildMines
|
||||||
else if buildingsCnt < 5
|
else if noTowerBuildingsCnt < 5
|
||||||
then case head $ nearFreeSites (queen units) sites of
|
then buildBarracks
|
||||||
Just site -> do
|
else if buildingsCnt < 8 || (minTowerRange sites) < 300
|
||||||
let typ = if not $ hasArcherBarrack sites then 1
|
then if buildingsCnt < 8 then buildTowers
|
||||||
else if not $ hasKnightsBarrack sites then 0
|
else refreshTowers
|
||||||
else 2
|
else if noTowerBuildingsCnt < 6
|
||||||
pure $ build site typ
|
then buildBarracks
|
||||||
Nothing -> refreshTowers
|
|
||||||
else if buildingsCnt < 8
|
|
||||||
then buildTowers
|
|
||||||
else refreshTowers
|
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 :: State GameState String
|
||||||
buildTowers = do
|
buildTowers = do
|
||||||
@@ -123,7 +138,6 @@ buildTowers = do
|
|||||||
refreshTowers :: State GameState String
|
refreshTowers :: State GameState String
|
||||||
refreshTowers = do
|
refreshTowers = do
|
||||||
towers <-friendlyTowersByAttraction
|
towers <-friendlyTowersByAttraction
|
||||||
|
|
||||||
case head towers of
|
case head towers of
|
||||||
Just site -> do
|
Just site -> do
|
||||||
touched <- gets _.touchedSite
|
touched <- gets _.touchedSite
|
||||||
@@ -143,6 +157,7 @@ buildMines :: State GameState String
|
|||||||
buildMines = do
|
buildMines = do
|
||||||
units <- gets _.units
|
units <- gets _.units
|
||||||
sites <- gets _.sites
|
sites <- gets _.sites
|
||||||
|
leftSide <- gets _.leftSide
|
||||||
case head $ nearNonEmptyMines (queen units) sites of
|
case head $ nearNonEmptyMines (queen units) sites of
|
||||||
Just site -> do
|
Just site -> do
|
||||||
touched <- gets _.touchedSite
|
touched <- gets _.touchedSite
|
||||||
@@ -180,15 +195,16 @@ trainAll = do
|
|||||||
sites <- gets _.sites
|
sites <- gets _.sites
|
||||||
units <- gets _.units
|
units <- gets _.units
|
||||||
|
|
||||||
let ownArchers = ownMinions units
|
let ownGiants = filter isGiant $ ownMinions units
|
||||||
let barrack =if gold > 140
|
let trainGiants = length (enemyTowers sites) > 2 && length ownGiants < 3
|
||||||
then
|
let barrack = if not trainGiants
|
||||||
if length ownArchers < 4 && length (enemyKnights units) /= 0
|
then knightBarracks sites
|
||||||
then archerBarrack sites
|
else if gold > 140 then
|
||||||
else if length (enemyTowers sites) > 2
|
--knightBarracks sites
|
||||||
then giantBarrack sites
|
|
||||||
else
|
-- if length ownArchers < 4 && length (enemyKnights units) /= 0
|
||||||
knightBarrack sites
|
-- then archerBarrack sites
|
||||||
|
giantBarrack sites
|
||||||
else []
|
else []
|
||||||
pure $ foldl siteToIds "TRAIN" barrack
|
pure $ foldl siteToIds "TRAIN" barrack
|
||||||
where
|
where
|
||||||
@@ -201,7 +217,7 @@ trainAll = do
|
|||||||
Nothing -> []
|
Nothing -> []
|
||||||
giantBarrack sites = case head $ giantBarracks sites of
|
giantBarrack sites = case head $ giantBarracks sites of
|
||||||
Just barrack -> [barrack]
|
Just barrack -> [barrack]
|
||||||
Nothing -> []
|
Nothing -> knightBarracks sites
|
||||||
|
|
||||||
build :: forall e. { id :: Int | e } -> Int -> String
|
build :: forall e. { id :: Int | e } -> Int -> String
|
||||||
build s typ = "BUILD " <> show s.id <> " BARRACKS-" <> t
|
build s typ = "BUILD " <> show s.id <> " BARRACKS-" <> t
|
||||||
@@ -230,6 +246,9 @@ friendlySites = filter (\s -> s.owner == 0)
|
|||||||
friendlyMines :: Array Site -> Array Site
|
friendlyMines :: Array Site -> Array Site
|
||||||
friendlyMines sites = filter (\s -> s.structureType == 0) $ friendlySites sites
|
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 :: Array Site -> Array Site
|
||||||
enemyTowers = filter isEnemy <<< filter isTower
|
enemyTowers = filter isEnemy <<< filter isTower
|
||||||
|
|
||||||
@@ -246,8 +265,8 @@ friendlyTowersByAttraction = do
|
|||||||
sites <- gets _.sites
|
sites <- gets _.sites
|
||||||
units <- gets _.units
|
units <- gets _.units
|
||||||
let q = queen units
|
let q = queen units
|
||||||
pure $ reverse $ sortBy (\t1 t2 -> compare (attraction t1 q) (attraction t2 q)) (friendlyTowers sites)
|
pure $ sortBy (\t1 t2 -> compare (attraction t1 q) (attraction t2 q)) (friendlyTowers sites)
|
||||||
where attraction t q = t.param1 - dist t q
|
where attraction t q = t.param1 + dist t q
|
||||||
|
|
||||||
nearSites :: forall a. { x :: Int, y :: Int | a } -> Array Site -> Array Site
|
nearSites :: forall a. { x :: Int, y :: Int | a } -> Array Site -> Array Site
|
||||||
nearSites minion sites = sortBy (compareSiteDist minion) sites
|
nearSites minion sites = sortBy (compareSiteDist minion) sites
|
||||||
|
|||||||
Reference in New Issue
Block a user