I have got only one question. How do I change the parenthesis in the GetNeighbors function?
Iâm not quite sure what you mean here.
Also sorry. Totally forgot I was going to look into that more.
The value in brackets for function seem to be called âParenthesisâ. If not wrong, when making a local function, the âParenthesisâ is just name for some object or value, but when we call for function, we replace that with the value we want:
local function Mathematics(a, b) -- a and b are both parenthesis in this scenario
local result = a - b
return result
end
-- calling function
print(Mathematics(10, 6)) -- parenthesis is replaced for what we want
-- result for print should be 4
But I actually thought of this, and it seems that I can just make a local like âupcomingâ, and change the instance for that local at the end of each iteration. Did not test it yet, but going to soon.
In idea is it is something like that:
local upcoming == ___ -- Some node
local function GetNeighbors(center)
-- code, bla bla bla, code
end
GetNeighbors(upcoming)
Did I understand it right, and would that even work?
Ahh. I think the term you mean is parameter. In this case yes, âcenterâ is a parameter for the function. So getNeighbors returns a list of neighbors for any node you pass in (the naming I chose could have been more clear, but I was trying to keep some of your variable names to make the relationship between my code and yours more direct).
In this case the parameter is meant to be the cheapest node in the openList that gets passed in since thatâs the one you are checking each time.
So as we loop we get what we assume is the cheapest node. We pull that from the open list. Get itâs neighbors (getNeighbor(currentNode)) and loop through each of those neighbors adding them to the open list if they donât already exist (or update them if they do). Finally checking to see if the finish is in the open list and generate the path from that.
Yeah, so I guess my example should work?
I believe so. Yes.
(Message length requirements).
Ok then, I will now attempt to make another one version of code with all the new data. Hope I can post it later today, thanks again for your help.
I made a new version which is quite successful. However, I ran into an issue. It seems that for some reason, only one part is being added into the âneighborsListâ, even though it used to put more before. I donât really know why this happens. Other than getting surrounded by âlockedListâ parts eventually, it works pretty well. Here is the code:
local active = false
local finish = workspace.Nodes.Finish
local start = workspace.Nodes.Start
local upComing
local Nodes = workspace.Nodes:GetChildren()
local openList = {}
local closedList = {}
local function GetNeighbors(Center) -- Get neighbors of current node, AKA upcoming
local neighbors = {}
for i, node in pairs(Nodes) do
if math.abs(node.Position.X / 8) == math.abs(Center.Position.X / 8) and math.abs(node.Position.Z / 8) == math.abs(Center.Position.Z / 8) + 1 then
table.insert(neighbors, node)
elseif math.abs(node.Position.X / 8) == math.abs(Center.Position.X / 8) and math.abs(node.Position.Z / 8) == math.abs(Center.Position.Z / 8) - 1 then
table.insert(neighbors, node)
elseif math.abs(node.Position.X / 8) == math.abs(Center.Position.X / 8) + 1 and math.abs(node.Position.Z / 8) == math.abs(Center.Position.Z / 8) then
table.insert(neighbors, node)
elseif math.abs(node.Position.X / 8) == math.abs(Center.Position.X / 8) - 1 and math.abs(node.Position.Z / 8) == math.abs(Center.Position.Z / 8) then
table.insert(neighbors, node)
end
end
return neighbors
end
local function UpdateNeighbors(Center, Neighbors) -- Detect if neighbors are occupied or already in openList
for i, neighbor in pairs(Neighbors) do
if table.find(closedList, neighbor) then continue end
if table.find(openList, neighbor) then
if neighbor:GetAttribute("MoveCost") == not 0 and neighbor:GetAttribute("MoveCost") < Center:GetAttribute("MoveCost") + 1 then
continue
end
end
local mCost = Center:GetAttribute("MoveCost") + 1
neighbor:SetAttribute("MoveCost", mCost)
local hCost = math.abs(finish.Position.X / 8 - neighbor.Position.X / 8) + math.abs(finish.Position.Z / 8 - neighbor.Position.Z / 8)
neighbor:SetAttribute("TotalCost", mCost + hCost)
neighbor:SetAttribute("CameFrom", Center.CFrame)
table.insert(openList, neighbor)
table.remove(openList, table.find(openList, Center))
table.insert(closedList, Center)
end
end
local function UpdateNodes() -- Update nodes: Their color and list references
for i, node in pairs(Nodes) do
if node:GetAttribute("Occupied") == true and table.find(closedList, node) then
continue
elseif node:GetAttribute("Occupied") == true and not table.find(closedList, node) then
table.insert(closedList, node)
end
if table.find(closedList, node) and node:GetAttribute("Occupied") == true then
node.Color = Color3.fromRGB(60, 0, 0)
elseif table.find(closedList, node) and node:GetAttribute("Occupied") == false then
node.Color = Color3.fromRGB(60, 60, 60)
elseif table.find(openList, node) then
node.Color = Color3.fromRGB(0, 180, 240)
end
end
end
local function GetUpcoming() -- Get best part for the next iteration
local Costs = {}
for i, node in pairs(openList) do
local tCost = node:GetAttribute("TotalCost")
table.insert(Costs, tCost)
end
local bestCost = math.min(unpack(Costs))
for i, node in pairs(openList) do
if node:GetAttribute("TotalCost") == bestCost then
upComing = node
break
else
continue
end
end
return upComing
end
local function Cycle()
repeat
UpdateNodes()
task.wait(1)
UpdateNeighbors(upComing, GetNeighbors(upComing))
task.wait(1)
GetUpcoming()
print(GetUpcoming())
until table.find(openList, finish)
end
script.Parent.MouseClick:Connect(function()
table.insert(openList, start)
upComing = start
Cycle()
end)
FIXED
Dude, I finally managed to make somewhat working! Look at that!
I will drop you the copy of the place so you can see for yourself, the process is quite satisfying!
Just added some decals and scaled the nodes for cooler visualisation.
Thatâs awesome! Iâm glad you got it working.
I am gonna try to develop the place with this algorithm. First I am currently trying to make some sort of a computer, on which player can choose their own field size. Then I am gonna add a tool that would choose the regular tiles to walls, and walls to tiles. Overall, as of now figuring out how buttons work, and made some sort of 2 working pages.
Main menu:
Edit menu:
Once everything works, I will probably make place public.
Made this trowel tool, that allows to change state of a part between a wall or regular tile. Gonna make 2 other tools, AKA flags for start and finish, to mark the corresponding tiles. Generating menu is also almost done, having just slight issues with remote events.
In theory, the game is ready to be released. The main functions work well, except the button. ClickDetectors and Tools seem to be confronting, and the button is just not pressed after interacting with tool, so I had to replace click detector with proximity prompt. I also didnât finalize function for random size generation, and currently adjusting tools functions.
I fixed click detector and tools issue. Just had to unbind action before deleting tool.
I think it is ready for the first test. I made the main functions of the game work properly. There might be still some issues that I did not think about. 1 button, âRandomâ, does not work as well because it is not as necessary as others, so I did not touch it yet. All the other buttons should work. Game link:
I guess that is it for now. Really like what I came out with, learned lots of new stuff. I probably will give solution to tlr22 because he helped me the most.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.