Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Table loop with players; works but then breaks. Any help? (Semi-Advanced)

Asked by 9 years ago

Reason for Script: I am making a game that requires 3 different teams. One is Bright red, One is Bright blue, and one is Medium stone grey(Which is for lobby). For my game I am trying to put 4 players on one team(red team) and 6 on the other(blue team). What my script does so far is put 3 players on the Bright blue team(I tested this in an 8 Player Server).

-This is my script:

01local players = game.Players:GetChildren()
02local redTable = {}
03local blueTable = {}
04local redPlayers = 4
05local bluePlayers = 6
06 
07for i = 1, redPlayers do
08local index = math.random(1, #players)
09table.insert(redTable, players[index])
10if players[index].TeamColor ~= BrickColor.Gray() then
11table.insert(redTable, players[index])
12players[index].TeamColor = BrickColor.Red()
13players[index] = nil
14end
15end
View all 27 lines...

1 answer

Log in to vote
0
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
9 years ago

First, house-keeping.

  • Tab your code correctly
  • Use :GetPlayers() instead of :GetChildren() when you want a list of players
  • You can use math.random(high) instead of math.random(1, high) (this will help shorten things up later)

The trouble you'll be having is that you are using players[index] = nil to remove a player from a list. This creates a "gap" and will cause you to miscalculate #players and lose track of all of the others:

1local list = {2, 3, 5, 7, 11, 13}
2list[4] = nil
3 
4-- list = {2, 3, 5, nil, 11, 13}
5 
6print(#list) -- 3

Instead, you want to table.remove(players, index). This also conveniently returns the thing removed.

Building redPlayers will now look like this:

1for i = 1, redPlayers do
2    local player = table.remove(players, math.random(#players))
3    table.insert(redTable, player)
4    if player.TeamColor ~= BrickColor.Gray() then
5        table.insert(redTable, player)
6        player.TeamColor = BrickColor.Red()
7    end
8end

I am not sure why you add the player to redTable twice... I'm guessing you just want simply this:

1for i = 1, redPlayers do
2    local player = table.remove(players, math.random(#players))
3    table.insert(redTable, player)
4    player.TeamColor = BrickColor.Red()
5end

If you only want to move players from the Gray team to Red and Blue, then players should have been built like that in the first place.

The resulting script could look something like this:

01local players = {}
02for _, player in pairs(game.Players:GetPlayers()) do
03    if player.TeamColor == BrickColor.Gray() then
04        table.insert(players, player)
05    end
06end
07-- players is only Gray-team players.
08 
09local redTable = {}
10local blueTable = {}
11local redPlayers = 4
12local bluePlayers = 6
13 
14for i = 1, redPlayers do
15    local player = table.remove(players, math.random(#players))
View all 24 lines...

The last thing to be wary of is that if there are fewer players than redPlayers + bluePlayers, you'll get an error. Also, if there's more, not everyone will be distributed to a team.

You might want to consider something like

1local redPlayers = math.floor(1/2 + #players * 4/6)
2local bluePlayers = #players - redPlayers

Semi-advanced

There's no such thing as "advanced" code. There is a such thing as complicated code.

Most complicated code is more complicated than it should be.

Most code can be very simple. If you compare this script to yours, which is simpler? (Which also happens to be the one that doesn't error/make mistakes?)

Ad

Answer this question