@kakegurui/shuffle
Version:
Shuffle utilities for Kakegurui Games
1 lines • 5.4 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Performs a simple shuffle using the Fisher-Yates algorithm.\n * @param array Array of elements to shuffle.\n * @returns The given array, which has also been modified in place.\n */\nexport function shuffle<T>(array: T[]): T[] {\n for (let i = array.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1)); // Generate a random index from 0 to i\n // Swap elements at indices i and j in-place\n [array[i], array[j]] = [array[j], array[i]];\n }\n\n return array;\n}\n\n/**\n * Gets a random number within the given range.\n * @param start The start range.\n * @param end The end range (inclusive).\n * @returns A random number within the given range.\n */\nexport function randomNumber(start: number, end: number): number {\n // Check if start and end are valid\n if (start > end) {\n throw new Error('Start value cannot be greater than end value.');\n }\n\n // Generate a random number within the range\n return Math.floor(Math.random() * (end - start + 1)) + start;\n}\n\n/**\n * Performs a riffle shuffle to combine two decks.\n * @param deck1 The first deck\n * @param deck2 The second deck\n * @returns The two decks combined with a riffle shuffle.\n */\nexport function riffleShuffle<T>(deck1: T[], deck2: T[]): T[] {\n const shuffledDeck: T[] = [];\n let deck1Index = 0;\n let deck2Index = 0;\n\n while (deck1Index < deck1.length && deck2Index < deck2.length) {\n // Randomly choose whether to take a card from deck1 or from deck2\n if (Math.random() < 0.5) {\n shuffledDeck.push(deck1[deck1Index]);\n deck1Index++;\n } else {\n shuffledDeck.push(deck2[deck2Index]);\n deck2Index++;\n }\n }\n\n // Add any remaining cards from deck1 or deck2\n while (deck1Index < deck1.length) {\n shuffledDeck.push(deck1[deck1Index]);\n deck1Index++;\n }\n\n while (deck2Index < deck2.length) {\n shuffledDeck.push(deck2[deck2Index]);\n deck2Index++;\n }\n\n return shuffledDeck;\n}\n\n/**\n * Deals the specified number of cards onto a seperate pile.\n * From top to bottom, hence the new pile will be in reverse.\n * @param cards Deck of cards.\n * @param numCards Number of cards to deal, must not exceed cards.length\n * @returns A new pile containing the dealt cards, the original array has also been modified and the cards have been removed.\n */\nexport function deal<T>(cards: T[], numCards: number): T[] {\n if (numCards > cards.length) {\n throw new Error('Not enough cards to deal.');\n }\n\n // Deal off a specified number of cards into a second pile, reversing them\n const pile = [];\n\n for (let i = 0; i < numCards; i++) {\n pile.unshift(cards.shift()!); // Unshift to add to beginning and reverse\n }\n\n return pile;\n}\n\n/**\n * Shuffles a deck by cutting it by the specified amount of times.\n * @param cards Deck of cards.\n * @param cuts How many times to cut.\n * @returns The deck shuffled by cutting the specified number of times, the array is also modified in place.\n */\nexport function cutDeck<T>(cards: T[], cuts: number): T[] {\n // Cut the deck a few times\n for (let i = 0; i < cuts; i++) {\n const cutPoint = Math.floor(Math.random() * cards.length);\n const top = cards.slice(0, cutPoint);\n const bottom = cards.slice(cutPoint);\n cards = bottom.concat(top);\n }\n\n return cards;\n}\n\n/**\n * Performs a Gilbreath shuffle as seen in Nim Type Zero in Kakegurui XX.\n * @param cards Deck of cards\n * @param split How many cards should be dealt onto a separate pile.\n * @returns The pile of cards, dealt into two piles and riffle shuffled. The array is also modified in place.\n */\nexport function gilbreathShuffle<T>(cards: T[], split: number) {\n const pile = deal(cards, split);\n return riffleShuffle(pile, cards);\n}\n"],"mappings":";;;;AAKO,SAAS,QAAW,OAAiB;AACxC,WAAS,IAAI,MAAM,SAAS,GAAG,IAAI,GAAG,KAAK;AACvC,UAAM,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,EAAE;AAE5C,KAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAAA,EAC9C;AAEA,SAAO;AACX;AARgB;AAgBT,SAAS,aAAa,OAAe,KAAqB;AAE7D,MAAI,QAAQ,KAAK;AACb,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACnE;AAGA,SAAO,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,QAAQ,EAAE,IAAI;AAC3D;AARgB;AAgBT,SAAS,cAAiB,OAAY,OAAiB;AAC1D,QAAM,eAAoB,CAAC;AAC3B,MAAI,aAAa;AACjB,MAAI,aAAa;AAEjB,SAAO,aAAa,MAAM,UAAU,aAAa,MAAM,QAAQ;AAE3D,QAAI,KAAK,OAAO,IAAI,KAAK;AACrB,mBAAa,KAAK,MAAM,UAAU,CAAC;AACnC;AAAA,IACJ,OAAO;AACH,mBAAa,KAAK,MAAM,UAAU,CAAC;AACnC;AAAA,IACJ;AAAA,EACJ;AAGA,SAAO,aAAa,MAAM,QAAQ;AAC9B,iBAAa,KAAK,MAAM,UAAU,CAAC;AACnC;AAAA,EACJ;AAEA,SAAO,aAAa,MAAM,QAAQ;AAC9B,iBAAa,KAAK,MAAM,UAAU,CAAC;AACnC;AAAA,EACJ;AAEA,SAAO;AACX;AA5BgB;AAqCT,SAAS,KAAQ,OAAY,UAAuB;AACvD,MAAI,WAAW,MAAM,QAAQ;AACzB,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC/C;AAGA,QAAM,OAAO,CAAC;AAEd,WAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AAC/B,SAAK,QAAQ,MAAM,MAAM,CAAE;AAAA,EAC/B;AAEA,SAAO;AACX;AAbgB;AAqBT,SAAS,QAAW,OAAY,MAAmB;AAEtD,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC3B,UAAM,WAAW,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM;AACxD,UAAM,MAAM,MAAM,MAAM,GAAG,QAAQ;AACnC,UAAM,SAAS,MAAM,MAAM,QAAQ;AACnC,YAAQ,OAAO,OAAO,GAAG;AAAA,EAC7B;AAEA,SAAO;AACX;AAVgB;AAkBT,SAAS,iBAAoB,OAAY,OAAe;AAC3D,QAAM,OAAO,KAAK,OAAO,KAAK;AAC9B,SAAO,cAAc,MAAM,KAAK;AACpC;AAHgB;","names":[]}