336 lines
9.6 KiB
JavaScript
336 lines
9.6 KiB
JavaScript
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($(`<option value="${e}">${e}</option>`))
|
|
}
|
|
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 = `
|
|
<li class="card ${cards[i].color}" id="card-${i}">
|
|
<span class="card-word">${cards[i].word}</span><br/>
|
|
<div class="card-bottom-bar">
|
|
<div id="card-${i}-a-public">A</div>
|
|
<button class="card-button" id="card-${i}-button">Toucher</button>
|
|
<div id="card-${i}-b-public">B</div>
|
|
</div>
|
|
</li>
|
|
`
|
|
$('#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($(`
|
|
<li>
|
|
${issuer} proposed "${hint}" in ${hintWordCount} word(s)
|
|
</li>
|
|
`))
|
|
}
|
|
|
|
function addPointEvent(issuer, cardIndex, color) {
|
|
$("#event-log").append($(`
|
|
<li>
|
|
${issuer} pointed card ${cards[cardIndex].word} (${color})
|
|
</li>
|
|
`))
|
|
}
|
|
|
|
function addEndGuessingEvent(issuer, manual) {
|
|
if(manual) {
|
|
$("#event-log").append($(`
|
|
<li>
|
|
${issuer} ended guessing
|
|
</li>
|
|
`))
|
|
} else {
|
|
$("#event-log").append($(`
|
|
<li>
|
|
${issuer} can't guess anymore
|
|
</li>
|
|
`))
|
|
}
|
|
}
|
|
function addSuddenDeathEvent() {
|
|
$("#event-log").append($(`
|
|
<li>
|
|
Starting sudden death
|
|
</li>
|
|
`))
|
|
}
|
|
function addEndGameEvent(issuer, won) {
|
|
if(won) {
|
|
$("#event-log").append($(`
|
|
<li>
|
|
You won the game !
|
|
</li>
|
|
`))
|
|
} else {
|
|
$("#event-log").append($(`
|
|
<li>
|
|
You lost the game !
|
|
</li>
|
|
`))
|
|
}
|
|
}
|
|
|
|
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<cards.length; i++) {
|
|
createCard(i)
|
|
updateCard(i)
|
|
}
|
|
phase = data['phase']
|
|
|
|
events = data.events
|
|
for(var i = 0; i<events.length; i++) {
|
|
e = events[i]
|
|
addEvent(e)
|
|
}
|
|
if(data['current-hint']) {
|
|
currentHint = data['current-hint']
|
|
}
|
|
|
|
|
|
currentGuessCount = data['current-guess-count']
|
|
currentHintCount = data['used-hints']
|
|
updatePhase()
|
|
}
|
|
|
|
function selectPlayer(player) {
|
|
wsHeaders = {
|
|
"room": roomId,
|
|
"player": player
|
|
}
|
|
|
|
$('#player-name').text(player)
|
|
$('#player-selector').hide()
|
|
$('#game-panel').show()
|
|
$('#side-panel').show()
|
|
$.ajax({
|
|
contentType: 'application/json',
|
|
type: "GET",
|
|
url: "/room/"+roomId+"/game/player-"+player.toLowerCase(),
|
|
success: initGame
|
|
})
|
|
|
|
socket = Stomp.over(new SockJS('/socket'));
|
|
socket.connect({}, function (frame) {
|
|
socket.subscribe('/topic/'+roomId+'/new-phase', onNewPhase);
|
|
socket.subscribe('/topic/'+roomId+'/new-event', onNewEvent);
|
|
socket.subscribe('/topic/'+roomId+'/update-card/' + player.toLowerCase(), onUpdateCard);
|
|
socket.subscribe('/topic/'+roomId+'/config-change', onConfigChange)
|
|
});
|
|
}
|
|
|
|
function submitHint(e) {
|
|
hint = $('#submit-hint-text').val()
|
|
hintWordCount = Number($('#submit-hint-wordcount option:selected').val())
|
|
socket.send('/app/submit-hint', wsHeaders, JSON.stringify({
|
|
'hint': hint,
|
|
'hintWordCount': hintWordCount
|
|
}))
|
|
}
|
|
function pointCard(e) {
|
|
cardIndex = Number(/card-([0-9]+)-button/.exec(e.target.id)[1])
|
|
socket.send('/app/point-card', wsHeaders, JSON.stringify({
|
|
'cardIndex': cardIndex,
|
|
}))
|
|
}
|
|
function endGuessing(e) {
|
|
socket.send('/app/end-guessing', wsHeaders, "")
|
|
}
|
|
function enterSuddenDeath(e) {
|
|
socket.send('/app/enter-sudden-death', wsHeaders, "")
|
|
}
|
|
function onNewPhase(m) {
|
|
phase = JSON.parse(m.body)
|
|
updatePhase()
|
|
}
|
|
function onNewEvent(m) {
|
|
e = JSON.parse(m.body)
|
|
addEvent(e)
|
|
}
|
|
|
|
function onUpdateCard(m) {
|
|
data = JSON.parse(m.body)
|
|
i = Number(m.headers['cardIndex'])
|
|
cards[i] = data
|
|
updateCard(i)
|
|
}
|
|
|
|
function onConfigChange(m) {
|
|
data = JSON.parse(m.body)
|
|
for(const [key, value] of Object.entries(data)) {
|
|
console.log("New config option : ", key, "=", value)
|
|
gc[key] = value
|
|
switch(key) {
|
|
case "available-hint-word-count":
|
|
registeredAvailableHintWordCountInvalid = true
|
|
updatePhase()
|
|
break
|
|
case "only-one-green-green":
|
|
for(var i = 0; i < cards.length; i++)
|
|
updateCard(i)
|
|
case "max-hint":
|
|
case "one-more-guess":
|
|
case "hint-max-length":
|
|
case "end-guessing":
|
|
case "sudden-death":
|
|
updatePhase()
|
|
break
|
|
case "hints-in-a-row":
|
|
// All the changes are made with phases
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
function initialize() {
|
|
$('#submit-hint button').on('click', submitHint)
|
|
$('#end-guessing-button').on('click', endGuessing)
|
|
$('#enter-sudden-death-button').on('click', enterSuddenDeath)
|
|
|
|
$('#game-panel').hide()
|
|
$('#side-panel').hide()
|
|
} |