mirror of
https://github.com/veden/Rampant.git
synced 2024-12-28 21:08:22 +02:00
242 lines
8.9 KiB
Racket
242 lines
8.9 KiB
Racket
;; Copyright (C) 2022 veden
|
|
|
|
;; This program is free software: you can redistribute it and/or modify
|
|
;; it under the terms of the GNU General Public License as published by
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
;; (at your option) any later version.
|
|
|
|
;; This program is distributed in the hope that it will be useful,
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
;; GNU General Public License for more details.
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
(module AiState racket
|
|
(provide (all-defined-out))
|
|
|
|
(require math/statistics)
|
|
|
|
(struct AiState (chunks
|
|
chunksLookup
|
|
minMaxes)
|
|
#:transparent)
|
|
|
|
(struct MinMax (min max)
|
|
#:transparent)
|
|
|
|
(struct ChunkRange (x
|
|
y
|
|
movement
|
|
base
|
|
player
|
|
resource
|
|
enemy
|
|
passable
|
|
tick
|
|
rating
|
|
nests
|
|
worms
|
|
rally
|
|
retreat
|
|
resourceGen
|
|
playerGen
|
|
deathGen
|
|
scoreResourceKamikaze
|
|
scoreResource
|
|
scoreSiegeKamikaze
|
|
scoreSiege
|
|
scoreAttackKamikaze
|
|
scoreAttack
|
|
pollution
|
|
aNe
|
|
aRNe
|
|
squads
|
|
baseAlign
|
|
hives
|
|
traps
|
|
utility
|
|
vg)
|
|
#:transparent)
|
|
|
|
(struct Chunk (x
|
|
y
|
|
movement
|
|
base
|
|
player
|
|
resource
|
|
enemy
|
|
passable
|
|
tick
|
|
rating
|
|
nests
|
|
worms
|
|
rally
|
|
retreat
|
|
resourceGen
|
|
playerGen
|
|
deathGen
|
|
scoreResourceKamikaze
|
|
scoreResource
|
|
scoreSiegeKamikaze
|
|
scoreSiege
|
|
scoreAttackKamikaze
|
|
scoreAttack
|
|
pollution
|
|
aNe
|
|
aRNe
|
|
squads
|
|
baseAlign
|
|
hives
|
|
traps
|
|
utility
|
|
vg)
|
|
#:transparent)
|
|
|
|
(require threading)
|
|
|
|
(define (getFile filePath)
|
|
(call-with-input-file filePath
|
|
(lambda (port)
|
|
(port->string port))))
|
|
|
|
(define (stringToChunk str)
|
|
(apply Chunk
|
|
(map string->number
|
|
(string-split str ","))))
|
|
|
|
(define (chunk->string chunk)
|
|
(string-append "x:" (~v (Chunk-x chunk)) "\n"
|
|
"y:" (~v (Chunk-y chunk)) "\n"
|
|
"m:" (~v (Chunk-movement chunk)) "\n"
|
|
"b:" (~v (Chunk-base chunk)) "\n"
|
|
"p:" (~v (Chunk-player chunk)) "\n"
|
|
"r:" (~v (Chunk-resource chunk)) "\n"
|
|
"e:" (~v (Chunk-enemy chunk)) "\n"
|
|
"pa:" (~v (Chunk-passable chunk)) "\n"
|
|
"t:" (~v (Chunk-tick chunk)) "\n"
|
|
"rat:" (~v (Chunk-rating chunk)) "\n"
|
|
"ne:" (~v (Chunk-nests chunk)) "\n"
|
|
"wo:" (~v (Chunk-worms chunk)) "\n"))
|
|
|
|
(define (chunk->string2 chunk)
|
|
(string-append "ral:" (~v (Chunk-rally chunk)) "\n"
|
|
"ret:" (~v (Chunk-retreat chunk)) "\n"
|
|
"rG:" (~v (Chunk-resourceGen chunk)) "\n"
|
|
"pG:" (~v (Chunk-playerGen chunk)) "\n"
|
|
"dG:" (~v (Chunk-deathGen chunk)) "\n"
|
|
"sA:" (~v (Chunk-scoreAttack chunk)) "\n"
|
|
"sAK:" (~v (Chunk-scoreAttackKamikaze chunk)) "\n"
|
|
"sS:" (~v (Chunk-scoreSiege chunk)) "\n"
|
|
"sSK:" (~v (Chunk-scoreSiegeKamikaze chunk)) "\n"
|
|
"sR:" (~v (Chunk-scoreResource chunk)) "\n"))
|
|
|
|
(define (chunk->string3 chunk)
|
|
(string-append "sRK:" (~v (Chunk-scoreResourceKamikaze chunk)) "\n"
|
|
"pu:" (~v (Chunk-pollution chunk)) "\n"
|
|
"aN:" (~v (Chunk-aNe chunk)) "\n"
|
|
"aRN:" (~v (Chunk-aRNe chunk)) "\n"
|
|
"sqs:" (~v (Chunk-squads chunk)) "\n"
|
|
"bA:" (~v (Chunk-baseAlign chunk)) "\n"
|
|
"H:" (~v (Chunk-hives chunk)) "\n"
|
|
"T:" (~v (Chunk-traps chunk)) "\n"
|
|
"U:" (~v (Chunk-utility chunk)) "\n"
|
|
"vg:" (~v (Chunk-vg chunk)) "\n"))
|
|
|
|
(define (normalizeRange xs)
|
|
(let* ((sDev (stddev xs))
|
|
(sMean (mean xs))
|
|
(target (* 2.5 sDev))
|
|
(cleanXs (filter (lambda (x)
|
|
(<= (abs (- x sMean)) target))
|
|
xs)))
|
|
(MinMax (apply min cleanXs)
|
|
(apply max cleanXs))))
|
|
|
|
(define (findChunkPropertiesMinMax chunks)
|
|
(let ((xs (map Chunk-x chunks))
|
|
(ys (map Chunk-y chunks))
|
|
(movements (map Chunk-movement chunks))
|
|
(bases (map Chunk-base chunks))
|
|
(players (map Chunk-player chunks))
|
|
(resources (map Chunk-resource chunks))
|
|
(enemy (map Chunk-enemy chunks))
|
|
(passables (map Chunk-passable chunks))
|
|
(ticks (map Chunk-tick chunks))
|
|
(ratings (map Chunk-rating chunks))
|
|
(nests (map Chunk-nests chunks))
|
|
(worms (map Chunk-worms chunks))
|
|
(rallys (map Chunk-rally chunks))
|
|
(retreats (map Chunk-retreat chunks))
|
|
(rGens (map Chunk-resourceGen chunks))
|
|
(pGens (map Chunk-playerGen chunks))
|
|
(dGens (map Chunk-deathGen chunks))
|
|
(sRKs (map Chunk-scoreResourceKamikaze chunks))
|
|
(sRs (map Chunk-scoreResource chunks))
|
|
(sSKs (map Chunk-scoreSiegeKamikaze chunks))
|
|
(sSs (map Chunk-scoreSiege chunks))
|
|
(sAKs (map Chunk-scoreAttackKamikaze chunks))
|
|
(sAs (map Chunk-scoreAttack chunks))
|
|
(pol (map Chunk-pollution chunks))
|
|
(aNe (map Chunk-aNe chunks))
|
|
(aRNe (map Chunk-aRNe chunks))
|
|
(sqs (map Chunk-squads chunks))
|
|
(bA (map Chunk-baseAlign chunks))
|
|
(H (map Chunk-hives chunks))
|
|
(T (map Chunk-traps chunks))
|
|
(U (map Chunk-utility chunks))
|
|
(vg (map Chunk-vg chunks)))
|
|
|
|
(ChunkRange (MinMax (apply min xs) (apply max xs))
|
|
(MinMax (apply min ys) (apply max ys))
|
|
(normalizeRange movements)
|
|
(normalizeRange bases)
|
|
(normalizeRange players)
|
|
(normalizeRange resources)
|
|
(normalizeRange enemy)
|
|
(MinMax (apply min passables) (apply max passables))
|
|
(normalizeRange ticks)
|
|
(normalizeRange ratings)
|
|
(MinMax (apply min nests) (apply max nests))
|
|
(MinMax (apply min worms) (apply max worms))
|
|
(MinMax (apply min rallys) (apply max rallys))
|
|
(MinMax (apply min retreats) (apply max retreats))
|
|
(MinMax (apply min rGens) (apply max rGens))
|
|
(MinMax (apply min pGens) (apply max pGens))
|
|
(MinMax (apply min dGens) (apply max dGens))
|
|
(normalizeRange sRKs)
|
|
(normalizeRange sRs)
|
|
(normalizeRange sSKs)
|
|
(normalizeRange sSs)
|
|
(normalizeRange sAKs)
|
|
(normalizeRange sAs)
|
|
(normalizeRange pol)
|
|
(MinMax (apply min aNe) (apply max aNe))
|
|
(MinMax (apply min aRNe) (apply max aRNe))
|
|
(MinMax (apply min sqs) (apply max sqs))
|
|
(MinMax (apply min bA) (apply max bA))
|
|
(MinMax (apply min H) (apply max H))
|
|
(MinMax (apply min T) (apply max T))
|
|
(MinMax (apply min U) (apply max U))
|
|
(MinMax (apply min vg) (apply max vg)))
|
|
))
|
|
|
|
(define (readState filePath)
|
|
(let* ((replayChunks (getFile filePath))
|
|
(chunks (map stringToChunk (string-split replayChunks "\n")))
|
|
(minMaxes (findChunkPropertiesMinMax chunks)))
|
|
(AiState chunks
|
|
(apply hash
|
|
(apply append
|
|
(map (lambda (chunk)
|
|
(list (list (Chunk-x chunk)
|
|
(Chunk-y chunk))
|
|
chunk))
|
|
chunks)))
|
|
minMaxes)))
|
|
|
|
(define (test)
|
|
(AiState-minMaxes (readState "/data/games/factorio/script-output/rampantState.txt"))))
|