#Hey I have 130 enemies fruits doesnt
1 messages · Page 1 of 1 (latest)
Hey!
So you have a list of items, and you want to pick a random element from that list, but each element should have a different chance of being picked
Right
All theoretical right now
So, instead of going for percentages, we start working with a concept called weights
This is because we can't guarantee that all of our percentages sum up to 100%
And realistically, a percentage can be expressed as a relation between the current and the other elements in the list
So lets say, you have your enemies, (fruits) and you want 2 apples for every kiwi
If you used percentages, you'd have a 66% chance for an apple and a 33% chance for a kiwi
(we just ran into the first problem for percentages, since these sum up to 99%)
We can instead express this the way I first said it, apples have a weight of 2 and kiwi's have a weight of 1
Imagine these numbers in a long line with the lengths of each fruit being proportional to its weight
So you'd have apples with length 2 and then kiwi's with length 1
yeah
What if we pick a random distance to walk down that line and then look at which fruit we arrive at?
I'm confused sorry, so the way you're trying to explain to me is that the fruits will have weights right?
Yes
Percentages are computed from the weights
Weights are basically how common a specific item is relative to the others in the set
Does that make sense?
right?
Yes alright, using them is the most complex part
Give me two seconds, ill try and draw something up
alright
Say we want this as a distrution
So for every kiwi, we will have 4 apples, 2 bananas and 3 grapefruits
or in percentages (40%, 20%, 30%, 10%)
put a yard stick and a ruler on the table, then pick a random point : you’re more likely to get the yard stick
So lets add all those numbers together
We get 10 right?
So what if, we then just pick a random number between 0 and 10?
And walk next to our line
and stop whenever we reach the right number
So in this case, we do rng(0,10), which gives us 6
if we walk the line till 6
we will land on the border between banana and grapefruit
but lets just say thats banana for now
Does this still make sense?
Cool so in short
- We have a list of fruits, with their weights
- We sum up the weights
- We roll a number between 0 and the sum
- We walk the line till we get to the randomly rolled number
Do you think you could implement this in c#?
I would give it a shot if I were you, and come back if you have a more specific problem
Right
Feel free to just tag me or @west crown in this chat, im sure he'll probably even respond faster than I do. (also checking if I gave enough information)
well, I'm not used to theese advanced features, i checked your code in #💻┃code-beginner and its interesting, because I'm not understanding it in code form
but let me figure it out
just give me a bit more clue
Its not fit for #💻┃code-beginner at all
But you could try to understand it
The steps are the same
Just using a couple of these
it has a few things that will be unfamiliar to novices
one is that it's an extension method: it adds a new method to IEnumerable<T>
(and thus, to anything that's derived from that, like List<T>)
it's a static method whose first parameter has the this keyword
it's very useful, and also what I do for this kind of thing
for example
public static T Draw<T>(this IEnumerable<T> self)
{
return self.ElementAt(UnityEngine.Random.Range(0, self.Count()));
}
now I can do someList.Draw();
ye
really not beginner at all
that just means it's not designed for one specific kind of thing
in this case, it works for literally any type
(very common for stuff with containers)
the other big thing is that it takes a Func<T, float> parameter
this is a function that takes T and returns a float
it's what assigns the weights
for example, here's my MinBy method...
public static T MinBy<T>(this IEnumerable<T> self, Func<T, float> metric)
{
if (self.Count() == 0)
return default;
float best = metric(self.First());
T result = self.First();
foreach (var elem in self)
{
if (metric(elem) < best)
{
best = metric(elem);
result = elem;
}
}
return result;
}
metric is a function that gives a float for each thing in the list
I'm starting to understand this code.
for example, to find the closest point in a list, I can do:
Vector3 point = // get this from somewhere
Vector3 closest = points.MinBy((other) => Vector3.Distance(point, other));
and then, MaxBy is just...
public static T MaxBy<T>(this IEnumerable<T> self, Func<T, float> metric)
{
return self.MinBy(x => -metric(x));
}
so what this does is returns the first float from something ? 😄
And also the last one will be assigned to the first one?
Am I completely wrong?
it picks the element that gives the smallest value when you run it through the metric function
well first != smallest but about that
might be worth noting, you can pass functions to functions
if metric is Vector3.Magnitude and you call this on a list of Vector3, it'll give you the shortest vector
this is where you really start saving effort
i don't have to write ten different functions to pick the smallest value in ten different ways
Well okay I get the concept
Also, how much practive and time do i need to accomplish stuff like tthis?
For now, ditch passing functions, ditch extension methods, ditch null-coelescing operators
just make a function GetRandomEnemyByWeight()
alright
did it
Does it work?
well, I dont know how to sum up the weights :I
Yet
I dont get what does it mean to sum up something here
Do you have your enemy weights?
I have a list yes
Or a list of your potential enemies?
I have a list of the weights
Whats the type of the list? I assume it would be List<Enemy>() right?
The weights? Thoose are floats
If you keep them seperate such as;
var enemies = new List<Enemy>();
var weights = new List<float>();
You have to be super careful that weights[index] corresponds to enemies[index]
But that's not really important
For now I would suggest you head to google and look up how to sum all values in a list :P
What does the Enemy refers to?
alright
I am assuming that you somewhere in your code has a list of prefabs that you can spawn
Not yet, that would be the next step
I would do that first actually
I dont need thoose by the way
Actually, it'll be just displayed in a text, because the "Fight" wont be visual
Like number of enemies in general: XYZ
Number of type 1 enemies:
type2:
etc.
You'd still need a list of all the possible enemies that you could spawn right?
If you want to be able to spawn them one by one that is
I dont think so I need to spawn them
Alright lets not call it spawning then, lets call it incrementing the counter for taht enemy
Sure
You want some sort of dictionary like this right:
var enemyWave = {
'kiwi': 100,
'apple': 20,
'banana': 15
};
You still need to know that you have kiwi, apple, banana as available enemies
So lets say you don't use gameobjects for your enemies, and you want a super simple way to get all of the possible enemies, you could just hardcode it like this:
var enemies = new List<string>() {"kiwi", "Apple", "Banana"}
var is just a shorthand
so instead of having to write List<string> enemies = new List<string>() {"kiwi", "Apple", "Banana"}
you just use var
c# will automatically try to figure out what the type is supposed to be
You can only use var if you directly assign a variable
else c# wont know what type it is
So if you're passing value to an existing float for example?
that way you can use vars?
uhh I don't quite understand what you are trying to say
Lets say you are calling a function, Vector3.Distance() for example
It is defined to return a float
var is used when declaring a variable, so I wouldn't expect anything to be already existing
this is not valid syntax
so am i a dummy
therefore you can do
var distance = Vector3.Distance()
and C# will figure out that its a float
yeah well i thought
well at least i know whats a variable 😄
notice how the declaration of weights has new() { /* stuff */ }
I was typing psuedocode
😄
yeah
you can create a dictionary with default values in a similar way
iirc it's...
var weights = new() {
{ "kiwi", 100 }
};
or was it square brackets
i should go check this
What does the number refer to?
Well, and what does the float do there? 😄
Dictionary<K, V> is a dictionary that has keys of type K and values of type V
therefore
Dictionary<string, float> looks up floats with string keys
map["hello"] = 12.5f;
Also, if you declare a variable on class level, you always have to define the type. If you do it in a function you can use var
indeed
it's only valid on a local variable
i.e. a variable declared inside of a function
Sure I'm watching some tutorials about lists and stuff like that to have a better understanding of whats going on before i start to make them
also, can you guys answer this one?
or did you have weeks, months off?
very intermittent
i went to college for both computer science and chemistry
i've been in grad school for CS for a while
i only really got back into 3D game dev about 2 years ago
the more experience you get with programming as a whole, the faster you can learn new things
things become more and more intuitive
so tutorials are notit
well, tutorials help you to do things that you can't figure out for yourself yet
you have to use what you have learned to actually learn them
some things are just impractical to figure out on your own
i am absolutely not figuring out how to write a custom post-processing pass in the URP on my own
tutorials are also handy because they give you something that (if you follow the tutorial properly) works
which means you can then modify it and, hopefully, get something else that works
well yeah but how do you progress effectively too?
just make games
and over the years you'll get better?
pretty much
when I ran into this exact problem -- weighted random draw -- I'd never implemented something exactly like it before
but I could immediately think of an algorithm for it
Hard to say, started programming about 10 years ago, mostly as something that looked interesting, ended up going to uni couple years later for software engineering, just finishing up a master's degree in AI. Learned a lot of different languages over the past few years, the more you program the more you realise that concepts and being able to understand them is more important than actually figuring out how to build them. As @west crown mentioned identifying a problem and then almost instantly coming up with an algo to solve it is the real skill here
Working partime as a full stack software developer for a couple of years also helps
Started with unity 2years ago I think
When I started programming one of my first things that I made was a very shitty cookie clicker clone
And slowly build it up to more complex projects, they usually have a lot of similar problems, just slightly different
well yeah thats the goal
i get it 🙂
can you make full time out of just unity btw?
I don't work with unity for my job
I don't think it's a very good career choice
Why not?
It's just the industry, it is very focussed around selling a product and if the product dies down you lose your job
There's also from what I've heard quite a bit of pressure
Since you deal with normal people who won't understand why the release date was pushed for 2ore weeks
i'm considering trying to bust into the industry after i leave grad school
You can always switch to game Dev or away from it
i'm very good at going on the computer and typing
but i've already had reasonable success from solo work
it's a tough business, for sure
Sounds hard to find a job though, such a niche
Where as I can literally call up 10 companies and have atleast 5 offers in 2 weeks
For software development that is
yeah well thats true
But by the sounds of it, you still have to go to college and stuff right?

Btw since you seem to be enjoying algorithms you might enjoy this @west crown https://adventofcode.com/2022/about unsure if I linked it before
Ah I see, they good fun, very specific kind of problem solving though
college? Well I'm in college
here you can go to special 6 grade colleges. and i didnt know what to do in 7th so i signed up and got in here.
so no learning from professors for the next 3 years at least
School systems are very different over here, I don't quite know what 6th, 7th grade and stuff are
We pick something at age of 17-18
wdym you pick something?
To do our bachelor's in, before that it's highschool stuff
ah yes sure. so well, i've done this little battle system here, I'll make the weights later. Can you check why are the attackers and the defenders are 0?
https://paste.ofcode.org/UPiVyiXSsSAcHBikzAJmJ - This controls the batlle but its not really relevant because the function doesnt actually occur because the values are 0.
https://paste.ofcode.org/8nmyxJfKmjQCX4UEx3RkYJ - And this when you click on "battle".
If I debug the kangarooenemies and the count it increases and its okay, but the index integers are 0
@near quest
Did you figure this out yet?
well not yet, i figured out that i 'm not adding to the list anything but do i need a list at all?
but the index integers are 0
What exactly do you mean by this?
@dull plank
What do you want (expect) to happen?
What is currently happening?
Then we can answer why it is happening
Also, allow me to introduce the switch statement
And then, switch expressions
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/switch-expression
probably cut your code down in half using that
And make it easier to read / maintain
Hey @near quest I'm not at home and I'm sorry because I didnt answer, now I:m following through some full game tutorials so maybe I can figure it on my own after thoose
Gotcha, if it is still relevant to this then you could post here bit at this point you might get help a lil bit quicker from the normal channel