252 lines
6.8 KiB
HTML
252 lines
6.8 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<style>
|
|
.letter {
|
|
padding: 0.1em;
|
|
}
|
|
|
|
.match {
|
|
background: lightgreen;
|
|
}
|
|
|
|
.exists {
|
|
background: yellow;
|
|
}
|
|
|
|
.notincluded {
|
|
color: grey;
|
|
}
|
|
|
|
.log {
|
|
padding: 1em;
|
|
border: solid;
|
|
}
|
|
|
|
|
|
</style>
|
|
|
|
<script type="text/javascript" src="wordle.js"></script>
|
|
<script type="text/javascript">
|
|
|
|
var words = []
|
|
|
|
function status(s) {
|
|
document.getElementById('status').innerText = s
|
|
}
|
|
|
|
function log(s) {
|
|
const elem = document.createElement('p')
|
|
elem.innerText = s
|
|
document.getElementById('log').appendChild(elem)
|
|
}
|
|
|
|
var valid_words = null;
|
|
|
|
(() => {
|
|
var req = new XMLHttpRequest()
|
|
req.open('GET', 'valid-wordle-words.txt')
|
|
req.addEventListener('load', e => {
|
|
const text = req.responseText
|
|
words = text.split('\n').map(line => line.trim())
|
|
console.log("found " + words.length+ " words")
|
|
status("found " + words.length + " words")
|
|
valid_words = gen_all_words_list()
|
|
})
|
|
req.send()
|
|
|
|
})()
|
|
|
|
var inited = false
|
|
const cur_status = [0, 0, 0, 0, 0]
|
|
var cur_guess = null
|
|
var num_guess = 0
|
|
var chosen_words = [];
|
|
|
|
(() => {
|
|
window.addEventListener('load', () => {
|
|
document.getElementById('init').addEventListener('click', e => {
|
|
if (!inited) {
|
|
precompute_all()
|
|
}
|
|
})
|
|
|
|
document.getElementById('reset').addEventListener('click', e => {
|
|
cur_guess = null
|
|
num_guess = 0
|
|
chosen_words.length = 0
|
|
valid_words = gen_all_words_list()
|
|
|
|
const history_elem = document.getElementById('history')
|
|
while (history_elem.firstChild) {
|
|
history_elem.removeChild(history_elem.lastChild)
|
|
}
|
|
|
|
const cur_word_elem = document.getElementById('cur-word')
|
|
while (cur_word_elem.firstChild) {
|
|
cur_word_elem.removeChild(cur_word_elem.lastChild)
|
|
}
|
|
|
|
const log_elem = document.getElementById('log')
|
|
while (log_elem.firstChild) {
|
|
log_elem.removeChild(log_elem.lastChild)
|
|
}
|
|
})
|
|
|
|
document.getElementById('find').addEventListener('click', e => {
|
|
if (!inited) {
|
|
status("please initialize the solver first")
|
|
return
|
|
}
|
|
if (words_len(valid_words) == 1) {
|
|
status("the word is " + words[valid_words[0]])
|
|
log("the word is " + words[valid_words[0]])
|
|
return
|
|
}
|
|
const [idx, entropy] = calc_best_word(valid_words)
|
|
status("best word is " + words[idx] + " , " + entropy)
|
|
log("best word " + words[idx] + " , " + entropy)
|
|
})
|
|
|
|
document.getElementById('submit').addEventListener('click', e => {
|
|
const input_elem = document.getElementById('guess')
|
|
const input = input_elem.value.trim()
|
|
|
|
var idx = -1
|
|
for (var i = 0; i < words.length; i++) {
|
|
if (words[i] == input) {
|
|
idx = i
|
|
break
|
|
}
|
|
}
|
|
|
|
if (idx == -1) {
|
|
status(input + " is not a valid word")
|
|
return
|
|
}
|
|
|
|
cur_guess = input
|
|
num_guess++
|
|
const my_num_guess = num_guess
|
|
for (var i = 0; i < 5; i++) {
|
|
cur_status[i] = 0
|
|
}
|
|
|
|
const cur_word = document.getElementById('cur-word')
|
|
while (cur_word.firstChild) {
|
|
cur_word.removeChild(cur_word.lastChild)
|
|
}
|
|
for (var i = 0; i < 5; i++) {
|
|
const elem = document.createElement('span')
|
|
elem.textContent = input[i].toUpperCase()
|
|
elem.classList.add('letter')
|
|
elem.classList.add('notincluded')
|
|
|
|
const char_idx = i
|
|
elem.addEventListener('click', e => {
|
|
if (num_guess != my_num_guess) return
|
|
|
|
cur_status[char_idx]++
|
|
if (cur_status[char_idx] >= 3) {
|
|
cur_status[char_idx] = 0
|
|
}
|
|
elem.classList.remove('match')
|
|
elem.classList.remove('exists')
|
|
elem.classList.remove('notincluded')
|
|
switch (cur_status[char_idx]) {
|
|
case 0:
|
|
elem.classList.add('notincluded')
|
|
break
|
|
case 1:
|
|
elem.classList.add('match')
|
|
break
|
|
case 2:
|
|
elem.classList.add('exists')
|
|
}
|
|
})
|
|
cur_word.appendChild(elem)
|
|
}
|
|
})
|
|
|
|
document.getElementById('confirm').addEventListener('click', e => {
|
|
if (!inited) {
|
|
status("please initialize the solver first")
|
|
return
|
|
}
|
|
if (cur_guess != null) {
|
|
var nodes = []
|
|
const cur_word = document.getElementById('cur-word')
|
|
while (cur_word.firstChild) {
|
|
nodes.push(cur_word.firstChild)
|
|
cur_word.removeChild(cur_word.firstChild)
|
|
}
|
|
|
|
const div_wrapper = document.createElement('div')
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
div_wrapper.appendChild(nodes[i])
|
|
}
|
|
document.getElementById('history').appendChild(div_wrapper)
|
|
|
|
var guess_idx = -1
|
|
for (var i = 0; i < words.length; i++) {
|
|
if (words[i] == cur_guess) {
|
|
guess_idx = i
|
|
break
|
|
}
|
|
}
|
|
if (guess_idx == -1) return
|
|
chosen_words.push([guess_idx, [...cur_status]])
|
|
invalidate_words(valid_words, guess_idx, undump_match(cur_status))
|
|
log("guessed " + cur_guess + " " + words_len(valid_words) + " words left")
|
|
status("guessed " + cur_guess + " " + words_len(valid_words) + " words left")
|
|
cur_guess = null
|
|
}
|
|
})
|
|
|
|
document.getElementById('back').addEventListener('click', e => {
|
|
if (chosen_words.length == 0) return
|
|
if (!inited) {
|
|
status("please initialize the solver first")
|
|
return
|
|
}
|
|
chosen_words.pop()
|
|
const history = document.getElementById('history')
|
|
history.removeChild(history.lastChild)
|
|
|
|
// replay the game up to this point
|
|
valid_words = gen_all_words_list()
|
|
for (var i = 0; i < chosen_words.length; i++) {
|
|
invalidate_words(valid_words, chosen_words[i][0], undump_match(chosen_words[i][1]))
|
|
}
|
|
const num_valid = words_len(valid_words)
|
|
log("removed last added word, " + num_valid + " words left")
|
|
status("removed last added word, " + num_valid + " words left")
|
|
})
|
|
})
|
|
})()
|
|
</script>
|
|
|
|
</head>
|
|
<body>
|
|
<div class="history" id="history"></div>
|
|
<div id="cur-word"></div>
|
|
<form>
|
|
<p>
|
|
<input id="guess" minlength=5 maxlength=5 size=5></input>
|
|
</p>
|
|
<p>
|
|
<input type=button id="init" value="Initialize"></input>
|
|
<input type=button id="reset" value="Reset game"></input>
|
|
<input type=button id="submit" value="Submit word"></input>
|
|
<input type=button id="confirm" value="Confirm word"></input>
|
|
<input type=button id="back" value="Back"></input>
|
|
<input type=button id="find" value="Find best"></input>
|
|
</p>
|
|
</form>
|
|
<div id=status>loading words...</div>
|
|
log:
|
|
<!-- TODO show a sorted list of all the valid words or all the best words to guess with -->
|
|
<div id=log class=log></div>
|
|
</body>
|
|
</html>
|