Hero Attribute Comparison// if equal then Food Comparison// if equal then throw dice...

Status
Not open for further replies.
Level 3
Joined
Mar 15, 2018
Messages
31
Hey dear community!

I'm struggling hard.

-> I need to compare the intelligence attributes of 2 to 5 units for figuring out who has the most. In the end I need to have a list of who is best, the second-best, the third-best and so on.

That means I can't have two units to be even. So..:

Let's say Unit A has 10 Intelligence and Unit B has 10 Intelligence.

If units are equally intelligent, I would compare the food of both owners as the second try to figure out which rank the unit gets in the list, but here is the first problem:

What if Unit A and Unit B have 10 intelligence as already mentioned, but Unit C and Unit D have both 6 intelligence?

Here my brain explodes. So far I would have used some awkward if/then/else chain with some loop around I guess, but here I don't have a nice idea how to go on, as we have two groups of units that have equal intelligence in a different way.

Furthermore when the food ends up being equal as well, I would then need to throw one dice per player involved.

Long Story short:
I need a trigger/system or whatever that concludes the following:

Unit A = 10 Intelligence -> Rank: 4 or 5 ?
Unit B = 10 Intelligence -> Rank: 4 or 5 ?
Unit C = 12 Intelligence -> Rank: 1, 2 or 3 ?
Unit D = 12 Intelligence -> Rank: 1, 2 or 3 ?
Unit E = 12 Intelligence -> Rank: 1, 2 or 3?
--->
Equal Intelligence triggers alternative comparison
Player of Unit A = 30 Food -> Rank: 4 or 5?
Player of Unit B = 30 Food -> Rank: 4 or 5?
Player of Unit C = 30 Food -> Rank: 1
Player of Unit D = 20 Food -> Rank: 2 or 3?
Player of Unit E = 20 Food -> Rank: 2 or 3?

---
> Equal Food triggers alternative comparison
Player of Unit A rolls a dice = 5 -> Rank: 4 or 5?
Player of Unit B rolls a dice = 5 -> Rank: 4 or 5?
Player of Unit D rolls a dice = 2 -> Rank: 2
Player of Unit E rolls a dice = 1 -> Rank: 3

---
> Equal cast of dice triggers another round of dice comparison
Player of Unit A rolls a dice again = 4 -> Rank: 4
Player of Unit B rolls a dice again = 1 -> Rank: 5


I hope this is understandable. If you have any questions, please ask immediately!
I would be soo grateful if someone knows a good way of doing this. Even if you provide only the logic it helps already.

Cheers
old_edge
 
Last edited:
Level 3
Joined
Mar 15, 2018
Messages
31
Yep. I did already briefly. It's quite overwhelming for such a seemingly mundane issue. So Im hoping someone here can give me some helpful hints on how to realize this in GUI.

Please! This is the most difficult part of my project! I'm quite frustrated with this at the moment.

Is it doable? Someone knows a way?
 
Level 12
Joined
Mar 24, 2011
Messages
1,082
This is one of the simplest and most basic things in programming.

You could do a Bubble Sort, which is the first, simplest to understand and the most basic one.
People say, NEVER RECOMMEND BUBBLE SORT, although it is perfect for novice learning purposes.
PS: It is one of the most inefficient sorting algorithms out there.

What it does is it loops through the array, checks if neighboring things are in order and swaps them if they are not. Repeats until everything is in order.

Pseudo code:
Code:
Loop through array
 Is intelligence of [X] < [X+1] ?
  Yes - Switch
  No - If (Int of [x] == [x+1]) AND (Food for [x] < [X+1])
   Yes - Switch
   No -If (Int of [x] == [x+1]) AND (Food for [x] == [X+1]) AND ( (Roll out of 100) < 50)
    Yes - Switch
    No - Those are in order
Have you done a switch at all?
 Yes - Go back to beginning
 No - You are done, hurray !

PS: I would HIGHLY RECOMMEND to remove the Roll, and just leave it to whatever order equal entries were registered in.

The Roll could get you in big trouble and would practically cause an infinite loop. There isn't a particularly flexible & simple way of doing the roll or at least I can't think of one at the moment, it would work with one of the more "complex" sorting algorthytms. If you do it just as described, you create a practical infinite loop.

EDIT// I've removed the GUI example as I had written it in plain text and had a logical error that I am too lazy to fix. :)

Hope this helps!
Regards
-Ned
 
