您需要匹配系统来优先考虑等待时间最长的玩家。
您只需要 1 个队列,还需要使用表格跟踪用户历史记录。如果您想要跨多个会话的永久数据或匹配服务器崩溃,该表可以是临时会话数据或数据库表。该表应该包含他们之前玩过的 playerID 和一组之前的 playerID。最好限制数组的大小并使用 LIFO,因为您可能不想只存储球员最近的比赛,即比赛历史。此外,如果玩家已经在网上与其他所有人进行过比赛,他们可能会用完可以与之对抗的玩家。该表应如下所示:
- 玩家ID(整数)
- previousPlayerIDs(整数数组)
当比赛开始时,您可以更新比赛中所有球员的 previousPlayerID。当玩家加入队列时,您需要监听一个事件,让我们调用它 onPlayerJoin()。如果队列中的玩家超过 1 人,您应该选择排队时间最长的玩家,并将他们的 playerID 与每个玩家的 previousPlayerID 进行比较,直到找不到匹配的历史记录。
const historyLimit = 10;
function onPlayerJoin(Player newPlayer){
playerQueue.push(newPlayer);
if(playerQueue.length > 1){
for(let a=0; a<playerQueue.length-1; a++){
Player player = playerQueue[a];
for(int i=a+1; i<playerQueue.length; i++){
Player otherPlayer = playerQueue[i];
//if the player have not played before
if(otherPlayer.previousPlayerIDs.indexOf(player.id) > -1){
//save match up
player.previousPlayerIDs.push(otherPlayer.id);
otherPlayer.previousPlayerIDs.push(player.id);
//limit matchup histroy
if(player.previousPlayerIDs.length > historyLimit){
player.previousPlayerIDs.removeAt(0);
}
if(otherPlayer.previousPlayerIDs.length > historyLimit){
otherPlayer.previousPlayerIDs.removeAt(0);
}
//create lobby and remove players from the queue
createLobby(player, otherPlayer);
playerQueue.removeAt(a);
playerQueue.removeAt(i);
}
}
}
}
}
一个玩家有可能和其他人玩过,他们正在等待一个他们以前没有玩过的人上线。您将需要一个重复事件来检查等待时间最长的玩家是否等待太久。如果是这种情况,只需忽略previousPlayerID 的匹配并为该玩家创建一个大厅,并与另一个可能等待很长时间的玩家一起。
如果您愿意,您可以在表中添加更多列,例如他们加入队列时的时间戳及其匹配排名 (elo)。但是,如果您只想优先考虑最近的播放器,则不需要这些其他列。
此外,如果您有大量并发用户,此解决方案可能无法很好地扩展,但如果您的并发用户少于 1,000-10,000,它应该没问题