Skip to content

Commit

Permalink
feat: add persons in rating objects
Browse files Browse the repository at this point in the history
Signed-off-by: Dup4 <lyuzhi.pan@gmail.com>
  • Loading branch information
Dup4 committed Jan 22, 2024
1 parent 44c592d commit c372996
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 23 deletions.
1 change: 1 addition & 0 deletions packages/libs/core/src/index.ts
Expand Up @@ -9,6 +9,7 @@ export * from "./battle-of-giants";
export * from "./contest-index";
export * from "./contest";
export * from "./image";
export * from "./person";
export * from "./problem";
export * from "./rank-statistics";
export * from "./rank";
Expand Down
42 changes: 42 additions & 0 deletions packages/libs/core/src/person.ts
@@ -0,0 +1,42 @@
import type { IPerson } from "@xcpcio/types";

export class Person {
name: string;

constructor(name = "") {
this.name = name;
}

toJSON(): IPerson {
return {
name: this.name,
};
}

static fromJSON(iPerson: IPerson | string): Person {
if (typeof iPerson === "string") {
iPerson = JSON.parse(iPerson) as IPerson;
}

const person = new Person();
person.name = iPerson.name;

return person;
}
}

export type Persons = Array<Person>;

export function createPersons(iPersons: string | Array<string>): Persons {
if (typeof iPersons === "string") {
for (const c of " ,、|") {
if (iPersons.includes(c)) {
return iPersons.split(c).map(name => new Person(name));
}
}

return [new Person(iPersons)];
}

return iPersons.map(name => new Person(name));
}
26 changes: 26 additions & 0 deletions packages/libs/core/src/rating/rating-history.ts
Expand Up @@ -2,11 +2,19 @@ import type { IRatingHistory } from "@xcpcio/types";

import type { dayjs } from "../utils";
import { createDayJS } from "../utils";
import { Person } from "../person";
import type { Persons } from "../person";

