Commit 4781ea09 authored by nanahira's avatar nanahira

Update src/tournament-rules/base.ts, src/tournament-rules/rules/swiss.ts files

parent 67c38b67
Pipeline #39596 failed with stages
in 2 minutes and 24 seconds
......@@ -48,20 +48,44 @@ export class TournamentRuleBase {
return this.tournament.matches.filter((m) => m.status === status);
}
participantScore(participant: Participant): Partial<ParticipantScore> {
private scoreMap: Map<number, ParticipantScore> | null = null;
protected getScoreMap(): Map<number, ParticipantScore> {
if (this.scoreMap) return this.scoreMap;
const finishedMatches = this.specificMatches(MatchStatus.Finished);
return {
win: finishedMatches.filter((m) => m.winnerId === participant.id).length,
lose: finishedMatches.filter(
(m) =>
m.winnerId &&
m.winnerId !== participant.id &&
m.participated(participant.id),
).length,
draw: finishedMatches.filter(
(m) => !m.winnerId && m.participated(participant.id),
).length,
};
const map = new Map<number, ParticipantScore>();
for (const match of finishedMatches) {
const { player1Id, player2Id, winnerId } = match;
if (!player1Id || !player2Id) continue;
if (!winnerId) {
for (const pid of [player1Id, player2Id]) {
const score = map.get(pid) ?? { win: 0, lose: 0, draw: 0 };
score.draw += 1;
map.set(pid, score);
}
} else {
const loserId = winnerId === player1Id ? player2Id : player1Id;
const winScore = map.get(winnerId) ?? { win: 0, lose: 0, draw: 0 };
winScore.win += 1;
map.set(winnerId, winScore);
const loseScore = map.get(loserId) ?? { win: 0, lose: 0, draw: 0 };
loseScore.lose += 1;
map.set(loserId, loseScore);
}
}
this.scoreMap = map;
return map;
}
participantScore(participant: Participant): Partial<ParticipantScore> {
return this.getScoreMap().get(participant.id) ?? { win: 0, lose: 0, draw: 0 };
}
participantScoreAfter(participant: Participant): Partial<ParticipantScore> {
......
......@@ -70,34 +70,76 @@ export class Swiss extends TournamentRuleBase {
return matches;
}
private participantRoundsMap: Map<number, Set<number>> | null = null;
private getParticipantRoundsMap(): Map<number, Set<number>> {
if (this.participantRoundsMap) return this.participantRoundsMap;
const map = new Map<number, Set<number>>();
for (const match of this.tournament.matches) {
const round = match.round;
if (!map.has(round)) {
map.set(round, new Set());
}
const set = map.get(round);
if (match.player1Id) set.add(match.player1Id);
if (match.player2Id) set.add(match.player2Id);
}
this.participantRoundsMap = map;
return map;
}
participantScore(participant: Participant): Partial<ParticipantScore> {
const data = super.participantScore(participant);
const baseScore = super.participantScore(participant);
const roundsMap = this.getParticipantRoundsMap();
let bye = 0;
for (let i = 1; i <= this.currentRoundCount(); ++i) {
if (
!this.tournament.matches.some(
(m) => m.round === i && m.participated(participant.id),
)
) {
const roundSet = roundsMap.get(i);
if (!roundSet?.has(participant.id)) {
++bye;
}
}
const score = data.win * this.settings.winScore +
data.draw * this.settings.drawScore +
const score =
baseScore.win * this.settings.winScore +
baseScore.draw * this.settings.drawScore +
bye * (participant.quit ? 0 : this.settings.byeScore);
return {
...data,
...baseScore,
bye,
score,
};
}
participantScoreAfter(participant: Participant): Partial<ParticipantScore> {
const opponentIds = this.specificMatches(MatchStatus.Finished)
.filter((m) => m.participated(participant.id))
.map((m) => m.opponentId(participant.id));
private opponentMap: Map<number, Set<number>> | null = null;
private getOpponentMap(): Map<number, Set<number>> {
if (this.opponentMap) return this.opponentMap;
const map = new Map<number, Set<number>>();
const finished = this.specificMatches(MatchStatus.Finished);
for (const match of finished) {
const [p1, p2] = [match.player1Id, match.player2Id];
if (!p1 || !p2) continue;
if (!map.has(p1)) map.set(p1, new Set());
if (!map.has(p2)) map.set(p2, new Set());
const opponents = opponentIds.map((id) => this.participantMap.get(id));
map.get(p1).add(p2);
map.get(p2).add(p1);
}
this.opponentMap = map;
return map;
}
participantScoreAfter(participant: Participant): Partial<ParticipantScore> {
const opponentIds = this.getOpponentMap().get(participant.id) ?? new Set();
const opponents = Array.from(opponentIds).map((id) => this.participantMap.get(id));
return {
tieBreaker: _.sumBy(opponents, (p) => p.score.score),
...(participant.quit ? { score: -1 } : {})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment