3 Commits

Author SHA1 Message Date
d2a1cb0d65 ajout de la logique du plateau 2025-10-29 00:57:30 +01:00
1c127319f9 Merge pull request 'initialisation des règles pour developer experience' (#5) from instructions-#4 into master
Reviewed-on: #5
Reviewed-by: Alistair VAISSE <alistair.vaisse@etu.u-pec.fr>
Reviewed-by: Clemence DUCREUX <clemence.ducreux@etu.u-pec.fr>
2025-10-16 10:58:40 +02:00
52d1488aca initialisation des règles pour developer experience 2025-10-16 10:53:54 +02:00
3 changed files with 333 additions and 1 deletions

116
README.md
View File

@@ -1 +1,115 @@
test
# Instructions de Travail sur les Tickets
Ce document présente la procédure à suivre lors de la création et de la gestion des tickets de développement. Veuillez suivre chaque étape avec attention.
## 1. Création du Ticket
### Titre du Ticket
Le titre doit décrire de manière générale la tâche à réaliser. Soyez précis, mais sans entrer dans les détails techniques. Par exemple :
Ajout d'une nouvelle fonctionnalité de recherche dans l'application
Correction du bug d'affichage sur la page d'accueil
### Description du Ticket
La description doit fournir une explication légèrement détaillée des tâches à réaliser. Elle doit inclure les éléments suivants :
Objectif global de la tâche
Étapes spécifiques ou parties du projet concernées
Comportement attendu une fois la tâche accomplie
## 2. Création de la Branche
Lorsque vous commencez à travailler sur un ticket, créez une nouvelle branche avec un nom particulier qui reflète le ticket en cours. Le format de la branche doit être :
nom-de-la-feature-#numeroduticket
### Pour créer une branche :
git checkout -b feature-recherche-#123
## 3. Commit des Changements
Les commits doivent suivre la convention suivante :
- Le message de commit doit décrire brièvement le changement effectué.
- À la fin du message de commit, vous devez toujours ajouter le numéro du ticket pour faciliter le suivi des tâches.
Exemple de message de commit :
Ajout du champ de recherche sur la page d'accueil #123
## 4. Push de la Branche
Après avoir effectué vos changements et effectué vos commits, vous devrez pousser la branche sur le dépôt distant. Lors de votre premier git push, vous recevrez un message pour définir l'upstream de la branche.
Exemple de message affiché :
```
fatal: The upstream branch 'origin/feature-recherche-#123' does not exist
To push the branch and set the upstream, use the following command:
git push --set-upstream origin nom-de-la-feature-#numero
```
Vous devez copier et coller la commande dans votre terminal pour effectuer le push. Une fois cette commande exécutée, votre branche sera poussée vers le dépôt distant.
## 5. Création d'une Pull Request (PR)
Une fois que vous avez poussé votre branche sur Gitea, vous devez ouvrir une pull request pour demander la révision de votre code.
Voici les étapes pour créer une pull request correctement :
- Allez sur Gitea et naviguez vers le projet concerné.
- Cliquez sur "Branches" et vous devriez voir la branche que vous venez de pousser.
- Cliquez sur le bouton "Create Pull Request" à côté de votre branche.
Remplissez les informations nécessaires :
- Titre de la PR : Utilisez le même titre que celui du ticket.
- Description de la PR : Décrivez brièvement ce que votre PR accomplit. Vous pouvez vous baser sur la description du ticket.
- Revues : Assurez-vous de demander une révision par deux membres de léquipe.
- Cliquez sur "Create Pull Request" pour soumettre.
Une fois la PR ouverte, vous devrez attendre la révision et lapprobation de léquipe avant de pouvoir fusionner la branche dans main ou develop selon le flux de travail de votre projet.
# Résumé des Commandes Git :
Voici un récapitulatif des commandes Git que vous utiliserez fréquemment :
## 1. Créer une branche
git checkout -b feature-recherche-#123
## 2. Ajouter les fichiers modifiés :
git add .
git add *
git add <nom_du_fichier>
## 3. Commit des changements :
git commit -m "Ajout de [...] #numeroticket"
## 4. Pousser la branche
git push -set-upstream origin <nom-de-la-branche-#numeroticket>
## 5. Supprimer une branche
git branch -d <nom_de_la_branche>

View File

@@ -0,0 +1,187 @@
package fr.iut_fbleau.HexGame;
import fr.iut_fbleau.GameAPI.*;
import java.util.*;
/**
* Plateau du jeu de Hex.
*
* Joueur 1 relie la gauche et la droite.
* Joueur 2 relie le haut et le bas.
*/
public class HexBoard extends AbstractBoard {
private final int size;
private Player[][] cells;
private Deque<AbstractPly> historyLocal;
private static final int[][] NEIGHBORS = {
{-1, 0}, {+1, 0},
{ 0, -1}, { 0, +1},
{-1, +1}, {+1, -1}
};
public HexBoard(int size) {
super();
this.size = size;
this.cells = new Player[size][size];
this.historyLocal = new ArrayDeque<>();
this.currentPlayer = Player.PLAYER1;
}
private boolean inBounds(int r, int c) {
return r >= 0 && r < size && c >= 0 && c < size;
}
private Player getCell(int r, int c) {
return cells[r][c];
}
private void setCell(int r, int c, Player p) {
cells[r][c] = p;
}
private boolean hasPlayer1Won() {
boolean[][] visited = new boolean[size][size];
Deque<int[]> stack = new ArrayDeque<>();
for (int r = 0; r < size; r++) {
if (getCell(r, 0) == Player.PLAYER1) {
visited[r][0] = true;
stack.push(new int[]{r, 0});
}
}
while (!stack.isEmpty()) {
int[] cur = stack.pop();
int cr = cur[0];
int cc = cur[1];
if (cc == size - 1) return true;
for (int[] d : NEIGHBORS) {
int nr = cr + d[0], nc = cc + d[1];
if (inBounds(nr, nc) && !visited[nr][nc] && getCell(nr, nc) == Player.PLAYER1) {
visited[nr][nc] = true;
stack.push(new int[]{nr, nc});
}
}
}
return false;
}
private boolean hasPlayer2Won() {
boolean[][] visited = new boolean[size][size];
Deque<int[]> stack = new ArrayDeque<>();
for (int c = 0; c < size; c++) {
if (getCell(0, c) == Player.PLAYER2) {
visited[0][c] = true;
stack.push(new int[]{0, c});
}
}
while (!stack.isEmpty()) {
int[] cur = stack.pop();
int cr = cur[0];
int cc = cur[1];
if (cr == size - 1) return true;
for (int[] d : NEIGHBORS) {
int nr = cr + d[0], nc = cc + d[1];
if (inBounds(nr, nc) && !visited[nr][nc] && getCell(nr, nc) == Player.PLAYER2) {
visited[nr][nc] = true;
stack.push(new int[]{nr, nc});
}
}
}
return false;
}
@Override
public boolean isLegal(AbstractPly move) {
if (!(move instanceof HexPly)) return false;
HexPly hp = (HexPly) move;
int r = hp.getRow(), c = hp.getCol();
return inBounds(r, c)
&& getCell(r, c) == null
&& hp.getPlayer() == this.getCurrentPlayer();
}
@Override
public void doPly(AbstractPly move) {
if (!(move instanceof HexPly))
throw new IllegalArgumentException("Coup invalide: " + move);
HexPly hp = (HexPly) move;
if (!isLegal(hp))
throw new IllegalStateException("Coup illégal: " + hp);
setCell(hp.getRow(), hp.getCol(), hp.getPlayer());
historyLocal.push(hp);
setNextPlayer();
}
@Override
public boolean isGameOver() {
return hasPlayer1Won() || hasPlayer2Won();
}
@Override
public Result getResult() {
if (hasPlayer1Won()) return Result.WIN;
if (hasPlayer2Won()) return Result.LOSS;
return Result.DRAW;
}
@Override
public Iterator<AbstractPly> getPlies() {
Player me = this.getCurrentPlayer();
List<AbstractPly> moves = new ArrayList<>();
for (int r = 0; r < size; r++) {
for (int c = 0; c < size; c++) {
if (getCell(r, c) == null) moves.add(new HexPly(me, r, c));
}
}
return moves.iterator();
}
@Override
public Iterator<AbstractPly> getHistory() {
return historyLocal.iterator();
}
@Override
public void undoLastPly() {
if (historyLocal.isEmpty()) return;
HexPly last = (HexPly) historyLocal.pop();
setCell(last.getRow(), last.getCol(), null);
this.currentPlayer = last.getPlayer();
}
@Override
public IBoard safeCopy() {
HexBoard copy = new HexBoard(this.size);
copy.currentPlayer = this.currentPlayer;
for (int r = 0; r < size; r++) {
for (int c = 0; c < size; c++) {
copy.cells[r][c] = this.cells[r][c];
}
}
copy.historyLocal = new ArrayDeque<>(this.historyLocal);
return copy;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int r = 0; r < size; r++) {
for (int k = 0; k < r; k++) sb.append(" ");
for (int c = 0; c < size; c++) {
Player p = getCell(r, c);
char ch = '.';
if (p == Player.PLAYER1) ch = '1';
else if (p == Player.PLAYER2) ch = '2';
sb.append(ch).append(" ");
}
sb.append("\n");
}
sb.append("Current player: ").append(getCurrentPlayer()).append("\n");
return sb.toString();
}
public int getSize() {
return size;
}
}

View File

@@ -0,0 +1,31 @@
package fr.iut_fbleau.HexGame;
import fr.iut_fbleau.GameAPI.*;
/**
* Représente un coup dans le jeu de Hex.
*/
public class HexPly extends AbstractPly {
private final int row;
private final int col;
public HexPly(Player j, int row, int col) {
super(j);
this.row = row;
this.col = col;
}
public int getRow() {
return this.row;
}
public int getCol() {
return this.col;
}
@Override
public String toString() {
return "HexPly{player=" + getPlayer() + ", row=" + row + ", col=" + col + "}";
}
}