• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Solved] Finding X lowest hp values in area

Status
Not open for further replies.
Level 37
Joined
Jul 22, 2015
Messages
3,485
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 40
Joined
Jun 9, 2011
Messages
13,183
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.
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
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 40
Joined
Jun 9, 2011
Messages
13,183
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,657
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 40
Joined
Jun 9, 2011
Messages
13,183
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
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
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