Commit 6d3a4bd9 authored by Gerson Sunyé's avatar Gerson Sunyé
Browse files

README - initial commit

parent c2200be9
# Jeu d'échecs en ligne
# Online Chess
Ce projet consiste à déployer une application web de jeu d'échecs jouable en multijoueur.
## Installation et lancement
## Objectifs
* Récupération du projet, des dépendances et compilation :
La fin du semestre approche, il est temps de montrer tout ce que vous avez appris et de proposer au monde entier votre première application web (webapp) !
L'objectif de ce mini-projet est d'intégrer et adapter tout le travail réalisé lors des TP et TD précédents, afin de réaliser une application de jeu d'échecs jouable (et observable) en multijoueur réseau.
```bash
git clone https://gitlab.univ-nantes.fr/tonneau-q/onlineChess.git
cd onlineChess
npm install
tsc
```
## Préparation
* Lancement du serveur :
1. Créez une fourche (Fork) du project sur votre compte GitLab: [Cliquez ici pour créer le Fork](https://gitlab.univ-nantes.fr/naomod/software-development-course/onlineChess/forks/new) (Éventuellement, Gitlab vous demandera de vous connecter).
```bash
node build/main.js
```
2. Créez et configurez une copie locale du projet. Ouvrez le **Terminal** et exécutez les commandes suivantes:
* Accès à l'application : http://adresseduserveur:8080 (ou http://localhost:8080 sur le pc local)
```bash
git clone https://gitlab.univ-nantes.fr/${USER}/onlineChess.git
cd onlineChess
npm install
```
3. Regardez la structure du projet. Le projet est organisé en différents dossiers:
```txt
|-- onlineChess
|-- client
|-- index.html
|-- script.js
|-- style.css
|-- src
|-- chessboard.ts
|-- main.ts
|-- move-validation.ts
|-- movements.ts
|-- piece.ts
|-- position.ts
|-- spec
|-- move-validation-spec.ts
|-- movements-spec.ts
|-- support
|-- jasmine.json
|-- node_modules
|-- package.json
|-- tsconfig.json
```
- `client` contient le code Javascript qui sera exécuté sur le browser. Vous ne devez pas modifier le contenu de ce dossier.
- `index.html` : page principale de l'application
- `style.css` : mise en forme de l'application
- `script.js` : algorithme(s) JavaScript côté client (affichage de l'échiquier)
- `src` contient le code source du serveur.
- `main.ts` : programme principal de création et gestion du serveur web
- `spec` contient les tests unitaires du serveur.
- `node_modules` contient les modules Node.js utilisés dans le projet. Vous ne devez pas modifier le contenu de ce dossier.
- `build` contient le code Javascript généré à partir des sources TypeScript contenus dans `src`. Vous ne devez pas modifier le contenu de ce dossier.
- `package.json` est le fichier de configuration s de **npm**. Vous n'avez pas besoin de le modifier.
- `tsconfig.json` est le fichier de configuration s de **TypeScript**. Vous n'avez pas besoin de le modifier.
## Test et lancement
- Le projet utilise l'outil de construction et de gestion de modules **npm**.
- Pour lancer tous les tests unitaires du projet avec Jasmine, exécutez: `npm test`.
- Pour lancer le serveur en mode développement (recommandé), exécutez: `npm run dev`.
- Pour lancer le serveur en mode normal, exécutez: `npm run serve`.
- Pour accéder à l'application, ouvrez l'URL suivante: [http://localhost:8080](http://localhost:8080).
- Pour accéder au contenu JSON de l'échiquier en cours, utilisez l'URL suivante: [http://localhost:8080/status.js](http://localhost:8080/status.js).
## Manuel d'utilisation
Indiquer dans le formulaire en bas de page la pièce à déplacer et sa destination au format `PieceColonneLigne` puis validez.
L'accronyme de la pièce est exprimé selon la liste suivante :
Pour déplacer les pièces sur l'échiquier, indiquez dans le formulaire en bas de page la pièce à déplacer et sa destination.
Utilisez la notation par coordonnées, qui inclut la place à partir de laquelle la pièce se déplace, ainsi que sa destination.
Par exemple:
| Coup | Coordonnées | Description |
| --- | --- | --- |
| 1. | E2-E4 E7-E5 | Pion blanc en E2 se déplace à E4. Pion noir en E7 se déplace à E5.
| 2. | G1-F3 B8-C6 | Cheval blanc en G1 se déplace à F3. Cheval noir en B8 se déplace à C6.
## Fonctionnement de l'application
Le programme principal du serveur (`main.ts`) est chargé de démarrer un mini-serveur web capable de recevoir les différentes requêtes provenant des navigateurs connectés à l'application :
- "/" : distribue le fichier `views/index.ejs`;
- "/ (post)" : reçoit et traite un coup à jouer;
- "/status.js" : génère et distribue l'échiquier en cours au format JSON.
Ces trois traitements correspondent aux différents appels à `app.get()` et `app.post()` du programme principal.
## Chronologie d'une partie
1. Lorsqu'un utilisateur se connecte à l'application (adresse **"/"**), le serveur distribue alors la page html principale composée d'un échiquier vierge et d'une zone de saisie permettant à l'utilisateur de remplir le coup à jouer.
2. Le navigateur internet récupère immédiatement les informations de la partie en cours présentes à l'adresse `/status.js`et remplit l'échiquier à l'aide d'un script situé dans le fichier `script.js`. Ces deux scripts se trouvent dans le dossier `client`.
3. Un clic sur le bouton "Envoyer" effectue une requête de type **POST** au à l'adresse **"/"** du serveur, contenant les informations du champs de texte associé.
Le serveur traite alors la requête afin de jouer le coup demandé.
4. La page internet du joueur est alors rechargée automatiquement, affichant ainsi le nouvel état de la partie.
5. etc...
## Travail à réaliser
### Validation des mouvements
La version actuelle permet le déplacement libre des pièces, sans respecter les règles des échecs.
Pour l'instant, seuls les déplacements des pions sont validés.
Vous devez mettre en oeuvre la validations des déplacements des autres pièces: le Roi, la Dame, le Cavalier, le Fou et la Tour.
Le traitement des déplacements se fait de la façon suivante:
1. Lorsqu'une requête **POST** arrive, le serveur extrait la valeur du champ envoyé et appelle la fonction `processMove()` du module `movements`.
2. La fonction `processMove()` appelle une autre fonction, `parseMoveString()`, qui transforme une chaîne de caractères en un déplacement (`interface Move`) entre 2 positions (`interface Position`).
3. La fonction `processMove()` appelle ensuite la fonction `isMovePossible()`, qui fait appel à différentes fonctions de validation spécifiques aux pièces de l'échiquier (une par type de pièce). Le module `move-validation` contient toutes les fonctions de validation de déplacements.
4. Par exemple, lorsqu'il s'agit d'un Pion blanc, la fonction `isMovePossible()` appelle la fonction `whitePawnMove()`, qui retourne `true` si le déplacement est possible ou `false` s'il ce n'est pas le cas.
5. Si le mouvement est possible, c'est à dire la fonction `isMovePossible()` retourne `true`, la fonction `processMove()` appelle la fonction `performMove(), qui effectue le déplacement.
Vous devez donc parcourir le module `move-validation` et coder les fonctions de validation contenant le commentaire "TODO:".
### Tests unitaires
Pour vérifier que les fonctions du module `move-validation` fonctionnent correctement, vous devez écrire des tests unitaires, qui vont vérifier que les fonctions acceptent les mouvements valides et n'acceptent pas les mouvements invalides.
Par exemple, pour tester
- valider les mouvements.
- tester
### Rendu
* R : roi
* D : dame
* Fc | Ff : fou initialement en colonne c|f
* Cb | Cg : cavalier initialement en colonne b|g
* Ta | Th : tour initialement en colonne a|h
* Pa | Pb | Pc | ... : pion initialement en colonne a|b|c|...
L'ensemble de votre projet doit être archivé au format zip et déposé sur Madoc au format
\begin{center}\verb+NOM1_NOM2_NOM3_NOM4.zip+\end{center} \textbf{avant la date indiquée sur la zone de dépôt}. Chaque fichier supplémentaire ajouté dans le projet doit contenir en entête un \textbf{commentaire} comportant une description du fichier et l'ensemble de vos noms et prénoms. Inspirez-vous des sources fournies dans le projet. Vous pouvez également modifier le fichier \texttt{README} pour y décrire l'organisation de vos modules, les fonctionnalités et les changements apportés dans le projet ainsi que les limites rencontrées.
>Exemple : PbB4 déplace le pion initialement en colonne B à la case `B4`.
### Derniers conseils
## Organisation des sources
- Rappelez-vous que «Une fonction sans test unitaire ne fonctionne pas»!
- Écrivez les tests unitaires avant ou en même temps que les fonctions. Ne les laissez pas pour la fin, les test unitaires sont très utiles pendant le développement et vous feront gagner du temps.
-
* server : sources relatives au serveur
* `main.ts` : algorithme principale de création et gestion du serveur
* client: sources relatives aux navigateur(s)
* `index.html` : page principale de l'application
* `style.css` : design de l'application
* `script.js` : algorithme(s) JavaScript côté client
* build : résultats de la compilation TypeScript
* node_modules : modules externes importés (express)
* `sujet.pdf` : sujet du projet
* `.gitignore` : filtre des fichiers à exclure dans le dépôt git
* `.tsconfig` et `package.json` : paramètres de compilation et d'exécution
## API
L'adresse [/status.js](http://localhost:8080/status.js) distribue toutes les informations de la partie en cours.
\ No newline at end of file
......@@ -15,6 +15,7 @@
"dependencies": {
"@types/express": "^4.16.1",
"body-parser": "^1.18.3",
"ejs": "^2.6.1",
"express": "^4.16.4",
"ts-node": "^8.0.2",
"ts-node-dev": "^1.0.0-pre.32",
......
......@@ -10,31 +10,37 @@ import { processMove } from './movements';
class HttpServer {
port : number;
port: number;
constructor(port: number) {
this.port = port;
}
public onStart(): void {
let chessboard: Chessboard = createInitialChessboard();
let chessboard: Chessboard = createInitialChessboard();
let app: express.Application = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(PUBLIC_DIR));
app.set('view engine', 'ejs')
app.listen(this.port, () => {
console.log("Application lancée à l'adresse http://localhost:" + this.port);
});
app.get('/', (req: express.Request, res: express.Response) => {
res.render('index', {error: "Erreur"});
})
app.get("/status.js", (req: express.Request, res: express.Response) => {
res.end("var boardJSON= "+JSON.stringify(chessboard));
res.end("var boardJSON= " + JSON.stringify(chessboard));
});
app.post("/", (req: express.Request, res: express.Response) => {
let coup : string = req.body.coup;
chessboard = processMove(chessboard, coup);
res.redirect("/");
let unparsedMove: string = req.body.move;
chessboard = processMove(chessboard, unparsedMove);
//res.redirect("/");
res.render('index', {error: null});
});
}
}
......
......@@ -31,9 +31,12 @@
<!-- Formulaire de saisie et emission du coup à jouer
Envoie une requêtes sur '/ (POST)' au serveur -->
<form method="POST">
<input type="text" name="coup" placeholder="Movement (d7-d6)" autofocus></input>
<input type="text" name="move" placeholder="Movement (d7-d6)" autofocus></input>
<input type="submit" value="Send"></input>
</form>
<% if(error !== null){ %>
<p><%= error %></p>
<% } %>
</center>
</body>
</html>
\ No newline at end of file
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