Sorting script

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
Locked
User avatar
chopkinsca
Posts: 1325
Joined: Thu Dec 11, 2003 5:03 pm

Sorting script

Post by chopkinsca »

I need a script that sorts five numbers and orders them from highest to lowest. I tried making my own script, but my head exploded from the logic. This is the mess I made before I got stuck:

Code: Select all

int scores[5] = { 200, 300, 100, 400, 0 };
int scoresarranged[5];
int scoredone[5];

//sort
int numberofscores;
int ishigh;
int reverse;
int highestarray;
script 26 (void) {
   scores[4] = points;
   numberofscores = 4;
   ishigh = 0;
   reverse = 0;

   while(numberofscores >= 0) {
         for(int x = 0; x <= 4; x++);
            if(ishigh > scores[x] && scoredone[x] != 1) {
               ishigh = scores[x];
               highestarray = x;
               
            }
         scoresarranged[reverse] = ishigh;
         scoredone[highestarray] = 1;
         ishigh = 0;
      }
   reverse++;
   numberofscores--;
   delay(1);
   for(int y = 0; y <= 4; y++){ 
      scoredone[y] = 0;
   }
   restart;
   
}
As it is, it's terminated as a runaway script, so something must be wrong with my logic.
User avatar
Demolisher
Posts: 1749
Joined: Mon Aug 11, 2008 12:59 pm
Graphics Processor: nVidia with Vulkan support
Location: Winchester, VA
Contact:

Re: Sorting script

Post by Demolisher »

Code: Select all

#include "zcommon.acs"

#define numscores 5

int scores[numscores] = { 200, 300, 100, 400, 0 };
int orderedscores[numscores];

function void sort(void)
{
	int currenthighest = scores[0];
	int currenthighestpos = 0;

	for(int c1 = 0; c1 < numscores; c1++)
	{
		for(int c2 = 0; c2 < numscores; c2++)
		{
			if(scores[c2] > currenthighest)
			{
				currenthighest = scores[c2];
				currenthighestpos = c2;
			}
		}
		
		orderedscores[c1] = currenthighest;
		scores[currenthighestpos] = 0;
		currenthighest = 0;
	}
}

script 999 enter
{
	for(int c = 0; c < numscores; c++)
	{
		log(s:"score[", i:c, s:"] = ", i:scores[c]);
	}
	
	sort();
	
	for(c = 0; c < numscores; c++)
	{
		log(s:"orderedscores[", i:c, s:"] = ", i:orderedscores[c]);
	}
}
Worst
Posts: 115
Joined: Sat Apr 28, 2007 5:29 am
Location: finland
Contact:

Re: Sorting script

Post by Worst »

If you want to sort them within the same array, you can just:

Code: Select all

  int temp;
  
  for (int i=0; i<numscores; i++)
  {
    for (int j=0; j<numscores; j++)
    {
      if(scores[j] > scores[i])
      {
        temp = scores[i];
        scores[i] = scores[j];
        scores[j] = temp;
      }
    }
  }
User avatar
chopkinsca
Posts: 1325
Joined: Thu Dec 11, 2003 5:03 pm

Re: Sorting script

Post by chopkinsca »

Demolisher wrote:*code*
That works, but now I'm having trouble printing the values for some reason. The first hudmessage prints the proper numbers, but every iteration after that just shows 0's for all values.

Code: Select all

script 27 (void) {
		sort();   
		
		SetHudSize(512, 384, 0); 
		for(int x = 0; x <= 4; x++) {
			hudmessage(i: orderedscores[x]; HUDMSG_PLAIN | HUDMSG_LOG , 888 + x, CR_gold, 0.1, (168.0 + x * 10.0), 1.0);
		}
		
		delay(35);
  restart;
        
}
Edit: the HUDMSG_LOG was just to test if it worked at all.
User avatar
Demolisher
Posts: 1749
Joined: Mon Aug 11, 2008 12:59 pm
Graphics Processor: nVidia with Vulkan support
Location: Winchester, VA
Contact:

Re: Sorting script

Post by Demolisher »

heh. fixed.

Code: Select all

#include "zcommon.acs"

#define numscores 5

int scores[numscores] = { 200, 300, 100, 400, 0 };
int temp[numscores];
int orderedscores[numscores];

function void sort(void)
{
	int currenthighest = scores[0];
	int currenthighestpos = 0;
	
	for(int c = 0; c < numscores; c++)
	{
		temp[c] = scores[c];
	}

	for(int c1 = 0; c1 < numscores; c1++)
	{
		for(int c2 = 0; c2 < numscores; c2++)
		{
			if(scores[c2] > currenthighest)
			{
				currenthighest = scores[c2];
				currenthighestpos = c2;
			}
		}
		
		orderedscores[c1] = currenthighest;
		scores[currenthighestpos] = 0;
		currenthighest = 0;
	}
	
	for(int c3 = 0; c3 < numscores; c3++)
	{
		scores[c3] = temp[c3];
	}
}

script 999 enter
{
	for(int c = 0; c < numscores; c++)
	{
		log(s:"score[", i:c, s:"] = ", i:scores[c]);
	}
	
	sort();
	
	for(c = 0; c < numscores; c++)
	{
		log(s:"orderedscores[", i:c, s:"] = ", i:orderedscores[c]);
	}
}
User avatar
chopkinsca
Posts: 1325
Joined: Thu Dec 11, 2003 5:03 pm

Re: Sorting script

Post by chopkinsca »

Sweet, that works, thanks. I'll be sure to credit you for this.

Edit: you left out the part where the 5th index of the point array is set to the variable "points". I can change this easily enough. If you are wondering what this is, it's to track your score compared to the high scores that are preset.
User avatar
chopkinsca
Posts: 1325
Joined: Thu Dec 11, 2003 5:03 pm

