Giter VIP home page Giter VIP logo

red-tetris-42-project's Introduction

Red-tetris-42-project

Test

Branch naming

✨ Feature ✨

  • feat/*
  • feature/*

🐛 Bug fix 🐛

  • fix/*
  • hotfix/*

♻️ Refactorisation du code ♻️

  • facto/*
  • refactorisation/*

Frontend

Framework

Commandes

Developpement and build

  • npm run install
  • npm run dev
  • npm run build

Format, Linter and Syntax

  • npm run format
  • npm run lint
  • npm run check

Test

  • npm run test

BackEnd Documentation

Stack

Static Badge Static Badge Static Badge Static Badge Static Badge

In a new terminal instance, do:

cd backend

Production environment

Install and run the server:

npm install
npm run start

Development environment

Install and run the server with nodemon watching:

npm install
npm run dev

Format & Lint

Run prettier
npm run format
Run eslint
npm run lint

or

npm run lint:fix
Run both
npm run indent

Transpiler

Run babel
npm run build

Units Tests with jest

Run and watch changes
npm run testDev
Run tests
npm run test
Get Coverage
npm run check

ou

npm run test:open

Indent + Build + Test

npm run ibt

.env file

The mandatory environment variables needed to be set are (prod mode):

HOST=localhost
PORT=8080
PROTOCOL=ws
DESTROY_TIMER=15
DISCO_TIMER=15
START_GAME_TIMER=10

The timers variables are set in seconds. Then, into codebase, it will be converted into milliseconds.

DEV

If the DEV variable is set to 1 the server will run in development mode. The timers are decreased to:

  • 10s for DESTROY_TIMER
  • 10s for DISCO_TIMER
  • 10s for START_GAME_TIMER The .env file is automatically created.

UNITSTESTS

If the UNITSTESTS variable is set to 1 the server will run in unit tests mode The timers are decreased to:

  • 1s for DESTROY_TIMER
  • 1s for DISCO_TIMER
  • 5s for START_GAME_TIMER The .env file is automatically created.

PROD

If the DEV and the UNITSTESTS variables are unset, we are in production mode. The timers are decreased to:

  • 15s for DESTROY_TIMER
  • 15s for DISCO_TIMER
  • 10s for START_GAME_TIMER The .env file should be handled by the provider.

Application

cp .env.example .env
docker-compose up

or

make start

red-tetris-42-project's People

Contributors

dependabot[bot] avatar louchebem06 avatar audeizreading avatar

Stargazers

Marjan Ahmed avatar  avatar

Watchers

 avatar

red-tetris-42-project's Issues

Page error

  • developement page error
  • test pour les page error code retour et titre page

Tests unitaires Sockets

A faire - En cours

  • TODO Backend
  • trouver comment recup id de la socket client (passe undefined pour le moment)
  • ACK client-serveur-client simple (sans data transformée juste on check que les datas circulent et correspondent a ce qu'elles sont transmises)
  • tester un client qui envoie plusieurs username, avec des symboles interdits et/ou valides
  • tester un client qui renvoie plusieurs ids
  • tester plusieurs clients, et un seul username, un seul id (test repere)
  • tester la gestion des pseudos et id sockets sur ce scenario:
    • connexion anon
    • connexion anon1
    • connexion anon2
    • connexion anon3
    • deconnexion anon2
    • deconnexion anon
    • reconnexion anon2
    • reconnexion anon
  • tester si c'est bien un player qui est retourné (en lien avec issue #70 )

Refact Player + List usernames

Faire un gestionnaire de player, rassembler la classe Player + UsernamesList en un vrai gestionnaire de Player, et laisser la classe Player pour être un Player
dsl, je ne sais pas pourquoi je l'ai pas vu avant

  • Fractorisation Player
  • List usernames

Broadcast Event

Event de broadcast:

  • incoming: lorsqu'un joueur entre dans une room, sauf si c'est le premier dans la room
  • outcoming: lorsqu'un joueur sort d'une room, sauf si c'est le dernier
  • specter: le niveau de pénalité? (pas tout compris ce que c'est le spectre)
  • debut jeu: (nom event non encore trouvé), lorsqu'une partie demarre broadcast a la room, et empecher de rejoindre le game

Game Events

Events:
-> Pour les mouvements
-> pour les scores
-> distribution des pieces du jeu
-> debut / fin / pause / relancement du jeu (certaines actions ne peuvent être que faites par le leader de la room)
...
à compléter

Event join

1er event de connexion:

  • join: établit la connexion srv/clt. Si la connexion est correctement établie un player Player est créé
    C'est ce player qui doit être retourné au client depuis:
    Pour le moment c'est ca qui est retrounée au front
app.ts
socket.emit("join", {username: player.username, id: player.socketId});

mais il faudrait retourner plutot qq chose comme ca (la game a pas encore commencé, ce serait juste avant d'intégrer la sall d'attente):

app.ts
socket.emit("join", {player: player, openRooms: rooms});

Les rooms ce seraient peut être pas encore la qu'il faudrait que je les passe, à étudier

  • TODO
    • backend
    • Rajouter les elts du player dans la classe player (score, level, nb de parties, si il est en train de jouer ou dispo pour jouer etc)
    • Créer une room salle d'attente et mettre le player dedans (ca pourra être un nouveau player, ou un reco - avec même socket id)

Page leaderboard

  • Backend #9
  • Design
  • front and back connecter
  • test unitaire
    • Return page and title
    • connection back

Bug run package.json

@AudeizReading en voulant convert ton fichier js en ts, je me suis apercu que ton format et lint ne sont pas bon.

  "scripts": {
    "test": "jest",
    "build": "npx tsc",
    "start": "TZ='UTC' node dist/app.js",
    "dev": "TZ='UTC' nodemon src/app.ts",
    "lint": "eslint src/**/*.ts",
    "format": "eslint src/**/*.ts --fix"
  },

