"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}".`
}
function keyHandler(key) {
if (key == 'Enter') {
document.getElementById('check').click()
return;
}
var el = document.querySelector(`[data-offset="${focused}"]`);
var offset = parseInt(el.getAttribute('data-offset'))
var nextel;
if (key == 'Backspace') {
el.innerText = '';
nextel = document.querySelector(`[data-offset="${offset-1}"]`);
} else if (key == 'ArrowLeft') {
nextel = document.querySelector(`[data-offset="${offset-1}"]`);
} else if (key == 'ArrowRight') {
nextel = document.querySelector(`[data-offset="${offset+1}"]`);
} else {
el.innerText = key.toUpperCase();
nextel = document.querySelector(`[data-offset="${offset+1}"]`);
}
if (nextel) {
focus(nextel);
unfocus(el);
}
}
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' && e.key != 'ArrowLeft' && e.key != 'ArrowRight')) {
return;
}
if (e.target.id == 'share') {
return;
}
e.preventDefault();
keyHandler(e.key)
})
document.addEventListener('mousedown', function(e) {
if (Array.from(e.target.classList).includes('entrybox')) {
e.preventDefault();
unfocus(document.querySelector(`[data-offset="${focused}"]`));
focus(e.target);
} else if (Array.from(e.target.classList).includes('key')) {
e.preventDefault();
var k = e.target.getAttribute('data-key')
keyHandler(k)
}
})
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')
}
function unfocus(el) {
el.classList.remove('focus')
}
var guesses = []
var challenge = getDailyChallenge()
entryEl.innerHTML = renderLine(challenge.line)
focus(document.querySelector(`[data-offset="0"]`));