Last edited:
Level 3
Joined
Mar 15, 2018
Messages
31
Ahh, I was already thinking a lot about switching, but I couldn't figure it out. Thanks!

There are a few things though, that are not completely clear to me.

1. If you set the int_Index to 0 in the loop and than use it afterwards in the comparison substracted by 1, does that work? Because I thought so far there are only positive arrays.

2. I don't understand the int_IsInOrder part either. Because it does look like it's causing an infinite loop. It seems like you are substracting in order to make the loop continue, right? This is quite clever. I was wondering why you got the option to put an own variable instead of Integer A and B into the loop already. Thank you! :) But still I wonder: If you leave it like this the whole looping only stops when the dice roll, which should actually be the exception in the game. Most things will be decided by the comparison of the Intelligence already. So what is the point of this in here?

3. If you compare equality of two numbers only to switch it, won't this cause an infinite loop as well? Becaue they always will stay equal like this right?

Thank you very much, though.
This is very helpful already! :))
 
Level 12
Joined
Mar 24, 2011
Messages
1,082
@old_edge5 I see that you have written this while I was deleting the GUI part... bugger...

Point 1 - In programming, counting starts from 0. A data array of size 3 is data[0], data[1], data[2]
If you try to access data[3] you will usually get an error because it does not exist.
In War3, depending on what the data type is, it will either expand the array to suit your needs, or do something weird, but it will not crash your game. Try not to go over 8000 though (or 30k with 1.29).

Point 2 - int_IsInOrder should be a Boolean really, we need either YES or NO for this, I just could not think of a way to do a loop with a Boolean without going all complicated again, something like:

Loop it 0 to Z
Switcheroo around

IS_THE_LIST_IN_ORDER_NOW?
NO - Go loop again
Yes - We are done here

I should have named it more like "Have_We_Made_A_Switch_In_The_Last_Loop"
It is not causing an infinite loop, it is causing a loop until we are happy with the arrangement.

Point 2.1 - Integer A/B are buggy. As I am aware (and this is from 3rd sources only, people like Dr.SuperGood, MAgtheridon, Nestharus, Bribe etc., who actually understand how the War3 engine works) those may conflict with simultaneous uses which is happening in this case... kind of. All in all, never use them.

Point 3 - If you look at the Edit// on my previous post, you have spotted the "epic logical error that I am tool lazy to fix" , well done ;) Take a look at the Pseudo code, this should point you in the right direction as it is simpler.

Hope this helps!
-Ned
 
