diff --git a/src/Questions.ts b/src/Questions.ts index 2c3f6d052..0ebfd50dc 100644 --- a/src/Questions.ts +++ b/src/Questions.ts @@ -1,57 +1,70 @@ -enum Category { +enum BaseCategory { POP = 'Pop', SCIENCE = 'Science', SPORTS = 'Sports', ROCK = 'Rock', } +type ExtendedCategories = BaseCategory | string; +type CategorySelector = (magicNumber: number) => boolean +type SelectCategoryRules = Record; + +type Props = { + extraCategoryRules?: SelectCategoryRules; +}; + export class Questions { - private questions: Record> = { + private DEFAULT_CATEGORY = BaseCategory.ROCK; + + private categorySelectionRules: SelectCategoryRules = { + [BaseCategory.POP]: (magicNumber) => [0, 4, 8].includes(magicNumber), + [BaseCategory.SCIENCE]: (magicNumber) => [1, 5, 9].includes(magicNumber), + [BaseCategory.SPORTS]: (magicNumber) => [2, 6, 10].includes(magicNumber), + } + + private questions: Record = { Pop: [], Rock: [], Science: [], Sports: [] } - constructor() { + constructor({ extraCategoryRules }: Props = {}) { + if (extraCategoryRules) { + Object.entries(extraCategoryRules).forEach(([category, selectionRule]) => { + this.categorySelectionRules[category as ExtendedCategories] = selectionRule; + this.questions[category as ExtendedCategories] = []; + }) + } + for (let i = 0; i < 50; i++) { Object.keys(this.questions).forEach((category) => { - this.questions[category as Category].push(category + " Question " + i) + this.questions[category as BaseCategory].push(category + " Question " + i) }); } } - public askOne(magicNumber: number): void { - const question = this.chooseOne(magicNumber); - - console.log(question); - } - - private chooseOne(magicNumber: number): string { + public chooseOne(magicNumber: number): string { const currentCategoryQuestions = this.currentCategoryQuestions(magicNumber); return currentCategoryQuestions.shift()!; } - private currentCategoryQuestions(magicNumber: number): string[] { - const category = this.currentCategory(magicNumber); + public currentCategory(magicNumber: number): ExtendedCategories { + for (const entries of Object.entries(this.categorySelectionRules)) { + const [category, shouldBeSelected] = entries; - return this.questions[category]; - } - - public currentCategory(magicNumber: number): Category { - if ([0, 4, 8].includes(magicNumber)) { - return Category.POP; + if (shouldBeSelected(magicNumber)) { + return category; + } } - if ([1, 5, 9].includes(magicNumber)) { - return Category.SCIENCE; - } + return this.DEFAULT_CATEGORY; + } - if ([2, 6, 10].includes(magicNumber)) { - return Category.SPORTS; - } + private currentCategoryQuestions(magicNumber: number): string[] { + const category = this.currentCategory(magicNumber); - return Category.ROCK; + return this.questions[category]; } } diff --git a/src/game.ts b/src/game.ts index c2de66607..0f7b5ef15 100644 --- a/src/game.ts +++ b/src/game.ts @@ -91,7 +91,13 @@ export class Game implements AnyGame { console.log(this.currentPlayer.name + "'s new location is " + this.currentPlayer.place); console.log("The category is " + this.questions.currentCategory(this.currentPlayer.place)); - this.questions.askOne(this.currentPlayer.place); + this.askQuestion(); + } + + private askQuestion() { + const question = this.questions.chooseOne(this.currentPlayer.place); + + console.log(question); } private handleCorrectAnswer(): boolean { diff --git a/tests/questions.test.ts b/tests/questions.test.ts new file mode 100644 index 000000000..45a01e54c --- /dev/null +++ b/tests/questions.test.ts @@ -0,0 +1,51 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { Questions } from '../src/Questions'; + +describe("Questions", () => { + describe("Categories", () => { + let selectedQuestions: string[]; + + beforeEach(() => { + selectedQuestions = []; + }) + + it("have a default set", () => { + const questions = new Questions(); + + selectedQuestions.push(questions.chooseOne(0)); + selectedQuestions.push(questions.chooseOne(1)); + selectedQuestions.push(questions.chooseOne(2)); + selectedQuestions.push(questions.chooseOne(3)); + + expect(selectedQuestions.join('')).to.equal( + 'Pop Question 0' + + 'Science Question 0' + + 'Sports Question 0' + + 'Rock Question 0' + ); + }) + + it("can be extended", () => { + const questions = new Questions({ + extraCategoryRules: { + Geography: (magicNumber: number) => [3, 7].includes(magicNumber) + } + }); + + selectedQuestions.push(questions.chooseOne(0)); + selectedQuestions.push(questions.chooseOne(1)); + selectedQuestions.push(questions.chooseOne(2)); + selectedQuestions.push(questions.chooseOne(3)); + selectedQuestions.push(questions.chooseOne(123)); + + expect(selectedQuestions.join('')).to.equal( + 'Pop Question 0' + + 'Science Question 0' + + 'Sports Question 0' + + 'Geography Question 0' + + 'Rock Question 0' + ); + }) + }) +});