diff --git a/app.js b/app.js new file mode 100644 index 0000000..aab09b4 --- /dev/null +++ b/app.js @@ -0,0 +1,177 @@ +const TESTS_LIST = ['Charles', 'Baruch','Frédéric', 'John', 'Dan', + 'Linus', 'Nina', 'Mikhaïl', 'Russel', 'Françoise', + 'Albert', 'Beth', 'Erykah', 'Aretha', 'Lucio', + 'Bartleby','Zach','Patti','Aesop','Vernon'] + +var participants; + +function loadParticipantsFileChooser(){ + document.getElementById('filechooser').click() +} +function loadTest(){ + addParticipants(TESTS_LIST) +} + +function loadParticipantsFromFile(file){ + + let reader = new FileReader(); + let contents = reader.readAsText(file); + reader.onload = function(event) { + let contents = reader.result; + let lines = contents.split('\n'); + addParticipants(lines) + }; + +} + +function addParticipants(list){ + list.forEach(function(item) { + if(item.trim() !== '') + addParticipant(item) + }); +} + +function addParticipant(name){ + var newInput = document.createElement('input'); + newInput.setAttribute('class','participant'); + newInput.setAttribute('placeholder','participant'); + if(name) + newInput.value = name; + document.getElementById('participants').appendChild(newInput) + +} + +function russellize(){ + let availablesPerParticipants = new Map() + + participants.forEach(function (p) { + availablesPerParticipants.set(p,participants.slice().filter(el => el !== p)) + }); + + let k = document.getElementById('nbPerGroup').value + let nbRounds = document.getElementById('nbRounds').value + let nbGroups = Math.ceil(participants.length / k) + let rounds = new Array() + + for(let i = 1; i <= nbRounds; i++){ + let round = new Array() + let availables = participants.slice() + for(let j = 0; j < nbGroups ; j++){ + let currentGroup = new Array() + let toTest = availables.slice() + while(currentGroup.length < k){ + let random = Math.floor(Math.random()*toTest.length) + let randomParticipant = toTest[random] + let ok = true + toTest.splice(random, 1); + // console.log(randomParticipant + '/' + random) + currentGroup.forEach(function (p) { + if(availablesPerParticipants.get(p).indexOf(randomParticipant)<0){ + ok = false + return + } + }) + + if(!ok && toTest.length === 0){ + return false + } + + if(ok){ + let randomEq = availables.indexOf(randomParticipant) + availables.splice(randomEq, 1); + // console.log(availables) + currentGroup.forEach(function (p) { + let l = availablesPerParticipants.get(p) + let index = l.indexOf(randomParticipant) + l.splice(index,1) + }) + currentGroup.push(randomParticipant) + } + } + round.push(currentGroup) + } + rounds.push(round) + } + + return rounds +} + + +function run(){ + doIt() +} + +function doIt(){ + + participants = new Array() + + var inputs = document.getElementsByClassName('participant') + for(var i = 0; i < inputs.length; i++){ + participants.push(inputs[i].value) + } + + let rounds = false + let attempts = 0 + while(!rounds){ + attempts ++ + rounds = russellize() + } + console.log(rounds) + console.log("Attempts = " + attempts) + let stats = new Map() + participants.forEach(function (p) { + let l = new Array() + stats.set(p,l) + rounds.forEach(function (round) { + round.forEach(function (group) { + if(group.indexOf(p)>=0){ + group.forEach(function (p2) { + if(p !== p2){ + l.push(p2) + } + }) + } + }) + }) + }) + + document.getElementById('rounds').innerHTML='' + let view = renderRounds(rounds) + document.getElementById('rounds').appendChild(view) +} + +function renderRounds(rounds){ + let x = 1 + let roundsBlock = document.createElement('div') + rounds.forEach(function (round) { + let roundBlockWrap = document.createElement('div') + let roundBlock = document.createElement('div') + let roundTitle = document.createElement('h2') + let roundTitleText = document.createTextNode('Round ' + x) + roundTitle.appendChild(roundTitleText) + roundBlockWrap.appendChild(roundTitle) + roundBlock.classList.add('round') + let y = 1 + round.forEach(function (group) { + let groupBlock = document.createElement('div') + let groupTitle = document.createElement('h4') + let groupTitleText = document.createTextNode('Group ' + y) + groupTitle.append(groupTitleText) + groupBlock.append(groupTitle) + roundBlock.append(groupBlock) + let list = document.createElement('ul') + groupBlock.appendChild(list) + groupBlock.classList.add('group') + group.forEach(function (p) { + let item = document.createElement('li') + item.appendChild(document.createTextNode(p)) + list.appendChild(item) + }) + y ++ + }) + x++ + roundBlockWrap.append(roundBlock) + roundsBlock.appendChild(roundBlockWrap) + }) + return roundsBlock +} diff --git a/css/app.css b/css/app.css new file mode 100644 index 0000000..4498415 --- /dev/null +++ b/css/app.css @@ -0,0 +1,79 @@ +@font-face { + font-family: 'Roboto'; + src: url('../fonts/Roboto-Light.ttf'); +} + +html, body{ + margin:0px; + padding:0px; + font-family: 'Roboto'; +} +#rounds, #participants{ + padding:10px; +} +.round{ + display:flex; + flex-wrap: wrap; +} +.group{ + margin:5px; + border: 1px solid #aaa; + border-radius:3px; + padding:5px; + width: 15%; + +} +h4{ + margin:5px; +} +.group ul { + list-style-type: square; +} +label{ + display:inline-block; +} + +.participant{ + margin:2px; +} + +#participants{ + border-bottom: 2px solid black; + padding-bottom:10px; + margin-top:20px; +} +nav{ + display: flex; + justify-content: space-between; + padding:10px; +} +button{ + background-color: white; + border: 1px solid #333; + border-radius: 2px; + cursor:pointer; +} + +button img{ + vertical-align: middle; +} +button:hover{ + background-color: #ddd; +} + +#settings > div{ + height:32px; +} + +#settings input{ + width:80px; +} + +#settings img{ + vertical-align: bottom; + margin-right:10px; +} + +#filechooser{ + display:none; +} diff --git a/fonts/Roboto-Light.ttf b/fonts/Roboto-Light.ttf new file mode 100644 index 0000000..664e1b2 Binary files /dev/null and b/fonts/Roboto-Light.ttf differ diff --git a/images/add.svg b/images/add.svg new file mode 100644 index 0000000..9349096 --- /dev/null +++ b/images/add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/group.svg b/images/group.svg new file mode 100644 index 0000000..6bcb859 --- /dev/null +++ b/images/group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/play.svg b/images/play.svg new file mode 100644 index 0000000..b882cee --- /dev/null +++ b/images/play.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/random.svg b/images/random.svg new file mode 100644 index 0000000..b4e0bd9 --- /dev/null +++ b/images/random.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/round.svg b/images/round.svg new file mode 100644 index 0000000..cc10f5b --- /dev/null +++ b/images/round.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/upload.svg b/images/upload.svg new file mode 100644 index 0000000..3ece831 --- /dev/null +++ b/images/upload.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..0502cb5 --- /dev/null +++ b/index.html @@ -0,0 +1,40 @@ + + + +
+ +