sendou.ink/app/modules/map-pool-serializer/map-pool.ts
Kalle 5e36b76ee8
TO Tools back (#1349)
* Remove friend code

* Revive TO Tools admin page

* Revive TO Tools maps page

* Initial one mode only map list

* Add modesIncluded arg

* Handle no maps picked for SZ only generation

* Tiebreaker is always from the maps of the teams

* Make modesIncluded necessary arg

* Tiebreaker is from neither team's pool if no overlap

* Handles worst case duplication

* Handles one team submitted no maps test

* Fix crash

* Seed

* Can change one mode tournament map pool

* Fix join page link

* Remove useless TODO

* Fixes related to mapListGeneratorAvailable

* Fix map list generation considering impossible map lists making it take forever

* Show unlisted select for both sides

* Add info texts

* Remove register button

* Add todos

* Finished version for ITZ

* Times

* Remove TODOs

* 23->24
2023-04-22 11:44:20 +03:00

164 lines
3.7 KiB
TypeScript

import {
mapPoolToSerializedString,
serializedStringToMapPool,
} from "./serializer";
import type { ReadonlyMapPoolObject, MapPoolObject } from "./types";
import clone from "just-clone";
import type { MapPoolMap } from "~/db/types";
import { mapPoolListToMapPoolObject } from "~/modules/map-list-generator";
import {
type ModeShort,
type StageId,
stageIds,
} from "~/modules/in-game-lists";
type DbMapPoolList = Array<Pick<MapPoolMap, "stageId" | "mode">>;
export class MapPool {
private source: string | ReadonlyMapPoolObject;
private asSerialized?: string;
private asObject?: ReadonlyMapPoolObject;
constructor(init: ReadonlyMapPoolObject | string | DbMapPoolList) {
this.source = Array.isArray(init) ? mapPoolListToMapPoolObject(init) : init;
}
static serialize(init: ReadonlyMapPoolObject | string | DbMapPoolList) {
return new MapPool(init).serialized;
}
static parse(init: MapPoolObject | string | DbMapPoolList) {
return new MapPool(init).parsed;
}
static toDbList(init: MapPoolObject | string | DbMapPoolList) {
return new MapPool(init).dbList;
}
get serialized(): string {
if (this.asSerialized !== undefined) {
return this.asSerialized;
}
return (this.asSerialized =
typeof this.source === "string"
? this.source
: mapPoolToSerializedString(this.source));
}
get parsed(): ReadonlyMapPoolObject {
if (this.asObject !== undefined) {
return this.asObject;
}
return (this.asObject =
typeof this.source === "string"
? serializedStringToMapPool(this.source)
: this.source);
}
get dbList(): DbMapPoolList {
return Object.entries(this.parsed).flatMap(([mode, stages]) =>
stages.flatMap((stageId) => ({ mode: mode as ModeShort, stageId }))
);
}
get stages() {
return Object.values(this.parsed).flat();
}
get stageModePairs() {
return Object.entries(this.parsed).flatMap(([mode, stages]) =>
stages.map((stageId) => ({ mode: mode as ModeShort, stageId }))
);
}
has({ stageId, mode }: { stageId: StageId; mode: ModeShort }) {
return this.parsed[mode].includes(stageId);
}
hasMode(mode: ModeShort): boolean {
return this.parsed[mode].length > 0;
}
hasStage(stageId: StageId): boolean {
return Object.values(this.parsed).some((stages) =>
stages.includes(stageId)
);
}
overlaps(other: MapPool): boolean {
return this.stageModePairs.some((pair) => other.has(pair));
}
isEmpty(): boolean {
return Object.values(this.parsed).every((stages) => stages.length === 0);
}
getClonedObject(): MapPoolObject {
return clone(this.parsed) as MapPoolObject;
}
toString() {
return this.serialized;
}
toJSON() {
return this.parsed;
}
[Symbol.iterator]() {
var index = -1;
var data = this.stageModePairs;
return {
next: () => ({ value: data[++index]!, done: !(index in data) }),
};
}
static EMPTY = new MapPool({
SZ: [],
TC: [],
CB: [],
RM: [],
TW: [],
});
static ALL = new MapPool({
SZ: [...stageIds],
TC: [...stageIds],
CB: [...stageIds],
RM: [...stageIds],
TW: [...stageIds],
});
static ANARCHY = new MapPool({
SZ: [...stageIds],
TC: [...stageIds],
CB: [...stageIds],
RM: [...stageIds],
TW: [],
});
static SZ = new MapPool({
...MapPool.EMPTY.parsed,
SZ: [...stageIds],
});
static TC = new MapPool({
...MapPool.EMPTY.parsed,
TC: [...stageIds],
});
static CB = new MapPool({
...MapPool.EMPTY.parsed,
CB: [...stageIds],
});
static RM = new MapPool({
...MapPool.EMPTY.parsed,
RM: [...stageIds],
});
static TW = new MapPool({
...MapPool.EMPTY.parsed,
TW: [...stageIds],
});
}