par

  "scripts": {
    "test": "jest",
    "build": "npx tsc",
    "start": "TZ='UTC' node dist/app.js",
    "dev": "TZ='UTC' nodemon src/app.ts",
    "lint": "prettier . --check . && eslint .",
    "lint:fix": "prettier . --check . && eslint . --fix"
    "format": "prettier  . --write .
  },

Une fois que tu fait ces modification, du coup ton code il n'est plus a la norm.
Parce que dans la version actuel le prettier n'es jamais call

Originally posted by @louchebem06 in #75 (comment)

Sound Effect

  • ajouter une musique pendant la game
  • ajouter du sound effect lorsque un move et impossible ou un deplacement, ...
  • bouton pour regle le niveau de la music
  • bouton pour regler le niveau des sound effect
  • bouton pour desactiver tout le son rapidement
  • Recuperer si possible les sound effect: https://tetris.com/play-tetris #67

Scoring

  • Counter Line
  • Counter Level
  • Soft Drop
  • Hard Drop
  • Single Line Clear
  • Double Line Clear
  • Triple Line Clear
  • Tetris Line Clear
  • T-Spin Single
  • T-Spin Double
  • T-Spin Triple
  • Back-To-Back
  • faire le comptage du score
  • afficher le score

level default: 1
10 lines == lvl++;

Soft Drop: 1 * lvl
Hard Drop: 2 * lvl
Single Line Clear: 100
Double Line Clear: 300
Triple Line Clear: 500
Tetris Line Clear: 800
T-Spin single: 800;
T-Spin double: 1200;
T-Spin Triple: 1600;
Back-to-back: 0.5 x Tetris or T-Spin

Soft Drop : Il s'agit de faire descendre rapidement la pièce en cours d'une seule rangée en appuyant doucement sur la touche de descente. Cela permet de positionner la pièce plus rapidement.

Hard Drop : Le Hard Drop consiste à faire tomber instantanément la pièce en cours en appuyant sur la touche de descente. La pièce se verrouille immédiatement à sa position finale.

Single Line Clear : Lorsque vous effacez une seule ligne complète de blocs, cela s'appelle une "Single Line Clear". C'est le moyen le plus basique d'effacer des lignes.

Double Line Clear : Effacer simultanément deux lignes complètes de blocs est appelé "Double Line Clear". Cela se produit généralement lorsque vous effectuez un "Tetris" en empilant quatre lignes de blocs d'une hauteur spécifique.

Triple Line Clear : Effacer trois lignes complètes de blocs d'un seul coup est appelé "Triple Line Clear". Cela se produit moins fréquemment que le Double Line Clear.

