How do I set random team selection based on player count?

So I’m running an infection style game mode where there are humans and zombies. Currently, my code only selects 1 random zombie (On Begin) no matter how many players there are. I want to make it where it selects 1 random zombie depending on my set conditions:
1 random zombie if <= 6
2 random zombies if >6 and <= 10… etc.


My code before this screen shot only chooses 1. I’ve added in the “ZombiesToChoose” and the conditionals below it.

I think changing this helps but don’t know what to do after. I also don’t want duplicates of zombies, if it hits a dupiclate, reroll.

if (Players.Length > 0):
for (X := 0…ZombiesToChoose):
RandomIndex := GetRandomInt(0, Players.Length -1)

Don’t know if thats correct or what to do next

After you set ZombiesToChoose

RandomPlayers := Shuffle(Players)
for(I := 0..ZombiesToChoose-1, RandomPlayer := RandomPlayers[I]):
    # MakeZombie(RandomPlayer)

This should ensure there’s no duplicates

2 Likes

The looks good to me, a few comments.

Instead of this - where it loops through all players looking for the matching index.

for (...):
   if (Player Index = RandomIndex):
     # Rest of code...

It’s more efficient and a little cleaner to do:

if:
  aPlayer := Players[RandomIndex]
then:
  # Rest of code...

My second comment is a bit trickier, about the following llne.

RandomIndex := GetRandomInt(0, Players.Length - 1)

This will correctly pick a random player, but it may pick the same player more than once.

You may want to pick three player numbers, but ensure they are all different numbers (unless picking same player more than once is valid for what you want to do).

There may be better ways, but what I’ve done in the past, is something like this.

# This picks the first player, just like the original code.
Index1 := GetRandomInt(0, Players.Length - 1)

# This picks from a range one smaller than the original range (may still be same index after this next line).
Index2 := GetRandomInt(0, Players.Length - 2)
# This ensures it's not the same index.
if (Index2 = Index1):
    set Index2 += 1

# Now we have two different random players.

# A third would look like this.
Index3:= GetRandomInt(0, Players.Length - 3)
if (Index3 = Index1):
    set Index3 += 1
if (Index3 = Index2):
    set Index3 += 1

I think this approach works.

Hope it helps.

1 Like

Replying to my own post :slight_smile:

Another approach would be to make a duplicate Players array and remove each player as you randomly pick them. In some ways that would be cleaner, but it results in multiple times the code has to copy the array (a copy is made each time a remove is done), so I’ve usually gone with the approach I outlined above.

1 Like

Trying this out first, so I applied my code and whats happening is its applying the human traits and zombie traits but its not actually doing the teamclass swap for humans like it did before. Im not sure if its doing the swap for zombies since my UI counter is showing 1 zombie and 0 humans

1 Like

A couple thoughts.

Minor typo on the first two “if” statements - for exactly 8 players ZombiesToChoose stays at 0. You probably want a <= 8 on the first “if”.

Is PlayerMap initialized with 0’s for every entry before this code runs? If not, I don’t know if Verse defaults to 0, if so the code should be ok, if not they the following would never be true.

if (PlayerMap[Player] = 0):

On second thought, if that’s an actual “map” (not array) then it would need to be initialized I think.

I don’t see anything else.

Awesome going to try this, also if you don’t mind, would you be able to write out your implementation using my code ? You don’t have to do the whole thing, just the part where its supposed to happen. Thanks in advance for the help!!!

Edit:

Yes, Playermap is initialized as a map. humans are set to playermap[player] = 0 and zombies are playermap[player] = 1

Do you mean this part?

for (Player : Players):
  if (PlayerMap[Player] = 0):
    # Rest of code...

If so, I think you can do it this way - have your code run if the map entry doesn’t exist. Might be able to do this with a “not” or something in the if itself, instead of the else.

for (Player : Players):
    if (PlayerMap[Player] = 0):
        # Probably do nothing
    else:
        # Put your code here

Something like that.

Seeing your edit above - if PlayerMap[Player] is initialized to 0 for humans prior to the code you show, then I don’t see an issue with your code.

When I’m uncertain what path code is taking, I add Print(“Something”) statements and look at what the code is doing.

So this fixed it:

1 Like

Great!

1 Like

You can debug by printing player names if you want [Feature request] Get player name in Verse - #3 by bananna_manuk