Reputation: 322
I have an enum indicating the eligibility of a spawn.
protected enum SpawnEligibility
{
Worst,
Ok,
Optimal
}
Then, I have a function to return the eligibility.
protected virtual SpawnEligibility GetEligibility(Vector3 spawn)
{
var players = _instance.FindPlayersInRadius(spawn, 10).ToList();
if (!players.Any())
return SpawnEligibility.Optimal;
return players.Any(x => _instance.CanSeeLocation(x, spawn))
? SpawnEligibility.Worst
: SpawnEligibility.Ok;
}
When selecting a spawn I'd like to pick a random spawn from those that have the highest level of eligibility, though they may all be Worst
, Ok
, Optimal
, or a mix. This is my code which I was using to select a spawn.
public virtual Vector3 FindSpawn(BasePlayer player) =>
_spawns.OrderByDescending(GetEligibility).First();
How can I either make a dictionary with a Spawn key and SpawnEligibility value OR return a random element from my list without calling the GetEligibility function again?
Upvotes: 2
Views: 136
Reputation: 1500275
It sounds to me like you want to group by eligibility, then order those groups by their key (descending), then take the first group:
var bestSpawnGroup = _spawns
.GroupBy(GetEligibility)
.OrderByDescending(g => g.Key)
.First();
If the method group conversion for GetEligibility
causes problems (I can never remember the circumstances under which it does) you can just call it from a lambda expression:
var bestSpawnGroup = _spawns
.GroupBy(s => GetEligibility(s))
.OrderByDescending(g => g.Key)
.First();
You can then tell the eligibility of that group (its Key
) and find a random element in the group. (You could either convert the group to a list/array or use code like this to pick a random element from the group without materializing it.)
Upvotes: 5