diff --git a/app.py b/app.py
index bb6b953..b30638d 100644
--- a/app.py
+++ b/app.py
@@ -53,7 +53,8 @@ def host():
games[secret] = {
'players': {}, 'order': [],
'current_q': 0, 'answered': [],
- 'started': False, 'finished': False
+ 'started': False, 'finished': False,
+ 'revealed': False
}
# build join URL + QR
@@ -256,6 +257,8 @@ def on_submit_answer(data):
if not secret or secret not in games or pid not in games[secret]['players']:
return
game = games[secret]
+ if game.get('revealed'):
+ return
if any(pid == p for p,_ in game['answered']):
return
@@ -301,7 +304,22 @@ def on_rejoin_game():
join_room('player')
join_room(pid)
_send_sync_state(pid, game)
-
+
+
+@socketio.on('show_answer')
+def on_show_answer():
+ secret = session.get('secret')
+ if session.get('role') != 'host' or not secret or secret not in games:
+ return
+ game = games[secret]
+ game['revealed'] = True
+ # find the correct answer text for current question
+ correct = questions[game['current_q']]['correct']
+ # emit to host so they can display it
+ emit('answer_revealed', {'correct': correct}, room='host')
+ # emit to all players so they can highlight it
+ socketio.emit('answer_revealed', {'correct': correct}, room='player')
+
# helpers
@@ -337,6 +355,7 @@ def _send_sync_state(pid, game):
def _send_question(secret):
game = games[secret]
+ game['revealed'] = False
q = questions[game['current_q']]
# clear previous answers
game['answered'].clear()
@@ -403,4 +422,9 @@ def _score_and_emit(secret):
if __name__ == '__main__':
+ # show own IP address
+ import socket
+ hostname = socket.gethostname()
+ ip_address = socket.gethostbyname(hostname)
+ print(f"Running on http://{ip_address}:5000/")
socketio.run(app, host='0.0.0.0', port=5000)
\ No newline at end of file
diff --git a/templates/host.html b/templates/host.html
index 114f523..1816bee 100644
--- a/templates/host.html
+++ b/templates/host.html
@@ -25,14 +25,15 @@
-
+
+
+
+
+
-
-
@@ -90,6 +91,9 @@
$('#qrContainer, #startBtn, #rosterHeader, #roster').hide();
$('#host-question').show();
$('#qText').text(data.question);
+ $('#host-results').hide();
+ $('#showAnswerBtn').prop({ disabled: false }).show();
+ $('#nextBtn').prop('disabled', true);
});
// Overall leaderboard updates (max 5 rows)
@@ -103,21 +107,31 @@
});
});
- // Per-question results
- socket.on('question_leader', data => {
- console.log('Question leader:', data.results);
- $('#perQ').empty();
- data.results.forEach(r => {
- $('#perQ').append(`
${r.name}: +${r.points}`);
- });
- });
-
// Next question
$('#nextBtn').off('click').on('click', () => {
console.log('Next question clicked');
socket.emit('next_question');
});
+ // when host clicks “Show Answer”
+ $('#showAnswerBtn').off('click').on('click', () => {
+ socket.emit('show_answer');
+ });
+
+ // once server confirms the answer is revealed
+ socket.on('answer_revealed', data => {
+ // display the correct answer on host screen
+ $('#perQ').empty();
+ $('#perQ').append(
+ `
${data.correct}`
+ );
+ $('#host-results').show();
+
+ // disable Show Answer button, enable Next
+ $('#showAnswerBtn').prop('disabled', true);
+ $('#nextBtn').prop('disabled', false);
+ });
+
// Show final top-10 when game_over arrives
socket.on('game_over', data => {
if (data.board) {
diff --git a/templates/player.html b/templates/player.html
index 3ac140e..03259d9 100644
--- a/templates/player.html
+++ b/templates/player.html
@@ -3,12 +3,15 @@
{% block content %}
@@ -93,6 +96,30 @@
renderOptions(data.options, false);
});
+
+ // when the right answer is revealed
+ socket.on('answer_revealed', data => {
+ $('.option').each(function() {
+ const $opt = $(this);
+ if ($opt.text() === data.correct) {
+ // highlight as correct with green outline
+ $opt
+ .addClass('correct')
+ .removeClass('btn-outline-primary disabled')
+ .prop('disabled', true);
+ } else {
+ // any un-clicked options become permanently disabled
+ if (!$opt.hasClass('selected')) {
+ $opt
+ .addClass('disabled')
+ .removeClass('btn-outline-primary btn-primary')
+ .prop('disabled', true);
+ }
+ }
+ });
+ });
+
+
// Handle answer clicks
$(document).on('click', '.option', function() {
const $all = $('.option');