Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added feature to select different numbers of questions #56

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
70 changes: 70 additions & 0 deletions extension/src/components/buttons/RoomSettingsButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ export default function RoomSettingsButton() {
setRoomSettings
}
/>
<NumberOfQuestionsSelector
roomSettings={roomSettings}
setRoomSettings={
setRoomSettings
}
/>
<button
onClick={closeModal}
className="rounded-lg bg-lc-fg-modal-light px-3 py-1.5 text-sm font-medium text-lc-text-light transition-all hover:bg-lc-fg-modal-hover-light dark:bg-lc-fg-modal dark:text-white dark:hover:bg-lc-fg-modal-hover"
Expand Down Expand Up @@ -463,3 +469,67 @@ function DurationSelector({
</div>
);
}

function NumberOfQuestionsSelector({
roomSettings,
setRoomSettings,
}: {
roomSettings: RoomSettings;
setRoomSettings: (roomSettings: RoomSettings) => void;
}) {
function handleIncrement() {
if (roomSettings.numberOfQuestions >= 8) {
return;
}
setRoomSettings({
...roomSettings,
duration: roomSettings.numberOfQuestions + 1,
});
}

function handleDecrement() {
if (roomSettings.numberOfQuestions <= 1) {
return;
}
setRoomSettings({
...roomSettings,
duration: roomSettings.numberOfQuestions - 1,
});
}

return (
<div className="flex grow flex-row items-stretch">
<div className="flex flex-row items-center gap-1 rounded-l-lg bg-lc-fg-modal-light py-1.5 pl-2 pr-2 text-xs font-medium text-lc-text-light transition-all dark:bg-lc-fg-modal dark:text-white">
<div
className={`w-[31px] text-center ${
roomSettings.numberOfQuestions ? "text-inherit" : "text-sm"
}`}
>
{roomSettings.numberOfQuestions}
</div>
</div>
<div className="flex flex-col rounded-r-md bg-lc-fg-modal-hover">
<button
onClick={handleIncrement}
className={
!roomSettings.numberOfQuestions
? "cursor-not-allowed rounded-tl-md"
: "cursor-pointer rounded-tr-md bg-[hsl(180,9%,84%)] transition-all hover:bg-[hsl(180,9%,78%)] dark:bg-[hsl(0,0%,38%)] dark:hover:bg-lc-fg-modal-hover"
}
>
<ChevronIcon />
</button>
<button
onClick={handleDecrement}
className={
roomSettings.numberOfQuestions && roomSettings.numberOfQuestions <= 15
? `rotate-180 cursor-not-allowed rounded-tl-md`
: `rotate-180 cursor-pointer rounded-tl-md bg-[hsl(180,9%,84%)] transition-all hover:bg-[hsl(180,9%,78%)] dark:bg-[hsl(0,0%,38%)] dark:hover:bg-lc-fg-modal-hover`
}
>
<ChevronIcon />
</button>
</div>
</div>
);
}
2 changes: 2 additions & 0 deletions extension/src/types/RoomSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export interface RoomSettings {
questionFilter: QuestionFilter;
duration?: number | null;
difficulty: RoomDifficulty;
numberOfQuestions: number;
}

export interface RoomDifficulty {
Expand Down Expand Up @@ -104,4 +105,5 @@ export const defaultRoomSettings: RoomSettings = {
Medium: true,
Hard: true,
},
numberOfQuestions: 4,
};
63 changes: 48 additions & 15 deletions server/src/api/rooms/rooms.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ export async function createRoom(
roomSettings.difficulty,
easyQuestions,
mediumQuestions,
hardQuestions
hardQuestions,
roomSettings.numberOfQuestions,
);

// Select 4 random questions
// Select random questions
let randomlySelectedEasyQuestions: Question[] = easyQuestions
.sort(() => Math.random() - 0.5)
.slice(0, numberOfEasy);
Expand Down Expand Up @@ -405,14 +406,16 @@ function getNumberOfQuestionsPerDifficulty(
roomDifficulty: RoomDifficulty,
easyQuestions: Question[],
mediumQuestions: Question[],
hardQuestions: Question[]
hardQuestions: Question[],
totalQuestions: number,
): RoomDifficultyNumberOfQuestions {
let { Easy: easy, Medium: medium, Hard: hard } = roomDifficulty;
if (easy && medium && hard) {
let distributions = getDistribution([3, 5, 3], totalQuestions);
let numberOfQuestions = {
Easy: 1,
Medium: 2,
Hard: 1,
Easy: distributions[0],
Medium: distributions[1],
Hard: distributions[2],
};

// If there are not enough easy questions, get more medium or hard questions.
Expand Down Expand Up @@ -453,9 +456,10 @@ function getNumberOfQuestionsPerDifficulty(

return numberOfQuestions;
} else if (easy && medium) {
let distributions = getDistribution([5, 5, 0], totalQuestions);
let numberOfQuestions = {
Easy: 2,
Medium: 2,
Easy: distributions[0],
Medium: distributions[1],
Hard: 0,
};

Expand All @@ -477,10 +481,11 @@ function getNumberOfQuestionsPerDifficulty(

return numberOfQuestions;
} else if (easy && hard) {
let distributions = getDistribution([5, 0, 5], totalQuestions);
let numberOfQuestions = {
Easy: 2,
Easy: distributions[0],
Medium: 0,
Hard: 2,
Hard: distributions[2],
};

if (easyQuestions.length < numberOfQuestions.Easy) {
Expand All @@ -501,10 +506,11 @@ function getNumberOfQuestionsPerDifficulty(

return numberOfQuestions;
} else if (medium && hard) {
let distribution = getDistribution([0, 6, 4], totalQuestions);
let numberOfQuestions = {
Easy: 0,
Medium: 2,
Hard: 2,
Medium: distribution[1],
Hard: distribution[2],
};

if (mediumQuestions.length < numberOfQuestions.Medium) {
Expand All @@ -526,21 +532,21 @@ function getNumberOfQuestionsPerDifficulty(
return numberOfQuestions;
} else if (easy) {
return {
Easy: 4,
Easy: totalQuestions,
Medium: 0,
Hard: 0,
};
} else if (medium) {
return {
Easy: 0,
Medium: 4,
Medium: totalQuestions,
Hard: 0,
};
} else if (hard) {
return {
Easy: 0,
Medium: 0,
Hard: 4,
Hard: totalQuestions,
};
}
return {
Expand All @@ -549,3 +555,30 @@ function getNumberOfQuestionsPerDifficulty(
Hard: 0,
};
}

function weightedRandomizer(
weights: number[]
): number {
const totalWeight = weights.reduce((acc, weight) => acc + weight, 0);
const randomValue = Math.random() * totalWeight;
let cumulativeWeight = 0;

for (let i = 0; i < weights.length; i++) {
cumulativeWeight += weights[i];
if (randomValue < cumulativeWeight) {
return i;
}
}
return 0;
}

function getDistribution(
weights: number[],
totalQuestions: number,
): number[] {
var distributions = [0, 0, 0];
for (let i = 0; i < totalQuestions; i++) {
distributions[weightedRandomizer(weights)] += 1;
}
return distributions;
}
2 changes: 2 additions & 0 deletions server/src/types/RoomSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export interface RoomSettings {
questionFilter: QuestionFilter;
duration?: number | null;
difficulty: RoomDifficulty;
numberOfQuestions: number;
}

export interface RoomDifficulty {
Expand Down Expand Up @@ -110,4 +111,5 @@ export const defaultRoomSettings: RoomSettings = {
Medium: true,
Hard: true,
},
numberOfQuestions: 4,
};