sorting variables help!

Blitz3D Forums/Blitz3D Beginners Area/sorting variables help!

tsmpaul(Posted 2009) [#1]
Hi guys. I'm making a game with combat in it. Combat is turn based. When combat begins, each character has an Initiative score. The characters with low scores have their turn first. The characters with higher scores go later.

The idea, is that a list is created, with an item for each character. Depending on their initiative score, they will be ordered in the list.

I made a simplified program to test it.

Dim char_initiative(14)
Dim char_turnorder(14)

Graphics 800,600,32,2

; random 1d10 initiative score for each character

For i=1 To 14
	randomize()
	char_initiative(i)=Rnd(1,10)
Next

; put them in order list in numerical order
For i=1 To 14
	char_turnorder(i)=i
Next

; now to sort it?

For loopit=1 To 14 ; run the sort a couple times to make sure it sorts everything nicely?

	For i=1 To 14 ; 14 characters to sort
		For j=1 To 14 ; compare character (i) to the other characters
			
			If char_initiative(j) > char_initiative(i) Then ; if comparison character is higher number than character, swap their turn order
				SWAP = char_turnorder(j) ; change j for i in the turn order list of characters
				char_turnorder(j)=char_turnorder(i)
				char_turnorder(i)=SWAP
			End If
		Next
	Next
	
Next

; now display the results
While Not MouseDown(1)
	For i=1 To 14 ; which turn order position
		For j=1 To 14 ; check order against each character
			If char_turnorder(j)=i Then ; is this character the current turn order position?
				Text 0,i*20, "Turn: "+i+" Character: "+j+" Initiative: "+char_initiative(j)
				j=15
			End If
		Next
	Next
	VWait()
	Flip()
Wend

Function randomize()
	SeedRnd(MilliSecs())
	tempnum= Rnd(3)
	Delay tempnum*2
	SeedRnd(MilliSecs()*tempnum)
	tempnum=Rnd(15)
	Delay tempnum*2
	SeedRnd(MilliSecs()*tempnum)
End Function



So, basically it's based on a sorting code I found in the code archives. However, there are two variables being used instead of just one, so I'm a little confused by the results.

char_initiative is a random initiative score assigned to one of 14 characters. It is a random 1d10 dice roll.

char_turnorder is turn 1 to turn 14, assigned the number of the character who gets to act on that turn. So, if char_turnorder(5)=3 it would mean on turn 5 of combat, character 3 gets to act.

The sorting means that the character with the lowest initiative score gets to be char_turnorder(1) and the character with the highest initiative score gets to be char_turnorder(14).

Characters with the same rolled number I assume would just appear next to each other.

My problem is, when I run this code, and it displays the turn order list for the characters, the initiative scores for those characters are not in ascending order: it's changing the order of the characters, but it doesn't appear to be sorting them in order...

I'm obviously doing something wrong here, and I never quite understood sorting anyhow. Any advice on changing this program so that the characters are sorted into the list according to their initiative scores?


Midimaster(Posted 2009) [#2]
Your algorithm is working with char_initiative , but you do a mistake in swapping char_turnorder depending on char_turnorder.

At first, here is an more efficient and clear sort algo:

Dim char_initiative(14)
Dim char_turnorder(14)

Graphics 800,600,32,2

SeedRnd MilliSecs()
For i=1 To 14
	char_initiative(i)=Rnd(1,10)
	char_turnorder(i)=i
Next

Print "before:"
For i=1 To 14
	Print i +". position    Character" + char_turnorder(i) + "  Initiative: "+ char_initiative(i)
Next

Sort 

Print 
Print "after:"
For i=1 To 14
	Print i +". position    Character" + char_turnorder(i) + "  Initiative: "+ char_initiative(i)
Next
Print 
WaitKey
End

Function Sort()
 	Repeat
   	    NotReady=0
	    For  i=1 To 13
	        If char_initiative(i) < char_initiative(i+1)
	             ;swap initative first
                     Swap= char_initiative(i+1)
                     char_initiative(i+1)= char_initiative(i)
                     char_initiative(i)=Swap
	             
                     ;now swap character no. too
                    Swap= char_turnorder(i+1)
                    char_turnorder(i+1)= char_turnorder(i)
                    char_turnorder(i)=Swap
                    NotReady=1
              EndIf
           Next
     Until NotReady=0
End Function




This kind of bubble-sort does the same like yours, but it is better to understand. Two neighbors are compared and swapped, if one is bigger than the other. If a swapping was necessary, the loop has to be repeatet. If no swapping was necessary, the sorting has come to an end.

If now two positions are to be swapped, the values are swapped, but also the marker "who is on this position".


tsmpaul(Posted 2009) [#3]
Thanks for the help Midimaster! Now it makes more sense to me, and I can adapt the sorting to my main program.