Remove /play

This commit is contained in:
Kalle (Sendou)
2021-08-03 18:40:17 +03:00
parent 0e167160f4
commit 9a19b8d0f8
5 changed files with 1 additions and 306 deletions

View File

@@ -1,5 +0,0 @@
import { GetAllLadderRegisteredTeamsData } from "prisma/queries/getAllLadderRegisteredTeams";
import useSWR from "swr";
export const useLadderTeams = (skip?: boolean) =>
useSWR<GetAllLadderRegisteredTeamsData>(skip ? null : "/api/play/teams");

View File

@@ -3,7 +3,6 @@ import { inferAsyncReturnType, inferProcedureOutput } from "@trpc/server";
import * as trpcNext from "@trpc/server/adapters/next";
import calendarApi from "routers/calendar";
import freeAgentsApi from "routers/freeagents";
import playApi from "routers/play";
import plusApi from "routers/plus";
import superjson from "superjson";
import { getMySession } from "utils/api";
@@ -23,8 +22,7 @@ export function createRouter() {
export const appRouter = createRouter()
.merge("plus.", plusApi)
.merge("calendar.", calendarApi)
.merge("freeAgents.", freeAgentsApi)
.merge("play.", playApi);
.merge("freeAgents.", freeAgentsApi);
// Exporting type _type_ AppRouter only exposes types that can be used for inference
// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export

View File

@@ -1,20 +0,0 @@
import { createRouter } from "pages/api/trpc/[trpc]";
import service from "services/play";
const playApi = createRouter()
.query("allRegisteredTeams", {
resolve() {
return service.allRegisteredTeams();
},
})
.query("nextLadderDay", {
resolve() {
return service.nextLadderDay();
},
})
.query("previousLadderDay", {
resolve() {
return service.previousLadderDay();
},
});
export default playApi;

View File

@@ -1,128 +0,0 @@
import { Prisma } from ".prisma/client";
import prisma from "prisma/client";
const allRegisteredTeams = async () =>
prisma.ladderRegisteredTeam.findMany({
include: {
roster: {
select: {
id: true,
discordAvatar: true,
discordId: true,
discriminator: true,
username: true,
team: {
select: {
name: true,
nameForUrl: true,
twitterName: true,
},
},
},
},
},
});
const allLadderRegisteredTeamsForMatches = async () =>
prisma.ladderRegisteredTeam.findMany({
select: {
id: true,
roster: {
select: {
id: true,
trueSkill: true,
},
},
},
});
export type NextLadderDay = Prisma.PromiseReturnType<typeof nextLadderDay>;
const nextLadderDay = async () => {
return prisma.ladderDay.findFirst({
where: { date: { gte: new Date() } },
include: {
matches: {
select: {
order: true,
maplist: true,
teamAScore: true,
teamBScore: true,
players: {
select: {
team: true,
user: {
select: {
id: true,
discordAvatar: true,
discordId: true,
discriminator: true,
username: true,
team: {
select: {
name: true,
nameForUrl: true,
twitterName: true,
},
},
},
},
},
},
},
},
},
});
};
export type PreviousLadderDay = Prisma.PromiseReturnType<
typeof previousLadderDay
>;
const previousLadderDay = async () => {
return prisma.ladderDay.findFirst({
where: { date: { lt: new Date() } },
orderBy: { date: "desc" },
select: {
date: true,
matches: {
select: {
order: true,
maplist: true,
teamAScore: true,
teamBScore: true,
players: {
select: {
team: true,
user: {
select: {
id: true,
discordAvatar: true,
discordId: true,
discriminator: true,
username: true,
team: {
select: {
name: true,
nameForUrl: true,
twitterName: true,
},
},
},
},
},
},
},
},
},
});
};
const playService = {
allRegisteredTeams,
allLadderRegisteredTeamsForMatches,
nextLadderDay,
previousLadderDay,
};
export default playService;

View File

@@ -1,150 +0,0 @@
import { GetAllLadderRegisteredTeamsForMatchesData } from "prisma/queries/getAllLadderRegisteredTeamsForMatches";
import { quality, Rating } from "ts-trueskill";
type TeamsWithRanking = {
id: number;
roster: {
id: number;
rating: Rating;
}[];
};
export const getLadderRounds = (
registeredTeams: GetAllLadderRegisteredTeamsForMatchesData
) => {
if (registeredTeams.length < 4) {
throw Error("registeredTeams length less than 4");
}
const teamsWithRanking: TeamsWithRanking[] = registeredTeams.map(
(registeredTeam) => ({
id: registeredTeam.id,
roster: registeredTeam.roster.map((user) => ({
id: user.id,
rating: user.trueSkill
? new Rating(user.trueSkill.mu, user.trueSkill.sigma)
: new Rating(),
})),
})
);
// this chooses the teams to sit out each round if uneven number of teams
// if even it just returns `teamsWithRanking` in both 0 index and 1 index
const [teamsRoundOne, teamsRoundTwo] = getTeamsForRounds();
// helper variable accessed from generatePairings
let bestRound: TeamsWithRanking[][] | undefined;
// helper variable accessed from generatePairings
let bestAverageQuality = -Infinity;
// first round matches actual
let firstRound: TeamsWithRanking[][] | undefined;
generatePairings(teamsRoundOne, 0);
firstRound = bestRound;
bestAverageQuality = -Infinity;
generatePairings(teamsRoundTwo, 0);
if (!firstRound || !bestRound || firstRound === bestRound) {
throw Error("unexpected falsy firstRound or bestPairs");
}
return [firstRound, bestRound];
// https://stackoverflow.com/a/37449857
// start is the current position in the list, advancing by 2 each time
// pass 0 as start when calling at the top level
function generatePairings(items: TeamsWithRanking[], start: number) {
if (items.length % 2 !== 0) {
throw Error("uneven number of teams in generatePairings");
}
// is this a complete pairing?
if (start === items.length) {
if (hasDuplicatePairing()) {
return;
}
let qualitySum = 0;
for (let i = 0; i < items.length; i += 2) {
const teamAlpha = items[i].roster.map((user) => user.rating);
const teamBravo = items[i + 1].roster.map((user) => user.rating);
qualitySum += quality([teamAlpha, teamBravo]);
}
qualitySum /= items.length / 2;
if (qualitySum > bestAverageQuality) {
bestAverageQuality = qualitySum;
bestRound = items
.map((team, i) => (i % 2 !== 0 ? null : [team, items[i + 1]]))
.filter((team) => team) as TeamsWithRanking[][];
}
return;
}
// for the next pair, choose the first element in the list for the
// first item in the pair (meaning we don't have to do anything
// but leave it in place), and each of the remaining elements for
// the second item:
for (let j = start + 1; j < items.length; j++) {
// swap start+1 and j:
let temp = items[start + 1];
items[start + 1] = items[j];
items[j] = temp;
// recurse:
generatePairings(items, start + 2);
// swap them back:
temp = items[start + 1];
items[start + 1] = items[j];
items[j] = temp;
}
function hasDuplicatePairing() {
if (!firstRound) return false;
for (let i = 0; i < items.length; i += 2) {
const teamAlpha = items[i];
const teamBravo = items[i + 1];
if (
firstRound.some(
([pairsAlpha, pairsBravo]) =>
(pairsAlpha.id === teamAlpha.id &&
pairsBravo.id === teamBravo.id) ||
(pairsAlpha.id === teamBravo.id && pairsBravo.id === teamAlpha.id)
)
) {
return true;
}
}
return false;
}
}
function getTeamsForRounds() {
if (teamsWithRanking.length % 2 === 0) {
return [teamsWithRanking, teamsWithRanking];
}
const firstTeamToSitOut = randomChoiceIndex();
let secondTeamToSitOut = randomChoiceIndex();
while (secondTeamToSitOut === firstTeamToSitOut) {
secondTeamToSitOut = randomChoiceIndex();
}
return [
teamsWithRanking.filter((_, i) => i !== firstTeamToSitOut),
teamsWithRanking.filter((_, i) => i !== secondTeamToSitOut),
];
function randomChoiceIndex() {
return Math.floor(Math.random() * teamsWithRanking.length);
}
}
};