Help with recursion

Trying to create a grid like you would make binary trees, using recursion.

I’m kinda confused by it atm thought so i’m wondering if anyone can solve it

My code:

local SS = game:GetService("ServerStorage")
local Zone = SS:WaitForChild("Zone")

local XMax = 5
local YMax = 5

local function MakeZoneObject(X, Y)
	local NewZone = {}
	NewZone.Part = Zone:Clone()
	if X < XMax then
		X = X + 1
		NewZone.Right = MakeZoneObject(X, Y)
		print("Created X part:")
	else
		X = 0
		if Y < YMax then
			Y = Y + 1
			NewZone.Up = MakeZoneObject(X, Y)
			print("Created Y part:")
		end
	end
	return NewZone
end

local Map = MakeZoneObject(1, 1)

The current output:

Expected output: I want it to simulate a 5 x 5 grid, so it would create a block, then a block to it’s right 4 times, then go up one block from the start, then 4 blocks to the right of that, and so on (This isn’t for a game, just to understand recursion better)

2 Likes

I’m not sure I understood your question correctly, but anyway here is my answer

local XMax = 5
local YMax = 5

local fcol 
fcol = function (y, x)
	if y <= 1 then
		return {"Zone" .. tostring(x) .. tostring(y)}
	else
		local row = fcol(y - 1, x)
		table.insert(row, "Zone" .. tostring(x) .. tostring(y))
		return row
	end
end

local frow
frow = function (x)
	if x <= 1 then
		return {fcol(YMax, x)}
	else
		local matrix = frow(x - 1)
		table.insert(matrix, fcol(YMax, x))
		return matrix
	end
end

local map = frow(XMax)

print(map)

look at the output

Your problem is that you’re setting X back to 0 as the starting point for every Y addition. Your starting point is X = 1, Y = 1 as defined in the function call parameters, but you’re setting the X back to 0 every time you update the Y, resulting in an incorrect grid.

You should change it to:

	else
	    X = 1

Because you want to make a 5 by 5 grid, not a 6 by 5 grid. Why does it run 6 times you may ask? With X as 0, your if statement will start counting from 0, add 1 to it until it has ran 6 times to make X = 5.

After making this change, this is the expected grid output visualized by parts:
expectedgrid

Would this output go up one after the 5th block to the right and then create 4 more blocks to the right of that one, instead of going up one block from the start and creating 4 more blocks to the right of that though?

No, it wouldn’t. Sorry I misunderstood your question.

This is what it currently does and this is what I thought you wanted:
clip

Yes that is what I wanted. But when the 5th part creates a newzone.right, won’t that end up being the part at the start of the next row? Since X is == XMax, so the 5th part’s newzone.right will be set to an up part, when the first newzone.up part should be the newzone.up of the first part made (since it’s directly above it)

1 Like

I understand now what you’re trying to do, so you’re returning the values of each recursion to the map. This creates the following output which is not according to the mapping:
wrong

In order to correct this, make the following change in your code:

if X <= XMax then

I’ve tested this on a XMax = 2 and YMax = 2 and (1, 1) as the function parameter starting point and it seems to give the correct mapping output (should work on 5 by 5 but the output is too long for me to debug):
right

Here’s the full code:

local SS = game:GetService("ServerStorage")
local Zone = SS:WaitForChild("Zone")

local XMax = 5
local YMax = 5

local function MakeZoneObject(X, Y)
	local NewZone = {}
	if X <= XMax then
		X = X + 1
		NewZone.Right = MakeZoneObject(X, Y)
		print("Created X part:")
	else
		X = 1
		if Y < YMax then
			Y = Y + 1
			NewZone.Up = MakeZoneObject(X, Y)
			print("Created Y part:")
		end
	end
	return NewZone
end

local Map = MakeZoneObject(1, 1)

Tested by making a 3 by 3 grid:
correctgrid

So since we’re making X <= XMax, we’re making it loop to its maximum 5 and returning that value. With X < XMax it’s ignoring the max value and staying 1 below its maximum limit.

1 Like