feat: bots

This commit is contained in:
Lala, Shahd
2026-06-10 09:31:27 +00:00
parent a2d2c00afe
commit fa27f2c23b
5 changed files with 149 additions and 1 deletions
+10
View File
@@ -0,0 +1,10 @@
export interface Bot {
id: string;
name: string;
rating: number;
createdAt: string;
}
export interface BotWithToken extends Bot {
token: string;
}
+66
View File
@@ -0,0 +1,66 @@
export interface BotRef {
id: string;
name: string;
}
export interface Clock {
limit: number;
increment: number;
}
export interface Variant {
key: string;
name: string;
}
export interface ResultDto {
rank: number;
points: number;
tieBreak: number;
bot: BotRef;
nbGames: number;
wins: number;
draws: number;
losses: number;
}
export interface Standing {
page: number;
players: ResultDto[];
}
export interface Tournament {
id: string;
fullName: string;
clock: Clock;
variant: Variant;
rated: boolean;
nbPlayers: number;
nbRounds: number;
createdBy: string;
startsAt: string | null;
status: string;
round: number;
standing: Standing;
winner: BotRef | null;
}
export interface TournamentList {
created: Tournament[];
started: Tournament[];
finished: Tournament[];
}
export interface Pairing {
id: string;
round: number;
white: BotRef | null;
black: BotRef;
gameId: string | null;
winner: string | null;
}
export interface RoundPairings {
round: number;
pairings: Pairing[];
}
+22
View File
@@ -0,0 +1,22 @@
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Bot, BotWithToken } from '../models/bot.models';
@Injectable({ providedIn: 'root' })
export class BotService {
private readonly http = inject(HttpClient);
private readonly base = '/api/account/official-bots';
list(): Observable<Bot[]> {
return this.http.get<Bot[]>(this.base);
}
create(name: string): Observable<BotWithToken> {
return this.http.post<BotWithToken>(this.base, { name });
}
delete(botId: string): Observable<void> {
return this.http.delete<void>(`${this.base}/${botId}`);
}
}
+1 -1
View File
@@ -40,7 +40,7 @@ export class GameApiService {
? { white: playerInfo, black: botInfo }
: { white: botInfo, black: playerInfo };
return this.http.post<GameFull>(`${this.apiBase}${this.apiPath}`, payload);
return this.http.post<GameFull>(`${this.apiBase}${this.apiPath}/vs-bot`, payload);
}
getGame(gameId: string): Observable<GameFull> {
+50
View File
@@ -0,0 +1,50 @@
import { Injectable, inject } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Tournament, TournamentList, RoundPairings } from '../models/tournament.models';
export interface CreateTournamentForm {
name: string;
nbRounds: number;
clockLimitMinutes: number;
clockIncrement: number;
rated: boolean;
}
@Injectable({ providedIn: 'root' })
export class TournamentService {
private readonly http = inject(HttpClient);
private readonly base = '/api/tournament';
list(): Observable<TournamentList> {
return this.http.get<TournamentList>(this.base);
}
get(id: string): Observable<Tournament> {
return this.http.get<Tournament>(`${this.base}/${id}`);
}
create(form: CreateTournamentForm): Observable<Tournament> {
const body = new URLSearchParams();
body.set('name', form.name);
body.set('nbRounds', String(form.nbRounds));
body.set('clockLimit', String(form.clockLimitMinutes * 60));
body.set('clockIncrement', String(form.clockIncrement));
body.set('rated', String(form.rated));
return this.http.post<Tournament>(this.base, body.toString(), {
headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' })
});
}
start(id: string): Observable<Tournament> {
return this.http.post<Tournament>(`${this.base}/${id}/start`, null);
}
join(id: string, botId: string, botName: string): Observable<void> {
return this.http.post<void>(`${this.base}/${id}/join`, { botId, botName });
}
roundPairings(id: string, round: number): Observable<RoundPairings> {
return this.http.get<RoundPairings>(`${this.base}/${id}/round/${round}`);
}
}