document.getElementById('start-ranking').addEventListener('click', startRanking); document.getElementById('help-button').addEventListener('click', toggleHelp); document.getElementById('copy-results').addEventListener('click', copyResultsToClipboard); let words = []; let currentPair = []; let scores = {}; let rounds = 0; let currentRound = 0; let playedPairs = new Set(); const scoreThreshold = 5; let totalVotes = 0; let votesDone = 0; function startRanking() { const wordList = document.getElementById('word-list').value.trim().split('\n'); words = wordList.filter(word => word.trim() !== ''); if (words.length < 2) { showMessage('Please enter at least two words.'); return; } words.forEach(word => scores[word] = 1000); rounds = Math.ceil(Math.log2(words.length)) + 2; // Number of rounds for Swiss-system currentRound = 0; playedPairs.clear(); totalVotes = rounds * (words.length / 2); votesDone = 0; document.getElementById('ranking-section').classList.remove('hidden'); document.getElementById('progress').style.width = '0%'; updateRankingList(); nextPair(); } function nextPair() { if (currentRound >= rounds) { showMessage('Ranking complete!'); disableVoteButtons(); return; } currentPair = getNextPair(); if (!currentPair) { currentRound++; nextPair(); return; } document.getElementById('word1').textContent = currentPair[0]; document.getElementById('word2').textContent = currentPair[1]; document.getElementById('word1').onclick = () => vote(currentPair[0], currentPair[1]); document.getElementById('word2').onclick = () => vote(currentPair[1], currentPair[0]); } function getNextPair() { const sortedWords = Object.keys(scores).sort((a, b) => scores[b] - scores[a]); for (let i = 0; i < sortedWords.length - 1; i++) { for (let j = i + 1; j < sortedWords.length; j++) { if (!hasPlayed(sortedWords[i], sortedWords[j]) && Math.abs(scores[sortedWords[i]] - scores[sortedWords[j]]) <= scoreThreshold) { return [sortedWords[i], sortedWords[j]]; } } } return null; } function hasPlayed(word1, word2) { const pair = [word1, word2].sort().join('-'); return playedPairs.has(pair); } function vote(winner, loser) { const k = 32; const expectedScoreWinner = 1 / (1 + Math.pow(10, (scores[loser] - scores[winner]) / 400)); const expectedScoreLoser = 1 - expectedScoreWinner; scores[winner] += k * (1 - expectedScoreWinner); scores[loser] += k * (0 - expectedScoreLoser); const pair = [winner, loser].sort().join('-'); playedPairs.add(pair); votesDone++; updateProgress(); updateRankingList(); nextPair(); } function updateProgress() { const progress = (votesDone / totalVotes) * 100; document.getElementById('progress').style.width = progress + '%'; } function updateRankingList() { const rankingList = document.getElementById('ranking-list'); rankingList.innerHTML = ''; const sortedWords = Object.keys(scores).sort((a, b) => scores[b] - scores[a]); sortedWords.forEach(word => { const listItem = document.createElement('li'); listItem.classList.add('ranking-item', 'p-2', 'border', 'rounded', 'bg-gray-100', 'flex', 'justify-between'); const wordSpan = document.createElement('span'); wordSpan.classList.add('word'); wordSpan.textContent = word; const scoreSpan = document.createElement('span'); scoreSpan.classList.add('score'); scoreSpan.textContent = Math.round(scores[word]); listItem.appendChild(wordSpan); listItem.appendChild(scoreSpan); rankingList.appendChild(listItem); }); } function disableVoteButtons() { document.getElementById('word1').disabled = true; document.getElementById('word2').disabled = true; document.getElementById('word1').classList.add('bg-gray-500', 'cursor-not-allowed'); document.getElementById('word2').classList.add('bg-gray-500', 'cursor-not-allowed'); } function toggleHelp() { const helpSection = document.getElementById('help-section'); helpSection.classList.toggle('hidden'); if (!helpSection.classList.contains('hidden')) { helpSection.style.maxHeight = helpSection.scrollHeight + "px"; } else { helpSection.style.maxHeight = null; } } function showMessage(message) { const messageBox = document.getElementById('message-box'); const messageText = document.getElementById('message-text'); messageText.textContent = message; messageBox.classList.remove('hidden'); } function copyResultsToClipboard() { const sortedWords = Object.keys(scores).sort((a, b) => scores[b] - scores[a]); const results = sortedWords.map(word => `${word}: ${Math.round(scores[word])}`).join('\n'); navigator.clipboard.writeText(results).then(() => { const clipboardOkIcon = document.querySelector('.clipboard-ok'); clipboardOkIcon.classList.remove('hidden'); setTimeout(() => { clipboardOkIcon.classList.add('hidden'); }, 5000); }).catch(err => { alert('Failed to copy results: ', err); }); }