• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Solved] Finding X lowest hp values in area

Status
Not open for further replies.
I've figured a way to find THE lowest hp of a unit in an area... but is there a way to find the two lowest? I'm thinking of doing comparisons, and then saving the last value:

LifeHP[1] = 101%

Pick every unit in area
If CurrentHP < LifeHP[1]
Set LifeHP[1] = LifeHP[1]
Set LifeHP[2] = CurrentHP

Pick every unit in area
If CurrentHP < LifeHP[2]
LifeHP[1] = LifeHP[2]
LifeHP[2] = CurrentHP​
 

Chaosy

Tutorial Reviewer
Level 41
Joined
Jun 9, 2011
Messages
13,239
Actually you could make it copy paste. Not really the best solution but it works.

set group1 = unit group in region x
set group2 = unit group in region x
(aka set them to the same thing)

pick every unit in group 1 and detect the one with the lowest hp.
remove lowest hp unit from group2
pick every unit in group 2 and detect the one with the lowest hp.
 
Actually you could make it copy paste. Not really the best solution but it works.

set group1 = unit group in region x
set group2 = unit group in region x
(aka set them to the same thing)

pick every unit in group 1 and detect the one with the lowest hp.
remove lowest hp unit from group2
pick every unit in group 2 and detect the one with the lowest hp.

But what if the unit with the lowest HP is in both groups? xD
 
Here is how you do it without pointlessly using groups in pseudo code:

- set lowest[1] = null
- set lowest[2] = null
- set lowestlife[1] = 100%
- set lowestlife[2] = 100%
- Pick all Units
- if picked unit life <= lowestlife[2]:
---> if picked unit life <= lowestlife[1]:
------> set lowest[2] = lowest[1]
------> set lowestlife[2] = lowestlife[1]
------> set lowest[1] = picked unit
------> set lowestlife[1] = picked unit life
---> else
------> set lowestlife[2] = picked unit life
------> set lowest[2] = picked unit
---> endif


If you need more than the 2 lowest units and perform the HP checks frequently, I recommend mapping all units in your map that you want monitored in a unit array (and a real array with their corresponding HP) and run an https://en.wikipedia.org/wiki/Insertion_sort algorithm whenever the HP of a unit changes (aka damage event).
 

Chaosy

Tutorial Reviewer
Level 41
Joined
Jun 9, 2011
Messages
13,239
Got somewhat interested so I tried to copy it myself, did not quite work out for me.
  • Untitled Trigger 002
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set A[0] = 5
      • Set A[1] = 3
      • Set A[2] = 6
      • Custom script: call wtf()
JASS:
//! zinc
	library test
	{
		public function wtf()
		{
			integer i, j, x = 0;
			for(0 <= i < 3)
			{
				x = udg_A[i];
				j = i;
				while(j > 0 && udg_A[j - 1] > x)
				{
					udg_A[j] = udg_A[j] - 1;
					j = j - 1;
				}
				udg_A[j] = x;
			}
			i = 0;
			for(0 <= i < 3)
			{
				BJDebugMsg(I2S(udg_A[i]));
			}
		}
	}
//! endzinc

It displays.
1d84160e606ceacf5d115be01718e799.png


Code from wikipedia:
Code:
for i = 1 to length(A) - 1
    x = A[i]
    j = i
    while j > 0 and A[j-1] > x
        A[j] = A[j-1]
        j = j - 1
    end while
    A[j] = x
 end for
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
Bleh, dont do it like that.

Just make an array of units in order of lowest to highest health.
Each time you check if the last unit has higher health than the picked unit.
Then you add all the units from the array in a new group and that group contains the N units with the lowest health.
 
Bleh, dont do it like that.

Just make an array of units in order of lowest to highest health.
Each time you check if the last unit has higher health than the picked unit.
Then you add all the units from the array in a new group and that group contains the N units with the lowest health.
That doesn't even make sense. If he has an ordered array already, why would he even need a group then? He can just take the N first array members.
 

Chaosy

Tutorial Reviewer
Level 41
Joined
Jun 9, 2011
Messages
13,239
Thank you, Zwie. It works now.

This is the code that worked in case someone finds this thread at a later date and wonders.
JASS:
//! zinc
    library test
    {
        public function wtf()
        {
            integer i, j, x = 0;
            for(0 <= i < 3)
            {
                x = udg_A[i];
                j = i;
                while(j > 0 && udg_A[j - 1] > x)
                {
                    udg_A[j] = udg_A[j - 1];
                    j = j - 1;
                }
                udg_A[j] = x;
            }
            i = 0;
            for(0 <= i < 3)
            {
                BJDebugMsg(I2S(udg_A[i]));
            }
        }
    }
//! endzinc
 
Bleh, dont do it like that.

Just make an array of units in order of lowest to highest health.
Each time you check if the last unit has higher health than the picked unit.
Then you add all the units from the array in a new group and that group contains the N units with the lowest health.

I will have to try this out when I get the chance!



Thank you everyone!
 
Status
Not open for further replies.
Top