前言
前段时间,公司要求做一个羽毛球比赛的小功能,那就是每个人都搭档一次,进行双打。而且每人上场的次数一样。比赛场数=A*(A-1)/4,A为选手人数,如8人,每人打七场,共打14场。如果碰到选手人数对于这个公式不整除的情况。每人打的场数累加,直到整除为止。
提示:以下是本篇文章正文内容,下面案例可供参考
一、分析规律是什么?
- 每个人大的场数都一样。
- 自己不可能跟自己搭档。
- 自己也不可能出现在对面。
二、先找出所有可能出现的搭档池
看以下代码
/**
*
* @param {array} peopleList 选手列表
* @param {number} round_num 每人打的场数,默认选手人数-1
*/
function getTempMatchList(peopleList,round_num) {
let p_num = peopleList.length;
let partner_group_list = []; //所有有可能搭档的组
let partner_group_list_real = []; //出场的搭档数组
let p_should_round_num = {}; //记录每人上场的次数对象
let ground_num = 0;
for (let i = 0; i < peopleList.length; i++) {
p_should_round_num[peopleList[i]] = peopleList.length-1; //预先定下前面的搭档池数
}
if((p_num*round_num)%4==0){ //整除
ground_num = Math.floor(peopleList.length*round_num/2);
for (let i = 0; i < peopleList.length; i++) {
const e = peopleList[i];
for (let j = i+1; j < peopleList.length; j++) {
const e1 = peopleList[j];
partner_group_list.push([e,e1]); //准确的搭档池
}
}
partner_group_list_real = [...partner_group_list];
if(round_num>peopleList.length-1){ //必须每人多打几场
let temp_partner_group_list = [...partner_group_list];
let flag = true;
while (flag) {
//随机拿一组出来
let index = Math.floor(Math.random()*temp_partner_group_list.length);
let partner_group_list_real_one = temp_partner_group_list.splice(index,1);
let p1 = partner_group_list_real_one[0][0];
let p2 = partner_group_list_real_one[0][1];
if(p_should_round_num[p1]<round_num&&p_should_round_num[p2]<round_num){
partner_group_list_real.push(partner_group_list_real_one[0]);
p_should_round_num[p1] +=1;
p_should_round_num[p2] +=1;
}
if(partner_group_list_real.length==ground_num){
flag = false;
}
}
}
return partner_group_list_real;
}else{
return [];
}
}
三、再根据搭档池进行两两配对
废话不多说,直接上代码。
function getMatchList(peopleList,round_num) {
while ((peopleList.length*round_num)%4!=0) {
round_num++;
}
let matchListPoor = getTempMatchList(peopleList,round_num);
let all_round = matchListPoor.length/2;
let res = [];
let rivalry = [];
let round = 0;
while (matchListPoor.length>0) {
let per = matchListPoor[0];
matchListPoor.splice(0,1);
if(rivalry.length==0){
rivalry.push(per);
round = 1;
}else if(!rivalry[0].includes(per[0])&&!rivalry[0].includes(per[1])){
rivalry.push(per);
}else{
matchListPoor.push(per);
round = 2;
}
if(rivalry.length==2){
res.push(rivalry);
rivalry = [];
}
if(matchListPoor.length==1&&round == 2){
matchListPoor = [...matchListPoor,...rivalry];
for (let j = 0; j < res.length; j++) {
if(!res[j][0].includes(matchListPoor[0][0])&&!res[j][0].includes(matchListPoor[0][1])){
let temp = res[j][1];
res[j][1] = matchListPoor[0];
matchListPoor[0] = temp;
if(!matchListPoor[0].includes(matchListPoor[1][0])&&!matchListPoor[0].includes(matchListPoor[1][1])){
res.push(matchListPoor);
break;
}
}
}
}
if(res.length==all_round){
break;
}
}
return res;
}
在上面配对的过程中,有可能出现只剩最后两组配不上的情况,这时就需要往回找,让他进行重排,直到剩余的两组能搭配上。
总结
写得一般,大家多多指正。