八人转和多人转查找对阵列表

244 阅读1分钟

前言

前段时间,公司要求做一个羽毛球比赛的小功能,那就是每个人都搭档一次,进行双打。而且每人上场的次数一样。比赛场数=A*(A-1)/4,A为选手人数,如8人,每人打七场,共打14场。如果碰到选手人数对于这个公式不整除的情况。每人打的场数累加,直到整除为止。


提示:以下是本篇文章正文内容,下面案例可供参考

一、分析规律是什么?

  1. 每个人大的场数都一样。
  2. 自己不可能跟自己搭档。
  3. 自己也不可能出现在对面。

二、先找出所有可能出现的搭档池

看以下代码

/**
 * 
 * @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;

}

在上面配对的过程中,有可能出现只剩最后两组配不上的情况,这时就需要往回找,让他进行重排,直到剩余的两组能搭配上。


总结

写得一般,大家多多指正。