Randomizer built using the Fisher-Yates shuffle

A random starting position generator for board games like Game of Thrones

For those who enjoy playing board games, here’s a randomizer that lets you randomize starting places for each player from a pool of options. This is also optimized for a 6-player Game of Thrones session.

This was built for my W&M MPP crew and in honor of the Fisher-Yates shuffle. Love you guys! And thanks for being so efficient, Fisher-Yates shuffle, you sexy beast!

Select the number of players (or just click the Game of Thrones button), enter player names (and options), and hit Randomize!


Player Name Option




For those interested, here’s the simple HTML & JavaScript I wrote for this:

<center>
<div>
  <select id = 'playersSelect'></select>
  <button id = 'gotButton'>Game of Thrones</button>
  <button id = 'randomizeButton'>Randomize</button>
</div>
</center>

<table style="margin: 20px;">
  <thead>
    <th>Player Name</th>
    <th>Option</th>
  </thead>
  <tbody id="playersTable">
  </tbody>
</table>

<script>

  const playersSelect = document.getElementById('playersSelect');
  const gotButton = document.getElementById('gotButton');
  const randomizeButton = document.getElementById('randomizeButton');
  const playersTable = document.getElementById('playersTable');
  const GOT_OPTIONS = [
    'Baratheon', 'Stark', 'Lannister',
    'Greyjoy', 'Tyrell', 'Martell'
  ];

  let playersNum = 0;
  populateOptions(12);
  updateRows(1);

  playersSelect.addEventListener('change', e => {
    const newPlayersNum = Number(e.target.value);
    updateRows(newPlayersNum);
  })

  gotButton.addEventListener('click', e => {
    updateRows(6);
    playersSelect.value = 6;
    const optionFields = getCurrentOptions();
    optionFields.forEach((option, idx) => {
      option.value = GOT_OPTIONS[idx];
    })
  })

  randomizeButton.addEventListener('click', e => {
    const optionFields = getCurrentOptions();
    const options = [...optionFields].map(o => o.value);
    for (let idx = options.length-1; idx >= 0; idx--) {
      const rand = Math.floor(Math.random() * (idx+1));
      [options[rand], options[idx]] = [options[idx], options[rand]];
      optionFields[idx].value = options[idx];
    }
  })

  function getCurrentOptions() {
    return document.querySelectorAll('.playerOption');
  }

  function updateRows(newPlayersNum) {
    const all = document.querySelectorAll(".playerRow");
    if (newPlayersNum < playersNum) {
      all.forEach((row, idx) => {
        if (idx >= newPlayersNum) {
          row.remove();
        } else {
          setTabIndexForOption(row, newPlayersNum, idx);
        }
      })
    } else if (newPlayersNum > playersNum) {
      all.forEach((row, idx) => {
        setTabIndexForOption(row, newPlayersNum, idx);
      });
      for (let idx = playersNum+1; idx <= newPlayersNum; idx++) {
        playersTable.insertAdjacentHTML('beforeend', `
        <tr class='playerRow'>
          <td>
            <input tabindex='${idx}'>
          </td>
          <td>
            <input tabindex='${newPlayersNum+idx}' class='playerOption'>
          </td>
        </tr>
        `);
      }
    }
    playersNum = newPlayersNum;
  }

  function setTabIndexForOption(rowElement, newPlayersNum, idx) {
    const option = rowElement.querySelector('.playerOption');
    option.tabIndex = newPlayersNum + idx + 1;
  }

  function populateOptions(max) {
    for(let num = 1; num <= max; num++) {
      const tempOption = document.createElement('option');
      tempOption.innerHTML = num;
      tempOption.value = num;
      playersSelect.appendChild(tempOption);
    }
    playersSelect.value = 1;
  }
</script>


Vahid Dejwakh
Vahid Dejwakh
Software Engineer at Microsoft;
Lover of good music and poetry

Vahid writes about interesting ideas at the intersection of software, system design, data, philosophy, psychology, policy, and business. He enjoys coffee and has a palate for spicy and diverse foods.

comments powered by Disqus

Related