-1

I have a problem with a Script in my Game. I have 6 Lanes in my Game and 4 Enemys at the moment. If an Enemy reaches the end of a lane, he respawns in a new lane. I want that no Enemy ever gets the same lane as above.

I did it like this

Randomlane = rnd.Next(1, 7);
Enemy1_Lane = Randomlane;

if (Enemy1_Lane == Enemy2_Lane)
{
    if (Enemy1_Lane == 6)
    {
        Enemy1_Lane -= 1;
    }
    else
    {
        Enemy1_Lane += 1;
    }
}


But this only works with 2 Enemies. Now I have 4. Maybe you can help me.
  • There is this question that asks about [how to randomize an array](https://stackoverflow.com/questions/44549740/randomly-shuffling-an-array). Its answer explains how to do that. You just need to create the range with the number of your lanes and then take the first four elements of that array – Steve Dec 26 '21 at 10:00

2 Answers2

1

you could do

// Creates an enumeration from 1 to 10
// orders it randomly
// then picks 4 items
var enemyLanes = Enumerable.Range(1, 10).OrderBy(c => rnd.Next()).Take(4).ToArray();

which will return an int[] with 4 elements which are unique random values between 1 and 10.


But further it sounds like you also additionally want that in the next iteration it doesn't pick the same lanes again as it had before so you could remember which lanes you used before and also filter out these and do e.g.

private int[] currentEnemyLanes;

...

// Except additionally removes all the elects of currentEnemyLanes from the options
// and keeps only these that are not currently occupied
var nextEnemyLanes = var enemyLanes = Enumerable.Range(1, 10).Except(currentEnemyLanes).OrderBy(c => rnd.Next()).Take(4).ToArray();

currentEnemyLanes = nextEnemyLanes;

In general though it would even be more optimized in my eyes if the enemies store their current lane and give it free again when picking the next one like e.g.

private int currentLane;

private static HashSet<int> availableLanes = new HashSet<int>() { 1,2,3,4,5,6,7,8,9,10 };

void PickNextLane()
{
    // pick a random entry from all available lanes
    var newLane = availableLanes.OrderBy(l => rnd.Next()).First();

    // remove this from the options so another instance won't pick the same one
    availableLanes.Remove(newLane);

    // if you had a valid lane already
    if(currentLane > 0)
    {
        // Now give it free so another one can pick it again
        availableLanes.Add(currentLane);
    }

    // finally store the new value
    currentLane = newLane;
}
derHugo
  • 83,094
  • 9
  • 75
  • 115
  • I really like your answer. But can i switch the Random.Value easily to rnd.Value cause i have created my own Random Value at the Top of my Script. – ConflictMeow Dec 26 '21 at 10:38
  • [`Random.value`](https://docs.unity3d.com/ScriptReference/Random-value.html) is Unity built-in so I would use that but sure you can use whatever you want that returns random values ;) – derHugo Dec 26 '21 at 10:40
  • My Game is only Visual Studio at the moment. This game don't require Unity. I don't know which of the 40 Mods who edited stuff here changed the tags to unity. PS: Your name sounds german :P – ConflictMeow Dec 26 '21 at 10:45
  • @ConflictMeow haha ok then I just changed it back to `rnd.Next()` again ^^ – derHugo Dec 26 '21 at 10:55
  • 1
    Fehler Eine Indizierung mit [] kann nicht auf einen Ausdruck vom Typ "HashSet" angewendet werden. ;) – ConflictMeow Dec 26 '21 at 17:39
-1

you need to save the lane for each enemy:

var lane_per_enemy = new List<int>();

If an Enemy reaches the end of a lane, compare the next lane to the entries of the list.

draz
  • 793
  • 6
  • 10