1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-26 20:54:12 +02:00

FACTO-265: Fixed visualizer

This commit is contained in:
Aaron Veden 2023-03-12 19:35:04 -07:00
parent 449b12446f
commit 664de5ba83
No known key found for this signature in database
GPG Key ID: FF5990B1C6DD3F84
5 changed files with 289 additions and 717 deletions

View File

@ -29,4 +29,7 @@
(projectile-project-uninstall-cmd . "./make.sh clear")
(projectile-uninstall-buffer-suffix . "install")
(projectile-project-test-cmd . "./make.sh visualize")
(projectile-test-buffer-suffix . "visual")
(projectile-project-run-cmd . "factorio"))))

View File

@ -1104,38 +1104,15 @@ script.on_event(defines.events.on_build_base_arrived, onBuilderArrived)
remote.add_interface("rampantTests",
{
pheromoneLevels = tests.pheromoneLevels,
activeSquads = tests.activeSquads,
entitiesOnPlayerChunk = tests.entitiesOnPlayerChunk,
findNearestPlayerEnemy = tests.findNearestPlayerEnemy,
morePoints = tests.morePoints,
aiStats = tests.aiStats,
dumpEnvironment = tests.dumpEnvironment,
fillableDirtTest = tests.fillableDirtTest,
tunnelTest = tests.tunnelTest,
dumpNatives = tests.dumpatives,
createEnemy = tests.createEnemy,
attackOrigin = tests.attackOrigin,
cheatMode = tests.cheatMode,
gaussianRandomTest = tests.gaussianRandomTest,
-- fillableDirtTest = tests.fillableDirtTest,
-- tunnelTest = tests.tunnelTest,
reveal = tests.reveal,
showMovementGrid = tests.showMovementGrid,
showBaseGrid = tests.showBaseGrid,
baseStats = tests.baseStats,
mergeBases = tests.mergeBases,
clearBases = tests.clearBases,
getOffsetChunk = tests.getOffsetChunk,
registeredNest = tests.registeredNest,
colorResourcePoints = tests.colorResourcePoints,
entityStats = tests.entityStats,
stepAdvanceTendrils = tests.stepAdvanceTendrils,
unitGroupBuild = tests.unitGroupBuild,
-- showMovementGrid = tests.showMovementGrid,
-- showBaseGrid = tests.showBaseGrid,
-- colorResourcePoints = tests.colorResourcePoints,
exportAiState = tests.exportAiState(nil),
createEnergyTest = tests.createEnergyTest,
killActiveSquads = tests.killActiveSquads,
scanChunkPaths = tests.scanChunkPaths,
scanEnemy = tests.scanEnemy,
getEnemyStructureCount = tests.getEnemyStructureCount,
chunkCount = tests.chunkCount
}
)

View File

@ -3,6 +3,8 @@
(require file/zip)
(require json)
(require "visualizer/visual.rkt")
(provide (all-from-out "visualizer/visual.rkt"))
(define modFolder "/mnt/gallery/gameFiles/factorio/mods/")
(define serverModFolder "/home/veden/Downloads/factorio/mods/")
@ -112,4 +114,5 @@
(cond ((equal? arg "copy") (copy))
((equal? arg "zip") (zipIt))
((equal? arg "clear") (clear))
(else "Invalid command arg [copy,zip]")))
((equal? arg "visualize") (visualize))
(else "Invalid command arg [copy,zip,clear,visualize]")))

507
tests.lua
View File

