I've got a question about how to do this one thing. Right now, I have set it up so each restaurant in the game gets assigned a 'overall score', which is a real number between 0 and 100. I am trying to make customers pick which restaurant to go to buy picking each house and then picking the closest 4 restaurants to it, and then comparing them. I've got 2 problems- the first is that I don't know how I should compare the 4 restaurants. I want it to be possible for the customer to choose any of the 4, but obviously restaurants with higher 'scores' should be more likely to be chosen. The 2nd problem is I get the error message "nested iteration detected"...This is cuz I have it pick each house and then inside that pick the 4 closest restaurants....So can sc2 not handle nested loops? Is there any way around this? If not, what should I do?
for those who dont know, a nested loop is when you have a loop inside another loop.
Rollback Post to RevisionRollBack
Feel free to Send me a PM if you have any questions/concerns!
Pick Each Unit In Unit Group cannot be nested. I believe it is because it would cause confusion about which unit the picked unit should refer to.
For Each Unit In Unit Group can be nested. Use this function instead. This function lets you define the unit variable yourself, so there is no confusion.
wow. thanks. Whats the point of having the 2 functions doing almost the same thing? Is pick each unit just a noob-friendly version of the for each unit? Anyways thanks. Still need help with the 2nd question so...if anybody has a suggestion that would be great!
I need to figure out how exactly to go about this...I want to pick each house, then pick the 4 closest restaurants (or less than 4 if only a few are available) and then compare their custom values in some way so that higher custom values make a higher chance of being picked as where the person will go to eat.
Yes, PickEach (int or unit) has predefined functions and variables and therefore can't be nested. I was also pretty confused about the error messages I saw ingame until I found this out.
I would recommand to always use ForEach, else you will for example have the same problem when you use PickEach in a function and another PickEach uses this function. Only in triggers which use their own thread it won't cause any problems.
For your second question: Use a forEachUnit loop to find all houses. Filter them out by unittype or whatever works in your map. Then you would need to know if there is a maximum distance between a restaurant and a house or a maximum distance someone would walk to a restaurant. If there is one, use ConvertCircleToRegion and filter all restaurants out with this. If not, then you will need to again loop through all restaurants in the map. This can become a little tricky,d epending on how many restaurants there are in total.
You could save all distances between the restaurants and the current house in a real array variable of a big size. Then you would need to sort this array to find the four smallest distances. Look in the standard library of blizzard. At the very bottom they gave us some sorting algortihms which you can simply copy and paste to use them for your own array.
If you finally found the four closest restaurants I would then design some function (linear or whatever) which converts the custom value to a percentage chance. When using random values and chances you will make sure that you implement this in a while-loop so that the unit will walk to one of the restaurants and not just stand still when all chances fail for the first run.
Okay, I have it so now it chooses each house, then picks 4 restaurants from a small radius around the house and saves them into a variable. (not the 4 closest but it probably doesn't matter too much). But could you explain more on the comparison thing? Each restaurant will have a custom value from 0 to 100, which is how 'awesome' it is. So say the 4 restaurant values are 20,30,40, and 75. I don't know how I could convert those into a chance..
edit- Also just FYI, I'm hoping to make it so there are multiple people in each house and they all can go to different restaurants...Again, more of them will go to restaurants with higher values.
set a local integer variable(A) to a random integer with a minimum of 0 and a maximum of the sum of W,X,Y and Z
use an If, then, else to check which one has selected through conditions
You will need 2 conditions for each variable(restaurant)
So If 0 < A ≤ W, then carry out the actions for restaurant number 1
If W < A ≤ W+X, then carry out the action for restaurant number 2
For restaurant 3 W+X < A ≤ W+X+Y
Finally for restaurant 4 W+X+Y < A ≤ W+X+Y+Z
EDIT: it would look something like this but you would need 2 things, the number of restaurants and each restaurant saved to the corresponding restaurant number
You can pick one at random by doing a loop. I haven't checked the math, but I think this shouldn't be biased.
for i from 1 to NumRestaurants
sum = 0
for j from i to NumRestaurants
sum =+ score[j]
if (randReal(0, 1) <= score[i]/sum) // score[i] and sum must be fixed reals
return i; // your winning restaurant
return NumRestaurants // in case it failed to return a value
sorry for the long response. I sort of got somewhat of a system working but its still glitchy and doesnt work quite the way I want. I attached a pic. I dont get any errs when I run it with the cutoff distance set to 100. But when I lower it to say, 30 (the distance I actually need to use) I get an error that says "could not get player from parameter in playerModifyProperty (16). " and the battlecruisers are created at the bottom left corner of the map randomly. FYI I created the battle cruisers just as a visual way for me to see which restaurants it was picking. Any ideas?
ATTACHMENTS
trigger-Pic_copy.png
Rollback Post to RevisionRollBack
Feel free to Send me a PM if you have any questions/concerns!
I didnt fully look at your code through the pic, I like looking at the map ... as its just easier to mess with. what I would do is 1, put some output messages at each stage of that script, (that way you know what loop its on, and what if check its doing at all times) so you can see the exact second you get the "playerModifyProperty" error, also, instead of all players, try making it all players other than player 16... just to see what happens.
It could be a easy find.. but like I said.. i just dont like looking a massive trigger pics with loads of vars... just to much going on to see,as im all about debugging.
Rollback Post to RevisionRollBack
Random Information
Tutorials - Map Development - Galaxy wiki
|Issues? PM me|
Wow. I was just about to post here and realized you made that for me :D Wasn't expecting that, thanks a bunch. But I do have a question about it. Does it give restaurants with a higher value a higher chance of being picked? It seems so but I just wanted to be sure, cuz I'm confused by that trigger O.o. Anyways, thanks a bunch for going above and beyond here, I really appreciate it. Your going in map credits for sure.
edit- Another question real quick. I see you have all the restaurants values stored in an array. I currently store thier values in a custom value inside the unit and extract it later. Since restaurants are constructed and de-constructed frequently, how would I know which restaurant got which value in the array? You just loop through the values and return which value was chosen. But how would I go about setting those values, since I dont know which restaurant corresponds to which value.... O.o
Ok here is a modified version that uses units instead.
EDIT: ok, so i'm pretty sure i got it
type create to make another SCV(restaurant)
How it works, every time a unit is created a value and custom value is set and the unit is set to a variable, Restaurants[(Triggering Player)][Number of Units in Unit Group UG]
(UG is set to all of restaurants owned by the triggering player)
Every time a restaurant is removed all of the restaurants above it are set to whatever they where -1
For Example if you had 4 restaurants owned by Player 1 they would be (1,1),(1,2)(1,3) and (1,4) if (1,2) was removed then (1,3) is set to (1,2) and (1,4) is set to (1,3). So your new restaurants are (1,1) (1,2) and (1,3)
I haven't looked into the guts of it yet but I noticed theres no trigger to make a new scv. Just wanted to make sure I got the right version of the trigger. And thanks for all the effort you put into this.
Rollback Post to RevisionRollBack
Feel free to Send me a PM if you have any questions/concerns!
I just typed "test" over and over. Sometimes it had no # output at all. When it did, it was always 11 (or at least 11 99% of the time).... weird bug or was unit #11 just really really high in value? Again, big thanks to you for doing all this.
Rollback Post to RevisionRollBack
Feel free to Send me a PM if you have any questions/concerns!
@zeldarules28: Go
just change set A to random number from 0 to max value to
Set A to random number from 1 to max value, that should fix you not getting a value
I downloaded the map and spammed test and i didnt get the #11 bug you got, make sure you type create to spawn another unit and remove to kill the selected unit. If there is only 1 restaurant to choose from it will only pick that 1 :P
Finally, the debug message works by the owner of unit (1) and what number restaurant it is (1)
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
I've got a question about how to do this one thing. Right now, I have set it up so each restaurant in the game gets assigned a 'overall score', which is a real number between 0 and 100. I am trying to make customers pick which restaurant to go to buy picking each house and then picking the closest 4 restaurants to it, and then comparing them. I've got 2 problems- the first is that I don't know how I should compare the 4 restaurants. I want it to be possible for the customer to choose any of the 4, but obviously restaurants with higher 'scores' should be more likely to be chosen. The 2nd problem is I get the error message "nested iteration detected"...This is cuz I have it pick each house and then inside that pick the 4 closest restaurants....So can sc2 not handle nested loops? Is there any way around this? If not, what should I do?
for those who dont know, a nested loop is when you have a loop inside another loop.
Pick Each Unit In Unit Group cannot be nested. I believe it is because it would cause confusion about which unit the picked unit should refer to.
For Each Unit In Unit Group can be nested. Use this function instead. This function lets you define the unit variable yourself, so there is no confusion.
wow. thanks. Whats the point of having the 2 functions doing almost the same thing? Is pick each unit just a noob-friendly version of the for each unit? Anyways thanks. Still need help with the 2nd question so...if anybody has a suggestion that would be great!
I need to figure out how exactly to go about this...I want to pick each house, then pick the 4 closest restaurants (or less than 4 if only a few are available) and then compare their custom values in some way so that higher custom values make a higher chance of being picked as where the person will go to eat.
@zeldarules28: Go
Your guess is as good as mine. Even if it is noob friendly (which I don't agree it is), I'm sure it's been the cause of many headaches.
Yes, PickEach (int or unit) has predefined functions and variables and therefore can't be nested. I was also pretty confused about the error messages I saw ingame until I found this out.
I would recommand to always use ForEach, else you will for example have the same problem when you use PickEach in a function and another PickEach uses this function. Only in triggers which use their own thread it won't cause any problems.
For your second question: Use a forEachUnit loop to find all houses. Filter them out by unittype or whatever works in your map. Then you would need to know if there is a maximum distance between a restaurant and a house or a maximum distance someone would walk to a restaurant. If there is one, use ConvertCircleToRegion and filter all restaurants out with this. If not, then you will need to again loop through all restaurants in the map. This can become a little tricky,d epending on how many restaurants there are in total.
You could save all distances between the restaurants and the current house in a real array variable of a big size. Then you would need to sort this array to find the four smallest distances. Look in the standard library of blizzard. At the very bottom they gave us some sorting algortihms which you can simply copy and paste to use them for your own array.
If you finally found the four closest restaurants I would then design some function (linear or whatever) which converts the custom value to a percentage chance. When using random values and chances you will make sure that you implement this in a while-loop so that the unit will walk to one of the restaurants and not just stand still when all chances fail for the first run.
good luck ;)
Thanks!
Okay, I have it so now it chooses each house, then picks 4 restaurants from a small radius around the house and saves them into a variable. (not the 4 closest but it probably doesn't matter too much). But could you explain more on the comparison thing? Each restaurant will have a custom value from 0 to 100, which is how 'awesome' it is. So say the 4 restaurant values are 20,30,40, and 75. I don't know how I could convert those into a chance..
edit- Also just FYI, I'm hoping to make it so there are multiple people in each house and they all can go to different restaurants...Again, more of them will go to restaurants with higher values.
@zeldarules28: Go
Let W,X,Y, and Z stand for your restaurant values
set a local integer variable(A) to a random integer with a minimum of 0 and a maximum of the sum of W,X,Y and Z
use an If, then, else to check which one has selected through conditions
You will need 2 conditions for each variable(restaurant)
So If 0 < A ≤ W, then carry out the actions for restaurant number 1
If W < A ≤ W+X, then carry out the action for restaurant number 2
For restaurant 3 W+X < A ≤ W+X+Y
Finally for restaurant 4 W+X+Y < A ≤ W+X+Y+Z
EDIT: it would look something like this but you would need 2 things, the number of restaurants and each restaurant saved to the corresponding restaurant number
@zeldarules28: Go
You can pick one at random by doing a loop. I haven't checked the math, but I think this shouldn't be biased.
@SexLethal: Go
using that you can get more than 1 result, also the randReal will be different for every score tested
@SexLethal: Go
I dont even see how those work lol .... O.o
sorry for the long response. I sort of got somewhat of a system working but its still glitchy and doesnt work quite the way I want. I attached a pic. I dont get any errs when I run it with the cutoff distance set to 100. But when I lower it to say, 30 (the distance I actually need to use) I get an error that says "could not get player from parameter in playerModifyProperty (16). " and the battlecruisers are created at the bottom left corner of the map randomly. FYI I created the battle cruisers just as a visual way for me to see which restaurants it was picking. Any ideas?
I didnt fully look at your code through the pic, I like looking at the map ... as its just easier to mess with. what I would do is 1, put some output messages at each stage of that script, (that way you know what loop its on, and what if check its doing at all times) so you can see the exact second you get the "playerModifyProperty" error, also, instead of all players, try making it all players other than player 16... just to see what happens.
It could be a easy find.. but like I said.. i just dont like looking a massive trigger pics with loads of vars... just to much going on to see,as im all about debugging.
@zeldarules28: Go
here is the trigger i posted earlier, it works
Type test to test it
Wow. I was just about to post here and realized you made that for me :D Wasn't expecting that, thanks a bunch. But I do have a question about it. Does it give restaurants with a higher value a higher chance of being picked? It seems so but I just wanted to be sure, cuz I'm confused by that trigger O.o. Anyways, thanks a bunch for going above and beyond here, I really appreciate it. Your going in map credits for sure.
edit- Another question real quick. I see you have all the restaurants values stored in an array. I currently store thier values in a custom value inside the unit and extract it later. Since restaurants are constructed and de-constructed frequently, how would I know which restaurant got which value in the array? You just loop through the values and return which value was chosen. But how would I go about setting those values, since I dont know which restaurant corresponds to which value.... O.o
@zeldarules28: Go
You're using units right?(for the restaurants)
Ok here is a modified version that uses units instead.
EDIT: ok, so i'm pretty sure i got it
type create to make another SCV(restaurant)
How it works, every time a unit is created a value and custom value is set and the unit is set to a variable, Restaurants[(Triggering Player)][Number of Units in Unit Group UG]
(UG is set to all of restaurants owned by the triggering player)
Every time a restaurant is removed all of the restaurants above it are set to whatever they where -1
For Example if you had 4 restaurants owned by Player 1 they would be (1,1),(1,2)(1,3) and (1,4) if (1,2) was removed then (1,3) is set to (1,2) and (1,4) is set to (1,3). So your new restaurants are (1,1) (1,2) and (1,3)
I haven't looked into the guts of it yet but I noticed theres no trigger to make a new scv. Just wanted to make sure I got the right version of the trigger. And thanks for all the effort you put into this.
@zeldarules28: Go
your right :P, i came across a really annoying bug if you have around 7 SCVs and remove the 4th one it screws up im looking around for the mistake
EDIT i think i fixed it, for some reason the Break action wasn't stopping the loop
EDIT2 nvm for some reason it only works the 1st time
EDIT3 i feel dumb, i just set the variables in the wrong order, will update
If you find any more bugs please let me know
I just typed "test" over and over. Sometimes it had no # output at all. When it did, it was always 11 (or at least 11 99% of the time).... weird bug or was unit #11 just really really high in value? Again, big thanks to you for doing all this.
@zeldarules28: Go just change set A to random number from 0 to max value to
Set A to random number from 1 to max value, that should fix you not getting a value
I downloaded the map and spammed test and i didnt get the #11 bug you got, make sure you type create to spawn another unit and remove to kill the selected unit. If there is only 1 restaurant to choose from it will only pick that 1 :P
Finally, the debug message works by the owner of unit (1) and what number restaurant it is (1)