在JS中创建新的类实例,直到满足条件



我对JS类的了解非常有限,所以我不知道这是否可能。

我的目标是从玩家列表中生成两个随机且平衡的(问题的关键)团队。

我的代码说明:

const玩家:它是一个对象数组。每一个都是一个玩家,有一个名字和一个级别。

函数diff(a, b):效用函数。返回两个整数之间的差值

函数shuffle(数组):效用函数。它打乱数组的内容。

类团队生成团队对象的类。它有一个属性"players"作为参数传递,还有一个属性"tier"这是所有玩家等级的总和。

function checkTeamsLevel(team1, team2):此功能检查两个团队是否平衡。只有当两支球队的级别之差等于或小于1时,它才返回true。

函数generateTeams () 这是应用程序的主要功能。它首先洗牌数组的球员,然后拼接他们在两个数组的球员。然后就产生了两支队伍。在这一点上,一切都很好,但我们不确定团队是否平衡。所以我的想法是运行一个while循环来生成新的团队,直到函数checkTeamsLevel()返回true。这段代码不能工作,因为当这个函数返回false时,循环不会停止。这是一个无限循环。

我怎么能实例化团队类,直到他们通过我的checkTeamsLevel()函数的过滤器?这真的可能吗?

下面是我的代码:
// Array of player objects
const players = [
  {name: 'John', tier: 1},
  {name: 'James', tier: 3},
  {name: 'Louis', tier: 2},
  {name: 'Rebeca', tier: 2},
  {name: 'Peter', tier: 4},
  {name: 'Oscar', tier: 3},
  {name: 'Laura', tier: 1},
  {name: 'Rebeca', tier: 2},
  {name: 'Paula', tier: 2},
  {name: 'Michael', tier: 4},
];

// Function to check difference between integers.
function diff(a, b) {
 return (a > b) ? (a - b) : (b - a);
}
// Function to shuffle array contents.
function shuffle(array) {
  var currentIndex = array.length;
  var temporaryValue, randomIndex;while (0 !== currentIndex) {
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }
  return array;
}
// Team Class
class Team {
  constructor(players) {
    this.players = players;
    this.tier = this.getTeamTier();
  }
  getTeamTier() {
    return this.players.reduce((total, player) => total + player.tier, 0);
  }
}

// Function to check if two teams are balanced.
function checkTeamsLevel(team1, team2) {
  let tierThreshold = 1;
  return ((team1 && team2) && diff(team1.tier, team2.tier) <= tierThreshold);
}

// Function to generate 2 balanced teams
function generateTeams(players) {
  // Shuffle players
  shuffle(players);
  
  // Divide players in 2 groups
  let middleIndex = Math.ceil(players.length / 2);
  let playersForTeam1 = players.splice(0, middleIndex);
  let playersForTeam2 = players.splice(-middleIndex);
  let team1 = new Team(playersForTeam1);
  let team2 = new Team(playersForTeam2);
  // This loop is not working.
  // I have to do something to generate two teams with a tier difference bellow 2.
  while (!checkTeamsLevel(team1, team2)) {
    team1 = new Team('yellow', playersForTeam1);
    team2 = new Team('black', playersForTeam2);
  }
  // Debug
  console.log(team1);
  console.log(team2);
  console.log(checkTeamsLevel(team1, team2));
  return [team1, team2];
}

// Run generateTeams
generateTeams(players);

看下面的代码。它像你(可能)期望的那样工作。

OP代码有什么问题:

  1. function diffMath.abs的一种自定义实现。最好使用本地Math.abs
  2. function shuffle太啰嗦。最好内联array.sort(function)
  3. class Team是好的(完美的)。
  4. function generateTeams中,Math.ceilplayers数组长度为奇数的情况下,高估了参赛队数组的长度。
  5. Array.splice从数组中删除元素。使用.slice将数组保持在do...while循环中。
  6. 以防万一,generateTeams(players.slice())保持初始数组不可变。

参见代码中的注释。

// Array of player objects
const players = [
  {  name: 'John', tier: 1 },
  { name: 'James', tier: 3 },
  { name: 'Louis', tier: 2 },
  { name: 'Rebeca', tier: 2 },
  { name: 'Peter', tier: 4 },
  { name: 'Oscar', tier: 3 },
  { name: 'Laura', tier: 1 },
  { name: 'Rebeca II', tier: 2 }, //duplicate name in OP
  { name: 'Paula', tier: 2 },
  { name: 'Michael', tier: 4 },
  {name: 'Chris', tier: 6}//added to test odd number
];
//No need to code diff. Use Math.abs instead
// Function to shuffle array contents.
//No need. Easy to inline
// Team Class
class Team {
  constructor(players) {
    this.players = players;
    this.teamTier = this.getTeamTier();
  }
  getTeamTier() {
    return this.players.reduce((total, player) => total + player.tier, 0);
  }
}

// Function to check if two teams are balanced.
function checkTeamsLevel(team1, team2) {
  let tierThreshold = 1;
  return team1 && team2 && Math.abs(team1.teamTier - team2.teamTier) <= tierThreshold;
}

// Function to generate 2 balanced teams
function generateTeams(players) {
  let cnt = 0;
  do {
    // Shuffle players
    // .sort acts on the array
    players.sort(() => Math.random() < 0.5 ? -1 : 1);
    // Divide players in 2 groups
    // use .floor instead of .ceil
    let middleIndex = Math.floor(players.length / 2); //if the number of players is odd then then someone go out of game
    //use slice; splice removes elements
    let playersForTeam1 = players.slice(0, middleIndex);
    let playersForTeam2 = players.slice(-middleIndex);
    var team1 = new Team(playersForTeam1);
    var team2 = new Team(playersForTeam2);
    // I have to do something to generate two teams with a tier difference bellow 2.
    cnt++;
    console.log(cnt);
  } while (!checkTeamsLevel(team1, team2) && /*limit the number of runs to avoid infinite loop */ cnt < 15);
  // Debug
  //console.log(team1);
  //console.log(team2);
  return [team1, team2];
}
// Run generateTeams
let [team1, team2] = generateTeams(players.slice());//slice to keep const players array immutable
console.log('team1', team1, 'nteam2', team2);
//check original players array
console.log('const players',players);

最新更新