Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/play/TossupClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const TossupClientMixin = (ClientClass) => class extends ClientClass {
}

updateQuestion ({ word }) {
if (word === '(*)' || word === '[*]') { return; }
if (word === '(*)' || word === '[*]' || word === '(+)') { return; }
document.getElementById('question').innerHTML += word + ' ';
}
};
Expand Down
4 changes: 3 additions & 1 deletion client/play/mp/MultiplayerTossupBonusClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,9 @@ export const MultiplayerClientMixin = (ClientClass) => class extends ClientClass
document.getElementById('buzz').disabled = !document.getElementById('toggle-rebuzz').checked && userId === this.USER_ID;
}

if (score > 10) {
if (score === 20) {
this.room.players[userId].superpowers++;
} else if (score === 15) {
this.room.players[userId].powers++;
} else if (score === 10) {
this.room.players[userId].tens++;
Expand Down
12 changes: 7 additions & 5 deletions client/play/tossups/SoloTossupClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ export default class SoloTossupClient extends TossupClient {
super.endCurrentTossup({ starred, tossup });
if (!isSkip && this.room.previousTossup.userId === this.USER_ID && (this.room.mode !== MODE_ENUM.LOCAL)) {
const previous = this.room.previousTossup;
const pointValue = previous.isCorrect ? (previous.inPower ? previous.powerValue : 10) : (previous.endOfQuestion ? 0 : previous.negValue);
const pointValue = previous.isCorrect
? (previous.inSuperpower ? previous.superpowerValue : (previous.inPower ? previous.powerValue : 10))
: (previous.endOfQuestion ? 0 : previous.negValue);
questionStats.recordTossup({
_id: previous.tossup._id,
celerity: previous.celerity,
Expand Down Expand Up @@ -203,12 +205,12 @@ export default class SoloTossupClient extends TossupClient {
}

/**
* Updates the displayed stat line.
*/
updateStatDisplay ({ powers, tens, negs, tuh, points, celerity }) {
* Updates the displayed stat line.
*/
updateStatDisplay ({ superpowers, powers, tens, negs, tuh, points, celerity }) {
const averageCelerity = celerity.correct.average.toFixed(3);
const plural = (tuh === 1) ? '' : 's';
document.getElementById('statline').innerHTML = `${powers}/${tens}/${negs} with ${tuh} tossup${plural} seen (${points} pts, celerity: ${averageCelerity})`;
document.getElementById('statline').innerHTML = `${superpowers}/${powers}/${tens}/${negs} with ${tuh} tossup${plural} seen (${points} pts, celerity: ${averageCelerity})`;

// disable clear stats button if no stats
document.getElementById('clear-stats').disabled = (tuh === 0);
Expand Down
8 changes: 6 additions & 2 deletions client/play/tossups/SoloTossupRoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ export default class SoloTossupRoom extends TossupRoom {
this.previousTossup.isCorrect = correct;
const multiplier = correct ? 1 : -1;

if (this.previousTossup.inPower) {
if (this.previousTossup.inSuperpower) {
this.players[userId].superpowers += multiplier * 1;
this.players[userId].points += multiplier * this.previousTossup.superpowerValue;
} else if (this.previousTossup.inPower) {
this.players[userId].powers += multiplier * 1;
this.players[userId].points += multiplier * this.previousTossup.powerValue;
} else {
Expand All @@ -103,8 +106,9 @@ export default class SoloTossupRoom extends TossupRoom {
this.players[userId].points += multiplier * -this.previousTossup.negValue;
}

const correctBuzzes = this.players[userId].superpowers + this.players[userId].powers + this.players[userId].tens;
this.players[userId].celerity.correct.total += multiplier * this.previousTossup.celerity;
this.players[userId].celerity.correct.average = this.players[userId].celerity.correct.total / (this.players[userId].powers + this.players[userId].tens);
this.players[userId].celerity.correct.average = this.players[userId].celerity.correct.total / correctBuzzes;

this.emitMessage({ type: 'toggle-correct', correct, userId });
}
Expand Down
3 changes: 2 additions & 1 deletion client/play/upsert-player-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function upsertPlayerItem (player, multiplayerOptions = {}) {
player.userId = escapeHTML(player.userId);
player.username = escapeHTML(player.username);

const { userId, username, powers = 0, tens = 0, negs = 0, tuh = 0, points = 0, online } = player;
const { userId, username, superpowers = 0, powers = 0, tens = 0, negs = 0, tuh = 0, points = 0, online } = player;
const celerity = player?.celerity?.correct?.average ?? player?.celerity ?? 0;

const { bonusStats = { 0: 0, 10: 0, 20: 0, 30: 0 } } = team;
Expand Down Expand Up @@ -75,6 +75,7 @@ export default function upsertPlayerItem (player, multiplayerOptions = {}) {
playerItem.setAttribute('data-bs-title', username);
playerItem.setAttribute('data-bs-content', `
<ul class="list-group list-group-flush">
<li class="list-group-item"><span>Superpowers</span><span id="superpowers-${userId}" class="float-end badge rounded-pill bg-secondary stats-${userId}">${superpowers}</span></li>
<li class="list-group-item"><span>Powers</span><span id="powers-${userId}" class="float-end badge rounded-pill bg-secondary stats-${userId}">${powers}</span></li>
<li class="list-group-item"><span>Tens</span><span id="tens-${userId}" class="float-end badge rounded-pill bg-secondary stats-${userId}">${tens}</span></li>
<li class="list-group-item"><span>Negs</span><span id="negs-${userId}" class="float-end badge rounded-pill bg-secondary stats-${userId}">${negs}</span></li>
Expand Down
4 changes: 3 additions & 1 deletion client/user/stats/tossup/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function showTossupGraphStats ({ cumulative = false, difficulties = '', filterLo
labels: stats.map(stat => stat._id),
datasets: [
{ data: accumulate(stats.map(stat => stat.count)), label: 'Total', borderColor: '#3e95cd', fill: false },
{ data: accumulate(stats.map(stat => stat.superpowers)), label: 'Superpowers', borderColor: '#ff9f40', fill: false },
{ data: accumulate(stats.map(stat => stat.powers)), label: 'Powers', borderColor: '#8e5ea2', fill: false },
{ data: accumulate(stats.map(stat => stat.tens)), label: 'Tens', borderColor: '#3cba9f', fill: false },
{ data: accumulate(stats.map(stat => stat.deads)), label: 'Dead', borderColor: '#e8c3b9', fill: false },
Expand All @@ -31,6 +32,7 @@ function showTossupGraphStats ({ cumulative = false, difficulties = '', filterLo
labels: stats.map(stat => stat._id),
datasets: [
{ data: stats.map(stat => stat.count), label: 'Total', borderColor: '#3e95cd', fill: false },
{ data: stats.map(stat => stat.superpowers), label: 'Superpowers', borderColor: '#ff9f40', fill: false },
{ data: stats.map(stat => stat.powers), label: 'Powers', borderColor: '#8e5ea2', fill: false },
{ data: stats.map(stat => stat.tens), label: 'Tens', borderColor: '#3cba9f', fill: false },
{ data: stats.map(stat => stat.deads), label: 'Dead', borderColor: '#e8c3b9', fill: false },
Expand All @@ -49,7 +51,7 @@ function showTossupGraphStats ({ cumulative = false, difficulties = '', filterLo
resultPerTossup.data = {
labels: stats.map(stat => stat._id),
datasets: [
{ data: stats.map(stat => 100 * stat.powers / stat.count), label: 'Power Percentage', borderColor: '#3e95cd', fill: false },
{ data: stats.map(stat => 100 * (stat.superpowers + stat.powers) / stat.count), label: 'Power Percentage', borderColor: '#3e95cd', fill: false },
{ data: stats.map(stat => 100 * (stat.deads + stat.negs) / stat.count), label: 'Neg or Dead Percentage', borderColor: '#8e5ea2', fill: false }
]
};
Expand Down
4 changes: 4 additions & 0 deletions client/user/stats/tossup/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
<tr>
<th scope="col">Category</th>
<th scope="col">TUH</th>
<th scope="col">(+)</th>
<th scope="col">15</th>
<th scope="col">10</th>
<th scope="col">-5</th>
Expand All @@ -208,6 +209,7 @@
<tr>
<th scope="col">Subcategory</th>
<th scope="col">TUH</th>
<th scope="col">(+)</th>
<th scope="col">15</th>
<th scope="col">10</th>
<th scope="col">-5</th>
Expand All @@ -227,6 +229,7 @@
<tr>
<th scope="col">Alternate Subcategory</th>
<th scope="col">TUH</th>
<th scope="col">(+)</th>
<th scope="col">15</th>
<th scope="col">10</th>
<th scope="col">-5</th>
Expand All @@ -246,6 +249,7 @@
<tr>
<th scope="col">Set Name</th>
<th scope="col">TUH</th>
<th scope="col">(+)</th>
<th scope="col">15</th>
<th scope="col">10</th>
<th scope="col">-5</th>
Expand Down
8 changes: 5 additions & 3 deletions client/user/stats/tossup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ async function fetchTossupStats ({ difficulties = '', setName = '', includeMulti
<tr>
<th scope="row">${stat._id}</th>
<td>${stat.count}</td>
<td>${stat['15s']}</td>
<td>${stat.superpowers}</td>
<td>${stat.powers}</td>
<td>${stat['10s']}</td>
<td>${stat['-5s']}</td>
<td>${averageCelerity.toFixed(3)}</td>
Expand All @@ -68,7 +69,8 @@ async function fetchTossupStats ({ difficulties = '', setName = '', includeMulti
<tr>
<th scope="col">Total</th>
<th scope="col">${totalStats.count ?? 0}</th>
<th scope="col">${totalStats['15s'] ?? 0}</th>
<th scope="col">${totalStats.superpowers ?? 0}</th>
<th scope="col">${totalStats.powers ?? 0}</th>
<th scope="col">${totalStats['10s'] ?? 0}</th>
<th scope="col">${totalStats['-5s'] ?? 0}</th>
<th scope="col">${totalStats.averageCelerity.toFixed(3)}</th>
Expand All @@ -93,7 +95,7 @@ document.getElementById('form').addEventListener('submit', event => {
attachDropdownChecklist();
fetchTossupStats();

const isNumericColumn = [false, true, true, true, true, true, true, true];
const isNumericColumn = [false, true, true, true, true, true, true, true, true];

document.getElementById('set-stats').querySelectorAll('th').forEach((th, index) => {
th.addEventListener('click', () => sortTable(index, isNumericColumn[index], 'set-stats-body', 0, 0));
Expand Down
6 changes: 4 additions & 2 deletions database/account-info/user-stats/get-summary-tossup-stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export default async function getSummaryTossupStats (userId, groupByField, query
{ $match: { 'data.user_id': userId } },
{
$addFields: {
is15: { $gt: ['$data.pointValue', 10] },
is20: { $eq: ['$data.pointValue', 20] },
is15: { $eq: ['$data.pointValue', 15] },
is10: { $eq: ['$data.pointValue', 10] },
isNeg5: { $lt: ['$data.pointValue', 0] }
}
Expand All @@ -32,7 +33,8 @@ export default async function getSummaryTossupStats (userId, groupByField, query
numCorrect: { $sum: { $cond: ['$data.isCorrect', 1, 0] } },
_id: '$' + groupByField,
count: { $sum: 1 },
'15s': { $sum: { $cond: ['$is15', 1, 0] } },
superpowers: { $sum: { $cond: ['$is20', 1, 0] } },
powers: { $sum: { $cond: ['$is15', 1, 0] } },
'10s': { $sum: { $cond: ['$is10', 1, 0] } },
'-5s': { $sum: { $cond: ['$isNeg5', 1, 0] } },
totalCelerity: { $sum: '$data.celerity' },
Expand Down
2 changes: 2 additions & 0 deletions database/account-info/user-stats/get-tossup-graph-stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ async function getTossupGraphStats (userId, query) {
result: {
$switch: {
branches: [
{ case: { $eq: ['$data.pointValue', 20] }, then: 'superpower' },
{ case: { $eq: ['$data.pointValue', 15] }, then: 'power' },
{ case: { $eq: ['$data.pointValue', 10] }, then: 'ten' },
{ case: { $eq: ['$data.pointValue', 0] }, then: 'dead' },
Expand All @@ -37,6 +38,7 @@ async function getTossupGraphStats (userId, query) {
pptu: { $avg: '$data.pointValue' },
count: { $sum: 1 },
correct: { $sum: { $cond: ['$data.isCorrect', 1, 0] } },
superpowers: { $sum: { $cond: [{ $eq: ['$result', 'superpower'] }, 1, 0] } },
powers: { $sum: { $cond: [{ $eq: ['$result', 'power'] }, 1, 0] } },
tens: { $sum: { $cond: [{ $eq: ['$result', 'ten'] }, 1, 0] } },
deads: { $sum: { $cond: [{ $eq: ['$result', 'dead'] }, 1, 0] } },
Expand Down
11 changes: 8 additions & 3 deletions quizbowl/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Player {
this.teamId = undefined;
this.username = '';
this.buzzes = 0;
this.superpowers = 0;
this.powers = 0;
this.tens = 0;
this.zeroes = 0;
Expand All @@ -27,6 +28,7 @@ class Player {
clearStats () {
this.buzzes = 0;
this.powers = 0;
this.superpowers = 0;
this.tens = 0;
this.zeroes = 0;
this.negs = 0;
Expand All @@ -49,7 +51,9 @@ class Player {
this.celerity.all.total += celerity;
this.celerity.all.average = this.celerity.all.total / this.tuh;

if (points > 10) {
if (points === 20) {
this.superpowers++;
} else if (points === 15) {
this.powers++;
} else if (points === 10) {
this.tens++;
Expand All @@ -60,8 +64,9 @@ class Player {
}

if (points > 0) {
const correctBuzzes = this.superpowers + this.powers + this.tens;
this.celerity.correct.total += celerity;
this.celerity.correct.average = this.celerity.correct.total / (this.powers + this.tens);
this.celerity.correct.average = this.celerity.correct.total / correctBuzzes;
}
}

Expand All @@ -70,7 +75,7 @@ class Player {
* @returns {boolean}
*/
hasActivity () {
return this.tuh > 0 || this.buzzes > 0 || this.powers > 0 || this.tens > 0 || this.zeroes > 0 || this.negs > 0;
return this.tuh > 0 || this.buzzes > 0 || this.powers > 0 || this.tens > 0 || this.zeroes > 0 || this.negs > 0 || this.superpowers > 0;
}

/**
Expand Down
16 changes: 12 additions & 4 deletions quizbowl/TossupRoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ export const TossupRoomMixin = (QuestionRoomClass) => class extends QuestionRoom
endOfQuestion: false,
isCorrect: true,
inPower: false,
inSuperpower: false,
negValue: -5,
powerValue: 15,
superpowerValue: 20,
tossup: {},
userId: null
};
Expand Down Expand Up @@ -209,7 +211,7 @@ export const TossupRoomMixin = (QuestionRoomClass) => class extends QuestionRoom
time += 2.5;
} else if (word.endsWith(',') || word.slice(-2) === ',\u201d') {
time += 1.5;
} else if (word === '(*)' || word === '[*]') {
} else if (word === '(*)' || word === '[*]' || word === '(+)') {
time = 0;
}

Expand All @@ -235,22 +237,28 @@ export const TossupRoomMixin = (QuestionRoomClass) => class extends QuestionRoom
scoreTossup ({ givenAnswer }) {
const celerity = this.questionSplit.slice(this.wordIndex).join(' ').length / this.tossup.question.length;
const endOfQuestion = (this.wordIndex === this.questionSplit.length);
const inPower = Math.max(this.questionSplit.indexOf('(*)'), this.questionSplit.indexOf('[*]')) >= this.wordIndex;
const superpowerIndex = this.questionSplit.indexOf('(+)');
const powerIndex = Math.max(this.questionSplit.indexOf('(*)'), this.questionSplit.indexOf('[*]'));
const inSuperpower = superpowerIndex !== -1 && superpowerIndex >= this.wordIndex;
const inPower = !inSuperpower && powerIndex !== -1 && powerIndex >= this.wordIndex;
const { directive, directedPrompt } = this.checkAnswer(this.tossup.answer, givenAnswer, this.settings.strictness);
const isCorrect = directive === 'accept';
const points = isCorrect ? (inPower ? this.previousTossup.powerValue : 10) : (endOfQuestion ? 0 : this.previousTossup.negValue);
const points = isCorrect
? (inSuperpower ? this.previousTossup.superpowerValue : (inPower ? this.previousTossup.powerValue : 10))
: (endOfQuestion ? 0 : this.previousTossup.negValue);

this.previousTossup = {
...this.previousTossup,
celerity,
endOfQuestion,
inPower,
inSuperpower,
isCorrect,
tossup: this.tossup,
userId: this.buzzedIn
};

return { celerity, directive, directedPrompt, endOfQuestion, inPower, points };
return { celerity, directive, directedPrompt, endOfQuestion, inPower, inSuperpower, points };
}

setReadingSpeed (userId, { readingSpeed }) {
Expand Down
Loading