Bobert13
Prince
- Joined
- Feb 25, 2013
- Messages
- 346
Humorous topic aside, I'm making this post to ask if anyone has heard of what I'm experiencing or could possibly look over my code and help me figure it out. To make a long story short, I've been optimizing my script and while memoizing a function, I realised that a function I had previously memoized should be outputting the exact same memo table. Now this is where things get real hairy-like...
The functions I'm dealing with are GetNeighbor(plotIndex, direction) which returns the index of the neighbor in the given direction and GetSpiral(plotIndex, minRadius, maxRadius) which I'm calling with radii of 1 and 1 (resulting in a table of neighbors).
I've made some minor tweaks, to both functions, to get the indexes of the tables stored at memoTable[plotIndex] to lineup. However, my spiral iterator appears to be storing it's indexes in whatever order it pleases instead of following the logical work flow of the function... It's literally random! This causes a disparity in the outputs which prevents me from using one memoized table to both return all neighbors of a plot as a list or return a specific neighbor in a given direction.
Lua console output of the tables:
Warning, code wall incoming:
I thought the issue might have been that I had defined a custom table.insert function as a closure within GetSpiral() but as you can see from the code, rolling the function out into the script directly, had no effect. I've not yet tested this behavior on Civ V's lua implementation nor luaJIT but I certainly wouldn't rule out Havok Script as the cause. Is it possible that Havok is optimizing my function in a way that breaks the table inserts (or running the for statements used to actually move the index in some kind of asynchronous parallelism?)
Edit: If anyone would like the whole script to mess with, I'd be happy to provide it (all 5000 lines
).
The functions I'm dealing with are GetNeighbor(plotIndex, direction) which returns the index of the neighbor in the given direction and GetSpiral(plotIndex, minRadius, maxRadius) which I'm calling with radii of 1 and 1 (resulting in a table of neighbors).
I've made some minor tweaks, to both functions, to get the indexes of the tables stored at memoTable[plotIndex] to lineup. However, my spiral iterator appears to be storing it's indexes in whatever order it pleases instead of following the logical work flow of the function... It's literally random! This causes a disparity in the outputs which prevents me from using one memoized table to both return all neighbors of a plot as a list or return a specific neighbor in a given direction.
Lua console output of the tables:
Spoiler :
Code:
Map Script: spiralTab[2439][1] = 2346; neighborTab[2439][1] = 2438
Map Script: spiralTab[2439][2] = 2347; neighborTab[2439][2] = 2530
Map Script: spiralTab[2439][3] = 2438; neighborTab[2439][3] = 2531
Map Script: spiralTab[2439][4] = 2440; neighborTab[2439][4] = 2440
Map Script: spiralTab[2439][5] = 2530; neighborTab[2439][5] = 2347
Map Script: spiralTab[2439][6] = 2531; neighborTab[2439][6] = 2346
Map Script: spiralTab[12][1] = 11; neighborTab[12][1] = 11
Map Script: spiralTab[12][2] = 104; neighborTab[12][2] = 103
Map Script: spiralTab[12][3] = -1; neighborTab[12][3] = 104
Map Script: spiralTab[12][4] = 13; neighborTab[12][4] = 13
Map Script: spiralTab[12][5] = -1; neighborTab[12][5] = -1
Map Script: spiralTab[12][6] = 103; neighborTab[12][6] = -1
Map Script: spiralTab[900][1] = 808; neighborTab[900][1] = 899
Map Script: spiralTab[900][2] = 993; neighborTab[900][2] = 992
Map Script: spiralTab[900][3] = 901; neighborTab[900][3] = 993
Map Script: spiralTab[900][4] = 992; neighborTab[900][4] = 901
Map Script: spiralTab[900][5] = 809; neighborTab[900][5] = 809
Map Script: spiralTab[900][6] = 899; neighborTab[900][6] = 808
Map Script: spiralTab[4308][1] = 4309; neighborTab[4308][1] = 4307
Map Script: spiralTab[4308][2] = 4307; neighborTab[4308][2] = 4399
Map Script: spiralTab[4308][3] = 4216; neighborTab[4308][3] = 4400
Map Script: spiralTab[4308][4] = 4215; neighborTab[4308][4] = 4309
Map Script: spiralTab[4308][5] = 4399; neighborTab[4308][5] = 4216
Map Script: spiralTab[4308][6] = 4400; neighborTab[4308][6] = 4215
Spoiler :
Code:
local spiralTab = {}
local GetSpiral = function (i,maxRadius,minRadius)
local ii = i
local justNeighbors = (minRadius == 1 and maxRadius == 1)
local memoize = false
if justNeighbors then
if spiralTab[ii] then
return spiralTab[ii] --returns the memoized result if it exists
else
memoize = true
end
end
local x = i % mapWidth
local y = (i - x) / mapWidth
local odd = y % 2
local tab = {-1, -1, -1, -1, -1}
local first = true
local index = 1
if minRadius == nil or minRadius == 0 then
tab[index] = i
index = index + 1
minRadius = 1
end
--[[
local Insert = function()
if (i > -1 and i < mapArea) then
--print(i)
tab[index] = i
index = index + 1
else
--print(i)
tab[index] = -1
index = index + 1
end
end
--]]
for r = minRadius, maxRadius, 1 do
if first == true then
--start r to the West on the first spiral
x = x - r
i = i - r
if (x < 0) then
x = x + mapWidth
i = i + mapWidth
end
first = false
else
--go West 1 tile before the next spiral
if x == 0 then
x = mapRight
i = i + mapRight
else
x = x - 1
i = i - 1
end
end
--Insert()
if i > -1 and i < mapArea then
tab[index] = i
index = index + 1
else
tab[index] = -1
index = index + 1
end
--Go r times to the NE
for z = 1, r, 1 do
if x == mapRight and odd == 0 then
x = 0
i = i + 1
else
x = x + odd
i = i + mapWidth + odd
end
--store the index value or -1 if the plot isn't on the map; flip odd
--Insert()
if i > -1 and i < mapArea then
tab[index] = i
index = index + 1
else
tab[index] = -1
index = index + 1
end
if odd == 1 then odd = 0 else odd = 1 end
end
--Go r times to the E
for z = 1, r, 1 do
if x == mapRight then
x = 0
i = i - mapRight
else
x = x + 1
i = i + 1
end
--store the index value or -1 if the plot isn't on the map
--Insert()
if i > -1 and i < mapArea then
tab[index] = i
index = index + 1
else
tab[index] = -1
index = index + 1
end
end
--Go r times to the SE
for z = 1, r, 1 do
if x == mapRight and odd == 0 then
x = 0
i = i - mapWidth - mapRight
else
x = x + odd
i = i - mapWidth + odd
end
--store the index value or -1 if the plot isn't on the map; flip odd
--Insert()
if i > -1 and i < mapArea then
tab[index] = i
index = index + 1
else
tab[index] = -1
index = index + 1
end
if odd == 1 then odd = 0 else odd = 1 end
end
--Go r times to the SW
for z = 1, r, 1 do
if x == 0 and odd == 0 then
x = mapRight
i = i - 1
else
x = x + odd - 1
i = i - mapWidth + odd - 1
end
--store the index value or -1 if the plot isn't on the map; flip odd
--Insert()
if i > -1 and i < mapArea then
tab[index] = i
index = index + 1
else
tab[index] = -1
index = index + 1
end
if odd == 1 then odd = 0 else odd = 1 end
end
--Go r times to the W
for z = 1, r, 1 do
if x == 0 then
x = mapRight
i = i + mapRight
else
x = x - 1
i = i - 1
end
--store the index value or -1 if the plot isn't on the map
--Insert()
if i > -1 and i < mapArea then
tab[index] = i
index = index + 1
else
tab[index] = -1
index = index + 1
end
end
--Go r times to the NW!!!!!
for z = 1, r, 1 do
if x == 0 and odd == 0 then
x = mapRight
i = i + mapWidth + mapRight
else
x = x - 1 + odd
i = i + mapRight + odd
end
--store the index value or -1 if the plot isn't on the map; flip odd
if z ~= r then -- we don't store the last plot in this line as it was stored when we moved West to begin the spiral.
--Insert()
if i > -1 and i < mapArea then
tab[index] = i
index = index + 1
else
tab[index] = -1
index = index + 1
end
end
if odd == 1 then odd = 0 else odd = 1 end
end
end
if memoize then --stores the result for memoization
spiralTab[ii] = tab
end
return tab
end
-------------------------------------------------------------------------------------------
local neighborTab = {}
local GetNeighbor = function (i,dir)
--[[
if spiralTab[i] then
return spiralTab[i][dir]
else
local tab = GetSpiral(i, 1, 1)
return tab[dir]
end
--]]
if neighborTab[i] then
if neighborTab[i][dir] then
return neighborTab[i][dir]
end
else
neighborTab[i] = {}
end
local neighbor
local x = i % mapWidth
local y = (i - x) / mapWidth
local odd = y % 2
if (dir == mc.W) then
if (x == 0) then
neighbor = i + mapRight
else
neighbor = i - 1
end
elseif (dir == mc.NW) then
if (x == 0) and (odd == 0) then
neighbor = i + mapWidth + mapRight
else
neighbor = i + mapRight + odd
end
elseif (dir == mc.NE) then
if (x == mapRight) and (odd == 1) then
neighbor = i + 1
else
neighbor = i + mapWidth + odd
end
elseif (dir == mc.E) then
if (x == mapRight) then
neighbor = i - mapRight
else
neighbor = i + 1
end
elseif (dir == mc.SE) then
if (x == mapRight) and (odd == 1) then
neighbor = i - mapWidth - mapRight
else
neighbor = i - mapWidth + odd
end
else -- dir == mc.SW
if (x == 0) and (odd == 0) then
neighbor = i - 1
else
neighbor = i - mapWidth + odd - 1
end
end
if (neighbor < 0) or (neighbor > mapLength) then
neighbor = -1
end
neighborTab[i][dir] = neighbor
return neighbor
end
I thought the issue might have been that I had defined a custom table.insert function as a closure within GetSpiral() but as you can see from the code, rolling the function out into the script directly, had no effect. I've not yet tested this behavior on Civ V's lua implementation nor luaJIT but I certainly wouldn't rule out Havok Script as the cause. Is it possible that Havok is optimizing my function in a way that breaks the table inserts (or running the for statements used to actually move the index in some kind of asynchronous parallelism?)
Edit: If anyone would like the whole script to mess with, I'd be happy to provide it (all 5000 lines