Level 3
Joined
Mar 15, 2018
Messages
31
Hey I did it now like this:

  • For each (Integer P3_SailCheck) from 1 to P3_CountfCheckThese, do (Actions)
    • Loop - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Intelligence of P3_CheckThese[P3_SailCheck] (Include bonuses)) Less than (Intelligence of P3_CheckThese[(P3_SailCheck + 1)] (Include bonuses))
        • Then - Actions
          • -------- Intelligence Check --------
          • Set P3_TempUnit = P3_CheckThese[(P3_SailCheck + 1)]
          • Set P3_CheckThese[(P3_SailCheck + 1)] = P3_CheckThese[P3_SailCheck]
          • Set P3_CheckThese[P3_SailCheck] = P3_TempUnit
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Intelligence of P3_CheckThese[P3_SailCheck] (Include bonuses)) Equal to (Intelligence of P3_CheckThese[(P3_SailCheck + 1)] (Include bonuses))
              • ((Owner of P3_CheckThese[P3_SailCheck]) Food used) Less than ((Owner of P3_CheckThese[(P3_SailCheck + 1)]) Food used)
            • Then - Actions
              • -------- If Intelligence is equal then Food check --------
              • Set P3_TempUnit = P3_CheckThese[(P3_SailCheck + 1)]
              • Set P3_CheckThese[(P3_SailCheck + 1)] = P3_CheckThese[P3_SailCheck]
              • Set P3_CheckThese[P3_SailCheck] = P3_TempUnit
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Owner of P3_CheckThese[P3_SailCheck]) Food used) Equal to ((Owner of P3_CheckThese[(P3_SailCheck + 1)]) Food used)
                • Then - Actions
                  • -------- If Food is equal then roll dice --------
                  • Set P3_Rolled[0] = (Random integer number between 1 and 6)
                  • Set P3_Rolled[1] = (Random integer number between 1 and 6)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • P3_Rolled[0] Less than P3_Rolled[1]
                    • Then - Actions
                      • Set P3_TempUnit = P3_CheckThese[(P3_SailCheck + 1)]
                      • Set P3_CheckThese[(P3_SailCheck + 1)] = P3_CheckThese[P3_SailCheck]
                      • Set P3_CheckThese[P3_SailCheck] = P3_TempUnit
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • P3_Rolled[0] Equal to P3_Rolled[1]
                        • Then - Actions
                          • -------- If first roll is equal then roll dice second time --------
                          • Set P3_Rolled[0] = (Random integer number between 1 and 6)
                          • Set P3_Rolled[1] = (Random integer number between 1 and 6)
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • P3_Rolled[0] Less than P3_Rolled[1]
                            • Then - Actions
                              • Set P3_TempUnit = P3_CheckThese[(P3_SailCheck + 1)]
                              • Set P3_CheckThese[(P3_SailCheck + 1)] = P3_CheckThese[P3_SailCheck]
                              • Set P3_CheckThese[P3_SailCheck] = P3_TempUnit
                            • Else - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • P3_Rolled[0] Equal to P3_Rolled[1]
                                • Then - Actions
                                  • -------- If second roll is equal then roll dice third time --------
                                  • Set P3_Rolled[0] = (Random integer number between 1 and 6)
                                  • Set P3_Rolled[1] = (Random integer number between 1 and 6)
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • P3_Rolled[0] Less than P3_Rolled[1]
                                    • Then - Actions
                                      • Set P3_TempUnit = P3_CheckThese[(P3_SailCheck + 1)]
                                      • Set P3_CheckThese[(P3_SailCheck + 1)] = P3_CheckThese[P3_SailCheck]
                                      • Set P3_CheckThese[P3_SailCheck] = P3_TempUnit
                                    • Else - Actions
                                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                        • If - Conditions
                                          • P3_Rolled[0] Equal to P3_Rolled[1]
                                        • Then - Actions
                                          • -------- If third roll is equal then set random winner --------
                                          • Set P3_Rolled[2] = (Random integer number between 0 and 1)
                                          • Set P3_Rolled[P3_Rolled[2]] = 6
                                          • Set P3_Rolled[(Abs((P3_Rolled[2] - 1)))] = 0
                                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                            • If - Conditions
                                              • P3_Rolled[0] Less than P3_Rolled[1]
                                            • Then - Actions
                                              • Set P3_TempUnit = P3_CheckThese[(P3_SailCheck + 1)]
                                              • Set P3_CheckThese[(P3_SailCheck + 1)] = P3_CheckThese[P3_SailCheck]
                                              • Set P3_CheckThese[P3_SailCheck] = P3_TempUnit
                                            • Else - Actions
                                        • Else - Actions
                                • Else - Actions
                        • Else - Actions
                • Else - Actions

When I use this over 4 units with 5 intelligence each, they seem to get into a right order, but the problem is, that when I trigger this again they remain in that same order, which is not the point of this. I need them to be random if equal.

Also:
My problem described in the first post is not really addressed by this when I think about it, because actually if 4 units have the same value in intelligence and food, they all need to roll a dice and then the order has to be concluded out of the cast of the dice.
You know what I mean? It's supposed to work like a boardgame would.

Do you or does anyone has a good idea how to get that done?

Cheers and thanks so far already! :)
old_edge5
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,285
Simple but inefficient approach...
  1. Place all units in an unsorted list.
  2. Create a new empty sorted list.
  3. Find the "best" unit in the unsorted list.
  4. Remove the "best" unit from the unsorted list.
  5. Append the "best" unit to the sorted list.
  6. Repeat until sorted list has as many units as required.
Finding the best in the unsorted list involves comparing the current potential best to each unit with 3 different tests.
  1. Test the intelligence of the unit. If this unit has more intelligence than the potential best then make this unit the new potential best. If intelligence is equal then go to test 2.
  2. Test the food of the owning players. If this unit's owner has more food than the potential best's owner then make this unit the new potential best. If food is equal then go to test 3.
  3. Dice logic! Now one has to be careful that each unit is selected fairly. If this unit passes the dice logic test then make this unit the new potential best.
The dice logic is tricky to do right. Even Blizzard failed to implement this properly in one of the random unit/units in unit group functions.

