Recalculate skills script

This commit is contained in:
Kalle
2022-03-26 10:34:16 +02:00
parent aed28496bc
commit 68184ee9fe
2 changed files with 83 additions and 1 deletions

View File

@@ -26,7 +26,7 @@
"cy:run": "npx cypress run",
"test:unit": "uvu -r tsm -r tsconfig-paths/register -i cypress",
"tests": "npm run lint:styles && npm run lint:ts && npm run prettier:check && npm run typecheck && npm run test:unit",
"matches": "node --experimental-specifier-resolution=node --loader ts-node/esm -r tsconfig-paths/register scripts/matchesWithoutDetails.ts"
"recalculate-skills": "node --experimental-specifier-resolution=node --loader ts-node/esm -r tsconfig-paths/register scripts/recalculateSkills.ts"
},
"dependencies": {
"@dnd-kit/core": "^5.0.3",

View File

@@ -0,0 +1,82 @@
import { Prisma, PrismaClient } from "@prisma/client";
import { rating } from "openskill";
import { adjustSkills } from "~/core/mmr/utils";
import { groupsToWinningAndLosingPlayerIds } from "~/core/play/utils";
const prisma = new PrismaClient();
type SkillWithDetails = {
mu: number;
sigma: number;
userId: string;
matchId: string;
};
type UserId = string;
type CurrentSkills = Record<UserId, Pick<SkillWithDetails, "mu" | "sigma">>;
async function main() {
const matches = (await allMatches()).filter((m) =>
m.stages.some((s) => s.winnerGroupId)
);
const newSkills: SkillWithDetails[] = [];
const currentSkills: CurrentSkills = {};
for (const match of matches) {
const adjustedSkills = adjustSkills({
skills: skillsPerUser({
currentSkills,
userIds: match.groups.flatMap((g) =>
g.members.flatMap((m) => m.memberId)
),
}),
playerIds: groupsToWinningAndLosingPlayerIds({
groups: match.groups.map((g) => ({
id: g.id,
members: g.members.map((m) => ({ user: { id: m.memberId } })),
})),
winnerGroupIds: match.stages.flatMap((s) =>
s.winnerGroupId ? [s.winnerGroupId] : []
),
}),
});
newSkills.push(...adjustedSkills.map((s) => ({ ...s, matchId: match.id })));
for (const skill of adjustedSkills) {
const { userId, ...rest } = skill;
currentSkills[userId] = rest;
}
}
await prisma.$transaction([
prisma.skill.deleteMany({}),
prisma.skill.createMany({ data: newSkills }),
]);
}
export type AllMatches = Prisma.PromiseReturnType<typeof allMatches>;
function allMatches() {
return prisma.lfgGroupMatch.findMany({
include: { stages: true, groups: { include: { members: true } } },
orderBy: { createdAt: "asc" },
});
}
function skillsPerUser({
currentSkills,
userIds,
}: {
currentSkills: CurrentSkills;
userIds: string[];
}): Omit<SkillWithDetails, "matchId">[] {
return userIds.map((id) => {
const skill = currentSkills[id] ? currentSkills[id] : rating();
return { userId: id, ...skill };
});
}
main()
// eslint-disable-next-line no-console
.then(() => console.log("done"))
.catch((e) => console.error(e));