Felipe
Felipe

Reputation: 462

Queue logic and a while

Hi I have a row of players, and from this row of players I get a player that matches two conditions

const condition = (5 / 100) * playerOne.mmr + playerOne.mmr
const condition2 = playerOne.mmr - ((5 / 100) * playerOne.mmr);

find another player who is between 5% less and 5% more than my player's mmr value

and then I did it

  searching(playerOne) {
    const condition = (5 / 100) * playerOne.mmr + playerOne.mmr
    const condition2 = playerOne.mmr - ((5 / 100) * playerOne.mmr);

    const player = playerOne;
    const playerTwo = this.players.find((playerTwo) => playerTwo.mmr < condition && playerTwo.mmr > condition2 && playerTwo.id != playerOne.id);

    while(!this.players.find((playerTwo) => playerTwo.mmr < condition && playerTwo.mmr > condition2 && playerTwo.id != playerOne.id)){
      const playerTwo = this.players.find((playerTwo) => playerTwo.mmr < condition && playerTwo.mmr > condition2 && playerTwo.id != playerOne.id);
      console.log(this.players);
    }

    const matchedPlayers = [
      player,
      playerTwo
    ]
    // remove matched players from this.players
    this.removePlayers(matchedPlayers);
    // return new Match with matched players
    return matchedPlayers;
  }
}

Good if I can't find a compatible mmr I go into the while forever

And even on my server I adding a player to the queue after

inside my while my queue continues with the same players and the new player I added in the queue does not appear

queue.addPlayer(new Player(1,'spt',970));
queue.addPlayer(new Player(2,'test2',1000));
queue.addPlayer(new Player(3,'test3',1050));
queue.addPlayer(new Player(4,'test4',70));

const playerOne = queue.players.find((playerOne) => playerOne.mmr === 70);
const players = queue.searching(playerOne);
queue.addPlayer(new Player(5,'test6',75));

I added my 5 player after I called my search function and inside my whilei I put to give console.log in my queue, but only 4 players appear and not my 5 player so it is in the infinite loop and I don't know where I went wrong or how I can fix or if my logic is very failed

[
  Player { id: 1, name: 'spt', mmr: 970 },
  Player { id: 2, name: 'test2', mmr: 1000 },
  Player { id: 3, name: 'test3', mmr: 1050 },
  Player { id: 4, name: 'test4', mmr: 70 }
]

Upvotes: 2

Views: 56

Answers (1)

epascarello
epascarello

Reputation: 207511

You need to make the searching happen in an asynchronous manner. There are a bunch of ways to accomplish it. Personally I am a fan of promises. Below is showing a basic way of creating a way to wait until a player is added in the range. I also added the ability to cancel the search.

const players = [
  { id: 1, name: 'spt', mmr: 970 },
  { id: 2, name: 'test2', mmr: 1000 },
  { id: 3, name: 'test3', mmr: 1050 },
  { id: 4, name: 'test4', mmr: 70 }
]

const makeMatch = (id) => {
  let timer
  let promiseResolve
  let promiseReject      
  const promise = new Promise((resolve, reject) => {
    promiseResolve = resolve
    promiseReject = reject
  });

  const playerDetails = players.find(p => p.id == id)
  const { mmr } = playerDetails

  const findMatchup = () => {
    const secondPlayer = players.find(p => 
      p.id !== id && 
      Math.abs(p.mmr - mmr) <= 10)
    if (secondPlayer) {
      console.log("match!", id)
      promiseResolve({ player1: playerDetails, player2: secondPlayer })
    } else {
      console.log("no matches", id)
      timer = window.setTimeout(findMatchup, 1000)
    }
  }
  
  findMatchup()
  
  return {
    kill: () => {
      timer && window.clearTimeout(timer)
      promiseReject('cancelled')
    },
    promise
  }
}



// Make up a match with player 4
// There are no matches so it will loop for awhile
var matchMaking = makeMatch(4)
matchMaking.promise.then( ({ player1, player2 }) => {
  console.log(player1, player2)
})

// Act like a new player signed on, push in the player
// We should be a match after this happens
window.setTimeout(() => { 
  console.log("Player is added");
  players.push({ id: 5, name: 'test5', mmr: 75 })
}, 5500)


//Example showing killing off

// Make up a match with player 1
// There are no matches so it will loop for awhile
var matchMaking2 = makeMatch(1)
matchMaking2.promise.then( ({ player1, player2 }) => {
  console.log(player1, player2)
}).catch((details) => {
  console.log(details);
})

// Acting like user clicked cancel button to stop playing
window.setTimeout(() => { 
  console.log("Player has cancelled");
  matchMaking2.kill()
}, 10000)

Upvotes: 1

Related Questions