Say you have 4 potential best units which are only separated by the dice logic. Each should have a 0.25 probability of being selected for a total of 1.0 probability (a unit is always selected).
  • A: 0.25
  • B: 0.25
  • C: 0.25
  • D: 0.25
However we need to achieve this by rolling random numbers for each of the units. This technically means that A, being picked first, is subject to more dice logic tests than D, being picked last. If these dice logic tests had a constant probability then one would be more likely to get D as the potential best unit rather than A since A has many more chances to fail than D. As such the dice logic must increase its chance of failure as it advances sequentially to be fair for A and give an equal probability of any of the units becoming the potential best. We can see this by working out the success probability for each of the units to become the new potential best.
  • A: 1.0 // Always success as it is the first!
  • B: 0.5 // A: 0.5 B 0.5
  • C: 0.333... // A OR B: 0.666... C: 0.333...
  • D: 0.25 // A OR B OR C: 0.75 D: 0.25
As one can see, the probability for any of the 4 units at any stage to become the new potential best is kept fair. One can also see that there is an inversely proportional relationship going on here where success probability is...
1 / {current attempt number}

This means you will need a variable to keep track of how many dice roll attempts have been made. Before executing test number 3 it is incremented by 1. Every time test number 2 finds a new potential best then this variable is reset to 1, representing the first roll always passing for subsequent rolls to be fair.

This should do exactly what you want. The only problem with it is the O(n^2) complexity. This means that sorting 100 units will perform in the order of ~10,000 comparisons. In reality it will only perform ~5,000 comparisons due to removing the potential best unit from the unsorted list. One might be able to improve complexity by pre-sorting the list in order of intelligence followed by owner food using a more efficient sorting algorithm. One then can more efficiently apply test 3 by pulling the top of list or performing test 3 on all elements until either food usage or intelligence changes.
 
Level 26
Joined
Aug 18, 2009
Messages
4,099
Code:
Loop through array
 Is intelligence of [X] < [X+1] ?
  Yes - Switch
  No - If (Int of [x] == [x+1]) AND (Food for [x] < [X+1])
   Yes - Switch
   No -If (Int of [x] == [x+1]) AND (Food for [x] == [X+1]) AND ( (Roll out of 100) < 50)
    Yes - Switch
    No - Those are in order
Have you done a switch at all?
 Yes - Go back to beginning
 No - You are done, hurray !

The predicate/comparator function is usually separated from the sorting algorithm. At least, it is too easy to make some mistake in the sorting algorithm and one would not want to write it over and over again. Of course, in wc3, dynamic invocation is very costly, so it may rather be done by macro and surely this is a task particularly unsuited for GUI. Other than for performance reasons, I would also leave out the random number generator and instead append a call to a dedicated shuffle method afterwards because the comparator function is actually to supposed to establish a total order to make it compatible to different sorting algorithms.
 
Level 3
Joined
Mar 15, 2018
Messages
31
Simple but inefficient approach...

Do you mean my approach or your's? :) Just for understanding what you've meant.

  1. Place all units in an unsorted list.
  2. Create a new empty sorted list.
  3. Find the "best" unit in the unsorted list.
  4. Remove the "best" unit from the unsorted list.
  5. Append the "best" unit to the sorted list.
  6. Repeat until sorted list has as many units as required.
How would you do the Append thing in GUI? That's what I wonder about. It would be super helpful, if you don't mind, if you could add a little example in GUI. :)


  1. Test the intelligence of the unit. If this unit has more intelligence than the potential best then make this unit the new potential best. If intelligence is equal then go to test 2.
  2. Test the food of the owning players. If this unit's owner has more food than the potential best's owner then make this unit the new potential best. If food is equal then go to test 3.
  3. Dice logic! Now one has to be careful that each unit is selected fairly. If this unit passes the dice logic test then make this unit the new potential best.

Ah allright, so you're staying with the bubble sort we talked about previously then right?

The dice logic is tricky to do right. Even Blizzard failed to implement this properly in one of the random unit/units in unit group functions.

Say you have 4 potential best units which are only separated by the dice logic. Each should have a 0.25 probability of being selected for a total of 1.0 probability (a unit is always selected).
  • A: 0.25
  • B: 0.25
  • C: 0.25
  • D: 0.25
