ajout de la logique du plateau

This commit is contained in:
2025-10-29 00:57:30 +01:00
parent 1c127319f9
commit d2a1cb0d65
2 changed files with 218 additions and 0 deletions

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 + "}";
}
}