Created
March 1, 2024 18:43
-
-
Save waprin/a5eae8a90c1847c6bdfad914a934e286 to your computer and use it in GitHub Desktop.
hacky live poker "spaced rep"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function shuffleArray(array) { | |
for (let i = array.length - 1; i > 0; i--) { | |
const j = Math.floor(Math.random() * (i + 1)); | |
[array[i], array[j]] = [array[j], array[i]]; // swap elements | |
} | |
} | |
function getRandomQuestions(questions, num=20) { | |
num = Math.min(num, questions.length); | |
shuffleArray(questions); | |
return questions.slice(0, num); | |
} | |
// Example usage | |
const allQuestions = [/* your big list of questions here */]; | |
const randomQuestions = getRandomQuestions(allQuestions); | |
export type Deck = { | |
questions: any[], | |
} | |
export type UserDeck = { | |
questions: any[] | |
} | |
// deck -> basically set if there is no history of user data, so just get random questions | |
// UserDeck -> has flashcard deck with user "grades" on each question | |
export const buildSessionQuestions = (deck : Deck, userDeckData : UserDeck, numQuestions : number) => { | |
if (!userDeckData) { // random mode | |
let sessionQuestions = [] | |
let deckQuestions = getRandomQuestions(deck.questions, numQuestions) | |
for (let question of deckQuestions) { | |
let sessionQuestion = { | |
...question, | |
"correct": null, | |
"response": null, | |
"acknowledged": false, | |
} | |
sessionQuestions.push(sessionQuestion) | |
} | |
return sessionQuestions | |
} else { | |
const questions = userDeckData.questions | |
let sessionQuestions = [] | |
let numEasy = numQuestions == 10 ? 2 : 4 | |
let easyQuestions = questions.filter( (question) => (question.grade > 2) ) | |
let mediumQuestions = questions.filter( (question) => (question.grade == 1 || question.grade == 2) ) | |
let hardQuestions = questions.filter( (question) => (question.grade == 0 ) && question.lastReviewed > 0 ) | |
shuffleArray(easyQuestions) | |
shuffleArray(mediumQuestions) | |
shuffleArray(hardQuestions) | |
// get numEasy questions from easyQuestions | |
let easySessionQuestions = easyQuestions.slice(0, Math.min(numEasy, easyQuestions.length)) | |
for (let question of easySessionQuestions) { | |
let sessionQuestion = { | |
...question, | |
"correct": null, | |
"response": null, | |
"acknowledged": false, | |
} | |
sessionQuestions.push(sessionQuestion) | |
} | |
// console.log("after easy questions got ", sessionQuestions.length, " questions") | |
let defaultNumMedium = numQuestions == 10 ? 4 : 8 | |
let numMedium = Math.max(defaultNumMedium, defaultNumMedium + (numEasy - sessionQuestions.length)) | |
// get numMedium questions from mediumQuestions | |
let mediumSessionQuestions = mediumQuestions.slice(0, Math.min(numMedium, mediumQuestions.length)) | |
for (let question of mediumSessionQuestions) { | |
let sessionQuestion = { | |
...question, | |
"correct": null, | |
"response": null, | |
"acknowledged": false, | |
} | |
sessionQuestions.push(sessionQuestion) | |
} | |
// console.log("after medium questions got ", sessionQuestions.length, " questions") | |
// get numHard questions from hardQuestions | |
let numHard = numQuestions - (sessionQuestions.length) | |
let hardSessionQuestions = hardQuestions.slice(0, Math.min(numHard, hardQuestions.length)) | |
// console.log("numHard", numHard, hardSessionQuestions.length) | |
for (let question of hardSessionQuestions) { | |
let sessionQuestion = { | |
...question, | |
"correct": null, | |
"response": null, | |
"acknowledged": false, | |
} | |
sessionQuestions.push(sessionQuestion) | |
} | |
console.log("after hard questions got ", sessionQuestions.length, " questions") | |
if (sessionQuestions.length < numQuestions) { | |
let remainingQuestions = questions.filter( (question) => (question.lastReviewed == 0 )) | |
shuffleArray(remainingQuestions) | |
let remainingSessionQuestions = remainingQuestions.slice(0, numQuestions - sessionQuestions.length) | |
for (let question of remainingSessionQuestions) { | |
console.log("adding new question", question) | |
let sessionQuestion = { | |
...question, | |
"correct": null, | |
"response": null, | |
"acknowledged": false, | |
} | |
sessionQuestions.push(sessionQuestion) | |
} | |
} | |
console.log("after all additions got ", sessionQuestions.length, " questions") | |
// if there are not enough unreviewed questions to fill the session, fill the rest with reviewed questions | |
// TODO: should probably prefer medium questions to hard here | |
while (sessionQuestions.length < numQuestions) { | |
// console.log("adding reviewed question") | |
let randomQuestions = questions | |
// generate random question from deck | |
let deckQuestionIndex = Math.floor(Math.random() * randomQuestions.length) | |
let deckQuestion = randomQuestions[deckQuestionIndex] | |
// dont add thsi question if sessionQuestions already has it | |
let found = false | |
for (let question of sessionQuestions) { | |
if (question.hand == deckQuestion.hand && question.position == deckQuestion.position) { | |
found = true | |
break | |
} | |
} | |
if (found) { | |
continue | |
} | |
sessionQuestions.push(deckQuestion) | |
} | |
return sessionQuestions | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment