Nested list based sorting system?

currently I’m working on a heart sorting system which would be able to take different variants of hearts and sort them by priority into an new list which can then be converted into the gui, however I have reached a point of confusion on how I could get the current system how I intended, currently I can’t even run the code as I can’t use nested lists in order to determine the hearts, Any feedback on what I could do to make this work or on the code in general

local counter=0
anim_full=hash("full")
anim_empty=hash("empty")
local heartcounter=56
local hearttable={0}
local deadheart="bruh"
local newtable = {}
local priority=0

local function clonehearts(self,garnish,bread)
	self.clone=	gui.new_box_node(vmath.vector3(0,0,0),vmath.vector3(70,65,0))
	gui.set_texture(self.clone, "heart")
	self.location=gui.set_screen_position(self.clone,vmath.vector3(heartcounter,690,0))
	if garnish == "spicy" then
		gui.play_flipbook(self.clone, "Spicy")
	else
		gui.play_flipbook(self.clone, "full")
	end
	self.heart = {garnish, "nul", self.priority}
end


local function redraw(self)
	while counter < #currenttable do
		if currenthearts[counter[0]]=="spicy" then
			self.priority = self.priority + 1
		end
		table.insert(newtable,self.priority,currenthearts))
		counter=counter+1
	end
	counter = 0
	while counter< #currenttable do
		collision_response
		clonehearts(self,newtable[1],newtable[2])
	end
end

function init(self)
	msg.post("/player character#pc script","heartsync",{hearts})
	redraw(self)
end

That “collision_response” looks odd

Overall I find the code hard to follow and I don’t really understand the problem. Could you please explain the problem more thoroughly?

Sorry this was first pass before properly debugging it, the main issue I’m having is using the nested lists. I’m currently using {{},{}}, I’m trying to use some sort of 2d array to properly display the characteristics while still remaining readable to me, however I’m now having an issue when I try to use if currenthearts[tonumber(counter)[0]]=="spicy"
due to an error of “attempting to index a number value”, the updated code is shown below

local counter=0
anim_full=hash("full")
anim_empty=hash("empty")
local heartcounter=56
local hearttable={0}
local deadheart="bruh"
local newtable = {}

--function used to draw the hearts on screen
local function clonehearts(self,garnish,bread)
	self.clone=	gui.new_box_node(vmath.vector3(0,0,0),vmath.vector3(70,65,0))
	gui.set_texture(self.clone, "heart")
	self.location=gui.set_screen_position(self.clone,vmath.vector3(heartcounter,690,0))
	if garnish == "spicy" then
		gui.play_flipbook(self.clone, "Spicy")
	else
		gui.play_flipbook(self.clone, "full")
	end
	self.heart = {garnish, "nul", self.priority}
end

--determins the priority of 
local function redraw(self)
	self.priority =0
	while counter < #currenthearts do
		if currenthearts[tonumber(counter)[0]]=="spicy" then
			self.priority = self.priority + 1
		end
		table.insert(newtable,tonumber(self.priority),currenthearts)
		counter=counter+1
	end
	counter = 0
	while counter< #newtable do
		clonehearts(self, newtable[2],newtable[3])
		counter=counter+1
	end
end

function init(self)
	msg.post("/player character#pc script","heartsync",{hearts})
	redraw(self)
end```

I suggest you split it up into two parts: sorting, and then rendering.

Since you mention the sorting is the problem, then I would leave out all the rendering/sprite related stuff from the question, and focus on sorting the table(s), and printing out the result.

Once that is done, then focus on the rendering.

2 Likes

First, I think the clonehearts should be named, createheart since it only spawns a single heart (and it’s not in fact cloning a node).

Second, the “self.heart” will only store the last spawned heart (and same with self.clone). Is that intentional?
Here, I’d instead store the heart in the table: table.insert(self.hearts, {garnish, nil, priority}) (I also pass in priorityto make it a bit more like a function.

Now, if you’ve called this clonehearts many times. You can gt the latest heart like so:

if next(self.hearts) ~= nil then
    local lastheart = self.hearts[#self.hearts]
end

And to sort the table, on priority, you can do it like so:

table.sort(self.hearts, function (a, b) return a[3] < b[3] end)

3 being the index in the hearts where the priority is stored.

At this point, I’d call the createheart a number of times, to populate the self.hearts, then call table.sort() on it.

Is this what you were looking for, apologies if it wasn’t. If not, perhaps you could explain a bit more.

1 Like

Thank, but I’ve already found a solution pretty similar, without using tablesort as I have had issues with it, this is my current solution:

to go into more detail, here is the extract from my design document about it:

This is the redraw code, at time of writing the most complicated thing I’ve ever programmed, its purpose is to determine the priority of an array value (shown as the second image) and put it into a table via a linear sort for an entire array with a dynamic length. To talk it through, the first while loop is used to output a array sorted by the priority of its contents, the loop is designed to end at the length of the table, length is set to +1 due to the counter starting at one to match the array, it then reads the first value of the sub-list dependent on the counter, which is reserved for the type of garnish and adjusts the priority, if bread was implemented it would be seen here too. It then converts the values into a variable called data, which is a list meant to be put into the new table to read both type and priority. This then starts the linear search, checking the hearts priority versus the heart one heart above it, if its less that’s it positions in the list. It then gets put into the new table and the variables are reset for the next loop and the counter is incremented.

Once the while loop is complete, the new table is fed into a new while loop looking at the length of the new table, this then feeds the appropriate information into the clone hearts function to display the hearts, and loops until all the hearts are displayed

this is the heart displaying code of my second attempt, while there are still called clones for convenience, they are new nodes entirely which I manually set the texture and animation to whatever type is provided (In this example 3), the 3 values entered into the code is “self”, which refers to the specific clone entity, “garnish”, which determines the ingredient and “bread” which determines the bread (in this version currently unimplemented), these values are provided by the new redraw code.

forgot the images


image