diff --git a/server/src/game/game.controller.ts b/server/src/game/game.controller.ts index 93651b7..3e3856c 100644 --- a/server/src/game/game.controller.ts +++ b/server/src/game/game.controller.ts @@ -1,19 +1,63 @@ -import { Controller, Get, UseGuards } from '@nestjs/common' +import { Controller, Delete, Get, HttpCode, Post, UseGuards } from '@nestjs/common' import { GameService } from './game.service' import { JwtAuthGuard } from 'src/auth/jwt-auth.guard' -import { ApiBearerAuth, ApiOkResponse, ApiUnauthorizedResponse } from '@nestjs/swagger' +import { ApiBearerAuth, ApiNoContentResponse, ApiOkResponse, ApiOperation, ApiUnauthorizedResponse } from '@nestjs/swagger' import { GameEntity } from './entities/game.entity' @Controller('game') export class GameController { constructor(private readonly gameService: GameService) {} + /** + * Récupérer l'objet du jeu + * + * @throws {401} Non authentifié⋅e + */ @Get() @UseGuards(JwtAuthGuard) @ApiBearerAuth() - @ApiOkResponse({ type: GameEntity }) - @ApiUnauthorizedResponse({ description: "Non authentifié⋅e" }) - async find() { + async find(): Promise { return new GameEntity(await this.gameService.find()) } + + /** + * Démarrer le jeu + * @remarks Lance le jeu, tire au sort læ joueur⋅se de départ et donne un solde initial pour acheter des trains. Le jeu ne doit pas être déjà démarré. + * + * @throws {401} Non authentifié⋅e + * @throws {409} La partie est déjà démarrée + */ + @Post('/start') + @UseGuards(JwtAuthGuard) + @ApiBearerAuth() + async start(): Promise { + return new GameEntity(await this.gameService.start()) + } + + /** + * Arrêter le jeu + * @remarks Arrête le jeu (si déjà lancé), à n'utiliser qu'en fin de partie. + * + * @throws {401} Non authentifié⋅e + * @throws {409} La partie n'est pas démarrée + */ + @Post('/stop') + @UseGuards(JwtAuthGuard) + @ApiBearerAuth() + async stop(): Promise { + return new GameEntity(await this.gameService.stop()) + } + + /** + * Réinitialiser le jeu + * @remarks Réinitialise toutes les données de jeu, supprimant les trains parcourus et les défis accomplis. À utiliser avec précaution. + * + * @throws {401} Non authentifié⋅e + */ + @Delete('/reset') + @UseGuards(JwtAuthGuard) + @ApiBearerAuth() + async reset(): Promise { + return new GameEntity(await this.gameService.reset()) + } } diff --git a/server/src/game/game.service.ts b/server/src/game/game.service.ts index 58e8467..61c6b18 100644 --- a/server/src/game/game.service.ts +++ b/server/src/game/game.service.ts @@ -1,4 +1,5 @@ -import { Injectable } from '@nestjs/common' +import { ConflictException, Injectable } from '@nestjs/common' +import { MoneyUpdateType } from '@prisma/client' import { PrismaService } from 'src/prisma/prisma.service' @Injectable() @@ -8,4 +9,59 @@ export class GameService { async find() { return await this.prisma.game.findUnique({ where: { id: 1 } }) } + + async start() { + const game = await this.find() + if (game.started) + throw new ConflictException("La partie a déjà démarré.") + const players = await this.prisma.player.findMany() + const alreadyStarted = game.currentRunnerId !== null + if (!alreadyStarted) { + for (const player of players) { + await this.prisma.moneyUpdate.create({ + data: { + playerId: player.id, + amount: 2000, + reason: MoneyUpdateType.START, + } + }) + } + } + const runnerId = alreadyStarted ? game.currentRunnerId : players[Math.trunc(players.length * Math.random())].id + return await this.prisma.game.update({ + where: { id: 1 }, + data: { + started: true, + currentRunnerId: runnerId, + }, + }) + } + + async stop() { + const game = await this.find() + if (!game.started) + throw new ConflictException("La partie n'a pas encore démarré.") + return await this.prisma.game.update({ + where: { id: 1 }, + data: { + started: false, + }, + }) + } + + async reset() { + await this.prisma.moneyUpdate.deleteMany() + await this.prisma.challengeAction.deleteMany() + await this.prisma.trainTrip.deleteMany() + await this.prisma.geolocation.deleteMany() + await this.prisma.player.updateMany({ data: { money: 0 } }) + await this.prisma.game.update({ + where: { id: 1 }, + data: { + started: false, + currentRunnerId: null, + }, + }) + return await this.find() + } }