Add full FSA mode (resolves #3)
This commit is contained in:
parent
2ef91956b4
commit
c19a7941fa
|
@ -91,8 +91,10 @@
|
|||
</div>
|
||||
<form>
|
||||
</form>
|
||||
<div id="fsateamcounttroll"></div>
|
||||
<input type="button" value="Submit" onclick="submitQuiz()" style="background: #008029" id="quizSubmitButton">
|
||||
<input type="button" value="Abort" onclick="abortQuiz()">
|
||||
<span id="submitinfo"></span>
|
||||
</div>
|
||||
|
||||
<div id="postscreen" class="view">
|
||||
|
|
144
web/quiz.js
144
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 += ` <span class="meta">${qinfo}</span>`
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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'))
|
||||
|
|
Loading…
Reference in New Issue