我对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代码有什么问题:
-
function diff
是Math.abs
的一种自定义实现。最好使用本地Math.abs
。 -
function shuffle
太啰嗦。最好内联array.sort(function)
。 -
class Team
是好的(完美的)。 - 在
function generateTeams
中,Math.ceil
在players
数组长度为奇数的情况下,高估了参赛队数组的长度。 -
Array.splice
从数组中删除元素。使用.slice
将数组保持在do...while
循环中。 - 以防万一,
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);