mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-29 22:58:18 -05:00
Map list algorithm better mode picking
Don't repeat a mode before other modes have appeared in the round
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Stage } from ".prisma/client";
|
||||
import type { Mode, Stage } from ".prisma/client";
|
||||
import clone from "just-clone";
|
||||
import { suite } from "uvu";
|
||||
import * as assert from "uvu/assert";
|
||||
@@ -8,6 +8,7 @@ import { generateMapListForRounds } from "./mapList";
|
||||
|
||||
const MapListForRounds = suite("generateMapListMapForRounds()");
|
||||
|
||||
const ALL_MODES_LENGTH = 4;
|
||||
const mapPool: Stage[] = JSON.parse(
|
||||
`[{"id":923,"mode":"TC","name":"The Reef"},{"id":925,"mode":"CB","name":"The Reef"},{"id":927,"mode":"SZ","name":"Musselforge Fitness"},{"id":929,"mode":"RM","name":"Musselforge Fitness"},{"id":934,"mode":"RM","name":"Starfish Mainstage"},{"id":942,"mode":"SZ","name":"Inkblot Art Academy"},{"id":943,"mode":"TC","name":"Inkblot Art Academy"},{"id":947,"mode":"SZ","name":"Sturgeon Shipyard"},{"id":948,"mode":"TC","name":"Sturgeon Shipyard"},{"id":953,"mode":"TC","name":"Moray Towers"},{"id":959,"mode":"RM","name":"Port Mackerel"},{"id":960,"mode":"CB","name":"Port Mackerel"},{"id":972,"mode":"SZ","name":"Snapper Canal"},{"id":978,"mode":"TC","name":"Blackbelly Skatepark"},{"id":980,"mode":"CB","name":"Blackbelly Skatepark"},{"id":985,"mode":"CB","name":"MakoMart"},{"id":987,"mode":"SZ","name":"Walleye Warehouse"},{"id":988,"mode":"TC","name":"Walleye Warehouse"},{"id":994,"mode":"RM","name":"Shellendorf Institute"},{"id":995,"mode":"CB","name":"Shellendorf Institute"},{"id":1007,"mode":"SZ","name":"Piranha Pit"},{"id":1012,"mode":"SZ","name":"Camp Triggerfish"},{"id":1019,"mode":"RM","name":"Wahoo World"},{"id":1020,"mode":"CB","name":"Wahoo World"},{"id":1027,"mode":"SZ","name":"Ancho-V Games"},{"id":1034,"mode":"RM","name":"Skipper Pavilion"}]`
|
||||
);
|
||||
@@ -42,4 +43,25 @@ MapListForRounds("Should have all the map and mode combos", () => {
|
||||
assert.equal(mapPoolToEmpty.length, 0);
|
||||
});
|
||||
|
||||
MapListForRounds(
|
||||
"Should not repeat mode (except SZ) in a round before other modes have appeared",
|
||||
() => {
|
||||
for (const side of [mapList.winners, mapList.losers]) {
|
||||
for (const round of side) {
|
||||
const modes: Mode[] = [];
|
||||
for (const stage of round) {
|
||||
if (
|
||||
modes.includes(stage.mode) &&
|
||||
modes.length < ALL_MODES_LENGTH &&
|
||||
stage.mode !== "SZ"
|
||||
) {
|
||||
throw new Error(`Repeated mode: ${JSON.stringify(round, null, 2)}`);
|
||||
}
|
||||
modes.push(stage.mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
MapListForRounds.run();
|
||||
|
||||
@@ -27,6 +27,7 @@ export function generateMapListForRounds({
|
||||
}, []);
|
||||
let currentModes = clone(modes);
|
||||
const hasSZ = mapPool.some((stage) => stage.mode === "SZ");
|
||||
const allModesLength = modes.length + Number(hasSZ);
|
||||
|
||||
return {
|
||||
winners: rounds.winners.map((round) => roundsMapList(round)),
|
||||
@@ -81,8 +82,18 @@ export function generateMapListForRounds({
|
||||
resetCurrentModesIfWouldHaveToRepeatMode(previous);
|
||||
currentModes = shuffle(currentModes);
|
||||
currentModes.sort((a, b) => {
|
||||
if (previous && previous === a[0]) return 1;
|
||||
if (previous && previous === b[0]) return -1;
|
||||
// Don't repeat a mode before all the modes have appeared in a round
|
||||
const modesOfTheRound = Array.from(new Set(resultWithNoNull));
|
||||
if (modesOfTheRound.length < allModesLength) {
|
||||
if (
|
||||
modesOfTheRound.includes(a[0]) &&
|
||||
modesOfTheRound.includes(b[0])
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
if (modesOfTheRound.includes(b[0])) return -1;
|
||||
if (modesOfTheRound.includes(a[0])) return 1;
|
||||
}
|
||||
|
||||
return b[1] - a[1];
|
||||
});
|
||||
@@ -171,7 +182,7 @@ export function generateMapListForRounds({
|
||||
!stagesAlreadyIncludedThisRound.includes(mapPoolMap.name)
|
||||
);
|
||||
|
||||
// TODO: handle this smarter
|
||||
// TODO: handle this fallback behavior smarter
|
||||
if (!stage) {
|
||||
stage = stages.find((mapPoolMap) => mapPoolMap.modes.includes(mode));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user