mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-12-24 02:29:25 +01:00
[Bug] Fix evil team admin randomization (#6830)
This commit is contained in:
parent
8f4243853d
commit
e8b1d0fd71
@ -12,7 +12,7 @@
|
||||
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import type { Mutable } from "#types/type-helpers";
|
||||
import { randSeedItem } from "#utils/common";
|
||||
import { randSeedItem, randSeedShuffle } from "#utils/common";
|
||||
|
||||
/**
|
||||
* Select a random element using an offset such that the chosen element is
|
||||
@ -21,9 +21,10 @@ import { randSeedItem } from "#utils/common";
|
||||
* @remarks
|
||||
* If the seed offset is greater than the number of choices, this will just choose a random element
|
||||
*
|
||||
* @param arr - The array of items to choose from
|
||||
* @param choices - The array of items to choose from
|
||||
* @param seedOffset - The offset into the array
|
||||
* @param scene - (default {@linkcode globalScene}); The scene to use for random seeding
|
||||
* @returns A random item from the array that is guaranteed to be different from the
|
||||
* @returns A random item from the array that is guaranteed to be different from the previous result
|
||||
* @typeParam T - The type of items in the array
|
||||
*
|
||||
* @example
|
||||
@ -38,8 +39,7 @@ import { randSeedItem } from "#utils/common";
|
||||
* ```
|
||||
*/
|
||||
export function randSeedUniqueItem<T>(choices: readonly T[], seedOffset: number, scene = globalScene): T {
|
||||
if (seedOffset === 0 || choices.length <= seedOffset) {
|
||||
// cast to mutable is safe because randSeedItem does not actually modify the array
|
||||
if (choices.length <= seedOffset) {
|
||||
return randSeedItem(choices as Mutable<typeof choices>);
|
||||
}
|
||||
|
||||
@ -47,14 +47,7 @@ export function randSeedUniqueItem<T>(choices: readonly T[], seedOffset: number,
|
||||
let choice: T;
|
||||
|
||||
scene.executeWithSeedOffset(() => {
|
||||
const curChoices = choices.slice();
|
||||
for (let i = 0; i < seedOffset; i++) {
|
||||
const previousChoice = randSeedItem(curChoices);
|
||||
curChoices.splice(curChoices.indexOf(previousChoice), 1);
|
||||
}
|
||||
choice = randSeedItem(curChoices);
|
||||
}, seedOffset);
|
||||
|
||||
// Bang is safe since there are at least `seedOffset` choices, so the method above is guaranteed to set `choice`
|
||||
choice = randSeedShuffle(choices.slice())[seedOffset];
|
||||
}, 0);
|
||||
return choice!;
|
||||
}
|
||||
|
||||
51
test/utils/random.test.ts
Normal file
51
test/utils/random.test.ts
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Pagefault Games
|
||||
* SPDX-FileContributor: SirzBenjie
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { GameManager } from "#test/test-utils/game-manager";
|
||||
import { randSeedUniqueItem } from "#utils/random";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
describe("Utils - Random", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
describe("randSeedUniqueItem", () => {
|
||||
// TODO: Remove `initialization of game` once `randSeedUniqueItem` stops using `executeWithSeedOffset`
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
});
|
||||
|
||||
it("should prevent duplicates when provided with different offsets", async () => {
|
||||
const choices = ["a", "b", "c", "d"];
|
||||
const choice1 = randSeedUniqueItem(choices, 0);
|
||||
const choice2 = randSeedUniqueItem(choices, 1);
|
||||
const choice3 = randSeedUniqueItem(choices, 2);
|
||||
expect(choice2).not.toEqual(choice1);
|
||||
expect(choice2).not.toEqual(choice3);
|
||||
expect(choice1).not.toEqual(choice3);
|
||||
});
|
||||
|
||||
it("should gracefully handle an offset larger than the choices", () => {
|
||||
const choices = ["a", "b", "c"];
|
||||
// 1) the function must not throw
|
||||
// 2) The output must be one of the choices
|
||||
const choice = randSeedUniqueItem(choices, 5);
|
||||
expect(choices).toContain(choice);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user