export class RatingHistory {
rank: number;
rating: number;

teamName: string;
organization: string;

members: Persons;
coaches: Persons;

contestID: string;
contestName: string;
contestLink: string;
Expand All @@ -16,6 +24,12 @@ export class RatingHistory {
this.rank = 0;
this.rating = 0;

this.teamName = "";
this.organization = "";

this.members = [];
this.coaches = [];

this.contestID = "";
this.contestName = "";
this.contestLink = "";
Expand All @@ -27,6 +41,12 @@ export class RatingHistory {
rank: this.rank,
rating: this.rating,

teamName: this.teamName,
organization: this.organization,

members: this.members.map(member => member.toJSON()),
coaches: this.coaches.map(coach => coach.toJSON()),

contestID: this.contestID,
contestName: this.contestName,
contestLink: this.contestLink,
Expand All @@ -43,6 +63,12 @@ export class RatingHistory {
ratingHistory.rank = iRatingHistory.rank;
ratingHistory.rating = iRatingHistory.rating;

ratingHistory.teamName = iRatingHistory.teamName;
ratingHistory.organization = iRatingHistory.organization;

ratingHistory.members = iRatingHistory.members.map(iMember => Person.fromJSON(iMember));
ratingHistory.coaches = iRatingHistory.coaches.map(iCoach => Person.fromJSON(iCoach));

ratingHistory.contestID = iRatingHistory.contestID;
ratingHistory.contestName = iRatingHistory.contestName;
ratingHistory.contestLink = iRatingHistory.contestLink;
Expand Down
21 changes: 20 additions & 1 deletion packages/libs/core/src/rating/rating-user.ts
@@ -1,9 +1,16 @@
import type { IRatingUser } from "@xcpcio/types/index";
import type { IRatingUser } from "@xcpcio/types";

import type { Persons } from "../person";
import { Person } from "../person";
import { type RatingHistories, RatingHistory } from "./rating-history";

export class RatingUser {
id: string;
name: string;
organization: string;

members: Persons;
coaches: Persons;

rating: number;
minRating: number;
Expand All @@ -20,6 +27,10 @@ export class RatingUser {
constructor() {
this.id = "";
this.name = "";
this.organization = "";

this.members = [];
this.coaches = [];

this.rating = 0;
this.minRating = 0x3F3F3F3F;
Expand All @@ -44,6 +55,10 @@ export class RatingUser {
return {
id: this.id,
name: this.name,
organization: this.organization,

members: this.members.map(member => member.toJSON()),
coaches: this.coaches.map(coach => coach.toJSON()),

rating: this.rating,
minRating: this.minRating,
Expand All @@ -62,6 +77,10 @@ export class RatingUser {

ratingUser.id = iRatingUser.id;
ratingUser.name = iRatingUser.name;
ratingUser.organization = iRatingUser.organization;

ratingUser.members = iRatingUser.members.map(member => Person.fromJSON(member));
ratingUser.coaches = iRatingUser.coaches.map(coach => Person.fromJSON(coach));

ratingUser.rating = iRatingUser.rating;
ratingUser.minRating = iRatingUser.minRating;
Expand Down
63 changes: 43 additions & 20 deletions packages/libs/core/src/rating/rating.ts
@@ -1,6 +1,8 @@
import type { IRating } from "@xcpcio/types/index";
import type { IRating } from "@xcpcio/types";

import type { Ranks } from "../rank";
import type { Team } from "../team";
import { createPersons } from "../person";

import { RatingCalculator } from "./rating-calculator";
import { RatingHistory } from "./rating-history";
Expand Down Expand Up @@ -34,48 +36,69 @@ export class Rating {
for (const rank of this.ranks) {
rank.buildRank();

for (const u of this.users) {
u.oldRating = u.rating;
}
const ratingCalculator = new RatingCalculator();

for (const t of rank.teams) {
const id = this.generateTeamId(t);

let u = null;

if (!this.userMap.has(id)) {
const u = new RatingUser();
u = new RatingUser();
u.id = id;
u.name = t.name;
u.organization = t.organization;

u.members = createPersons(t.members ?? []);
u.coaches = createPersons(t.coach ?? []);

u.rank = t.rank;
u.oldRating = this.baseRating;
u.UpdateRating(this.baseRating);

this.userMap.set(id, u);
this.users.push(u);

ratingCalculator.users.push(u);
} else {
u = this.userMap.get(id)!;
u.rank = t.rank;
u.oldRating = u.rating;
ratingCalculator.users.push(u);
}
}

const ratingCalculator = new RatingCalculator();
ratingCalculator.users = this.users;
ratingCalculator.calculate();
{
const h = new RatingHistory();
h.rank = t.rank;
h.rating = u.rating;

h.teamName = t.name;
h.organization = t.organization;

h.members = createPersons(t.members ?? []);
h.coaches = createPersons(t.coach ?? []);

for (const u of this.users) {
const h = new RatingHistory();
h.rank = u.rank;
h.rating = u.rating;
h.contestID = rank.contest.id;
h.contestLink = h.contestID;
h.contestName = rank.contest.name;
h.contestTime = rank.contest.startTime;

h.contestID = rank.contest.id;
h.contestLink = h.contestID;
h.contestName = rank.contest.name;
h.contestTime = rank.contest.startTime;
u.ratingHistories.push(h);
}
}

ratingCalculator.calculate();

u.ratingHistories.push(h);
for (const u of ratingCalculator.users) {
u.ratingHistories.at(-1)!.rating = u.rating;
}
}
}

generateTeamId(t: Team) {
if (Array.isArray(t.members) && t.members.length > 0) {
return t.members.join("|");
const persons = createPersons(t.members ?? []);
if (persons.length > 0) {
return persons.map(person => person.name).join("|");
}

return `${t.organization}-${t.name}`;
Expand Down
59 changes: 57 additions & 2 deletions packages/libs/core/test/rating.test.ts
Expand Up @@ -46,7 +46,7 @@ describe("contest", () => {
expect(firstUser.rank).toMatchInlineSnapshot("1");
expect(firstUser.rating).toMatchInlineSnapshot("1714");

const lastUser = ratingCalculator.users[ratingCalculator.users.length - 1];
const lastUser = ratingCalculator.users.at(-1)!;
expect(lastUser.rank).toMatchInlineSnapshot("129");
expect(lastUser.rating).toMatchInlineSnapshot("1402");

Expand Down Expand Up @@ -77,7 +77,7 @@ describe("contest", () => {
expect(rating.users.length).toMatchInlineSnapshot("132");

const firstUser = rating.users[0];
const lastUser = rating.users[rating.users.length - 1];
const lastUser = rating.users.at(-1)!;

expect(firstUser.ratingHistories.length).toMatchInlineSnapshot("3");
expect(firstUser.rating).toMatchInlineSnapshot("1973");
Expand All @@ -102,35 +102,90 @@ describe("contest", () => {
expect(newRating.users.length).toMatchInlineSnapshot("132");
expect(newRating.users[0]).toMatchInlineSnapshot(`
{
"coaches": [],
"id": "王展鹏|罗煜翔|蒋凌宇",
"maxRating": 1973,
"members": [
{
"name": "王展鹏",
},
{
"name": "罗煜翔",
},
{
"name": "蒋凌宇",
},
],
"minRating": 1500,
"name": "重生之我是菜狗",
"organization": "北京大学",
"rating": 1973,
"ratingHistories": [
{
"coaches": [],
"contestID": "2023/ccpc/final",
"contestLink": "2023/ccpc/final",
"contestName": "第八届中国大学生程序设计竞赛总决赛(正式赛)",
"contestTime": 2023-05-14T01:10:00.000Z,
"members": [
{
"name": "王展鹏",
},
{
"name": "罗煜翔",
},
{
"name": "蒋凌宇",
},
],
"organization": "北京大学",
"rank": 1,
"rating": 1714,
"teamName": "重生之我是菜狗",
},
{
"coaches": [],
"contestID": "2023/ccpc/final",
"contestLink": "2023/ccpc/final",
"contestName": "第八届中国大学生程序设计竞赛总决赛(正式赛)",
"contestTime": 2023-05-14T01:10:00.000Z,
"members": [
{
"name": "王展鹏",
},
{
"name": "罗煜翔",
},
{
"name": "蒋凌宇",
},
],
"organization": "北京大学",
"rank": 1,
"rating": 1861,
"teamName": "重生之我是菜狗",
},
{
"coaches": [],
"contestID": "2023/ccpc/final",
"contestLink": "2023/ccpc/final",
"contestName": "第八届中国大学生程序设计竞赛总决赛(正式赛)",
"contestTime": 2023-05-14T01:10:00.000Z,
"members": [
{
"name": "王展鹏",
},
{
"name": "罗煜翔",
},
{
"name": "蒋凌宇",
},
],
"organization": "北京大学",
"rank": 1,
"rating": 1973,
"teamName": "重生之我是菜狗",
},
],
}
Expand Down
1 change: 1 addition & 0 deletions packages/libs/types/src/index.ts
Expand Up @@ -3,6 +3,7 @@ export * from "./constant";
export * from "./contest-index";
export * from "./contest";
export * from "./lang";
export * from "./person";
export * from "./problem";
export * from "./rating";
export * from "./submission-status";
Expand Down
5 changes: 5 additions & 0 deletions packages/libs/types/src/person.ts
@@ -0,0 +1,5 @@
export interface IPerson {
name: string;
}

export type IPersons = Array<IPerson>;

0 comments on commit c372996

Please sign in to comment.