@ -17,13 +17,8 @@
local tests = {}
local constants = require("libs/Constants")
local mathUtils = require("libs/MathUtils")
local chunkUtils = require("libs/ChunkUtils")
local chunkPropertyUtils = require("libs/ChunkPropertyUtils")
local mapUtils = require("libs/MapUtils")
local baseUtils = require("libs/BaseUtils")
local Utils = require("libs/Utils")
-- local tendrilUtils = require("libs/TendrilUtils")
function tests.chunkCount()
local count = 0
@ -33,178 +28,6 @@ function tests.chunkCount()
print(count)
end
function tests.pheromoneLevels(size)
local player = game.player.character
local playerChunkX = math.floor(player.position.x / 32) * constants.CHUNK_SIZE
local playerChunkY = math.floor(player.position.y / 32) * constants.CHUNK_SIZE
if not size then
size = 3 * constants.CHUNK_SIZE
else
size = size * constants.CHUNK_SIZE
end
print("------")
print(#global.map.processQueue)
print(playerChunkX .. ", " .. playerChunkY)
print("--")
for y=playerChunkY-size, playerChunkY+size,32 do
for x=playerChunkX-size, playerChunkX+size,32 do
if (global.map[x] ~= nil) then
local chunk = global.map[x][y]
if (chunk ~= nil) then
local str = ""
for i=1,#chunk do
str = str .. " " .. tostring(i) .. "/" .. tostring(chunk[i])
end
str = str .. " " .. "p/" .. game.get_surface(global.natives.activeSurface).get_pollution(chunk) .. " " .. "n/" .. chunkPropertyUtils.getNestCount(global.map, chunk) .. " " .. "w/" .. chunkPropertyUtils.getTurretCount(global.map, chunk) .. " pg/" .. chunkPropertyUtils.getPlayerBaseGenerator(global.map, chunk)
if (chunk.x == playerChunkX) and (chunk.y == playerChunkY) then
print("=============")
print(chunk.x, chunk.y, str)
print("=============")
else
print(chunk.x, chunk.y, str)
end
-- print(str)
print("----")
end
end
end
print("------------------")
end
end
function tests.killActiveSquads()
print("--")
for i=1, global.natives.squads.len do
local squad = global.natives.squads[i]
if (squad.group.valid) then
local members = squad.group.members
for x=1, #members do
local member = members[x]
local val = member.valid and member.die()
end
end
end
end
function tests.activeSquads()
print("-----")
print(defines.group_state.gathering .. " is equal to gathering")
print(defines.group_state.finished .. " is equal to finished")
-- print("Squads", global.natives.groupNumberToSquad)
for un, squad in pairs(global.natives.groupNumberToSquad) do
print("-")
-- local squad = global.natives.squads[i]
local squadHealth = 0
local squadMakeup = {}
if squad.group.valid then
-- for x=1,#squad.group.members do
-- local member = squad.group.members[x].prototype
-- if not squadMakeup[member.name] then
-- squadMakeup[member.name] = 0
-- end
-- squadHealth = squadHealth + member.max_health
-- squadMakeup[member.name] = squadMakeup[member.name] + 1
-- end
print(math.floor(squad.group.position.x * 0.03125), math.floor(squad.group.position.y * 0.03125), squad.status, squad.group.state, #squad.group.members, squad.cycles, squad.group.group_number -- , squadHealth
)
-- print(serpent.dump(squadResistances))
-- print(serpent.dump(squadMakeup))
-- print(serpent.dump(squad))
end
end
-- print("---")
-- print("pending", global.natives.pendingAttack.len)
-- for i=1, global.natives.pendingAttack.len do
-- print("-")
-- local squad = global.natives.pendingAttack[i]
-- local squadHealth = 0
-- local squadMakeup = {}
-- if squad.group.valid then
-- -- for x=1,#squad.group.members do
-- -- local member = squad.group.members[x].prototype
-- -- if not squadMakeup[member.name] then
-- -- squadMakeup[member.name] = 0
-- -- end
-- -- squadHealth = squadHealth + member.max_health
-- -- squadMakeup[member.name] = squadMakeup[member.name] + 1
-- -- end
-- print(math.floor(squad.group.position.x * 0.03125), math.floor(squad.group.position.y * 0.03125), squad.status, squad.group.state, #squad.group.members, squad.cycles, -- squadHealth,
-- squad.group.group_number)
-- -- print(serpent.dump(squadResistances))
-- -- print(serpent.dump(squadMakeup))
-- -- print(serpent.dump(squad))
-- end
-- end
-- print("---")
-- print("building", #global.natives.building)
-- for i=1, #global.natives.building do
-- print("-")
-- local squad = global.natives.building[i]
-- local squadHealth = 0
-- local squadMakeup = {}
-- if squad.group.valid then
-- -- for x=1,#squad.group.members do
-- -- local member = squad.group.members[x].prototype
-- -- if not squadMakeup[member.name] then
-- -- squadMakeup[member.name] = 0
-- -- end
-- -- squadHealth = squadHealth + member.max_health
-- -- squadMakeup[member.name] = squadMakeup[member.name] + 1
-- -- end
-- print(math.floor(squad.group.position.x * 0.03125), math.floor(squad.group.position.y * 0.03125), squad.status, squad.group.state, #squad.group.members, squad.cycles, squad.group.group_number, squadHealth)
-- -- print(serpent.dump(squadResistances))
-- -- print(serpent.dump(squadMakeup))
-- -- print(serpent.dump(squad))
-- end
-- end
end
function tests.entitiesOnPlayerChunk()
local playerPosition = game.players[1].position
local chunkX = math.floor(playerPosition.x * 0.03125) * 32
local chunkY = math.floor(playerPosition.y * 0.03125) * 32
local entities = game.get_surface(global.natives.activeSurface).find_entities_filtered({area={{chunkX, chunkY},
{chunkX + constants.CHUNK_SIZE, chunkY + constants.CHUNK_SIZE}},
force="player"})
for i=1, #entities do
print(entities[i].name)
end
print("--")
end
function tests.findNearestPlayerEnemy()
local playerPosition = game.players[1].position
local chunkX = math.floor(playerPosition.x * 0.03125) * 32
local chunkY = math.floor(playerPosition.y * 0.03125) * 32
local entity = game.get_surface(global.natives.activeSurface).find_nearest_enemy({position={chunkX, chunkY},
max_distance=constants.CHUNK_SIZE,
force = "enemy"})
if (entity ~= nil) then
print(entity.name)
end
print("--")
end
function tests.morePoints(points)
global.natives.points = global.natives.points + points
end
function tests.getOffsetChunk(x, y)
local playerPosition = game.players[1].position
local chunkX = math.floor(playerPosition.x * 0.03125)
local chunkY = math.floor(playerPosition.y * 0.03125)
local chunk = mapUtils.getChunkByIndex(global.map, chunkX + x, chunkY + y)
print(serpent.dump(chunk))
end
function tests.aiStats()
print(global.natives.points, game.tick, global.natives.state, global.natives.temperament, global.natives.stateTick, global.natives.temperamentTick, global.natives.activeNests, global.natives.activeRaidNests)
end
function tests.fillableDirtTest()
local playerPosition = game.players[1].position
local chunkX = math.floor(playerPosition.x * 0.03125) * 32
@ -223,119 +46,12 @@ function tests.tunnelTest()
game.get_surface(global.natives.activeSurface).create_entity({name="tunnel-entrance-rampant", position={chunkX, chunkY}})
end
function tests.createEnemy(x,d)
local playerPosition = game.players[1].position
local chunkX = math.floor(playerPosition.x * 0.03125) * 32
local chunkY = math.floor(playerPosition.y * 0.03125) * 32
local a = {name=x, position={chunkX, chunkY}, force="enemy"}
if d then
a['direction'] = d
end
return game.get_surface(global.natives.activeSurface).create_entity(a)
end
function tests.attackOrigin()
local enemy = game.get_surface(global.natives.activeSurface).find_nearest_enemy({position={0,0},
max_distance = 1000})
if (enemy ~= nil) and enemy.valid then
print(enemy, enemy.unit_number)
enemy.set_command({type=defines.command.go_to_location,
destination={0,0},
radius=15})
end
end
function tests.dumpNatives()
print(serpent.dump(global.natives))
end
function tests.cheatMode()
game.players[1].cheat_mode = true
game.forces.player.research_all_technologies()
end
function tests.gaussianRandomTest()
local result = {}
for x=0,100,1 do
result[x] = 0
end
for _=1,10000 do
local s = mathUtils.roundToNearest(mathUtils.gaussianRandomRange(50, 25, 0, 100), 1)
result[s] = result[s] + 1
end
for x=0,100,1 do
print(x, result[x])
end
end
function tests.reveal (size)
local pos = game.player.character.position
game.player.force.chart(game.player.surface,
{{x=-size+pos.x, y=-size+pos.y}, {x=size+pos.x, y=size+pos.y}})
end
function tests.baseStats()
local natives = global.natives
print ("x", "y", "distanceThreshold", "tick", "points", "temperament", "temperamentTick", "state", "stateTick", "alignments")
for i=1, #natives.bases do
local base = natives.bases[i]
print(base.x,
base.y,
base.distanceThreshold,
base.tick,
base.points,
base.temperament,
base.temperamentTick,
base.state,
base.stateTick,
serpent.dump(base.alignment))
print("---")
end
end
function tests.clearBases()
local surface = game.get_surface(global.natives.activeSurface)
for x=#global.natives.bases,1,-1 do
local base = global.natives.bases[x]
for c=1,#base.chunks do
local chunk = base.chunks[c]
chunkUtils.clearChunkNests(chunk, surface)
end
base.chunks = {}
if (surface.can_place_entity({name="biter-spawner-powered", position={base.cX * 32, base.cY * 32}})) then
surface.create_entity({name="biter-spawner-powered", position={base.cX * 32, base.cY * 32}})
local slice = math.pi / 12
local pos = 0
for i=1,24 do
if (math.random() < 0.8) then
local distance = mathUtils.roundToNearest(mathUtils.gaussianRandomRange(45, 5, 37, 60), 1)
if (surface.can_place_entity({name="biter-spawner", position={base.cX * 32 + (distance*math.sin(pos)), base.cY * 32 + (distance*math.cos(pos))}})) then
if (math.random() < 0.3) then
surface.create_entity({name="small-worm-turret", position={base.cX * 32 + (distance*math.sin(pos)), base.cY * 32 + (distance*math.cos(pos))}})
else
surface.create_entity({name="biter-spawner", position={base.cX * 32 + (distance*math.sin(pos)), base.cY * 32 + (distance*math.cos(pos))}})
end
end
end
pos = pos + slice
end
else
table.remove(global.natives.bases, x)
end
end
end
function tests.mergeBases()
local natives = global.natives
baseUtils.mergeBases(global.natives)
end
function tests.unitBuildBase()
end
function tests.showBaseGrid(time)
local map = global.universe.maps[game.player.surface.index]
local chunks = map.chunkToBase
@ -352,65 +68,37 @@ function tests.showBaseGrid(time)
end
end
function tests.getEnemyStructureCount()
local map = global.universe.maps[game.player.surface.index]
local chunk = mapUtils.getChunkByPosition(map, game.player.character.position)
-- function tests.showMovementGrid()
-- local chunks = global.map.processQueue
-- for i=1,#chunks do
-- local chunk = chunks[i]
-- local color = "concrete"
-- if (chunkPropertyUtils.getPassable(global.map, chunk) == constants.CHUNK_ALL_DIRECTIONS) then
-- color = "hazard-concrete-left"
-- elseif (chunkPropertyUtils.getPassable(global.map, chunk) == constants.CHUNK_NORTH_SOUTH) then
-- color = "concrete"
-- elseif (chunkPropertyUtils.getPassable(global.map, chunk) == constants.CHUNK_EAST_WEST) then
-- color = "stone-path"
-- end
-- chunkUtils.colorChunk(chunk.x, chunk.y, color, game.get_surface(global.natives.activeSurface))
-- end
-- end
print(chunk.x, chunk.y, chunkPropertyUtils.getEnemyStructureCount(map, chunk))
end
function tests.scanEnemy()
local map = global.universe.maps[game.player.surface.index]
local chunk = mapUtils.getChunkByPosition(map, game.player.character.position)
local universe = map.universe
local query = universe.filteredEntitiesEnemyStructureQuery
Utils.setAreaInQuery(query, chunk, constants.CHUNK_SIZE)
local buildings = map.surface.find_entities_filtered(query)
local counts = map.chunkScanCounts
for i=1,#constants.HIVE_BUILDINGS_TYPES do
counts[constants.HIVE_BUILDINGS_TYPES[i]] = 0
end
for i=1,#buildings do
local building = buildings[i]
local hiveType = constants.BUILDING_HIVE_TYPE_LOOKUP[building.name] or
(((building.type == "turret") and "turret") or "biter-spawner")
counts[hiveType] = counts[hiveType] + 1
end
print(game.tick, serpent.dump(counts))
end
function tests.showMovementGrid()
local chunks = global.map.processQueue
for i=1,#chunks do
local chunk = chunks[i]
local color = "concrete"
if (chunkPropertyUtils.getPassable(global.map, chunk) == constants.CHUNK_ALL_DIRECTIONS) then
color = "hazard-concrete-left"
elseif (chunkPropertyUtils.getPassable(global.map, chunk) == constants.CHUNK_NORTH_SOUTH) then
color = "concrete"
elseif (chunkPropertyUtils.getPassable(global.map, chunk) == constants.CHUNK_EAST_WEST) then
color = "stone-path"
end
chunkUtils.colorChunk(chunk.x, chunk.y, color, game.get_surface(global.natives.activeSurface))
end
end
function tests.colorResourcePoints()
local chunks = global.map.processQueue
for i=1,#chunks do
local chunk = chunks[i]
local color = "concrete"
if (chunk[constants.RESOURCE_GENERATOR] ~= 0) and (chunk[constants.NEST_COUNT] ~= 0) then
color = "hazard-concrete-left"
elseif (chunk[constants.RESOURCE_GENERATOR] ~= 0) then
color = "deepwater"
elseif (chunk[constants.NEST_COUNT] ~= 0) then
color = "stone-path"
end
chunkUtils.colorChunk(chunk.x, chunk.y, color, game.get_surface(global.natives.activeSurface))
end
end
-- function tests.colorResourcePoints()
-- local chunks = global.map.processQueue
-- for i=1,#chunks do
-- local chunk = chunks[i]
-- local color = "concrete"
-- if (chunk[constants.RESOURCE_GENERATOR] ~= 0) and (chunk[constants.NEST_COUNT] ~= 0) then
-- color = "hazard-concrete-left"
-- elseif (chunk[constants.RESOURCE_GENERATOR] ~= 0) then
-- color = "deepwater"
-- elseif (chunk[constants.NEST_COUNT] ~= 0) then
-- color = "stone-path"
-- end
-- chunkUtils.colorChunk(chunk.x, chunk.y, color, game.get_surface(global.natives.activeSurface))
-- end
-- end
function tests.entityStats(name, d)
local playerPosition = game.players[1].position
@ -485,7 +173,7 @@ function tests.exportAiState()
for i=1,#chunks do
local chunk = chunks[i]
local base = chunkPropertyUtils.getChunkBase(map, chunk)
local base = chunk.base
local alignmentCount = 0
if base then
@ -498,21 +186,21 @@ function tests.exportAiState()
s = s .. table.concat({chunk.x,
chunk.y,
chunkPropertyUtils.getCombinedDeathGeneratorRating(map, chunk),
chunkPropertyUtils.getCombinedDeathGeneratorRating(chunk),
chunk[constants.BASE_PHEROMONE],
chunk[constants.PLAYER_PHEROMONE],
chunk[constants.RESOURCE_PHEROMONE],
chunk[constants.ENEMY_PHEROMONE],
chunkPropertyUtils.getPassable(map, chunk),
chunkPropertyUtils.getPassable(chunk),
chunk[constants.CHUNK_TICK],
chunkPropertyUtils.getPathRating(map, chunk),
chunkPropertyUtils.getNestCount(map, chunk),
chunkPropertyUtils.getTurretCount(map, chunk),
chunkPropertyUtils.getRallyTick(map, chunk),
chunkPropertyUtils.getRetreatTick(map, chunk),
chunkPropertyUtils.getResourceGenerator(map, chunk),
chunkPropertyUtils.getPlayerBaseGenerator(map, chunk),
chunkPropertyUtils.getCombinedDeathGenerator(map, chunk),
chunkPropertyUtils.getPathRating(chunk),
chunk.nestCount or 0,
chunk.turretCount or 0,
chunkPropertyUtils.getRallyTick(chunk) or 0,
chunkPropertyUtils.getRetreatTick(chunk) or 0,
chunk.resourceGenerator or 0,
chunk.playerBaseGenerator or 0,
chunkPropertyUtils.getCombinedDeathGenerator(chunk),
scoreResourceLocationKamikaze(map, chunk),
scoreResourceLocation(map, chunk),
scoreSiegeLocationKamikaze(map, chunk),
@ -520,14 +208,14 @@ function tests.exportAiState()
scoreAttackKamikazeLocation(map, chunk),
scoreAttackLocation(map, chunk),
game.get_surface(game.players[1].surface.index).get_pollution(chunk),
chunkPropertyUtils.getNestActiveness(map, chunk),
chunkPropertyUtils.getRaidNestActiveness(map, chunk),
table_size(chunkPropertyUtils.getSquadsOnChunk(map, chunk)),
(chunkPropertyUtils.isActiveNest(chunk) and 1) or 0,
(chunkPropertyUtils.isActiveRaidNest(chunk) and 1) or 0,
table_size(chunk.squads or {}),
alignmentCount,
chunkPropertyUtils.getHiveCount(map, chunk),
chunkPropertyUtils.getTrapCount(map, chunk),
chunkPropertyUtils.getUtilityCount(map, chunk),
global.universe.chunkToVictory[chunk] or 0
chunk.hiveCount or 0,
chunk.trapCount or 0,
chunk.utilityCount or 0,
global.universe.chunkToVictory[chunk.id] or 0
}, ",") .. "\n"
end
game.write_file("rampantState.txt", s, false)
@ -548,107 +236,8 @@ function tests.exportAiState()
end
end
function tests.createEnergyTest(x)
local entity = tests.createEnemy(x)
local playerPosition = game.players[1].position
local chunkX = math.floor(playerPosition.x * 0.03125) * 32
local chunkY = math.floor(playerPosition.y * 0.03125) * 32
local entities = game.get_surface(global.natives.activeSurface).find_entities_filtered({area={{chunkX, chunkY},
{chunkX + constants.CHUNK_SIZE, chunkY + constants.CHUNK_SIZE}},
type = "electric-pole",
force="player"})
-- for i=1, #entities do
-- print(entities[i].name)
-- end
local wires
if #entities > 0 then
entity.connect_neighbour(entities[1])
end
-- if wires then
-- for connectType,neighbourGroup in pairs(wires) do
-- if connectType == "copper" then
-- for _,v in pairs(neighbourGroup) do
-- ;
-- end
-- end
-- end
-- end
end
-- function tests.unitGroupBuild()
-- local surface = game.get_surface(global.natives.activeSurface)
-- local group = surface.create_unit_group({position={-32, -32}})
-- for i=1,10 do
-- group.add_member(surface.create_entity({name="small-biter", position={-32, -32}}))
-- end
-- group.set_command({
-- type = defines.command.build_base,
-- destination = {-64, -64},
-- distraction = defines.distraction.by_enemy,
-- ignore_planner = true
-- })
-- end
function tests.unitGroupBuild()
local surface = game.get_surface(global.natives.activeSurface)
local group = surface.create_unit_group({position={-32, -32}})
for i=1,10 do
group.add_member(surface.create_entity({name="small-biter", position={-32, -32}}))
-- surface.create_entity({name="small-biter", position={-32, -32}})
end
local group2 = surface.create_unit_group({position={32, 32}})
for i=1,10 do
-- group2.add_member(surface.create_entity({name="small-biter", position={32, 32}}))
surface.create_entity({name="small-biter", position={32, 32}})
end
group.destroy()
-- group.set_command({
-- type = defines.command.build_base,
-- destination = {-64, -64},
-- distraction = defines.distraction.by_enemy,
-- ignore_planner = true
-- })
surface.set_multi_command({
command = {
type = defines.command.group,
group = group2,
distraction = defines.distraction.none,
use_group_distraction = false
},
unit_count = 900,
unit_search_distance = 32 * 8
})
end
function tests.dumpEnvironment(x)
print (serpent.dump(global[x]))
end
-- function tests.scanChunkPaths()
-- local surface = game.get_surface(global.natives.activeSurface)
-- local playerPosition = game.players[1].position
-- local chunk = mapUtils.getChunkByPosition(global.map, playerPosition)
-- print("------")
-- print(chunkUtils.scanChunkPaths(chunk, surface, global.map))
-- print("------")
-- end
function tests.stepAdvanceTendrils()
-- for _, base in pairs(global.natives.bases) do
-- tendrilUtils.advanceTendrils(global.map, base, game.get_surface(global.natives.activeSurface), {nil,nil,nil,nil,nil,nil,nil,nil})
-- end
end
return tests

View File

@ -13,279 +13,279 @@
;; 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 AiVisualizer racket
(provide (all-defined-out))
(require "parseState.rkt")
(require racket/gui/base)
(require plot)
(require "parseState.rkt")
(provide (all-from-out "parseState.rkt"))
(require racket/gui/base)
(require plot)
(define CHUNK_SIZE 32)
(define CHUNK_SIZE 32)
(define INVALID_CHUNK (Chunk -1 -1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0))
(define INVALID_CHUNK (Chunk -1 -1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0))
(define windowX 500)
(define windowY 0)
(define windowWidth 1024)
(define windowHeight 1024)
(define windowX 500)
(define windowY 0)
(define windowWidth 1024)
(define windowHeight 1024)
(define activeHighlight null)
(define activeLayer "movement")
(define activeHighlight null)
(define activeLayer "movement")
(define (normalize v low high)
(/ (- v low)
(- high low)))
(define (normalize v low high)
(/ (- v low)
(- high low)))
(define (fromNormalize x low high)
(+ (* (- high low)
x)
low))
(define (fromNormalize x low high)
(+ (* (- high low)
x)
low))
(define (roundTo x digits)
(* (floor (/ x digits))
digits))
(define (roundTo x digits)
(* (floor (/ x digits))
digits))
(define (runIt)
(define frameWithEvents% (class frame%
(define/override (on-subwindow-char r event)
(when (eq? (send event get-key-code) #\c)
(exit))
(super on-subwindow-char r event))
(super-new)))
(define (visualize)
(define frameWithEvents% (class frame%
(define/override (on-subwindow-char r event)
(when (eq? (send event get-key-code) #\c)
(exit))
(super on-subwindow-char r event))
(super-new)))
(define (newFrame width height x y [label ""])
(new frameWithEvents%
[label label]
[width width]
[height height]
[x x]
[y y]))
(define (newFrame width height x y [label ""])
(new frameWithEvents%
[label label]
[width width]
[height height]
[x x]
[y y]))
(define templates (list '(250 750 0 0 "controls")
(list windowWidth windowHeight windowX windowY "map")))
(define frames (map (lambda (frame)
(match-let (((list width height x y name) frame))
(newFrame width height x y name)))
templates))
(define templates (list '(250 750 0 0 "controls")
(list windowWidth windowHeight windowX windowY "map")))
(define frames (map (lambda (frame)
(match-let (((list width height x y name) frame))
(newFrame width height x y name)))
templates))
(define mainFrame (first frames))
(define mapFrame (second frames))
(define mainFrame (first frames))
(define mapFrame (second frames))
(define activeChunkSet null)
(define activeChunkSetLookup null)
(define activeChunkMinMaxSet null)
(define activeChunkSet null)
(define activeChunkSetLookup null)
(define activeChunkMinMaxSet null)
(define topPanel (new panel%
[parent mainFrame]
(alignment '(left top))))
(define topPanel (new panel%
[parent mainFrame]
(alignment '(left top))))
(define botPanel (new panel%
[parent mainFrame]
(alignment '(right bottom))))
(define botPanel (new panel%
[parent mainFrame]
(alignment '(right bottom))))
(define statusBox (new message%
(define statusBox (new message%
[parent topPanel]
[label (~v "")]
[vert-margin 16]))
(define siteBox (new message%
[parent topPanel]
[label (~v "")]
[vert-margin 16]))
(define siteBox (new message%
[parent topPanel]
[label ""]
[vert-margin 30]))
(define siteBox2 (new message%
[parent topPanel]
[label ""]
[horiz-margin 300]))
(define siteBox3 (new message%
[parent topPanel]
[label ""]
[vert-margin 300]))
[label ""]
[vert-margin 30]))
(define siteBox2 (new message%
[parent topPanel]
[label ""]
[horiz-margin 300]))
(define siteBox3 (new message%
[parent topPanel]
[label ""]
[vert-margin 300]))
(new button%
[parent mainFrame]
[label "Quit"]
(callback (lambda (button event)
(exit))))
(new button%
[parent mainFrame]
[label "Quit"]
(callback (lambda (button event)
(exit))))
(define tileWidth 0)
(define tileHeight 0)
(define tileWidth 0)
(define tileHeight 0)
(define minX 0)
(define maxX 0)
(define minY 0)
(define maxY 0)
(define minX 0)
(define maxX 0)
(define minY 0)
(define maxY 0)
(define canvasWithEvents% (class canvas%
(define/override (on-event event)
(match (send event get-event-type)
((== 'motion) (displayChunk (send event get-x) (send event get-y)))
((== 'left-down) (displayHighlight (send event get-x) (send event get-y)))
((== 'right-down) (begin (set! activeHighlight null)
(refresh (send this get-dc))))
(t (super on-event event))))
(super-new)))
(define canvasWithEvents% (class canvas%
(define/override (on-event event)
(match (send event get-event-type)
((== 'motion) (displayChunk (send event get-x) (send event get-y)))
((== 'left-down) (displayHighlight (send event get-x) (send event get-y)))
((== 'right-down) (begin (set! activeHighlight null)
(refresh (send this get-dc))))
(t (super on-event event))))
(super-new)))
(define (refresh dc)
(when (not (null? dc))
(drawFrame dc)))
(define (refresh dc)
(when (not (null? dc))
(drawFrame dc)))
(define drawFrame (lambda (context)
null))
(define drawFrame (lambda (context)
null))
(define canvass (map (lambda (frame)
(let ((c (new canvasWithEvents%
[parent frame]
[paint-callback (lambda (canvas dc)
(drawFrame dc))])))
(send c set-canvas-background (make-object color% 111 111 111))
c))
(cdr frames)))
(define dcs (map (lambda (canvas)
(send canvas get-dc))
canvass))
(define canvass (map (lambda (frame)
(let ((c (new canvasWithEvents%
[parent frame]
[paint-callback (lambda (canvas dc)
(drawFrame dc))])))
(send c set-canvas-background (make-object color% 111 111 111))
c))
(cdr frames)))
(define dcs (map (lambda (canvas)
(send canvas get-dc))
canvass))
(define (showVisual dc aiState)
(let* ((chunkMinMaxes (AiState-minMaxes aiState))
(minMaxX (ChunkRange-x chunkMinMaxes))
(minMaxY (ChunkRange-y chunkMinMaxes)))
(set! activeChunkSet (AiState-chunks aiState))
(set! activeChunkMinMaxSet chunkMinMaxes)
(set! activeChunkSetLookup (AiState-chunksLookup aiState))
(define (showVisual dc aiState)
(let* ((chunkMinMaxes (AiState-minMaxes aiState))
(minMaxX (ChunkRange-x chunkMinMaxes))
(minMaxY (ChunkRange-y chunkMinMaxes)))
(set! activeChunkSet (AiState-chunks aiState))
(set! activeChunkMinMaxSet chunkMinMaxes)
(set! activeChunkSetLookup (AiState-chunksLookup aiState))
(when (Chunk? activeHighlight)
(set! activeHighlight (findChunk (Chunk-x activeHighlight)
(Chunk-y activeHighlight))))
(when (Chunk? activeHighlight)
(set! activeHighlight (findChunk (Chunk-x activeHighlight)
(Chunk-y activeHighlight))))
(set! minX (MinMax-min minMaxX))
(set! maxX (MinMax-max minMaxX))
(set! minY (MinMax-min minMaxY))
(set! maxY (MinMax-max minMaxY))
(set! minX (MinMax-min minMaxX))
(set! maxX (MinMax-max minMaxX))
(set! minY (MinMax-min minMaxY))
(set! maxY (MinMax-max minMaxY))
(set! tileWidth (ceiling (/ windowWidth (+ (abs (/ (- maxX minX) CHUNK_SIZE)) 3))))
(set! tileHeight (ceiling (/ windowHeight (+ (abs (/ (- maxY minY) CHUNK_SIZE)) 3))))
(set! tileWidth (ceiling (/ windowWidth (+ (abs (/ (- maxX minX) CHUNK_SIZE)) 3))))
(set! tileHeight (ceiling (/ windowHeight (+ (abs (/ (- maxY minY) CHUNK_SIZE)) 3))))
(refresh dc)
(refresh dc)
(thread (lambda ()
(sync (filesystem-change-evt "/mnt/gallery/gameFiles/factorio/script-output/rampantState.txt"))
(showVisual dc (readState "/mnt/gallery/gameFiles/factorio/script-output/rampantState.txt"))))))
(thread (lambda ()
(sync (filesystem-change-evt "/mnt/gallery/gameFiles/factorio/script-output/rampantState.txt"))
(showVisual dc (readState "/mnt/gallery/gameFiles/factorio/script-output/rampantState.txt"))))))
(define dcMap (first dcs))
(define dcMap (first dcs))
(showVisual dcMap (readState "/mnt/gallery/gameFiles/factorio/script-output/rampantState.txt"))
(showVisual dcMap (readState "/mnt/gallery/gameFiles/factorio/script-output/rampantState.txt"))
(define (chunkX->screenX x)
(roundTo (* (normalize x minX maxX)
windowWidth)
tileWidth))
(define (chunkX->screenX x)
(roundTo (* (normalize x minX maxX)
windowWidth)
tileWidth))
(define (chunkY->screenY y)
(roundTo (* (normalize y minY maxY)
windowHeight)
tileHeight))
(define (chunkY->screenY y)
(roundTo (* (normalize y minY maxY)
windowHeight)
tileHeight))
(define (screenX->chunkX x)
(roundTo (fromNormalize (/ x windowWidth)
minX
maxX)
CHUNK_SIZE))
(define (screenX->chunkX x)
(roundTo (fromNormalize (/ x windowWidth)
minX
maxX)
CHUNK_SIZE))
(define (screenY->chunkY y)
(roundTo (fromNormalize (/ y windowHeight)
minY
maxY)
CHUNK_SIZE))
(define (screenY->chunkY y)
(roundTo (fromNormalize (/ y windowHeight)
minY
maxY)
CHUNK_SIZE))
(set! drawFrame (lambda (context)
(send context suspend-flush)
(send context clear)
(let ((chunkField (eval (string->symbol (string-append "Chunk-" activeLayer))))
(chunkRangeField (eval (string->symbol (string-append "ChunkRange-" activeLayer)))))
(map (lambda (chunk)
(let ((x (chunkX->screenX (Chunk-x chunk)))
(y (chunkY->screenY (Chunk-y chunk))))
(if (eq? activeHighlight chunk)
(send context set-pen (make-object color% 255 255 255) 1 'solid)
(send context set-pen (make-object color% 0 0 0) 1 'solid))
(define (dcDraw dc property minMax)
(scaleColor dc property (MinMax-min minMax) (MinMax-max minMax))
(send dc draw-rectangle x y tileWidth tileHeight))
(dcDraw context
(chunkField chunk)
(chunkRangeField activeChunkMinMaxSet))))
activeChunkSet))
(send context resume-flush)))
(set! drawFrame (lambda (context)
(send context suspend-flush)
(send context clear)
(let ((chunkField (eval (string->symbol (string-append "Chunk-" activeLayer))))
(chunkRangeField (eval (string->symbol (string-append "ChunkRange-" activeLayer)))))
(map (lambda (chunk)
(let ((x (chunkX->screenX (Chunk-x chunk)))
(y (chunkY->screenY (Chunk-y chunk))))
(if (eq? activeHighlight chunk)
(send context set-pen (make-object color% 255 255 255) 1 'solid)
(send context set-pen (make-object color% 0 0 0) 1 'solid))
(define (dcDraw dc property minMax)
(scaleColor dc property (MinMax-min minMax) (MinMax-max minMax))
(send dc draw-rectangle x y tileWidth tileHeight))
(dcDraw context
(chunkField chunk)
(chunkRangeField activeChunkMinMaxSet))))
activeChunkSet))
(send context resume-flush)))
(define (findChunk x y)
(hash-ref activeChunkSetLookup (list x y) INVALID_CHUNK))
(define (findChunk x y)
(hash-ref activeChunkSetLookup (list x y) INVALID_CHUNK))
(define (displayChunk x y)
(let ((chunk (if (Chunk? activeHighlight)
activeHighlight
(findChunk (screenX->chunkX x)
(screenY->chunkY y)))))
(send siteBox set-label
(chunk->string chunk))
(send siteBox2 set-label
(chunk->string2 chunk))
(send siteBox3 set-label
(chunk->string3 chunk))))
(define (displayChunk x y)
(let ((chunk (if (Chunk? activeHighlight)
activeHighlight
(findChunk (screenX->chunkX x)
(screenY->chunkY y)))))
(send siteBox set-label
(chunk->string chunk))
(send siteBox2 set-label
(chunk->string2 chunk))
(send siteBox3 set-label
(chunk->string3 chunk))))
(define (displayHighlight x y)
;; (display (list (screenX->chunkX x)
;; (screenY->chunkY y)
;; x
;; y))
;; (display "\n")
(define (displayHighlight x y)
;; (display (list (screenX->chunkX x)
;; (screenY->chunkY y)
;; x
;; y))
;; (display "\n")
(let ((chunk (findChunk (screenX->chunkX x)
(screenY->chunkY y))))
(set! activeHighlight chunk))
(refresh dcMap))
(let ((chunk (findChunk (screenX->chunkX x)
(screenY->chunkY y))))
(set! activeHighlight chunk))
(refresh dcMap))
(define (normalizeLog x low high)
(if (= (- high low) 0)
0
(/ (- x low)
(- high low))))
(define (normalizeLog x low high)
(if (= (- high low) 0)
0
(/ (- x low)
(- high low))))
(define (scaleColor dc value low high)
(let* ((v (normalizeLog value low high))
(r (cond ((= v 0) 0)
((> 0.75 v) 150)
((> 0.50 v) 100)
(#t 50)))
(g (inexact->exact (round (* v 255)))))
(send dc
set-brush
(make-object color%
(min (max r 0) 255)
(min (max g 0) 255)
0)
'solid)))
(define (scaleColor dc value low high)
(let* ((v (normalizeLog value low high))
(r (cond ((= v 0) 0)
((> 0.75 v) 150)
((> 0.50 v) 100)
(#t 50)))
(g (inexact->exact (round (* v 255)))))
(send dc
set-brush
(make-object color%
(min (max r 0) 255)
(min (max g 0) 255)
0)
'solid)))
(new button%
[parent mainFrame]
[label "Retry"]
(callback (lambda (button event)
(showVisual dcMap (readState "/mnt/gallery/gameFiles/factorio/script-output/rampantState.txt")))))
(new button%
[parent mainFrame]
[label "Retry"]
(callback (lambda (button event)
(showVisual dcMap (readState "/mnt/gallery/gameFiles/factorio/script-output/rampantState.txt")))))
(new radio-box%
[label "Show Layer"]
[choices (list "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")]
[selection 0]
[parent botPanel]
(callback (lambda (radioButton event)
(set! activeLayer (send radioButton get-item-label (send radioButton get-selection)))
(refresh dcMap))))
(map (lambda (f)
(send f show #t))
frames))
(runIt)
(new radio-box%
[label "Show Layer"]
[choices (list "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")]
[selection 0]
[parent botPanel]
(callback (lambda (radioButton event)
(set! activeLayer (send radioButton get-item-label (send radioButton get-selection)))
(refresh dcMap))))
(map (lambda (f)
(send f show #t))
frames)))