Check user-supplied answers for possible correctness

This commit is contained in:
Neale Pickett 2019-02-24 11:53:22 -07:00
parent c726847cb9
commit 15503cb45b
4 changed files with 47 additions and 7 deletions

View File

@ -40,8 +40,6 @@ def get_puzzle(request, data=None):
puzzle = cat.puzzle(points)
return puzzle
# OMG what is this I hate Python now
@asyncio.coroutine
async def handle_answer(request):
data = await request.post()
puzzle = get_puzzle(request, data)

View File

@ -15,9 +15,9 @@ import tempfile
messageChars = b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
def djb2hash(buf):
def djb2hash(str):
h = 5381
for c in buf:
for c in str.encode("utf-8"):
h = ((h * 33) + c) & 0xffffffff
return h
@ -277,7 +277,7 @@ class Puzzle:
def hashes(self):
"Return a list of answer hashes"
return [djb2hash(a.encode('utf-8')) for a in self.answers]
return [djb2hash(a) for a in self.answers]
class Category:

View File

@ -22,7 +22,7 @@
<input type="hidden" name="cat">
<input type="hidden" name="points">
Team ID: <input type="text" name="id"> <br>
Answer: <input type="text" name="answer" id="answer"> <br>
Answer: <input type="text" name="answer" id="answer"> <span id="answer_ok"></span><br>
<input type="submit" value="Submit">
</form>
<div id="devel"></div>

View File

@ -44,7 +44,17 @@ function devel_addin(obj, e) {
}
}
// The routine used to hash answers in compiled puzzle packages
function djb2hash(buf) {
let h = 5381
for (let c of (new TextEncoder).encode(buf)) { // JavaScript is weird.
h = ((h * 33) + c) & 0xffffffff
}
return h
}
// Pop up a message
function toast(message, timeout=5000) {
let p = document.createElement("p")
@ -56,7 +66,7 @@ function toast(message, timeout=5000) {
)
}
// When the user submits an answer
function submit(e) {
e.preventDefault()
fetch("answer", {
@ -92,6 +102,9 @@ function loadPuzzle(categoryName, points, puzzleId) {
// Populate authors
document.getElementById("authors").textContent = obj.authors.join(", ")
// Make the whole puzzle available
window.puzzle = obj
// If answers are provided, this is the devel server
if (obj.answers) {
devel_addin(obj, document.getElementById("devel"))
@ -139,6 +152,32 @@ function loadPuzzle(categoryName, points, puzzleId) {
document.querySelector("input[name=points]").value = points
}
function answerCheck(e) {
let answer = e.target.value
let ok = document.querySelector("#answer_ok")
// You have to provide someplace to put the check
if (! ok) {
return
}
let possiblyCorrect = false
let answerHash = djb2hash(answer)
for (let correctHash of window.puzzle.hashes) {
if (correctHash == answerHash) {
possiblyCorrect = true
}
}
if (possiblyCorrect) {
ok.textContent = "🙆"
ok.title = "Possibly correct"
} else {
ok.textContent = "🙅"
ok.title = "Definitely not correct"
}
}
function init() {
let params = new URLSearchParams(window.location.search)
let categoryName = params.get("cat")
@ -154,6 +193,9 @@ function init() {
document.querySelector("input[name=id]").value = teamId
}
if (document.querySelector("#answer")) {
document.querySelector("#answer").addEventListener("input", answerCheck)
}
document.querySelector("form").addEventListener("submit", submit)
}