Ad

Can't Get Stable Result With Copying Random Values From Array To An Object

So I'm in process of creating a bot for a tournament and I got stuck on the part where I want to split players in pairs for play-off-style tournament. I just want to take 2 random players, get them from an array and write it as a value to a key as a round id for an object. Also I should not use those players again in the pair, so need to delete them or smth.
Here's the code:

var users = inc.funcs.getDatabase() //Getting a raw array of users (using my func that's basically a simplified fs.readFileSync func)
var tournamentPairs = new Object() //Object initialization

var id = 1
for (var i = 0; i < 16; i = i + 2) {
   var first = Math.floor(Math.random() * (users.length + 1)) //Randomizing 2 indexes
   var second = Math.floor(Math.random() * (users.length + 1))

   var player1 = client.users.get(users[first]) //Getting the players by id 
   var player2 = client.users.get(users[second])

   tournamentPairs[id++] = [player1.id, player2.id] //Writing to the object

   users.splice(first, 1) //Deleting user's indexes from the array to not use them anymore.
   users.splice(second, 1)
}
console.log(tournamentPairs)

It works perfectly on the outside, but has a bad habit of duplicating users and I once could have a gamergod98 vs gamergod98 for example. I tried console.log this crap but it often get an error when trying to console.logplayer2 because it's undefined for some reason. If I try to print users[second] I get undefined though it never happened for the first player. So I tried different ways to prevent situations like this: first == second. Long story short it didn't help much.
I have 9 days 'till tournament starts, any ideas on how to improve this code?

Ad

Answer

You are getting undefined because you are going out of bounds of your users list. For a list of length the last element is list[length-1], but you are generating random numbers up to length.

To fix duplicate users, remove the first selected user from the list before selecting the second one (or for a less destructive approach, mark already selected users).

var id = 1
for (var i = 0; i < 16; i = i + 2) {
   var first = Math.floor(Math.random() * users.length)
   var player1 = client.users.get(users[first]) 
   users.splice(first, 1)

   var second = Math.floor(Math.random() * users.length) 
   var player2 = client.users.get(users[second])
   users.splice(second, 1)

   tournamentPairs[id++] = [player1.id, player2.id]
}
Ad
source: stackoverflow.com
Ad