Skip to content

Commit

Permalink
hmmm
Browse files Browse the repository at this point in the history
  • Loading branch information
senloris committed Feb 24, 2024
1 parent 5e616ab commit cc28373
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 40 deletions.
9 changes: 9 additions & 0 deletions src/common/binaryHeap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ require('coordinate')
BinaryHeap = {}
BinaryHeap.__index = BinaryHeap

function BinaryHeap:__tostring()
local str = "BinaryHeap: {"
for i, v in ipairs(self.heap) do
str = str .. "\n\t" .. tostring(v.coordinate) .. " : " .. v.priority
end
str = str .. "\n}"
return str
end

function BinaryHeap:new()
local newHeap = {}
setmetatable(newHeap, self)
Expand Down
11 changes: 6 additions & 5 deletions src/common/coordinate.lua
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,16 @@ Coordinate = {
}

function Coordinate.parse(o)
if type(o) == "table" then
if getmetatable(o) == Coordinate then
return o
elseif type(o) == "table" then
if o.x and o.y and o.z then
return Coordinate:new(o.x, o.y, o.z, o.direction or directions.any)
elseif type(o[1]) == "number" and type(o[2]) == "number" and type(o[3]) == "number" then
return Coordinate:new(o[1], o[2], o[3], o[4] or directions.any)
else
error("Invalid arguments for Coordinate.parse")
end
elseif getmetatable(o) == Coordinate then
return o
elseif o == nil then
return nil
else
Expand Down Expand Up @@ -155,14 +155,15 @@ function Coordinate:__tostring()
return "["..self.x..", "..self.y..", "..self.z.."]"
end

function Coordinate:__eq(o, t)
function Coordinate.__eq(o, t)
logger:debug("Comparing " .. tostring(o) .. " and " .. tostring(t))
if getmetatable(t) ~= Coordinate then
t = Coordinate.parse(t)
end
if getmetatable(o) ~= Coordinate then
o = Coordinate.parse(o)
end
if o == t == nil then
if o == nil and t == nil then
return true
elseif o == nil or t == nil then
return false
Expand Down
90 changes: 65 additions & 25 deletions src/common/environment.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require('Logger')

require('coordinate')

local logger = Logger:new(Logger.levels.TRACE, "Environment")
local logger = Logger:new(Logger.levels.DEBUG, "Environment")

