Home > Blockchain >  Javascript: Distribute values into two arrays
Javascript: Distribute values into two arrays

Time:01-18

Im new here and into programming. Im not native english so please apologize if you dont understand me very well :-)

I`ve started learning Javascript and still doing. Now I want to achieve a simple project which gives me two Teams with equal skills.

Questions:

  1. It seems to work but I want to get random teams. This gives me always the same. How can I resolve this?
  2. I am able to print the values to see that its correct, but how can I print the player names (Variables like P1, P2, P3...)

Thank you

//Player skill values

let P1 = 2;
let P2 = 3;
let P3 = 1;
let P4 = 3;
let P5 = 4;
let P6 = 4;
let P7 = 5;
let P8 = 2;

//try to achieve two equal teams

function aufteilen(arr) {
    arr.sort().reverse()
    let a = [], b = [], sumA = 0, sumB = 0, i = 0

    while (i < arr.length) {
        if (!sumA && !sumB || sumA == sumB) {
            a.push(arr[i])
            sumA  = arr[i]
        } else if (sumA < sumB) {
            a.push(arr[i])
            sumA  = arr[i];
        } else if (sumB < sumA) {
            b.push(arr[i])
            sumB  = arr[i];
        }
        i  
    }

    console.log(`Total: ${sumA} ${sumB}`)
    return [a, b]
}

console.log(aufteilen([P1, P2, P3, P4, P5, P6, P7, P8]))

CodePudding user response:

Creating a team selection based on skill and making it random using the OP's algorithm is not really possible.

It's also possible for the OP's code to make teams based on player count not equal, I would assume a team picker would try to make teams equal on players & skill.

So one approach is just a simple brute force one, basically randomly pick teams, and compare the skills. Stop comparing after a set amount of time, just in case a perfectly equal skill cannot be met, or when skills are equal.

Below is a working example doing the above, it will also handle making the teams equal if we don't have an even number of players.

const players = [
  {name: 'P1', skill: 2},
  {name: 'P2', skill: 3},
  {name: 'P3', skill: 1},
  {name: 'P4', skill: 3},
  {name: 'P5', skill: 4},
  {name: 'P6', skill: 4},
  {name: 'P7', skill: 5},
  {name: 'P8', skill: 2},
];

const score = team =>
  team.reduce((a, v) => {
    a  = v.skill;
    return a;
  }, 0);

function createFairTeam(players) {
  function createTeams() {
    const team = {
      team1: [],
      team2: [],
      skillTot1: 0,
      skillTot2: 0,
      score: 0
    }
    const p = [...players];
    const t1size = Math.trunc(players.length / 2);
    //fill team1
    for (let l = 0; l < t1size; l  ) {
      const pos = Math.trunc(Math.random() * p.length);
      const f = p.splice(pos, 1)[0];
      team.skillTot1  = f.skill;
      team.team1.push(f);
    }
    //fill team2
    for (let l = 0; l < p.length;) {
      const pos = Math.trunc(Math.random() * p.length);
      const f = p.splice(pos, 1)[0];
      team.team2.push(f);
      team.skillTot2  = f.skill; 
    }
    //calc score.
    team.score = Math.abs(
      score(team.team1) -
      score(team.team2)
    );
    return team;
  }
  const team = createTeams();
  let best = team;
  const start_time = Date.now();
  while (Date.now() - start_time < 200) {
    //if total skill is odd, the best score
    //would be 1, if even it would be 0
    //so lets check for less than equal to 1
    //for early termination.
    if (best.score <= 1) break;
    const newTeams = createTeams();
    if (newTeams.score < best.score) 
      best = newTeams;
  }
  return best;
}


function doIt() {
  const teams = createFairTeam(players);
  const table = document.querySelector('table');
  const tbody = table.querySelector('tbody');
  tbody.innerHTML = '';
  for (let l = 0; 
  l < Math.max(teams.team1.length, teams.team2.length); l   ) {        
    const p1 = teams.team1[l];
    const p2 = teams.team2[l];
    const tr = document.createElement('tr');
    ////
    let td = document.createElement('td');
    td.innerText = p1 ? p1.name : '';
    tr.appendChild(td);
    ////
    td = document.createElement('td');
    td.innerText = p1 ? p1.skill : '';   
    tr.appendChild(td);
    ////
    td = document.createElement('td');
    td.innerText = p2 ? p2.name : '';   
    tr.appendChild(td);
    tbody.appendChild(tr);
    ////
    td = document.createElement('td');
    td.innerText = p2 ? p2.skill : '';   
    tr.appendChild(td);
    tbody.appendChild(tr);
  }
  //// tots
  document.querySelector('#t1total').innerText =  teams.skillTot1;
  document.querySelector('#t2total').innerText = 
 teams.skillTot2;
}

doIt();

document.querySelector('button').addEventListener('click', doIt);
table {
  width: 100%;
}
<button>Another Team</button>
<table border="1">
  <thead>
    <tr>
      <th colspan="2">Team 1</th>
      <th colspan="2">Team 2</th>
    </tr>
    <tr>
      <th>Player</th>
      <th>Skill</th>
      <th>Player</th>
      <th>Skill</th>
    </tr>
  </thead>
  <tbody></tbody>
  <tfoot>
    <tr>
      <td>Total</td><td id="t1total"></td>
      <td>Total</td><td id="t2total"></td>
    </tr>
  </tfoot>
</table>

CodePudding user response:

1 - you need a shuffle method, something like below or from a library:

function shuffle(array) {
  array.sort(() => Math.random() - 0.5);
}

2 - you need an object to display player names. your players are just numbers.

// your player
let P1 = 2;

// what you would need to display a name
let P1 = { id: 2, name: "Mario" }

// then u can display the name with
P1.name // "Mario"

CodePudding user response:

Your array.sort().reverse() is the reason why you get this.

I would recommend to shuffle() before passing it to your function.

Here is my guess :

function shuffle(arr) {
    for (let i = arr.length - 1; i > 0; i--) {
        let j = Math.floor(Math.random() * (i   1));
        [arr[i], arr[j]] = [arr[j], arr[i]];
    }
    return arr;
}

console.log(aufteilen(shuffle([P1, P2, P3, P4, P5, P6, P7, P8])));

You can then create an object Players, add all infos you want and do it like this :

let players = {
    P1: 2,
    P2: 3,
    P3: 1,
    P4: 3,
    P5: 4,
    P6: 4,
    P7: 5,
    P8: 2,
};

let playerSkills = Object.values(players);
console.log(aufteilen(shuffle(playerSkills)));

Hope it will help !

  • Related