However we need to achieve this by rolling random numbers for each of the units. This technically means that A, being picked first, is subject to more dice logic tests than D, being picked last. If these dice logic tests had a constant probability then one would be more likely to get D as the potential best unit rather than A since A has many more chances to fail than D. As such the dice logic must increase its chance of failure as it advances sequentially to be fair for A and give an equal probability of any of the units becoming the potential best. We can see this by working out the success probability for each of the units to become the new potential best.
  • A: 1.0 // Always success as it is the first!
  • B: 0.5 // A: 0.5 B 0.5
  • C: 0.333... // A OR B: 0.666... C: 0.333...
  • D: 0.25 // A OR B OR C: 0.75 D: 0.25
As one can see, the probability for any of the 4 units at any stage to become the new potential best is kept fair. One can also see that there is an inversely proportional relationship going on here where success probability is...

Oh wow, this seems like advanced logic here. I'll have to reread that some times to fully get it. I would love to see an example here as well, but thanks so far already! :)
1 / {current attempt number}

This means you will need a variable to keep track of how many dice roll attempts have been made. Before executing test number 3 it is incremented by 1. Every time test number 2 finds a new potential best then this variable is reset to 1, representing the first roll always passing for subsequent rolls to be fair.
Understoood.

This should do exactly what you want. The only problem with it is the O(n^2) complexity. This means that sorting 100 units will perform in the order of ~10,000 comparisons. In reality it will only perform ~5,000 comparisons due to removing the potential best unit from the unsorted list. One might be able to improve complexity by pre-sorting the list in order of intelligence followed by owner food using a more efficient sorting algorithm. One then can more efficiently apply test 3 by pulling the top of list or performing test 3 on all elements until either food usage or intelligence changes.

The complexity won't be a thing, as I will compare 5 Units at maximum. :)

The predicate/comparator function is usually separated from the sorting algorithm. At least, it is too easy to make some mistake in the sorting algorithm and one would not want to write it over and over again. Of course, in wc3, dynamic invocation is very costly, so it may rather be done by macro and surely this is a task particularly unsuited for GUI. Other than for performance reasons, I would also leave out the random number generator and instead append a call to a dedicated shuffle method afterwards because the comparator function is actually to supposed to establish a total order to make it compatible to different sorting algorithms.

Hey WaterKnight! I think I know you from the German forums. :D

I fully understand that GUI is unsuited for this, but as this will be my first project and maybe for now my last, I just need that to work quickly and inefficient :D There are only 5 units to be sorted anyway so I thought that might be no major problem. But if you could give me a JASS example that works I'm very super grateful and happy to implement it. Like the shuffle method, which sounds very interesting and like a chance to learn from. :)
But apart from that: Are you saying I should first sort out all of the equality issues before I apply the sorting algorithm in order to make it more structured and less buggy? Because this actually sounds like a good idea. (Just wanna state here that examples are very welcome! Sorry, it's not about lazyness!)

Can I just say that if you help me to make this work, I promise to help at least 5 people in the forums back! ;D (Just a little motvation. I just would be so excited to get this mountain climb done! ;) )
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,285
Do you mean my approach or your's? :) Just for understanding what you've meant.
I was describing my approach as simple but inefficient.
How would you do the Append thing in GUI? That's what I wonder about. It would be super helpful, if you don't mind, if you could add a little example in GUI.
In your case it would be swapping elements in an array with 2 separate counters to keep track of the number of elements in each list. One could make it that the counter for the sorted list is the starting index of the unsorted list. Once a new best unit is determined from the unsorted list it is swapped for the element in the array located at the sorted list count index, done using an intermediate variable, and the sorted list count is incremented by 1 and unsorted list count is decremented by 1.
Ah allright, so you're staying with the bubble sort we talked about previously then right?
No I was suggesting a Selection Sort. Ugly and inefficient but fairly simple to implement and understand.

It has the advantage that if one only wants the top 10 units one can stop sorting after that sort list count. This helps combat the O(n^2) complexity. It also has the advantage that each best element is compared only once, making the random nature of ordering less of a problem to implement.

If you are still having problems later today just say so and I will see if I can wip up an example. The example would use hard coded test data, but the idea is one could change this test data for real data and then run the same sorting code.
 
