"use strict"; var entryEl = document.getElementById("entry") var guessesEl = document.getElementById("guesses") var winEl = document.getElementById("win") function renderWord(word, wordIdx, guess, score, offset) { var els = [] var c = 0; for (var syllable of word) { var sylEls = [] var shouldStress = syllable[0] == "/"; if (shouldStress) { syllable = syllable.slice(1) } var stress = shouldStress ? "stress" : "" for (var _ in syllable) { var charclass = '' var able = '' if (score) { if (score.greens[c]) { charclass += 'green' } else if (score.yellows[c]) { charclass += 'yellow' } else if (score.greys[c]) { charclass += 'grey' } able = 'disabled' } var val = guess ? guess[wordIdx][c] : '' var typ = guess ? 'solbox' : 'entrybox' sylEls.push(`
${val}
`) c++; } els.push(`
` + sylEls.join('') + `
`) } return `
` + els.join('') + `
` } function renderLine(line, guess, scores) { var els = [] var offset = 0; for (var wordIdx in line) { var word = line[wordIdx] els.push(renderWord(word, wordIdx, guess, scores && scores[wordIdx], offset)) offset += word.join('').replaceAll('/', '').length } return `
` + els.join('') + `
` } function consumeInput() { var els = Array.from(document.getElementsByClassName("entrybox")); for (var el of els) { if (el.innerText.trim().length == '') { return null } } els.sort((x, y) => { var xword = x.getAttribute('data-word') var xchar = x.getAttribute('data-character') var yword = y.getAttribute('data-word') var ychar = y.getAttribute('data-character') if (xword != yword) { return xword - yword; } return xchar - ychar; }) var words = {} for (var el of els) { words[el.getAttribute('data-word')] = (words[el.getAttribute('data-word')] || '') + el.innerText.trim().toUpperCase() } return words } function scoreLine(guess, answer) { var scores = [] for (var idx in guess) { var guessword = guess[idx] var answerword = answer[idx].join('').replaceAll('/', '').toUpperCase() scores.push(scoreWord(guessword, answerword)) } return scores } function scoreWord(guess, answer) { var greens = {} var yellows = {} var greys = {} var counts = {} var placed = {} for (var idx in guess) { if (guess[idx] == answer[idx]) { greens[idx] = 1 placed[answer[idx]] = (placed[answer[idx]] || 0) + 1 } counts[answer[idx]] = (counts[answer[idx]] || 0) + 1 } for (var idx in guess) { if (greens[idx]) { continue } if ((placed[guess[idx]] || 0) < counts[guess[idx]]) { yellows[idx] = 1 placed[guess[idx]] = (placed[guess[idx]] || 0) + 1; } else { greys[idx] = 1 } } return {greens: greens, yellows: yellows, greys: greys} } var focused = null; document.getElementById('clear').onclick = function(e) { e.preventDefault(); for (var el of document.getElementsByClassName('entrybox')) { el.innerText = '' } unfocus(document.querySelector(`[data-offset="${focused}"]`)); focus(document.querySelector(`[data-offset="0"]`)) } document.getElementById('check').addEventListener('click', function(e) { var guess = consumeInput() if (guess == null) { return; } guesses.push(guess) var scores = scoreLine(guess, challenge.line) var linehtml = renderLine(challenge.line, guess, scores) guessesEl.innerHTML = linehtml + guessesEl.innerHTML var win = true; for (var score of scores) { if (Object.keys(score.yellows).length || Object.keys(score.greys).length) { win = false; } } if (win) { entryEl.innerHTML = linehtml winGame(challenge) } }) function winGame(challenge) { winEl.style = 'display: block;' document.getElementById('btns').style = 'display: none;' document.getElementById('meter').innerText = challenge.meter document.getElementById('ctx').innerHTML = challenge.ctx.replaceAll(/^(.*)/gm, ' $1') + `\n\t${challenge.title}, ${challenge.collection}, ${challenge.author}` var date = new Date().toISOString().slice(0, 10) var firstguess = Object.values(guesses[0]).join(' ') document.getElementById('share').value = `I solved the ${date} Prosodyle at cyfraeviolae.org/prosodyle. My first guess was: "${firstguess}".` } document.addEventListener('keydown', function(e) { // if (!Array.from(e.target.classList).includes('entrybox')) { // return; // } // if (e.ctrlKey || e.altKey || (e.key.length != 1 && e.key != 'Backspace')) { // return; // } if (e.ctrlKey || e.altKey || (!"ABCDEFGHIJKLMNOPQRSTUVWXYZ".includes(e.key.toUpperCase()) && e.key != 'Backspace' && e.key != 'Enter')) { return; } if (e.target.id == 'share') { return; } e.preventDefault(); if (e.key == 'Enter') { document.getElementById('check').click() return; } var el = document.querySelector(`[data-offset="${focused}"]`); var offset = parseInt(el.getAttribute('data-offset')) var nextel; if (e.key == 'Backspace') { el.innerText = ''; nextel = document.querySelector(`[data-offset="${offset-1}"]`); } else { el.innerText = e.key.toUpperCase(); nextel = document.querySelector(`[data-offset="${offset+1}"]`); } if (nextel) { focus(nextel); unfocus(el); } }) document.addEventListener('mousedown', function(e) { console.log('click', e.target) if (Array.from(e.target.classList).includes('entrybox')) { unfocus(document.querySelector(`[data-offset="${focused}"]`)); focus(e.target); } }) function getDailyChallenge() { // https://stackoverflow.com/a/8619946 var now = new Date(); var start = new Date(now.getFullYear(), 0, 0); var diff = now - start; var oneDay = 1000 * 60 * 60 * 24; var day = Math.floor(diff / oneDay); // end snippet return challenges[day-57] } document.getElementById('copy').addEventListener('click', function(e) { e.preventDefault(); document.getElementById('share').select() document.execCommand('copy'); }) function focus(el) { focused = parseInt(el.getAttribute('data-offset')) el.classList.add('focus') document.getElementById('kb').focus() } function unfocus(el) { el.classList.remove('focus') } var guesses = [] var challenge = getDailyChallenge() entryEl.innerHTML = renderLine(challenge.line) focus(document.querySelector(`[data-offset="0"]`));