modaq
Version:
Quiz Bowl Reader using TypeScript, React, and MobX
933 lines • 71.3 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const GameFormats = __importStar(require("src/state/GameFormats"));
const QBJ = __importStar(require("src/qbj/QBJ"));
require("src/qbj/QBJ");
const GameState_1 = require("src/state/GameState");
const PacketState_1 = require("src/state/PacketState");
const TeamState_1 = require("src/state/TeamState");
require("src/state/IGameFormat");
require("src/IResult");
require("src/state/Cycle");
const firstTeamPlayers = [
new TeamState_1.Player("Alice", "A", /* isStarter */ true),
new TeamState_1.Player("Alan", "A", /* isStarter */ true),
new TeamState_1.Player("Anna", "A", /* isStarter */ false),
];
const secondTeamPlayer = new TeamState_1.Player("Bob", "B", /* isStarter */ true);
const players = firstTeamPlayers.concat(secondTeamPlayer);
const defaultPacket = new PacketState_1.PacketState();
defaultPacket.setTossups([
new PacketState_1.Tossup("first q", "first a"),
new PacketState_1.Tossup("second q", "second a"),
new PacketState_1.Tossup("third q (*) has a power marker", "third a"),
new PacketState_1.Tossup("fourth q", "fourth a"),
]);
defaultPacket.setBonuses([
new PacketState_1.Bonus("first leadin", [
{ question: "first q", answer: "first a", value: 10 },
{ question: "first q 2", answer: "first a 2", value: 10 },
{ question: "first q 3", answer: "first a 3", value: 10 },
]),
new PacketState_1.Bonus("second leadin", [
{ question: "second q", answer: "second a", value: 10 },
{ question: "second q 2", answer: "second a 2", value: 10 },
{ question: "second q 3", answer: "second a 3", value: 10 },
]),
new PacketState_1.Bonus("third leadin", [
{ question: "third q", answer: "third a", value: 10 },
{ question: "third q 2", answer: "third a 2", value: 10 },
{ question: "third q 3", answer: "third a 3", value: 10 },
]),
new PacketState_1.Bonus("fourth leadin", [
{ question: "fourth q", answer: "fourth a", value: 10 },
{ question: "fourth q 2", answer: "fourth a 2", value: 10 },
{ question: "fourth q 3", answer: "fourth a 3", value: 10 },
]),
]);
function createDefaultMatch() {
const game = new GameState_1.GameState();
game.loadPacket(defaultPacket);
game.setPlayers(players);
game.setGameFormat(GameFormats.ACFGameFormat);
return QBJ.toQBJ(game, "Packet", 1);
}
function verifyBuzz(buzz, player, position, points) {
chai_1.expect(buzz.buzz_position.word_index).to.equal(position);
chai_1.expect(buzz.team.name).to.equal(player.teamName);
chai_1.expect(buzz.player.name).to.equal(player.name);
chai_1.expect(buzz.result.value).to.equal(points);
}
function verifyFromQBJ(match, verifyGame) {
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
if (!result.success) {
chai_1.assert.fail(`Failed to parse the QBJ file into a game. Error: '${result.message}'`);
}
verifyGame(result.value);
}
function verifyToQBJ(updateGame, verifyMatch) {
const game = new GameState_1.GameState();
game.loadPacket(defaultPacket);
game.addNewPlayers(players);
updateGame(game);
const qbj = QBJ.toQBJString(game);
chai_1.expect(qbj).to.not.be.undefined;
const match = JSON.parse(qbj);
verifyMatch(match, game);
}
function verifyFromQBJRoundtrip(game) {
const qbj = QBJ.toQBJ(game, "Packet", 1);
const roundtrippedGameResult = QBJ.fromQBJ(qbj, game.packet, game.gameFormat);
if (!roundtrippedGameResult.success) {
chai_1.assert.fail(`Failed to parse the QBJ. Error: '${roundtrippedGameResult.message}'`);
}
const roundtrippedGame = roundtrippedGameResult.value;
chai_1.expect(roundtrippedGame).to.not.be.undefined;
chai_1.expect(roundtrippedGame.players).to.deep.equal(game.players);
chai_1.expect(roundtrippedGame.packet).to.deep.equal(game.packet);
// We can't use deep equal aganist cycles because protests aren't preserved. So compare individual fields
chai_1.expect(roundtrippedGame.cycles.length).to.equal(game.cycles.length, "Cycle lengths don't match");
for (let i = 0; i < game.cycles.length; i++) {
const expectedCycle = game.cycles[i];
const roundtrippedCycle = roundtrippedGame.cycles[i];
chai_1.expect(roundtrippedCycle.bonusAnswer).to.deep.equal(expectedCycle.bonusAnswer, `Bonus answer mismatch at index ${i}`);
chai_1.expect(roundtrippedCycle.correctBuzz).to.deep.equal(expectedCycle.correctBuzz, `Correct buzz mismatch at index ${i}`);
chai_1.expect(roundtrippedCycle.thrownOutBonuses).to.deep.equal(expectedCycle.thrownOutBonuses, `Thrown out bonuses mismatch at index ${i}`);
chai_1.expect(roundtrippedCycle.thrownOutTossups).to.deep.equal(expectedCycle.thrownOutTossups, `Thrown out tossups mismatch at index ${i}`);
// Player order for subs and join/leave differ, so just make sure that the names are in each others sets
for (const teamName of game.teamNames) {
const roundtrippedActivePlayers = roundtrippedGame.getActivePlayers(teamName, i);
const originalActivePlayers = game.getActivePlayers(teamName, i);
chai_1.expect(roundtrippedActivePlayers.size).to.equal(originalActivePlayers.size, `Active players size different at index ${i}`);
for (const player of originalActivePlayers.values()) {
chai_1.expect(roundtrippedActivePlayers.has(player), `Player '${player.name}' of team '${player.teamName}' not found in roundtripped players at index ${i}`);
}
}
}
}
describe("QBJTests", () => {
describe("fromQBJ", () => {
it("No buzz game", () => {
const firstTeamPlayers = [{ name: "Alice" }, { name: "Andy" }];
const secondTeamPlayers = [{ name: "Bob" }];
const match = {
match_questions: [
{
buzzes: [],
question_number: 1,
tossup_question: { question_number: 1, type: "tossup", parts: 1 },
},
],
match_teams: [
{
bonus_points: 0,
team: {
name: "Alpha",
players: firstTeamPlayers,
},
lineups: [{ first_question: 0, players: firstTeamPlayers }],
match_players: firstTeamPlayers.map((player) => {
return { player, answer_counts: [], tossups_heard: defaultPacket.tossups.length };
}),
},
{
bonus_points: 0,
team: {
name: "Beta",
players: secondTeamPlayers,
},
lineups: [{ first_question: 0, players: secondTeamPlayers }],
match_players: secondTeamPlayers.map((player) => {
return { player, answer_counts: [], tossups_heard: defaultPacket.tossups.length };
}),
},
],
tossups_read: 2,
};
verifyFromQBJ(match, (game) => {
chai_1.expect(game.finalScore).to.deep.equal([0, 0]);
chai_1.expect(game.cycles.length).to.equal(defaultPacket.tossups.length);
for (let i = 0; i < defaultPacket.tossups.length; i++) {
if (game.cycles[i].correctBuzz != undefined) {
chai_1.assert.fail("Correct buzz found at index " + i);
}
}
});
});
it("Game->QBJ->Game round trip", () => {
const game = new GameState_1.GameState();
game.loadPacket(defaultPacket);
game.setPlayers(players);
game.setGameFormat(GameFormats.ACFGameFormat);
// Add a variety of events
// - Team 1 negs on question 1, team 2 gets it, gets the second and third bonus parts. Bonus protest 1st one, tossup protest 1st one
// - Leave/join for team 1. TU 2 is thrown out. TU is answered by team 1
// - Team 1 gets first part of bonus
// - Sub for team 2. The sub gets TU 3
// - Bonus 3 is thrown out. Parts 1 gotten.
const firstCycle = game.cycles[0];
firstCycle.addWrongBuzz({ player: firstTeamPlayers[0], points: -5, position: 0, isLastWord: false }, 0, GameFormats.ACFGameFormat);
firstCycle.addCorrectBuzz({ player: secondTeamPlayer, points: 10, position: 1 }, 0, GameFormats.ACFGameFormat, 0, 3);
firstCycle.setBonusPartAnswer(1, secondTeamPlayer.teamName, 10);
firstCycle.setBonusPartAnswer(2, secondTeamPlayer.teamName, 10);
firstCycle.addBonusProtest(0, 0, "Right", "Reason", secondTeamPlayer.teamName);
const secondCycle = game.cycles[1];
secondCycle.addThrownOutTossup(1);
secondCycle.addCorrectBuzz({
player: firstTeamPlayers[1],
points: 10,
position: 1,
}, 2, GameFormats.ACFGameFormat, 1, 3);
secondCycle.setBonusPartAnswer(0, firstTeamPlayers[0].teamName, 10);
const thirdCycle = game.cycles[2];
const newPlayer = new TeamState_1.Player("Brenda", secondTeamPlayer.teamName, /* isStarter */ false);
game.addNewPlayer(newPlayer);
thirdCycle.addPlayerJoins(newPlayer);
thirdCycle.addPlayerLeaves(secondTeamPlayer);
thirdCycle.addCorrectBuzz({ player: newPlayer, points: 10, position: 0 }, 3, GameFormats.ACFGameFormat, 2, 3);
thirdCycle.addThrownOutBonus(2);
thirdCycle.setBonusPartAnswer(0, secondTeamPlayer.teamName, 10);
verifyFromQBJRoundtrip(game);
});
it("Roundtrip game with multiple thrown out tossups", () => {
const game = new GameState_1.GameState();
game.loadPacket(defaultPacket);
game.setPlayers(players);
game.setGameFormat(GameFormats.ACFGameFormat);
const firstCycle = game.cycles[0];
firstCycle.addThrownOutTossup(0);
firstCycle.addThrownOutTossup(1);
firstCycle;
firstCycle.addWrongBuzz({ player: firstTeamPlayers[0], points: -5, position: 0, isLastWord: false }, 2, GameFormats.ACFGameFormat);
firstCycle.addCorrectBuzz({ player: secondTeamPlayer, points: 10, position: 1 }, 2, GameFormats.ACFGameFormat, 0, 3);
firstCycle.setBonusPartAnswer(0, secondTeamPlayer.teamName, 10);
verifyFromQBJRoundtrip(game);
});
it("Roundtrip game with multiple thrown out bonuses", () => {
const game = new GameState_1.GameState();
game.loadPacket(defaultPacket);
game.setPlayers(players);
game.setGameFormat(GameFormats.ACFGameFormat);
const firstCycle = game.cycles[0];
firstCycle.addCorrectBuzz({ player: secondTeamPlayer, points: 10, position: 1 }, 0, GameFormats.ACFGameFormat, 0, 3);
firstCycle.addThrownOutBonus(0);
firstCycle.addThrownOutBonus(1);
firstCycle.setBonusPartAnswer(2, secondTeamPlayer.teamName, 10);
verifyFromQBJRoundtrip(game);
});
it("Invalid QBJ - undefined and empty match_players", () => {
const match = createDefaultMatch();
if (match.match_teams) {
match.match_teams[1].match_players = undefined;
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
match.match_teams[1].match_players = [];
const secondResult = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(secondResult.success).to.be.false;
});
it("Invalid QBJ - less than 2 teams", () => {
const match = createDefaultMatch();
match.match_teams = [
{
bonus_points: 0,
team: {
name: "Alpha",
players: firstTeamPlayers,
},
lineups: [{ first_question: 0, players: firstTeamPlayers }],
match_players: firstTeamPlayers.map((player) => {
return { player, answer_counts: [], tossups_heard: defaultPacket.tossups.length };
}),
},
];
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
});
it("Invalid QBJ - more than 2 teams", () => {
const match = createDefaultMatch();
match.match_teams = ["Alpha", "Beta", "Gamma"].map((teamName) => {
return {
bonus_points: 0,
team: {
name: teamName,
players: firstTeamPlayers,
},
lineups: [{ first_question: 0, players: firstTeamPlayers }],
match_players: firstTeamPlayers.map((player) => {
return { player, answer_counts: [], tossups_heard: defaultPacket.tossups.length };
}),
};
});
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
});
it("Invalid QBJ - undefined and empty lineup", () => {
const match = createDefaultMatch();
if (match.match_teams) {
match.match_teams[0].lineups = undefined;
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
match.match_teams[0].lineups = [];
const secondResult = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(secondResult.success).to.be.false;
});
it("Invalid QBJ - undefined and empty match questoins", () => {
const match = createDefaultMatch();
if (match.match_questions) {
match.match_questions = undefined;
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
match.match_questions = [];
const secondResult = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(secondResult.success).to.be.false;
});
it("Invalid QBJ - negative bonus points", () => {
const match = createDefaultMatch();
if (match.match_teams) {
match.match_teams[0].bonus_points = -5;
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
});
it("Invalid QBJ - same team name", () => {
const match = createDefaultMatch();
const name = "Same";
if (match.match_teams) {
match.match_teams[0].team.name = name;
match.match_teams[1].team.name = name;
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
});
it("Invalid QBJ - empty player name", () => {
const match = createDefaultMatch();
if (match.match_teams) {
match.match_teams[0].match_players[0].player.name = "";
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
});
it("Invalid QBJ - duplicate player name", () => {
const match = createDefaultMatch();
const name = "Same";
if (match.match_teams) {
match.match_teams[0].match_players[0].player.name = name;
match.match_teams[0].match_players[1].player.name = name;
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
});
it("Invalid QBJ - buzz by undefined player", () => {
const match = createDefaultMatch();
if (match.match_questions) {
match.match_questions[0].buzzes = [
{
buzz_position: { word_index: 0 },
team: match.match_teams[0].team,
player: undefined,
result: { value: -5 },
},
];
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
});
it("Invalid QBJ - buzz by unknown player", () => {
const match = createDefaultMatch();
if (match.match_questions) {
const player = Object.assign({}, match.match_teams[0].match_players[0].player);
player.name = "Some other guy";
match.match_questions[0].buzzes = [
{
buzz_position: { word_index: 0 },
team: match.match_teams[0].team,
player,
result: { value: -5 },
},
];
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
});
it("Invalid QBJ - lineups at invalid time", () => {
const game = new GameState_1.GameState();
game.loadPacket(defaultPacket);
game.setPlayers(players);
game.setGameFormat(GameFormats.ACFGameFormat);
const newPlayer = new TeamState_1.Player("Arthur", game.teamNames[0], /* isStarter */ false);
game.cycles[1].addSwapSubstitution(newPlayer, firstTeamPlayers[0]);
const match = QBJ.toQBJ(game, "Packet", 1);
if (match.match_teams) {
match.match_teams[0].lineups[0].first_question = -1;
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
match.match_teams[0].lineups[0].first_question = game.packet.tossups.length + 1;
const secondResult = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(secondResult.success).to.be.false;
});
it("Invalid QBJ - lineups in wrong order", () => {
const game = new GameState_1.GameState();
game.loadPacket(defaultPacket);
game.setPlayers(players);
game.setGameFormat(GameFormats.ACFGameFormat);
const newPlayer = new TeamState_1.Player("Arthur", game.teamNames[0], /* isStarter */ false);
game.cycles[1].addSwapSubstitution(newPlayer, firstTeamPlayers[0]);
const match = QBJ.toQBJ(game, "Packet", 1);
if (match.match_teams) {
match.match_teams[0].lineups[0].first_question = 2;
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
});
it("Invalid QBJ - buzz at invalid time", () => {
const match = createDefaultMatch();
if (match.match_questions) {
match.match_questions[0].buzzes = [
{
buzz_position: { word_index: -1 },
team: match.match_teams[0].team,
player: match.match_teams[0].match_players[0].player,
result: { value: -5 },
},
];
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
match.match_questions[0].buzzes = [
{
buzz_position: {
word_index: defaultPacket.tossups[0].getWords(GameFormats.ACFGameFormat).length + 1,
},
team: match.match_teams[0].team,
player: match.match_teams[0].match_players[0].player,
result: { value: -5 },
},
];
const secondResult = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(secondResult.success).to.be.false;
});
it("Invalid QBJ - tossup answered during thrown out tossup", () => {
const game = new GameState_1.GameState();
game.loadPacket(defaultPacket);
game.setPlayers(players);
game.setGameFormat(GameFormats.ACFGameFormat);
const match = QBJ.toQBJ(game, "Packet", 1);
if (match.match_questions) {
match.match_questions[0].buzzes = [
{
buzz_position: { word_index: 0 },
team: match.match_teams[0].team,
player: match.match_teams[0].match_players[0].player,
result: { value: 10 },
},
];
match.match_questions[0].tossup_question.question_number = 2;
match.match_questions[1].buzzes = [
{
buzz_position: { word_index: 1 },
team: match.match_teams[0].team,
player: match.match_teams[0].match_players[0].player,
result: { value: 10 },
},
];
match.match_questions[1].tossup_question.question_number = 1;
}
const result = QBJ.fromQBJ(match, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
});
it("Invalid QBJ - undefined passed in", () => {
const result = QBJ.fromQBJ(undefined, defaultPacket, GameFormats.ACFGameFormat);
chai_1.expect(result.success).to.be.false;
});
});
describe("toQBJ", () => {
it("No buzz game", () => {
verifyToQBJ(
// eslint-disable-next-line @typescript-eslint/no-empty-function
() => { }, (match) => {
chai_1.expect(match.tossups_read).to.equal(4);
chai_1.expect(match.match_teams.length).to.equal(2);
chai_1.expect(match.match_teams[0].lineups).to.deep.equal([
{
first_question: 1,
players: firstTeamPlayers
.filter((p) => p.isStarter)
.map((p) => {
return {
name: p.name,
};
}),
},
]);
chai_1.expect(match.match_teams[1].lineups).to.deep.equal([
{
first_question: 1,
players: [{ name: "Bob" }],
},
]);
chai_1.expect(match.match_questions.map((q) => q.buzzes).every((buzzes) => buzzes.length === 0)).to.be
.true;
chai_1.expect(match.match_questions.map((q) => q.question_number)).to.deep.equal([1, 2, 3, 4]);
});
});
it("Four buzzes (-5, 0, 10, 15)", () => {
verifyToQBJ((game) => {
game.setGameFormat(GameFormats.StandardPowersMACFGameFormat);
game.cycles[0].addWrongBuzz({
player: firstTeamPlayers[0],
points: -5,
position: 0,
isLastWord: false,
}, 0, game.gameFormat);
game.cycles[0].addWrongBuzz({
player: secondTeamPlayer,
points: 0,
position: 1,
isLastWord: true,
}, 0, game.gameFormat);
game.cycles[1].addCorrectBuzz({
player: firstTeamPlayers[1],
points: 10,
position: 1,
isLastWord: true,
}, 1, game.gameFormat, 0, 3);
game.cycles[1].setBonusPartAnswer(1, firstTeamPlayers[1].teamName, 10);
game.cycles[2].addCorrectBuzz({
player: secondTeamPlayer,
points: 15,
position: 0,
isLastWord: false,
}, 2, game.gameFormat, 1, 3);
}, (match) => {
chai_1.expect(match.tossups_read).to.equal(4);
chai_1.expect(match.match_questions.map((q) => q.question_number)).to.deep.equal([1, 2, 3, 4]);
const firstCycleBuzzes = match.match_questions[0].buzzes;
chai_1.expect(firstCycleBuzzes.length).to.equal(2);
verifyBuzz(firstCycleBuzzes[0], firstTeamPlayers[0], 0, -5);
verifyBuzz(firstCycleBuzzes[1], secondTeamPlayer, 1, 0);
const secondCycleBuzzes = match.match_questions[1].buzzes;
chai_1.expect(secondCycleBuzzes.length).to.equal(1);
verifyBuzz(secondCycleBuzzes[0], firstTeamPlayers[1], 1, 10);
const thirdCycleBuzzes = match.match_questions[2].buzzes;
chai_1.expect(thirdCycleBuzzes.length).to.equal(1);
verifyBuzz(thirdCycleBuzzes[0], secondTeamPlayer, 0, 15);
});
});
it("Bonuses (0, 10, 30)", () => {
verifyToQBJ((game) => {
// 0 on the bonus
game.cycles[0].addCorrectBuzz({
player: firstTeamPlayers[0],
points: 10,
position: 1,
isLastWord: true,
}, 1, game.gameFormat, 0, 3);
// 10
game.cycles[1].addCorrectBuzz({
player: secondTeamPlayer,
points: 10,
position: 1,
isLastWord: true,
}, 2, game.gameFormat, 1, 3);
game.cycles[1].setBonusPartAnswer(1, secondTeamPlayer.teamName, 10);
// 30 on the bonus
game.cycles[2].addCorrectBuzz({
player: secondTeamPlayer,
points: 15,
position: 0,
isLastWord: true,
}, 3, game.gameFormat, 2, 3);
for (let i = 0; i < 3; i++) {
game.cycles[2].setBonusPartAnswer(i, secondTeamPlayer.teamName, 10);
}
}, (match) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
chai_1.expect(match.tossups_read).to.equal(4);
chai_1.expect(match.match_questions.map((q) => q.question_number)).to.deep.equal([1, 2, 3, 4]);
const firstCycleBonus = match.match_questions[0].bonus;
if (firstCycleBonus == undefined) {
chai_1.assert.fail("First bonus wasn't found");
}
chai_1.expect((_a = firstCycleBonus.question) === null || _a === void 0 ? void 0 : _a.parts).to.equal(3);
chai_1.expect((_b = firstCycleBonus.question) === null || _b === void 0 ? void 0 : _b.question_number).to.equal(1);
chai_1.expect((_c = firstCycleBonus.question) === null || _c === void 0 ? void 0 : _c.type).to.equal("bonus");
chai_1.expect(firstCycleBonus.parts.map((p) => p.controlled_points)).deep.equals([0, 0, 0]);
const secondCycleBonus = match.match_questions[1].bonus;
if (secondCycleBonus == undefined) {
chai_1.assert.fail("Second bonus wasn't found");
}
chai_1.expect((_d = secondCycleBonus.question) === null || _d === void 0 ? void 0 : _d.parts).to.equal(3);
chai_1.expect((_e = secondCycleBonus.question) === null || _e === void 0 ? void 0 : _e.question_number).to.equal(2);
chai_1.expect((_f = secondCycleBonus.question) === null || _f === void 0 ? void 0 : _f.type).to.equal("bonus");
chai_1.expect(secondCycleBonus.parts.map((p) => p.controlled_points)).deep.equals([0, 10, 0]);
const thirdCycleBonus = match.match_questions[2].bonus;
if (thirdCycleBonus == undefined) {
chai_1.assert.fail("Third bonus wasn't found");
}
chai_1.expect((_g = thirdCycleBonus.question) === null || _g === void 0 ? void 0 : _g.parts).to.equal(3);
chai_1.expect((_h = thirdCycleBonus.question) === null || _h === void 0 ? void 0 : _h.question_number).to.equal(3);
chai_1.expect((_j = thirdCycleBonus.question) === null || _j === void 0 ? void 0 : _j.type).to.equal("bonus");
chai_1.expect(thirdCycleBonus.parts.map((p) => p.controlled_points)).deep.equals([10, 10, 10]);
chai_1.expect(match.match_teams.length).to.equal(2);
chai_1.expect(match.match_teams[0].bonus_points).to.equal(0);
chai_1.expect(match.match_teams[1].bonus_points).to.equal(40);
});
});
it("Bonus bouncebacks", () => {
verifyToQBJ((game) => {
game.setGameFormat(Object.assign(Object.assign({}, game.gameFormat), { bonusesBounceBack: true }));
// 0 on the bonus
game.cycles[0].addCorrectBuzz({
player: firstTeamPlayers[0],
points: 10,
position: 1,
isLastWord: true,
}, 1, game.gameFormat, 0, 3);
// Receiving team get 10, other team gets 10
game.cycles[0].setBonusPartAnswer(0, firstTeamPlayers[0].teamName, 10);
game.cycles[0].setBonusPartAnswer(2, secondTeamPlayer.teamName, 10);
// Receiving team gets 0, other team gets 20
game.cycles[1].addCorrectBuzz({
player: secondTeamPlayer,
points: 10,
position: 1,
isLastWord: true,
}, 2, game.gameFormat, 1, 3);
game.cycles[1].setBonusPartAnswer(0, firstTeamPlayers[0].teamName, 10);
game.cycles[1].setBonusPartAnswer(1, firstTeamPlayers[0].teamName, 10);
}, (match) => {
var _a, _b, _c, _d, _e, _f;
chai_1.expect(match.tossups_read).to.equal(4);
chai_1.expect(match.match_questions.map((q) => q.question_number)).to.deep.equal([1, 2, 3, 4]);
const firstCycleBonus = match.match_questions[0].bonus;
if (firstCycleBonus == undefined) {
chai_1.assert.fail("First bonus wasn't found");
}
chai_1.expect((_a = firstCycleBonus.question) === null || _a === void 0 ? void 0 : _a.parts).to.equal(3);
chai_1.expect((_b = firstCycleBonus.question) === null || _b === void 0 ? void 0 : _b.question_number).to.equal(1);
chai_1.expect((_c = firstCycleBonus.question) === null || _c === void 0 ? void 0 : _c.type).to.equal("bonus");
chai_1.expect(firstCycleBonus.parts.map((p) => p.controlled_points)).deep.equals([10, 0, 0]);
chai_1.expect(firstCycleBonus.parts.map((p) => p.bounceback_points)).deep.equals([0, 0, 10]);
const secondCycleBonus = match.match_questions[1].bonus;
if (secondCycleBonus == undefined) {
chai_1.assert.fail("Second bonus wasn't found");
}
chai_1.expect((_d = secondCycleBonus.question) === null || _d === void 0 ? void 0 : _d.parts).to.equal(3);
chai_1.expect((_e = secondCycleBonus.question) === null || _e === void 0 ? void 0 : _e.question_number).to.equal(2);
chai_1.expect((_f = secondCycleBonus.question) === null || _f === void 0 ? void 0 : _f.type).to.equal("bonus");
chai_1.expect(secondCycleBonus.parts.map((p) => p.controlled_points)).deep.equals([0, 0, 0]);
chai_1.expect(secondCycleBonus.parts.map((p) => p.bounceback_points)).deep.equals([10, 10, 0]);
chai_1.expect(match.match_teams.length).to.equal(2);
chai_1.expect(match.match_teams[0].bonus_points).to.equal(10);
chai_1.expect(match.match_teams[0].bonus_bounceback_points).to.equal(20);
chai_1.expect(match.match_teams[1].bonus_points).to.equal(0);
chai_1.expect(match.match_teams[1].bonus_bounceback_points).to.equal(10);
});
});
it("Sub-in player", () => {
verifyToQBJ((game) => {
game.cycles[1].addSwapSubstitution(firstTeamPlayers[2], firstTeamPlayers[0]);
game.cycles[1].addWrongBuzz({
player: firstTeamPlayers[2],
points: -5,
position: 0,
isLastWord: false,
}, 0, game.gameFormat);
}, (match) => {
chai_1.expect(match.tossups_read).to.equal(4);
chai_1.expect(match.match_questions.map((q) => q.question_number)).to.deep.equal([1, 2, 3, 4]);
const secondCycleBuzzes = match.match_questions[1].buzzes;
chai_1.expect(secondCycleBuzzes.length).to.equal(1);
verifyBuzz(secondCycleBuzzes[0], firstTeamPlayers[2], 0, -5);
chai_1.expect(match.match_teams.length).to.equal(2);
chai_1.expect(match.match_teams[0].match_players.length).to.equal(3);
const outFirstTeamPlayer = match.match_teams[0].match_players[0];
chai_1.expect(outFirstTeamPlayer.player.name).to.equal(firstTeamPlayers[0].name);
chai_1.expect(outFirstTeamPlayer.tossups_heard).to.equal(1);
const inFirstTeamPlayer = match.match_teams[0].match_players[2];
chai_1.expect(inFirstTeamPlayer.player.name).to.equal(firstTeamPlayers[2].name);
chai_1.expect(inFirstTeamPlayer.tossups_heard).to.equal(3);
// Verify the lineups
const firstTeam = match.match_teams[0];
chai_1.expect(firstTeam.lineups.length).to.equal(2);
chai_1.expect(firstTeam.lineups[0]).to.deep.equal({
first_question: 1,
players: firstTeamPlayers
.filter((p) => p.isStarter)
.map((p) => {
return { name: p.name };
}),
});
chai_1.expect(firstTeam.lineups[1]).to.deep.equal({
first_question: 2,
players: [{ name: "Alan" }, { name: "Anna" }],
});
});
});
it("Player leaves", () => {
verifyToQBJ((game) => {
game.cycles[2].addPlayerLeaves(firstTeamPlayers[0]);
}, (match) => {
chai_1.expect(match.tossups_read).to.equal(4);
chai_1.expect(match.match_questions.map((q) => q.question_number)).to.deep.equal([1, 2, 3, 4]);
chai_1.expect(match.match_teams.length).to.equal(2);
chai_1.expect(match.match_teams[0].match_players.length).to.equal(3);
const outFirstTeamPlayer = match.match_teams[0].match_players[0];
chai_1.expect(outFirstTeamPlayer.player.name).to.equal(firstTeamPlayers[0].name);
chai_1.expect(outFirstTeamPlayer.tossups_heard).to.equal(2);
// Verify the lineups
const firstTeam = match.match_teams[0];
chai_1.expect(firstTeam.lineups.length).to.equal(2);
chai_1.expect(firstTeam.lineups[0]).to.deep.equal({
first_question: 1,
players: firstTeamPlayers
.filter((p) => p.isStarter)
.map((p) => {
return { name: p.name };
}),
});
chai_1.expect(firstTeam.lineups[1]).to.deep.equal({
first_question: 3,
players: [{ name: "Alan" }],
});
});
});
it("Player joins", () => {
const newPlayerName = "Bianca";
verifyToQBJ((game) => {
const newPlayer = new TeamState_1.Player(newPlayerName, secondTeamPlayer.teamName,
/* isStarter */ false);
game.addNewPlayer(newPlayer);
game.cycles[3].addPlayerJoins(newPlayer);
}, (match) => {
chai_1.expect(match.tossups_read).to.equal(4);
chai_1.expect(match.match_questions.map((q) => q.question_number)).to.deep.equal([1, 2, 3, 4]);
chai_1.expect(match.match_teams.length).to.equal(2);
chai_1.expect(match.match_teams[1].match_players.length).to.equal(2);
const secondTeam = match.match_teams[1];
const inSecondTeamPlayer = secondTeam.match_players[1];
chai_1.expect(inSecondTeamPlayer.player.name).to.equal(newPlayerName);
chai_1.expect(inSecondTeamPlayer.tossups_heard).to.equal(1);
// Verify the lineups
chai_1.expect(secondTeam.lineups.length).to.equal(2);
chai_1.expect(secondTeam.lineups[0]).to.deep.equal({
first_question: 1,
players: [
{
name: secondTeamPlayer.name,
},
],
});
chai_1.expect(secondTeam.lineups[1]).to.deep.equal({
first_question: 4,
players: [{ name: secondTeamPlayer.name }, { name: newPlayerName }],
});
});
});
it("Player stats", () => {
verifyToQBJ((game) => {
game.setGameFormat(GameFormats.StandardPowersMACFGameFormat);
const packet = new PacketState_1.PacketState();
const tossups = [];
for (let i = 0; i < 6; i++) {
tossups.push(new PacketState_1.Tossup(`Power (*) question ${i}`, `A${i}`));
}
packet.setTossups(tossups);
game.loadPacket(packet);
game.cycles[0].addWrongBuzz({
player: secondTeamPlayer,
points: -5,
position: 0,
isLastWord: false,
}, 0, game.gameFormat);
game.cycles[1].addWrongBuzz({
player: secondTeamPlayer,
points: 0,
position: 3,
isLastWord: true,
}, 1, game.gameFormat);
game.cycles[2].addCorrectBuzz({
player: secondTeamPlayer,
points: 10,
position: 2,
isLastWord: true,
}, 2, game.gameFormat, 0, 3);
game.cycles[3].addCorrectBuzz({
player: secondTeamPlayer,
points: 15,
position: 0,
isLastWord: true,
}, 3, game.gameFormat, 1, 3);
game.cycles[4].addCorrectBuzz({
player: secondTeamPlayer,
points: 15,
position: 0,
isLastWord: false,
}, 4, game.gameFormat, 1, 3);
game.cycles[5].addCorrectBuzz({
player: firstTeamPlayers[0],
points: 10,
position: 2,
isLastWord: true,
}, 5, game.gameFormat, 1, 3);
}, (match) => {
chai_1.expect(match.tossups_read).to.equal(6);
chai_1.expect(match.match_questions.map((q) => q.question_number)).to.deep.equal([1, 2, 3, 4, 5, 6]);
chai_1.expect(match.match_teams.length).to.equal(2);
chai_1.expect(match.match_teams[0].match_players.length).to.equal(3);
const firstFirstTeamPlayer = match.match_teams[0].match_players[0];
chai_1.expect(firstFirstTeamPlayer.player.name).to.equal(firstTeamPlayers[0].name);
chai_1.expect(firstFirstTeamPlayer.tossups_heard).to.equal(6);
chai_1.expect(firstFirstTeamPlayer.answer_counts.length).to.equal(1);
chai_1.expect(firstFirstTeamPlayer.answer_counts[0]).to.deep.equal({
number: 1,
answer: {
value: 10,
},
});
const lastFirstTeamPlayer = match.match_teams[0].match_players[2];
chai_1.expect(lastFirstTeamPlayer.tossups_heard).to.equal(0);
chai_1.expect(lastFirstTeamPlayer.player.name).to.equal(firstTeamPlayers[2].name);
chai_1.expect(match.match_teams[1].match_players.length).to.equal(1);
const secondPlayer = match.match_teams[1].match_players[0];
chai_1.expect(secondPlayer.player.name).to.equal(secondTeamPlayer.name);
chai_1.expect(secondPlayer.tossups_heard).to.equal(6);
// expect(secondPlayer.answer_counts.length).to.equal(4);
chai_1.expect(secondPlayer.answer_counts).to.deep.equal([
{
number: 1,
answer: {
value: -5,
},
},
{
number: 1,
answer: {
value: 0,
},
},
{
number: 1,
answer: {
value: 10,
},
},
{
number: 2,
answer: {
value: 15,
},
},
]);
});
});
it("Tossup protest", () => {
const firstProtestReason = "First protest";
const firstProtestAnswer = "First answer";
const secondProtestReason = "Second protest";
const secondProtestAnswer = "Second answer";
verifyToQBJ((game) => {
game.cycles[0].addWrongBuzz({
player: firstTeamPlayers[0],
points: -5,
position: 0,
isLastWord: false,
}, 0, game.gameFormat);
game.cycles[0].addTossupProtest(firstTeamPlayers[0].teamName, 0, 0, firstProtestAnswer, firstProtestReason);
game.cycles[1].addWrongBuzz({
player: secondTeamPlayer,
points: 0,
position: 1,
isLastWord: true,
}, 1, game.gameFormat);
game.cycles[1].addTossupProtest(secondTeamPlayer.teamName, 1, 1, secondProtestAnswer, secondProtestReason);
}, (match) => {
chai_1.expect(match.tossups_read).to.equal(4);
chai_1.expect(match.match_questions.map((q) => q.question_number)).to.deep.equal([1, 2, 3, 4]);
if (match.notes == undefined) {
chai_1.assert.fail("match.notes should be defined.");
}
const lines = match.notes.split("\n");
chai_1.expect(lines.length).to.equal(2);
chai_1.expect(lines[0]).to.equal(`Tossup protest on question 1. Team "${firstTeamPlayers[0].teamName}" protested because of this reason: "${firstProtestReason}".`);
chai_1.expect(lines[1]).to.equal(`Tossup protest on question 2. Team "${secondTeamPlayer.teamName}" protested because of this reason: "${secondProtestReason}".`);
});
});
it("Bonus protest", () => {
const firstProtestReason = "First protest";
const firstProtestAnswer = "First answer";
const secondProtestReason = "Second protest";
const secondProtestAnswer = "Second answer";
verifyToQBJ((game) => {
game.cycles[0].addCorrectBuzz({
player: firstTeamPlayers[0],
points: 10,
position: 0,
isLastWord: false,
}, 0, game.gameFormat, 0, 3);
game.cycles[0].addBonusProtest(0, 0, firstProtestAnswer, firstProtestReason, firstTeamPlayers[0].teamName);
game.cycles[1].addCorrectBuzz({
player: firstTeamPlayers[0],
points: 10,
position: 1,
isLastWord: true,
}, 1, game.gameFormat, 1, 3);
game.cycles[1].setBonusPartAnswer(2, firstTeamPlayers[0].teamName, 10);
game.cycles[1].addBonusProtest(1, 2, secondProtestAnswer, secondProtestReason, secondTeamPlayer.teamName);
}, (match) => {
chai_1.expect(match.tossups_read).to.equal(4);
chai_1.expect(match.match_questions.map((q) => q.question_number)).to.deep.equal([1, 2, 3, 4]);
if (match.notes == undefined) {
chai_1.assert.fail("match.notes should be defined.");
}
const lines = match.notes.split("\n");
chai_1.expect(lines.length).to.equal(2);
chai_1.expect(lines[0]).to.equal(`Bonus protest on question 1. Team "${firstTeamPlayers[0].teamName}" protested part 1 because of this reason: "${firstProtestReason}".`);
chai_1.expect(lines[1]).to.equal(`Bonus protest on question 2. Team "${secondTeamPlayer.teamName}" protested part 3 because of this reason: "${secondProtestReason}".`);
});
});
it("Thrown out tossup", () => {
verifyToQBJ((game) => {
game.cycles[0].addThrownOutTossup(0);
game.cycles[0].addCorrectBuzz({
player: firstTeamPlayers[0],
points: 10,
position: 1,
isLastWord: true,
}, 1, game.gameFormat, 0, 3);
}, (match) => {
chai_1.expect(match.tossups_read).to.equal(4);
chai_1.expect(match.match_questions.map((q) => q.question_number)).to.deep.equal([1, 2, 3, 4]);
if (match.notes == undefined) {
chai_1.assert.fail("match.notes should be defined.");
}
const lines = match.notes.split("\n");
chai_1.expect(lines.length).to.equal(1);
chai_1.expect(lines[0]).to.equal("Tossup thrown out on question 1");
const replacementTossup = match.match_questions[0].replacement_tossup_question;
if (replacementTossup == undefined) {
chai_1.ass