diff --git a/web/index.html b/web/index.html
index 4fde4d4..cf38e5b 100644
--- a/web/index.html
+++ b/web/index.html
@@ -91,8 +91,10 @@
+
+
diff --git a/web/quiz.js b/web/quiz.js
index 03a27eb..23e5c05 100644
--- a/web/quiz.js
+++ b/web/quiz.js
@@ -1,19 +1,44 @@
+function showFSATeamCountTroll() {
+
+ var fsatctel = document.getElementById('fsateamcounttroll')
+ fsatctel.innerHTML = (state.fsaTeamCountTroll + ' teams have already answered this question')
+
+}
+
+function updateFSATeamCountTroll() {
+
+ if (state.fsaTeamCountTroll > (128*Math.random())) {
+ showFSATeamCountTroll()
+ return
+ }
+
+ var time = state.questions[state.currentQuestion].time
+ var timeratio = 1 - (state.submitTimer / time)
+ var slowAnswerChance = Math.random()*2*Math.pow(timeratio, 2)
+ var quickAnswerChance = (Math.random()+Math.sqrt(69/time))/3
+ var chance = Math.round(slowAnswerChance + quickAnswerChance)
+ var magnitude = Math.round((Math.random()/2+timeratio)*6)
+ var nt = chance * magnitude
+ state.fsaTeamCountTroll += nt
+
+ showFSATeamCountTroll()
+
+}
+
function updateTotalTimer() {
var timerEls = document.querySelectorAll('.totaltimer')
- var minutes = Math.floor(state.totalTimer / 60)
- var seconds = state.totalTimer % 60
-
- var text = minutes + ':' + ('0' + seconds).slice(-2)
-
for (timerEl of timerEls)
- timerEl.innerHTML = text
+ timerEl.innerHTML = formatTime(state.totalTimer);
state.totalTimer++
localStorage.setItem('state', JSON.stringify(state))
+ if (state.style == 'FSA')
+ updateFSATeamCountTroll()
+
}
@@ -27,9 +52,34 @@ function startTotalTimer() {
}
-function updateSubmitButton() {
+function updateSubmitInfo() {
var button = document.getElementById('quizSubmitButton')
+ var si = document.getElementById('submitinfo')
+
+ if (getRule('submitTimeout') || state.waitNextQuestion) {
+ if (state.submitTimer > 0) {
+ si.innerHTML = state.waitNextQuestion ? 'Waiting for next question' : 'Wait to retry'
+ button.value = 'Wait ' + formatTime(state.submitTimer)
+ button.disabled = true
+ return
+ }
+ }
+
+ si.innerHTML = ''
+ button.disabled = false
+
+ if (getRule('questionTimeout')) {
+ if (state.submitTimer > 0) {
+ if (getRule('allowQOvertime'))
+ si.innerHTML = ('Losing bonus points in ' + formatTime(state.submitTimer))
+ else
+ si.innerHTML = ('Forced hand-in in ' + formatTime(state.submitTimer))
+ } else {
+ if (getRule('allowQOvertime'))
+ document.getElementById('submitinfo').innerHTML = 'Bonus points lost.'
+ }
+ }
var lastQuestion = (state.currentQuestion == (state.questions.length - 1))
@@ -37,39 +87,23 @@ function updateSubmitButton() {
}
-function resetSubmitButton() {
-
- updateSubmitButton()
- document.getElementById('quizSubmitButton').disabled = false
-
-}
-
-function formatTime(seconds) {
- return (seconds > 60)
- ? Math.floor(seconds / 60) + ':' + (('0' + (seconds % 60)).slice(-2))
- : seconds + 's'
-}
-
function updateSubmitTimer() {
- var button = document.getElementById('quizSubmitButton')
-
- if (state.submitTimer > 0) {
-
- button.value = 'Wait ' + formatTime(state.submitTimer)
- button.disabled = true
+ if (state.submitTimer > 0)
state.submitTimer -= 1
- } else {
+ if (state.submitTimer == 0) {
- resetSubmitButton()
clearInterval(state.submitInterval)
- if (getRule('sequential') && !getRule('allowQOvertime'))
- submitQuiz()
+ if (getRule('questionTimeout'))
+ if (state.waitNextQuestion || !getRule('allowQOvertime'))
+ submitQuiz() // Force next question
}
+ updateSubmitInfo()
+
}
@@ -88,16 +122,16 @@ function startSubmitTimer(time) {
}
-function showSequentialQuestion() {
+function showSequentialQuestion(n) {
var questions = document.querySelectorAll('.question')
for (q of questions)
q.style.display = null
- updateSubmitButton()
+ updateSubmitInfo()
- if (state.currentQuestion !== null) {
- var q = document.querySelector('#quiz form #question' + state.currentQuestion)
+ if (n !== null) {
+ var q = document.querySelector('#quiz form #question' + n)
q.style.display = 'block'
}
@@ -108,6 +142,21 @@ function nextQuestion() {
// Save time taken
state.questions[state.currentQuestion].timeTaken = state.totalTimer - state.questionStartTotalTimer
+ if (getRule('questionTimeout') && (state.submitTimer > 0)
+ && (state.currentQuestion != (state.questions.length-1))) {
+ state.waitNextQuestion = true;
+ showSequentialQuestion(null) // hide question
+ return
+ }
+
+ state.waitNextQuestion = false
+
+ if (state.style == 'FSA') {
+ state.fsaTeamCountTroll = 0
+ showFSATeamCountTroll()
+ }
+
+ // Start next question
state.questionStartTotalTimer = state.totalTimer
state.currentQuestion++
@@ -115,13 +164,11 @@ function nextQuestion() {
if (state.currentQuestion == state.questions.length)
state.currentQuestion = null
- showSequentialQuestion()
+ showSequentialQuestion(state.currentQuestion)
if (state.currentQuestion !== null && getRule('questionTimeout'))
startSubmitTimer()
- return state.currentQuestion
-
}
@@ -184,14 +231,14 @@ function startQuiz() {
changeView('quiz')
if (getRule('sequential'))
- showSequentialQuestion()
+ showSequentialQuestion(state.currentQuestion)
if (state.submitTimer > 0)
startSubmitTimer(state.submitTimer)
else if (getRule('questionTimeout'))
startSubmitTimer()
else
- resetSubmitButton()
+ updateSubmitInfo()
startTotalTimer()
state.running = true
@@ -206,6 +253,7 @@ function reStartQuiz() {
state.responses = defaultState.responses
state.currentQuestion = defaultState.currentQuestion
+ state.waitNextQuestion = defaultState.waitNextQuestion
state.success = defaultState.success
state.submitTry = defaultState.submitTry
state.submitTimer = defaultState.submitTimer
@@ -213,6 +261,7 @@ function reStartQuiz() {
state.questionStartTotalTimer = defaultState.questionStartTotalTimer
state.totalTimer = defaultState.totalTimer
state.totalInterval = defaultState.totalInterval
+ state.fsaTeamCountTroll = defaultState.fsaTeamCountTroll
changeView('prescreen')
@@ -319,7 +368,13 @@ function showQuizResults() {
el.appendChild(meta)
var qinfo = (value.correct) ? '✅ Correct' : '❌ Incorrect'
- if (q.timeTaken) qinfo += ('. Time taken: ' + formatTime(q.timeTaken))
+ if (q.timeTaken) {
+ qinfo += ('. Time taken: ' + formatTime(q.timeTaken))
+ if (value.correct && getRule('allowQOvertime'))
+ qinfo += (', Bonus points ' + ((q.timeTaken <= q.time) ? 'received' : 'lost'))
+ else if (q.timeTaken == q.time)
+ qinfo += ', Time ran out'
+ }
el.querySelector('h3').innerHTML += ` ${qinfo}`
}
@@ -344,14 +399,17 @@ function mergeKeyReducer(acc, entry) {
function submitQuiz() {
// If not running, we're most likely in review mode. Just switch back.
- if (state.running == false)
+ if (state.running == false) {
changeView('postscreen')
+ return
+ }
if (getRule('sequential')) {
- var n = nextQuestion()
+ nextQuestion()
- if (n !== null)
+ // Not at the end of the quiz yet
+ if (state.currentQuestion !== null)
return
}
diff --git a/web/style.css b/web/style.css
index f729bbb..9615ab0 100644
--- a/web/style.css
+++ b/web/style.css
@@ -182,3 +182,15 @@ input[type="radio"]:hover + p, input[type="checkbox"]:hover + p {
font-size: 16px;
margin: 16px 0;
}
+
+#submitinfo {
+ float: right;
+ margin: 16px 0;
+ padding: 12px 0;
+}
+
+#fsateamcounttroll {
+ text-align: right;
+ font-size: 15px;
+ font-style: italic;
+}
diff --git a/web/util.js b/web/util.js
index 5f9242d..d890c97 100644
--- a/web/util.js
+++ b/web/util.js
@@ -6,6 +6,7 @@ const defaultState = {
questions: [],
responses: null,
currentQuestion: 0,
+ waitNextQuestion: false,
success: false,
submitTry: 0,
submitTries: 1,
@@ -15,6 +16,7 @@ const defaultState = {
questionStartTotalTimer: 0,
totalTimer: 0,
totalInterval: null,
+ fsaTeamCountTroll: 0
}
var state
@@ -88,6 +90,13 @@ function applyRuleSettingsFromForm() {
}
+function formatTime(seconds) {
+ return (seconds > 60)
+ ? Math.floor(seconds / 60) + ':' + (('0' + (seconds % 60)).slice(-2))
+ : seconds + 's'
+}
+
+
function changeView(view) {
for (el of document.querySelectorAll('.view'))