Level 3
Joined
Mar 15, 2018
Messages
31
Hey here is how I tried to implement it:

  • For each (Integer P3_SelSort) from 0 to (P3_CountfCheckThese - 1), do (Actions)
    • Loop - Actions
      • For each (Integer P3_SelSort2) from 1 to P3_CountfCheckThese, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Intelligence of P3_CheckThese[P3_SelSort2] (Include bonuses)) Less than (Intelligence of P3_CheckThese[P3_SelSort] (Include bonuses))
            • Then - Actions
              • Game - Display to (All players) the text: (1 + (( + ((String(P3_SelSort)) + (, + ((String(P3_SelSort2)) + ))))))
              • -------- Intelligence Check --------
              • Set P3_TempUnit = P3_CheckThese[P3_SelSort]
              • Set P3_CheckThese[P3_SelSort] = P3_CheckThese[P3_SelSort2]
              • Set P3_CheckThese[P3_SelSort2] = P3_TempUnit
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Intelligence of P3_CheckThese[P3_SelSort2] (Include bonuses)) Equal to (Intelligence of P3_CheckThese[P3_SelSort] (Include bonuses))
                  • ((Owner of P3_CheckThese[P3_SelSort2]) Food used) Less than ((Owner of P3_CheckThese[P3_SelSort]) Food used)
                • Then - Actions
                  • Game - Display to (All players) the text: (2 + (( + ((String(P3_SelSort)) + (, + ((String(P3_SelSort2)) + ))))))
                  • -------- If Intelligence is equal then Food check --------
                  • Set P3_TempUnit = P3_CheckThese[P3_SelSort]
                  • Set P3_CheckThese[P3_SelSort] = P3_CheckThese[P3_SelSort2]
                  • Set P3_CheckThese[P3_SelSort2] = P3_TempUnit
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • ((Owner of P3_CheckThese[P3_SelSort2]) Food used) Equal to ((Owner of P3_CheckThese[P3_SelSort]) Food used)
                    • Then - Actions
                      • Game - Display to (All players) the text: (3 + (( + ((String(P3_SelSort)) + (, + ((String(P3_SelSort2)) + ))))))
                      • -------- If Food is equal then roll dice --------
                      • Set P3_Rolled[0] = (Random integer number between 1 and 6)
                      • Set P3_Rolled[1] = (Random integer number between 1 and 6)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • P3_Rolled[0] Less than P3_Rolled[1]
                        • Then - Actions
                          • Game - Display to (All players) the text: (3.1 + (( + ((String(P3_SelSort)) + (, + ((String(P3_SelSort2)) + ))))))
                          • Set P3_TempUnit = P3_CheckThese[P3_SelSort]
                          • Set P3_CheckThese[P3_SelSort] = P3_CheckThese[P3_SelSort2]
                          • Set P3_CheckThese[P3_SelSort2] = P3_TempUnit
                        • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • P3_Rolled[0] Equal to P3_Rolled[1]
                            • Then - Actions
                              • -------- If first roll is equal then roll dice second time --------
                              • Game - Display to (All players) the text: (4 + (( + ((String(P3_SelSort)) + (, + ((String(P3_SelSort2)) + ))))))
                              • Set P3_Rolled[0] = (Random integer number between 1 and 6)
                              • Set P3_Rolled[1] = (Random integer number between 1 and 6)
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • P3_Rolled[0] Less than P3_Rolled[1]
                                • Then - Actions
                                  • Game - Display to (All players) the text: (4.1 + (( + ((String(P3_SelSort)) + (, + ((String(P3_SelSort2)) + ))))))
                                  • Set P3_TempUnit = P3_CheckThese[P3_SelSort]
                                  • Set P3_CheckThese[P3_SelSort] = P3_CheckThese[P3_SelSort2]
                                  • Set P3_CheckThese[P3_SelSort2] = P3_TempUnit
                                • Else - Actions
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • P3_Rolled[0] Equal to P3_Rolled[1]
                                    • Then - Actions
                                      • Game - Display to (All players) the text: (5 + (( + ((String(P3_SelSort)) + (, + ((String(P3_SelSort2)) + ))))))
                                      • -------- If second roll is equal then roll dice third time --------
                                      • Set P3_Rolled[0] = (Random integer number between 1 and 6)
                                      • Set P3_Rolled[1] = (Random integer number between 1 and 6)
                                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                        • If - Conditions
                                          • P3_Rolled[0] Less than P3_Rolled[1]
                                        • Then - Actions
                                          • Game - Display to (All players) the text: (5.1 + (( + ((String(P3_SelSort)) + (, + ((String(P3_SelSort2)) + ))))))
                                          • Set P3_TempUnit = P3_CheckThese[P3_SelSort]
                                          • Set P3_CheckThese[P3_SelSort] = P3_CheckThese[P3_SelSort2]
                                          • Set P3_CheckThese[P3_SelSort2] = P3_TempUnit
                                        • Else - Actions
                                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                            • If - Conditions
                                              • P3_Rolled[0] Equal to P3_Rolled[1]
                                            • Then - Actions
                                              • Game - Display to (All players) the text: (6 + (( + ((String(P3_SelSort)) + (, + ((String(P3_SelSort2)) + ))))))
                                              • -------- If third roll is equal then set random winner --------
                                              • Set P3_Rolled[2] = (Random integer number between 0 and 1)
                                              • Set P3_Rolled[P3_Rolled[2]] = 6
                                              • Set P3_Rolled[(Abs((P3_Rolled[2] - 1)))] = 0
                                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                                • If - Conditions
                                                  • P3_Rolled[0] Less than P3_Rolled[1]
                                                • Then - Actions
                                                  • Game - Display to (All players) the text: (6.1 + (( + ((String(P3_SelSort)) + (, + ((String(P3_SelSort2)) + ))))))
                                                  • Set P3_TempUnit = P3_CheckThese[P3_SelSort]
                                                  • Set P3_CheckThese[P3_SelSort] = P3_CheckThese[P3_SelSort2]
                                                  • Set P3_CheckThese[P3_SelSort2] = P3_TempUnit
                                                • Else - Actions
                                                  • Game - Display to (All players) the text: !?
                                            • Else - Actions
                                    • Else - Actions
                            • Else - Actions
                    • Else - Actions