blockType = {
WASTE = {},
Expand All @@ -31,44 +31,52 @@ function Environment:getBlockAtPosition(coordinate)
if getmetatable(coordinate) ~= Coordinate then
coordinate = Coordinate.parse(coordinate)
end
local blockType = self.checkedBlocks[coordinate.y] and self.checkedBlocks[coordinate.y][coordinate.x] and self.checkedBlocks[coordinate.y][coordinate.x][coordinate.z] or blockType.UNKNOWN
return blockType
if self.checkedBlocks[coordinate.y] and self.checkedBlocks[coordinate.y][coordinate.x] and self.checkedBlocks[coordinate.y][coordinate.x][coordinate.z] then
local blockType = self.checkedBlocks[coordinate.y][coordinate.x][coordinate.z]
return blockType
else
return blockType.UNKNOWN
end
end

function Environment:getNeighbours(coordinate)
local neighbours = {}
for _, v in pairs(directions) do
local neighbour = coordinate + v.vector
local blockType = self:getBlockAtPosition(neighbour)
table.insert(neighbours, {[v] = {position = neighbour, type = blockType}})
if getmetatable(v) == Direction and v.name ~= "any" then
logger:trace("Checking neighbour in direction " .. tostring(v.name))
local neighbour = coordinate + v.vector
logger:trace("Neighbour in direction " .. tostring(v.name) .. " is at position " .. tostring(neighbour))
local blockType = self:getBlockAtPosition(neighbour)
neighbours[v] = {position = neighbour, type = blockType}
end
end
return neighbours
end

-- load wasteBlocks from file
local function loadWasteBlocks()
logger:debug("Starting to load waste blocks from file")
logger:trace("Starting to load waste blocks from file")
local file = io.open("wasteBlocks", "r")
local line = file:read()
while line do
table.insert(Environment.wasteBlocks, line)
line = file:read()
end
file:close()
logger:debug("Finished loading waste blocks from file")
logger:trace("Finished loading waste blocks from file")
end

-- load fuels from file
local function loadFuels()
logger:debug("Starting to load fuels from file")
logger:trace("Starting to load fuels from file")
local file = io.open("fuels", "r")
local line = file:read()
while line do
table.insert(Environment.fuels, line)
line = file:read()
end
file:close()
logger:debug("Finished loading fuels from file")
logger:trace("Finished loading fuels from file")
end

local function loadBlockers()
Expand Down Expand Up @@ -177,9 +185,17 @@ function Environment:storeFuelLocation(coordinate)
end

function Environment:dijkstra(source, target)
if getmetatable(source) ~= Coordinate then
source = Coordinate.parse(source)
end
if getmetatable(target) ~= Coordinate then
target = Coordinate.parse(target)
end
logger:debug("Starting Dijkstra algorithm from " .. tostring(source) .. " to " .. tostring(target))
local distance = {}
local previous = {}
local queue = BinaryHeap:new()
local visited = {}

for y, row in pairs(self.checkedBlocks) do
for x, column in pairs(row) do
Expand All @@ -190,24 +206,39 @@ function Environment:dijkstra(source, target)
else
distance[coordinate] = math.huge
end
queue:insert(coordinate, distance[coordinate] + self:heuristic(coordinate, target))
queue:insert(coordinate, self:heuristic(coordinate, source) + self:heuristic(coordinate, target))
end
end
end

distance[source] = 0
queue:insert(source, 0)
--queue:insert(source, distance[source] + self:heuristic(source, target))
--queue:insert(target, self:heuristic(source, target))
logger:debug(tostring(queue))
-- sleep for 10 second
-- os.sleep(10)
while not queue:isEmpty() do
local current = queue:pop()
if not visited[current] then
visited[current] = true

if current == target then
break
end
if current == target then
break
end
for direction, data in pairs(self:getNeighbours(current)) do
local alt = distance[current] + self:getCost(data.type)
logger:debug("New calculated distance for " .. tostring(data.position) .. " is " .. tostring(alt))
if distance[data.position] then
--distance[data.position] = math.huge
--queue:insert(data.position, 0)

for direction, data in pairs(self:getNeighbours(current)) do
local alt = distance[current] + self:getCost(data.type)
if alt < distance[data.position] then
distance[data.position] = alt
previous[data.position] = current
queue:decreaseKey(data.position, alt + self:heuristic(data.position, target))
if alt < distance[data.position] then
logger:debug("Updating distance for " .. tostring(data.position) .. " to " .. tostring(alt))
distance[data.position] = alt
previous[data.position] = current
queue:decreaseKey(data.position, alt)
end
end
end
end
end
Expand All @@ -221,16 +252,25 @@ function Environment:dijkstra(source, target)
end
end

-- Add logging here
print("Path length: " .. #path)
for i, distance in ipairs(path) do
print("Step " .. i .. ": from " .. tostring(distance.from) .. " to " .. tostring(distance.to))
end

return path
end

function Environment:getCost(blockType)
if blockType == blockType.FUEL or blockType == blockType.AIR then
function Environment:getCost(_blockType)
if not _blockType then
_blockType = blockType.AIR
end
if _blockType == blockType.FUEL or _blockType == blockType.AIR then
return 1
elseif blockType == blockType.WASTE or blockType == blockType.OTHER then
elseif _blockType == blockType.WASTE or _blockType == blockType.OTHER then
return 10
else
return math.huge
return 1000
end
end

Expand Down
25 changes: 15 additions & 10 deletions tests/src/unitTests.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ function TestCoordinate:testMultiplyCoordinates()
lu.assertEquals(result.z, 6)
end

function TestCoordinate:testEquality()
local coordinate1 = Coordinate:new(1, 2, 3, directions.any)
local coordinate2 = Coordinate:new(1, 2, 3, directions.forward)
lu.assertEquals(coordinate1, coordinate2)
end

TestDirection = {}

function TestDirection:testNewDirection()
Expand Down Expand Up @@ -359,16 +365,15 @@ function TestEnvironment:testDijkstraWithPopulatedCheckedBlocks()
local environment = Environment:new()
local source = Coordinate:new(1, 2, 3)
local target = Coordinate:new(4, 5, 6)
environment.checkedBlocks = {
[2] = {
[1] = { [3] = blockType.AIR },
[2] = { [3] = blockType.AIR },
[3] = { [3] = blockType.AIR },
[4] = { [3] = blockType.AIR },
[5] = { [3] = blockType.AIR },
[6] = { [3] = blockType.AIR }
}
}
for y = 0, 6 do
environment.checkedBlocks[y] = {}
for x = 0, 6 do
environment.checkedBlocks[y][x] = {}
for z = 0, 6 do
environment.checkedBlocks[y][x][z] = blockType.WASTE
end
end
end
local path = environment:dijkstra(source, target)
lu.assertEquals(#path, 3)
lu.assertEquals(path[1].from.x, 1)
Expand Down

0 comments on commit cc28373

Please sign in to comment.