Anyone who knows about railroads and fixed block signaling would have an easier time understanding my situation.
I am working on a plugin that is supposed to mimic a railroad interlocking control panel. You can fill the upper and lower levels of a tile (frame on screenGUI) with lines representing tracks, and based on the direction of the line you pick, new tiles open up adjacently to be filled with more tracks. There is an option to select a specific side/point of a tile, either Top, Bottom, Left, or Right. You can decide if this point, along with its adjacent point of the adjacent tile (example - if the bottom point of a tile (lower or upper level) is a block boundary, then the top of the tile below it (lower or upper level) will automatically be a block boundary as well. In order to define blocks of track by finding the connections between tiles, I wrote this recursive function. It is so long because it accounts for times that a point has more than one connection within a tile (example - the left side of a tile is connected to both the top and the right), and also when a block of track takes up more than one tile.
local function adjustBlocks(ti, lvl, pt, num)
local mainPos = getTilePos(ti)
local mainX = mainPos[1]
local mainY = mainPos[2]
local tilePt = tilePointData[ti][lvl][pt]
local inbound = {}
if tilePt.blockBoundary == true then inbound[#inbound + 1] = {Tile = ti, Level = lvl, Point = pt} end
local outbound = {}
local function blockRec()
local A
local B
if num % 2 == 0 then
A = inbound
B = outbound
else
A = outbound
B = inbound
end
local connection = tilePt.connectedPoint
if typeof(connection) == "string" then
local otherPoint = tilePointData[ti][lvl][connection]
local otherConnection = otherPoint.connectedPoint
if otherPoint.blockBoundary == true then
A[#A + 1] = {Tile = ti, Level = lvl, Point = connection}
else
if typeof(otherConnection) == "table" then
for i = 1, #otherConnection do
if otherConnection[i] ~= pt then
local secondaryPoint = tilePointData[ti][lvl][otherConnection[i]]
print(secondaryPoint)
if secondaryPoint.blockBoundary == true then
B[#B + 1] = {Tile = ti, Level = lvl, Point = otherConnection[i]}
else
if secondaryPoint.adjLevel then
if otherConnection[i] == "Top" then
blockRec(tiles[mainX][mainY - 1], secondaryPoint.adjLevel, "Bottom", num + 1)
elseif otherConnection[i] == "Bottom" then
blockRec(tiles[mainX][mainY + 1], secondaryPoint.adjLevel, "Top", num + 1)
elseif otherConnection[i] == "Right" then
blockRec(tiles[mainX + 1][mainY], secondaryPoint.adjLevel, "Left", num + 1)
elseif otherConnection[i] == "Left" then
blockRec(tiles[mainX - 1][mainY], secondaryPoint.adjLevel, "Right", num + 1)
end
end
end
end
end
else
if otherPoint.adjLevel then
if connection == "Top" then
blockRec(tiles[mainX][mainY - 1], otherPoint.adjLevel, "Bottom", num)
elseif connection == "Bottom" then
blockRec(tiles[mainX][mainY + 1], otherPoint.adjLevel, "Top", num)
elseif connection == "Right" then
blockRec(tiles[mainX + 1][mainY], otherPoint.adjLevel, "Left", num)
elseif connection == "Left" then
blockRec(tiles[mainX - 1][mainY], otherPoint.adjLevel, "Right", num)
end
end
end
end
elseif typeof(connection) == "table" then
for i = 1, #connection do
local otherPoint = tilePointData[ti][lvl][connection[i]]
local otherConnection = otherPoint.connectedPoint
if otherPoint.blockBoundary == true then
B[#B + 1] = {Tile = ti, Level = lvl, Point = connection[i]}
else
if typeof(otherConnection) == "table" then
for i = 1, #otherConnection do
if otherConnection[i] ~= pt then
local secondaryPoint = tilePointData[ti][lvl][otherConnection[i]]
if secondaryPoint.blockBoundary == true then
A[#A + 1] = {Tile = ti, Level = lvl, Point = otherConnection[i]}
else
if secondaryPoint.adjLevel then
if otherConnection[i] == "Top" then
blockRec(tiles[mainX][mainY - 1], secondaryPoint.adjLevel, "Bottom", num)
elseif otherConnection[i] == "Bottom" then
blockRec(tiles[mainX][mainY + 1], secondaryPoint.adjLevel, "Top", num)
elseif otherConnection[i] == "Right" then
blockRec(tiles[mainX + 1][mainY], secondaryPoint.adjLevel, "Left", num)
elseif otherConnection[i] == "Left" then
blockRec(tiles[mainX - 1][mainY], secondaryPoint.adjLevel, "Right", num)
end
end
end
end
end
else
if otherPoint.adjLevel then
if connection == "Top" then
blockRec(tiles[mainX][mainY - 1], otherPoint.adjLevel, "Bottom", num)
elseif connection == "Bottom" then
blockRec(tiles[mainX][mainY + 1], otherPoint.adjLevel, "Top", num)
elseif connection == "Right" then
blockRec(tiles[mainX + 1][mainY], otherPoint.adjLevel, "Left", num)
elseif connection == "Left" then
blockRec(tiles[mainX - 1][mainY], otherPoint.adjLevel, "Right", num)
end
end
end
end
end
end
end
blockRec()
return {inbound, outbound}
end
The function only works properly when it only has to traverse one tile to define each block (if two tiles are connected by straight tracks, then I can make the point where they meet a block boundary without a problem). However, if the function actually needs to be recursive (the function needs to search the next tile), there is a stack overflow, and the output says that there were over 16000 instances of recursion, even though there were only 3 tiles I was trying to connect. How can I prevent this problem?
