2

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.log player2 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?

The Developer
  • 319
  • 2
  • 4
  • 15
  • Your random is using `users.length + 1` so you occasionally get that value, or `users.length`, neither of which are valid indexes in the array. You probably want to look at shuffling the array instead of pulling random indexes. – Heretic Monkey Aug 17 '19 at 21:39
  • Possible duplicate of [Getting a random value from a JavaScript array](https://stackoverflow.com/questions/4550505/getting-a-random-value-from-a-javascript-array) – Heretic Monkey Aug 17 '19 at 21:41
  • @HereticMonkey, I might have the type of an issue, but I also struggle to avoid reusing randomized values again. – The Developer Aug 18 '19 at 06:32

2 Answers2

1

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]
}
hyperflat
  • 128
  • 4
0

Create a collection of used indexes and then if first or second are in used indexes then continue

var usedIndices = [] ;

if (usedIndices.indexOf(first) >= 0 || 
usedIndices.indexOf(second) >= 0) {
continue;
} else { 
usedIndices.push(first);
usedIndices.push(second);
}

Put the usedIndices variable before for loop and the if else block inside loop after second

muasif80
  • 5,586
  • 4
  • 32
  • 45