Help with fixing a rotating puzzle

Hi there! So I have created a rotating puzzle, but I need a way to figure out if it has been solved. So far I have been experimenting with scripts from this thread:

I am using their method in detecting this puzzle, with some edits. Basically, how this system works is by taking the absolute values of the “Outlets” at the end of each frame
Screen Shot 2022-01-13 at 10.50.09 pm

This is my maze. At the end of every “Entrance” or “Opening”, there is an invisible outlet.

Basically, I need a reliable algorithm that can detect when all the outlets are lined up. However, as you can see from the picture above, it isn’t exactly lined up like one would hope. The reason it isn’t is because I manually had lay each frame out, because UIGridlayouts don’t support rotation.

So basically, I created a modified version of the script:

local function CheckFinished()
	local CheckComplete = {}

	for i, v in pairs(partsOutlet) do
		if table.find(CheckComplete, v) == nil then
			local AbsP1 = v.AbsolutePosition

			for n, k in pairs(partsOutlet) do
				if v ~= k then
					
					local AbsP2 = k.AbsolutePosition 
					local XValue1 = AbsP1.X
					local YValue1 = AbsP1.Y
					local XValue2 = AbsP2.X
					local YValue2 = AbsP2.Y
					local check1 = false
					local check2 = false

					if XValue1 and YValue1 and XValue2 and YValue2 then
						if XValue1 > XValue2 then
							if XValue1 - XValue2 <= 5 then
								print(XValue1 - XValue2)
								check1 = true
							end
						elseif XValue1 < XValue2 then
							if XValue2 - XValue1 <= 5 then
								print(XValue2 - XValue1)
								check1 = true
							end
						else
							check1 = true
						end

						if YValue1 > YValue2 then
							if YValue1 - YValue2 <= 5 then
								print(YValue1 - YValue2)
								check2 = true
							end
						elseif YValue1 < YValue2 then
							
							if YValue2 - YValue1 <= 5 then
								print(YValue2 - YValue1)
								check2 = true
							end
						else
							check2 = true
						end
					end
					if check1 == true and check2 == true then
						table.insert(CheckComplete, v)
						table.insert(CheckComplete, k)
					end
				end
			end
		end
		
	end

	if #CheckComplete == (#partsOutlet) then

		return true
		
	else
		return false, #CheckComplete, #partsOutlet
	end
end

partsOutlet is a table that I have already inserted all the outlets.
I know it’s kinda inefficient, basically what I am doing is breaking down each absolute position then seeing if their absolute positions are within 5 pixels of each other. if it is, then that means those two outlets are solved, and it puts that into a “solved” table

But for some reason, it’s acting weird. I have a print function that displays how many are completed compared to how many there are. But I get inconsistent and varied results:
This solved puzzle prints 46 / 48

This unsolved puzzle however, prints 48/48

Also note that I added two outlets at the start and the end (the purple things at the start and end) and also 2 squares do not have any outlets due to them being blank.

So I’m just confused at how to approach this right now. If anyone has a better method to check if it is done, or a suitable solution to this problem, that would be great.

Thanks!

1 Like

Hmm, can’t spot the issue. Here’s a simplified version that does the same thing. Maybe it’s easier for you to spot the issue with simpler code?

local function Check2Finished()
	local Connected = {}

	for _, c1 in ipairs(partsOutlet) do
		if Connected[c1] then continue end

		for _, c2 in ipairs(partsOutlet) do
			if c1 == c2 then continue end

			local x1 = c1.AbsolutePosition.X
			local y1 = c1.AbsolutePosition.Y
			local x2 = c2.AbsolutePosition.X
			local y2 = c2.AbsolutePosition.Y

			if math.abs(x1 - x2) <= 5 and math.abs(y1 - y2) <= 5 then
				Connected[c1] = true
				Connected[c2] = true
			end
		end
	end

	local ConnectedArray = {}
	for c, _ in pairs(Connected) do
		table.insert(ConnectedArray, c)
	end
	
	if #ConnectedArray == #partsOutlet then
		return true
	else
		return false, #ConnectedArray, #partsOutlet
	end
end

As for the UIGridLayout rotation issue, have you tried having each grid entry be an un-rotated object and them add rotated children to those? That way the grid layout doesn’t directly interact with any rotated objects.

Hi there! Thanks for this script. So the problem was actually that I was calling it before the puzzle had finished rotating, giving the script incorrect absolute positions which was messing it up. Thanks for the neatened code however :slight_smile:
As for the UI Grid Layout issue, your solution would definitely work in theory but I’m just too lazy to change it now that I got it working. Thanks!

1 Like