T-Spin Simple : Un "T-Spin Simple" se produit lorsque vous faites tourner une pièce en forme de T (ou une pièce similaire) dans un emplacement où elle s'emboîte en effectuant une rotation spéciale, généralement dans un coin. Cela vous permet d'effacer des lignes même si elles ne sont pas complètement remplies.

T-Spin Double : Le "T-Spin Double" est une version plus avancée du T-Spin Simple, où vous effectuez deux T-Spins consécutifs pour effacer des lignes. Cela nécessite généralement un emplacement plus précis et des compétences de rotation de pièces plus avancées.

T-Spin Triple : Le "T-Spin Triple" est la version la plus avancée des T-Spins, où vous effectuez trois T-Spins consécutifs pour effacer des lignes. C'est une manœuvre très difficile et exigeante en termes de compétences.

Back-to-Back : Lorsque vous effectuez une combinaison de mouvements qui consiste en un T-Spin (simple, double ou triple) suivi immédiatement d'un "Tetris" (effacement de quatre lignes d'un coup), on appelle cela un "Back-to-Back". Cela augmente généralement votre score et est considéré comme une réalisation impressionnante dans le jeu Tetris.

.env Backend

Gérer l'environnement via un fichier .env et dotfile + config si node est en prod ou en dev

  • Backend:
  • .env.example a générer et a push
  • script qui demande les infos sensibles et genere le.env
  • dans le workflow concerné (back/ test) link ce .env a toute la procedure de test (sinon ca va fail)
  • HttpServer -> a update
  • app.ts -> a update
  • App.ts -> a update
  • Verif si d'autres classes sont pas impactees
  • tests unitaires en rapports aux classe a update

Gestion erreur socket

En commencant les tests unitaires, je pense avoir trouvé comment faire si erreur (dans le pseudo socket id toussa) => socket serveur emettre event error, et dans l'event error de la socket, deconnecter la socket

la socket serveur semble aussi pouvoir recevoir le player via sa prop data. Par contre avec typescript, on peut pas creer de prop direct sur la Socket.

Player Update

Comment update le player?

-> Quelles strucutures insérer:

  • datas id player
  • datas de jeux
  • datas de messages privés

-> Les events qui updatent un joueur?

  • des qu'une piece du jeu bouge
  • des qu'un message arrive

PlayerService.ts

La classe devra gerer:

  • creation player
  • update player
  • suppression player
  • gestion usernames unique
  • obtention infos joueur
  • etc
  • PlayerController devra utiliser ses services
  • PlayerManager devra aussi utiliser ses services afin de deleguer le "service" de joueur (creation, update, delete) afin de pouvoir se concentrer sur la logique métier, c'est a dire jouer au jeu, intégrer des rooms etc.
  • ServerSocket aussi a update
  • Tests unitaires
  • Remove la classe PlayerFactory car double emploi

Exemple de mise en place (via chatGPT)

// PlayerService.ts
import { Player } from './player';
import { UsernameManager } from './username-manager';

class PlayerService {
  private players: Map<string, Player> = new Map();

  constructor(private usernameManager: UsernameManager) {}

  createPlayer(socketId: string, userData: any): Player {
    // Gérez la création d'un joueur en utilisant les données utilisateur et le socketId
    const username = this.usernameManager.getUniqueUsername(userData.username);
    const player = new Player(socketId, username);
    this.players.set(socketId, player);
    return player;
  }

  getPlayer(socketId: string): Player | undefined {
    return this.players.get(socketId);
  }

  // Ajoutez d'autres méthodes pour gérer les joueurs, par exemple, pour mettre à jour ou supprimer un joueur
}

export default PlayerService;

// PlayerController.ts
...
import { Socket } from 'socket.io';
import PlayerService from '../service/PlayerService'; // Importez le service Player

class PlayerController {
  constructor(private io: Server, private playerService: PlayerService) {
    this.initSocketEvents();
  }

  private initSocketEvents() {
    this.io.on('connection', (socket: Socket) => {
      this.handleNewConnection(socket);
    });
  }

