var socket = null
var player = '_'
var wsHeaders = {}
var cards = []
var gc = {}
var currentHint = null
var currentHintCount = -1
var currentGuessCount = -1
var phase = {}
// This variable is here to check for updates to availableHintWordCount, as updating it is a bit expensive
var registeredAvailableHintWordCountInvalid = true
/*
* Update html to match state
* This is idempotent
*/
function updatePhase() {
$('#hint-counter-num').text(currentHintCount)
$('#hint-counter-den').text(gc["max-hint"])
if(currentHint) {
$('#hint-text').text(currentHint['word']+" in "+currentHint['word-count'])
$('#guess-counter-num').text(currentGuessCount)
if(gc['one-more-guess']) {
$('#guess-counter-den').text(currentHint['word-count'] + "(+1)")
} else {
$('#guess-counter-den').text(currentHint['word-count'])
}
}
if(registeredAvailableHintWordCountInvalid) {
$('#submit-hint-wordcount').empty()
for (let i = 0; i < gc['available-hint-word-count'].length; i++) {
const e = gc['available-hint-word-count'][i];
$('#submit-hint-wordcount').append($(``))
}
registeredAvailableHintWordCountInvalid = false
}
$('#submit-hint-text').attr('maxlength', gc['hint-max-length'])
p = player.toLowerCase()
o = (player=='A')?'b':'a'
if(phase[p+'-guessing']) {
$('.card-button').css('visibility', 'visible')
$('.card-button.untouchable').css('visibility', 'hidden')
} else {
$('.card-button').css('visibility', 'hidden')
$('#end-guessing-button').hide()
}
if(phase['name'] == 'need_more_hints_a' || phase['name'] == 'need_more_hints_b') {
$('#enter-sudden-death-button').show()
} else {
$('#enter-sudden-death-button').hide()
}
if((phase['name'] == 'waiting_for_one_more_'+p) ||
(phase[p+'-guessing'] &&
(gc['end-guessing'] || (currentHint && currentGuessCount >= currentHint['word-count'])))) {
$('#end-guessing-button').show()
} else {
$('#end-guessing-button').hide()
}
if(phase[p+'-guessing'] || phase[o+'-guessing']) {
$('#hint-text').show()
$('#guess-counter').show()
} else {
$('#hint-text').hide()
$('#guess-counter').hide()
}
if(phase[p+'-hinting']) {
$('#submit-hint').show()
} else {
$('#submit-hint').hide()
}
if(!phase[p+'-guessing'] && !phase[p+'-hinting']) {
$('#other-playing').show()
} else {
$('#other-playing').hide()
}
}
function createCard(i) {
html = `
${cards[i].word}
`
$('#cards-list').append($(html))
$(`#card-${i}-button`).on('click', pointCard)
}
function updateCard(i) {
card = cards[i]
if(card['revealed-a']) {
$(`#card-${i}-b-public`).addClass((player=='A')?card.otherColor:card.color)
$(`#card-${i}-b-public`).css('visibility', 'visible')
} else {
$(`#card-${i}-b-public`).css('visibility', 'hidden')
}
if(card['revealed-b']) {
$(`#card-${i}-a-public`).addClass((player=='B')?card.otherColor:card.color)
$(`#card-${i}-a-public`).css('visibility', 'visible')
} else {
$(`#card-${i}-a-public`).css('visibility', 'hidden')
}
cardDone = (
gc["only-one-green-green"] &&
((card['revealed-a'] && ((player=='A')?card.otherColor:card.color == "green")) ||
(card['revealed-b'] && ((player=='B')?card.otherColor:card.color == "green")))) ||
(card['revealed-a'] && card['revealed-b']);
if(cardDone) $(`#card-${i}`).addClass('card-done')
cantTouch = cardDone ||
(player=='A' && card['revealed-a']) ||
(player=='B' && card['revealed-b']);
if(cantTouch) {
$(`#card-${i}-button`).addClass('untouchable')
$(`#card-${i}-button`).css('visibility', 'hidden')
}
}
function addHintEvent(issuer, hint, hintWordCount) {
$("#event-log").append($(`
${issuer} proposed "${hint}" in ${hintWordCount} word(s)
`))
}
function addPointEvent(issuer, cardIndex, color) {
$("#event-log").append($(`
${issuer} pointed card ${cards[cardIndex].word} (${color})
`))
}
function addEndGuessingEvent(issuer, manual) {
if(manual) {
$("#event-log").append($(`
${issuer} ended guessing
`))
} else {
$("#event-log").append($(`
${issuer} can't guess anymore
`))
}
}
function addSuddenDeathEvent() {
$("#event-log").append($(`
Starting sudden death
`))
}
function addEndGameEvent(issuer, won) {
if(won) {
$("#event-log").append($(`
You won the game !
`))
} else {
$("#event-log").append($(`
You lost the game !
`))
}
}
function addEvent(e) {
switch(e.type) {
case "HintEvent":
addHintEvent(e.issuer, e.word, e['word-count'])
currentHint = {word: e.word, 'word-count': e['word-count']}
currentHintCount += 1
currentGuessCount = 0
updatePhase()
break
case "GuessEvent":
addPointEvent(e.issuer, e['card-index'], e.color)
currentGuessCount += 1
break
case "EndGuessingEvent":
addEndGuessingEvent(e.issuer, e.manual)
currentHint = null
currentGuessCount = 0
break
case "GameEndEvent":
addEndGameEvent(e.issuer, e.win)
currentHint = null
currentGuessCount = 0
break
case "EnterSuddenDeathEvent":
addSuddenDeathEvent()
currentHint = null
currentGuessCount = 0
break
}
}
/*
* Listeners
*/
function initGame(data) {
gc = data.config
cards = data.cards
$('#cards-list').empty()
for(var i = 0; i