Commit 66e65fea authored by nanahira's avatar nanahira

fix swiss matching same

parent 31672c79
Pipeline #40297 passed with stages
in 5 minutes and 48 seconds
...@@ -50,17 +50,43 @@ export class Swiss extends TournamentRuleBase { ...@@ -50,17 +50,43 @@ export class Swiss extends TournamentRuleBase {
nextRound(): Partial<Match[]> { nextRound(): Partial<Match[]> {
this.tournament.calculateScore(); this.tournament.calculateScore();
// score asc
const participants = this.tournament.participants const participants = this.tournament.participants
.filter((p) => !p.quit) .filter((p) => !p.quit)
.reverse(); .reverse()
.map((p) => {
const opponentIds =
this.getOpponentMap().get(p.id) ?? new Map<number, number>();
return {
p,
opponentIds,
};
});
const nextRoundCount = this.nextRoundCount(); const nextRoundCount = this.nextRoundCount();
const matches = this.tournament.matches.filter( const matches = this.tournament.matches.filter(
(m) => m.round === nextRoundCount, (m) => m.round === nextRoundCount,
); );
for (const match of matches) { for (const match of matches) {
match.status = MatchStatus.Running; match.status = MatchStatus.Running;
match.player1Id = participants.pop()?.id; const player1 = participants.pop();
match.player2Id = participants.pop()?.id; if (player1 && participants.length) {
match.player1Id = player1.p.id;
let player2Index = -1;
for (let i = 0; i < 10 && player2Index === -1; ++i) {
player2Index = participants.findLastIndex((p) => {
const metCount = player1.opponentIds.get(p.p.id);
return !metCount || metCount <= i;
});
}
if (player2Index === -1) {
// No suitable player found, so ignore condition of non-met
player2Index = participants.length - 1;
}
const player2 = participants.splice(player2Index, 1)[0];
if (player2) {
match.player2Id = player2.p.id;
}
}
if (!match.player1Id || !match.player2Id) { if (!match.player1Id || !match.player2Id) {
match.status = MatchStatus.Abandoned; match.status = MatchStatus.Abandoned;
match.player1Id = null; match.player1Id = null;
...@@ -116,23 +142,31 @@ export class Swiss extends TournamentRuleBase { ...@@ -116,23 +142,31 @@ export class Swiss extends TournamentRuleBase {
}; };
} }
private opponentMap: Map<number, Set<number>> | null = null; private opponentMap: Map<number, Map<number, number>> | null = null;
private getOpponentMap(): Map<number, Set<number>> { private getOpponentMap(): Map<number, Map<number, number>> {
if (this.opponentMap) return this.opponentMap; if (this.opponentMap) return this.opponentMap;
const map = new Map<number, Set<number>>(); const map = new Map<number, Map<number, number>>();
const finished = this.specificMatches(MatchStatus.Finished); const finished = this.specificMatches(MatchStatus.Finished);
for (const match of finished) { for (const match of finished) {
const [p1, p2] = [match.player1Id, match.player2Id]; const [p1, p2] = [match.player1Id, match.player2Id];
if (!p1 || !p2) continue; if (!p1 || !p2) continue;
if (!map.has(p1)) map.set(p1, new Set()); if (!map.has(p1)) map.set(p1, new Map());
if (!map.has(p2)) map.set(p2, new Set()); if (!map.has(p2)) map.set(p2, new Map());
map.get(p1).add(p2); const bind = (a: number, b: number) => {
map.get(p2).add(p1); const p1Map = map.get(a);
if (!p1Map.has(b)) {
p1Map.set(b, 1);
} else {
p1Map.set(b, p1Map.get(b) + 1);
}
};
bind(p1, p2);
bind(p2, p1);
} }
this.opponentMap = map; this.opponentMap = map;
...@@ -140,8 +174,8 @@ export class Swiss extends TournamentRuleBase { ...@@ -140,8 +174,8 @@ export class Swiss extends TournamentRuleBase {
} }
participantScoreAfter(participant: Participant): Partial<ParticipantScore> { participantScoreAfter(participant: Participant): Partial<ParticipantScore> {
const opponentIds = this.getOpponentMap().get(participant.id) ?? new Set(); const opponentIds = this.getOpponentMap().get(participant.id) ?? new Map();
const opponents = Array.from(opponentIds).map((id) => const opponents = Array.from(opponentIds.keys()).map((id) =>
this.participantMap.get(id), this.participantMap.get(id),
); );
return { return {
......
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