  private handleNewConnection(socket: Socket) {
    socket.on('join', async (data: { username?: string; id?: string }) => {
      try {
        const player = this.playerService.createPlayer(socket.id, data);
        socket.emit('join', { player });
      } catch (error) {
        socket.emit('error', error.message);
      }
    });

    // Gérez d'autres événements ici en utilisant le playerService
  }
}

export default PlayerController;

// PlayerManager.ts
...
import PlayerService from '../service/PlayerService'; // Importez le service Player

class PlayerManager {
  constructor(private playerService: PlayerService) {}

  // Utilisez le PlayerService pour accéder aux joueurs et effectuer des opérations sur eux
}

export default PlayerManager;

...
// ServerSocket.ts
import { Server, Socket } from 'socket.io';
import PlayerService from '.../service/PlayerService'; // Importez le service Player

class ServerSocket {
  constructor(private io: Server, private playerService: PlayerService) {
    this.setupSocketEvents();
  }

  private setupSocketEvents() {
    this.io.on('connection', (socket: Socket) => {
      this.handleNewConnection(socket);
    });
  }

  private handleNewConnection(socket: Socket) {
    socket.on('join', async (data: { username?: string; id?: string }) => {
      try {
        const player = this.playerService.createPlayer(socket.id, data);
        socket.emit('join', { player });
      } catch (error) {
        socket.emit('error', error.message);
      }
    });

    // Gérez d'autres événements ici en utilisant le playerService
  }
}

export default ServerSocket;

...

Base socket.io client

  • TODO

    • #52
    • #66 (comment)
    • #48
    • #47
    • #82
    • redirection, salle attente / chat, game, registration, liste room
    • add username in localstorage #51
    • verification #27
    • test unitaire
  • http://<server_name_or_ip>:<port>/

    • Registration
  • http://<server_name_or_ip>:<port>/#<room>[<player_name>]

    • Game si deja lancer
    • Default salle attente / chat
  • Si trop ou pas assez info dans url renvoyer a / ou /#<room>[<player_name>] selon les information disponible

Send Private Message

L'event est installé mais pas géré

-> revoir la classe de Message
-> comment l'integrer (collection dans le Player?)
-> prevoir l'event de reception en consequence

username - symboles interdits

Pour le username il faudrait interdire la saisie des caracteres suivants:

  • #

Back: # semble ok ✅ -> redirige vers un event "error username"
Frontend: Ne pas laisser utiliser le caractère dans les inputs de creation/modification de username.

Je m'assigne aussi au cas ou y'ait d'autres symboles à gérer

  • Backend
  • test unitaire back
  • Frontend #43
  • test unitaire front #43

Github Action

.github
├── dependabot.yml
└── workflows
    ├── backend.yaml
    ├── dependabot.yaml
    ├── frontend.yaml
    ├── lint-back.yaml
    ├── lint-front.yaml
    ├── main.yaml
    ├── test-back.yaml
    └── test-front.yaml

Il faurais peut etre structurer les fichier du Workflow differament
Tout les fichier qui sont declancher par workflow_call devrais etre dans un dossier hors du dossier workflows car vue le nom du declancheur, ces n'est pas des workflows ?

Forbidden tag

Ajouter au linter ou a check de svelte l'interdiction d'utiliser.

<table />
<canvas />
<svg />

Room websocket

A default d'avoir un vrais docs pour le WS, tu peut me faire une route genre GET /api/docs
et chaque fois que tu cree une room ou un truck dans le genre tu cree un line et tu me renvoie son nom et son payload attendu.
Ou un truck dans le genre pour eviter quand je vais commencer de chercher dans le code ou de te demander toute les 30sec, ou un .txt a la racine du backend ou un truck dans le genre.

leaderboard

gerer route backend pour le leaderboard via /api avec système de pagination si l'user veut un certain nb de pages

  • Route leaderboard GET /api/leaderboard
  • query page
  • query resultOfPage
  • resultat obtenue
      {
        "page": 1,
        "totalPage": 1,
        "nbOfResult": 1,
        "result": [
            {
                 "username": "Master of cheef",
                 "score": 1248320,
                 "leaderboardPosition": 1
             }
        ]
      }
  • Test unitaire

Workflow Main

Ajouter une condition de verification pour savoir si un des test que il veut executer n'est pas deja en cours via le push

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.