This trigger really doesn't work. Sometimes the units get two arrays and one isn't saved at all. And even if there is a unit with more intelligence than the others and without any equality it is still randomly placed. I don't understand what is happening. :(

I am very aware of that this is still not the solution for the part where I need to put the units with equal values in one group to let them sort seperately, at least I think that would be the way. Maybe you have an example for that.

But more importantly I first want to understand why the trigger is not working this far.

Here are the messages that were spit out one time in case you are interested:

There is one unit with 10 intelligence and 3 other with 5 intelligence.

Number of action (See trigger) (P3_SelSort, P3_SelSort2)
  1. 3 (0, 1)
  2. 3.1 (0, 1)
  3. 1 (0, 2)
  4. 3 (0, 3)
  5. 3 (0, 4)
  6. 4 (0, 4)
  7. 4.1 (0, 4)
  8. 3 (1, 1)
  9. 3 (1, 2)
  10. 3 (1, 3)
  11. 3 (1, 4)
  12. 1 (2, 1)
  13. 3 (2, 2)
  14. 3.1 (2, 2)
  15. 3 (2, 3)
  16. 3 (2, 4)
  17. 3.1 (2, 4)
  18. 3 (3, 1)
  19. 3 (3, 2)
  20. 4 (3, 2)
  21. 3 (3, 3)
  22. 4 (3, 3)
  23. 5 (3, 3)
  24. 5.1 (3, 3)
  25. 3 (3, 4)
I really would appreciate a nice GUI example at this point.

Cheers
Old_edge
 
Last edited:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,285
Attached is the solution I mentioned. Basically need to change the arrays to a single unit array and change the tests to dynamically fetch the appropriate values. Press ESC or type -sort to see it in action on the test data. Feel free to alter the test data to check that it works.

