I mocked up a demo that still uses sorting but only sorts when necessary.
I did this quick and I am not %100 sure it works as I want it to and I would bet that not the most efficient it could be.
The demo creates a dictionary of 6 marbles (1 through 6). They begin with a score of 0 each and each frame there is a chance to add to their score.
It is 1 in 7 chance that scores change. The random value must == 1.
Each frame loops all 6 marbles to check if their score is > the marble previous. If that condition is true then a complete sort is done and no further checks are needed in that frame.
You can see from the output that the sort is only done when necessary.
(I used a seed because it turns out with only 10 laps a 1 in 7 chance doesn’t come up very often)
extends Node2D
var marbles:Dictionary[int, int] = {
1:0, 2:0, 3:0, 4:0, 5:0, 6:0
}
var leader_board:Array[int] = [1,2,3,4,5,6]
const NUMBER_OF_LAPS:int = 10
var current_lap:int = 0
func _ready() -> void:
seed(1) # uncomment this if you want repeatable results
pass
func adjust_leader_board()->void:
for n:int in range(5,2,-1):
var front_marble:int = leader_board[n]
var test_marble:int = leader_board[n-1]
if marbles[front_marble] > marbles[test_marble]:
prints(marbles, "scores/positions are changed")
sort_leaderboard()
return
pass
func sort_leaderboard()->void:
prints("-----> positions changed so need to sort")
leader_board.sort_custom(func (a, b): return marbles[a] > marbles[b] )
print("")
prints(leader_board, "new leader board")
print("")
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta: float) -> void:
current_lap += 1
if current_lap > NUMBER_OF_LAPS:
set_process(false)
print("")
print("----------------------finished")
print(marbles)
print(leader_board)
return
var x:int = randi() % 7
prints(x, "anything but 1 is no change/no sort")
if x == 1:
for n:int in range(1,7):
set_pace(n)
else:
prints(marbles, "same order as last frame (or after sort)")
adjust_leader_board()
pass
func set_pace(n:int)->void:
marbles[n] += randi() % 6
Here is the output I get:
6 anything but 1 is no change/no sort
{ 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 } same order as last frame (or after sort)
0 anything but 1 is no change/no sort
{ 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 } same order as last frame (or after sort)
5 anything but 1 is no change/no sort
{ 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 } same order as last frame (or after sort)
1 anything but 1 is no change/no sort
{ 1: 3, 2: 5, 3: 1, 4: 5, 5: 3, 6: 5 } scores/positions are changed
-----> positions changed so need to sort
[2, 4, 6, 1, 5, 3] new leader board
0 anything but 1 is no change/no sort
{ 1: 3, 2: 5, 3: 1, 4: 5, 5: 3, 6: 5 } same order as last frame (or after sort)
6 anything but 1 is no change/no sort
{ 1: 3, 2: 5, 3: 1, 4: 5, 5: 3, 6: 5 } same order as last frame (or after sort)
1 anything but 1 is no change/no sort
{ 1: 6, 2: 8, 3: 4, 4: 5, 5: 3, 6: 7 } scores/positions are changed
-----> positions changed so need to sort
[2, 6, 1, 4, 3, 5] new leader board
6 anything but 1 is no change/no sort
{ 1: 6, 2: 8, 3: 4, 4: 5, 5: 3, 6: 7 } same order as last frame (or after sort)
6 anything but 1 is no change/no sort
{ 1: 6, 2: 8, 3: 4, 4: 5, 5: 3, 6: 7 } same order as last frame (or after sort)
2 anything but 1 is no change/no sort
{ 1: 6, 2: 8, 3: 4, 4: 5, 5: 3, 6: 7 } same order as last frame (or after sort)
----------------------finished
{ 1: 6, 2: 8, 3: 4, 4: 5, 5: 3, 6: 7 }
[2, 6, 1, 4, 3, 5]
Like I said, there is little doubt that this can’t be improved on. (and also still not sure it works perfectly, lol)