Re: Sorting script

Post by chopkinsca »

Something else that I want to this script to do is to have a parallel array with names tied to the high scores. Also I'd like to be able to access what index of the sorted array the player owns so I can give that hudmessage a different colour.

The way I'm doing it now is hacky and doesn't account for lining up the names for the other scores.

Edit: I made scores[numscores] a 2 dimensional array with the first bracket being level number. I also added scores[getlevelinfo(2)][4] = points; to the first line of sort().

Code: Select all

int hudcolours[5] = { 9, 9, 9, 9, 9 };

script 910 (void) {
		sort();
		for(int blah = 0; blah <= 4; blah++){
			if(orderedscores[blah] == scores[getlevelinfo(2)][4]){
				hudcolours[blah] = 5; //gold
			}
			else{
				hudcolours[blah] = 9; //white
			}
		}		

		
		SetHudSize(512, 384, 0); 
		for(int x = 0; x <= 4; x++) {
			hudmessage(i: orderedscores[x]; HUDMSG_PLAIN | HUDMSG_LOG , 888 + x, hudcolours[x], 0.1, (168.0 + x * 10.0), 1.0);
		}
		
		delay(1);
  restart;
        
}
User avatar
Demolisher
Posts: 1749
Joined: Mon Aug 11, 2008 12:59 pm
Graphics Processor: nVidia with Vulkan support
Location: Winchester, VA
Contact:

Re: Sorting script

Post by Demolisher »

Code: Select all

#include "zcommon.acs"

#define numscores 5

str names[numscores] = { "rachael", "ryan", "george", "bill", "sammy" };
str orderednames[numscores];

int scores[numscores] = { 200, 300, 100, 400, 0 };
int temp[numscores];
int orderedscores[numscores];

function void sort(void)
{
	int currenthighest = scores[0];
	int currenthighestpos = 0;
	
	for(int c = 0; c < numscores; c++)
	{
		temp[c] = scores[c];
	}

	for(int c1 = 0; c1 < numscores; c1++)
	{
		for(int c2 = 0; c2 < numscores; c2++)
		{
			if(scores[c2] > currenthighest)
			{
				currenthighest = scores[c2];
				currenthighestpos = c2;
			}
		}
		
		orderedscores[c1] = currenthighest;
		orderednames[c1] = names[currenthighestpos];
		scores[currenthighestpos] = 0;
		currenthighest = 0;
	}
	
	for(int c3 = 0; c3 < numscores; c3++)
	{
		scores[c3] = temp[c3];
	}
}

script 999 enter
{
	for(int c = 0; c < numscores; c++)
	{
		log(s:"score[", i:c, s:"] = ", i:scores[c], s:" (", s:names[c], s:")");
	}
	
	sort();
	
	for(c = 0; c < numscores; c++)
	{
		log(s:"orderedscores[", i:c, s:"] = ", i:orderedscores[c], s:" (", s:orderednames[c], s:")");
	}
}
User avatar
chopkinsca
Posts: 1325
Joined: Thu Dec 11, 2003 5:03 pm

Re: Sorting script

Post by chopkinsca »

Thank you very much :D

I don't see it in the script, but I want a variable set to which position score[4] goes into. That's the player's score and changes, which is what I want this sort script for.
User avatar
Demolisher
Posts: 1749
Joined: Mon Aug 11, 2008 12:59 pm
Graphics Processor: nVidia with Vulkan support
Location: Winchester, VA
Contact:

Re: Sorting script

Post by Demolisher »

Just set score[4] and call sort() again, unless you want to color that line differently, then here's a script with an extra var to get the index of the player in orderedscores[].

Code: Select all

#include "zcommon.acs"

#define numscores	5

str names[numscores] = { "rachael", "ryan", "george", "bill", "<player>" };
str orderednames[numscores];

int scores[numscores] = { 200, 300, 100, 400, 0 };
int temp[numscores];
int orderedscores[numscores];

int playerscoreindex; // Var to get the player's ordered score.

//Usage:
//
//orderedscores[playerscoreindex]

function void sort(void)
{
	int currenthighest = scores[0];
	int currenthighestpos = 0;
	
	for(int c = 0; c < numscores; c++)
	{
		temp[c] = scores[c];
	}

	for(int c1 = 0; c1 < numscores; c1++)
	{
		for(int c2 = 0; c2 < numscores; c2++)
		{
			if(scores[c2] > currenthighest)
			{
				currenthighest = scores[c2];
				currenthighestpos = c2;
			}
		}
		
		orderedscores[c1] = currenthighest;
		orderednames[c1] = names[currenthighestpos];
		
		if(currenthighestpos == 4)
		{
			playerscoreindex = c1;
		}
		
		scores[currenthighestpos] = 0;
		currenthighest = 0;
	}
	
	for(int c3 = 0; c3 < numscores; c3++)
	{
		scores[c3] = temp[c3];
	}
}

script 999 enter
{
	for(int c = 0; c < numscores; c++)
	{
		log(s:"score[", i:c, s:"] = ", i:scores[c], s:" (", s:names[c], s:")");
	}
	
	sort();
	
	for(c = 0; c < numscores; c++)
	{
		log(s:"orderedscores[", i:c, s:"] = ", i:orderedscores[c], s:" (", s:orderednames[c], s:")");
	}
}
User avatar
chopkinsca
Posts: 1325
Joined: Thu Dec 11, 2003 5:03 pm

Re: Sorting script

Post by chopkinsca »

It works great except for a couple of issues. One being if there are scores that are the same value. Once I get a set of high scores that are all different, this won't be an issue unless the player ties for one of the spots. The second issue is when the script starts before the player gets any points, the first entry is tagged as the player's score.
Locked

Return to “Editing (Archive)”