Here are the triggers for anyone interest.
  • Sort
    • Events
      • Player - Player 1 (Red) types a chat message containing -sort as An exact match
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • -------- Initialize test data. --------
      • -------- These arrays would be replaced by a unit array which is filled from a unit group. --------
      • Set SortListLength = 0
      • Set SortUnitUID[SortListLength] = A
      • Set SortUnitInt[SortListLength] = 5
      • Set SortUnitFood[SortListLength] = 27
      • Set SortListLength = (SortListLength + 1)
      • Set SortUnitUID[SortListLength] = B
      • Set SortUnitInt[SortListLength] = 5
      • Set SortUnitFood[SortListLength] = 27
      • Set SortListLength = (SortListLength + 1)
      • Set SortUnitUID[SortListLength] = C
      • Set SortUnitInt[SortListLength] = 5
      • Set SortUnitFood[SortListLength] = 27
      • Set SortListLength = (SortListLength + 1)
      • Set SortUnitUID[SortListLength] = D
      • Set SortUnitInt[SortListLength] = 5
      • Set SortUnitFood[SortListLength] = 22
      • Set SortListLength = (SortListLength + 1)
      • Set SortUnitUID[SortListLength] = E
      • Set SortUnitInt[SortListLength] = 4
      • Set SortUnitFood[SortListLength] = 22
      • Set SortListLength = (SortListLength + 1)
      • Set SortUnitUID[SortListLength] = F
      • Set SortUnitInt[SortListLength] = 6
      • Set SortUnitFood[SortListLength] = 1
      • Set SortListLength = (SortListLength + 1)
      • -------- Sort data. --------
      • Set SortSortedLength = 0
      • Set SortBestIndex = 0
      • For each (Integer SortSortedLength) from 0 to (SortListLength - 1), do (Actions)
        • Loop - Actions
          • -------- Find the best. --------
          • Set SortBestIndex = SortSortedLength
          • Set SortChanceCount = 1
          • For each (Integer SortLoopIndex) from (SortSortedLength + 1) to (SortListLength - 1), do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SortUnitInt[SortLoopIndex] Greater than SortUnitInt[SortBestIndex]
                • Then - Actions
                  • -------- More int so better. --------
                  • Set SortBestIndex = SortLoopIndex
                  • Set SortChanceCount = 1
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • SortUnitInt[SortLoopIndex] Equal to SortUnitInt[SortBestIndex]
                      • SortUnitFood[SortLoopIndex] Greater than SortUnitFood[SortBestIndex]
                    • Then - Actions
                      • -------- More food so better. --------
                      • Set SortBestIndex = SortLoopIndex
                      • Set SortChanceCount = 1
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • SortUnitInt[SortLoopIndex] Equal to SortUnitInt[SortBestIndex]
                          • SortUnitFood[SortLoopIndex] Equal to SortUnitFood[SortBestIndex]
                        • Then - Actions
                          • -------- Down to luck. --------
                          • Set SortChanceCount = (SortChanceCount + 1)
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Random integer number between 1 and SortChanceCount) Equal to 1
                            • Then - Actions
                              • -------- Lucky so is better. --------
                              • Set SortBestIndex = SortLoopIndex
                            • Else - Actions
                              • -------- Unluckly so is worse. --------
                        • Else - Actions
                          • -------- Worse than potential best. --------
          • -------- Append best to sorted list. --------
          • Set SortSwapString = SortUnitUID[SortSortedLength]
          • Set SortUnitUID[SortSortedLength] = SortUnitUID[SortBestIndex]
          • Set SortUnitUID[SortBestIndex] = SortSwapString
          • Set SortSwapInt = SortUnitInt[SortSortedLength]
          • Set SortUnitInt[SortSortedLength] = SortUnitInt[SortBestIndex]
          • Set SortUnitInt[SortBestIndex] = SortSwapInt
          • Set SortSwapInt = SortUnitFood[SortSortedLength]
          • Set SortUnitFood[SortSortedLength] = SortUnitFood[SortBestIndex]
          • Set SortUnitFood[SortBestIndex] = SortSwapInt
      • -------- Print results. --------
      • Game - Display to (All players) for 120.00 seconds the text: Results:
      • For each (Integer SortLoopIndex) from 0 to (SortListLength - 1), do (Actions)
        • Loop - Actions
          • Game - Display to (All players) for 120.00 seconds the text: (((ID= + SortUnitUID[SortLoopIndex]) + ( INT= + (String(SortUnitInt[SortLoopIndex])))) + ( FOOD= + (String(SortUnitFood[SortLoopIndex]))))
 

Attachments

  • old_edge5 Sorting System.w3x
    12.8 KB · Views: 34
Level 3
Joined
Mar 15, 2018
Messages
31
Man thank you so much!

This is incredible! :D

So I got a promise to keep :)

If I get any problems I come back to you but it seems to be working pretty good so far!

+rep!

Can I just ask one question though? Where exactly did you make sure that if there are several groups that are equal that they can only swap within themselves?
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,285
Can I just ask one question though?
Sure.
Where exactly did you make sure that if there are several groups that are equal that they can only swap within themselves?
By resetting the SortChanceCount to 1 after the other comparison branches find a new potential best. For each new potential best found one only cares about other equal members. It loops through every element to find a best and then does that until no elements remain, hence complexity of O(n^2).
 
Status
Not open for further replies.
Top