package fr.iut_fbleau.Avalam; import fr.iut_fbleau.GameAPI.AbstractBoard; import fr.iut_fbleau.GameAPI.AbstractPly; import fr.iut_fbleau.GameAPI.IBoard; import fr.iut_fbleau.GameAPI.Player; import fr.iut_fbleau.GameAPI.Result; import java.util.ArrayDeque; import java.util.Iterator; public class AvalamBoard extends AbstractBoard { public static final int SIZE = 9; private static final int MAX_HEIGHT = 5; private final Tower[][] grid; private boolean gameOver = false; private Result result = null; public AvalamBoard(Tower[][] initialGrid, Player startingPlayer) { super(startingPlayer, new ArrayDeque<>()); this.grid = new Tower[SIZE][SIZE]; for (int r = 0; r < SIZE; r++) for (int c = 0; c < SIZE; c++) this.grid[r][c] = initialGrid[r][c]; } public AvalamBoard(Tower[][] initialGrid) { this(initialGrid, Player.PLAYER1); } private AvalamBoard(Tower[][] grid, Player current, boolean gameOver, Result result) { super(current, new ArrayDeque<>()); this.grid = grid; this.gameOver = gameOver; this.result = result; } public Tower getTowerAt(int row, int col) { return inBounds(row, col) ? grid[row][col] : null; } private boolean inBounds(int r, int c) { return r >= 0 && r < SIZE && c >= 0 && c < SIZE; } private boolean areAdjacent(int r1, int c1, int r2, int c2) { int dr = Math.abs(r1 - r2); int dc = Math.abs(c1 - c2); return (dr <= 1 && dc <= 1 && !(dr == 0 && dc == 0)); } private Color colorForPlayer(Player p) { return (p == Player.PLAYER1 ? Color.YELLOW : Color.RED); } @Override public boolean isGameOver() { if (gameOver) return true; Iterator it = iterator(); if (it.hasNext()) return false; gameOver = true; return true; } @Override public Result getResult() { if (!isGameOver()) return null; if (result != null) return result; int yellow = 0; int red = 0; for (int r = 0; r < SIZE; r++) for (int c = 0; c < SIZE; c++) { Tower t = grid[r][c]; if (t == null) continue; if (t.getColor() == Color.YELLOW) yellow++; else if (t.getColor() == Color.RED) red++; } if (yellow > red) result = Result.WIN; else if (yellow < red) result = Result.LOSS; else result = Result.DRAW; return result; } @Override public boolean isLegal(AbstractPly c) { if (!(c instanceof AvalamPly)) return false; AvalamPly p = (AvalamPly) c; int xF = p.getXFrom(), yF = p.getYFrom(); int xT = p.getXTo(), yT = p.getYTo(); if (!inBounds(xF, yF) || !inBounds(xT, yT)) return false; if (xF == xT && yF == yT) return false; Tower src = grid[xF][yF]; Tower dst = grid[xT][yT]; if (src == null || dst == null) return false; if (src.getColor() != colorForPlayer(getCurrentPlayer())) return false; if (!areAdjacent(xF, yF, xT, yT)) return false; if (src.getColor() == dst.getColor()) return false; if (src.getHeight() + dst.getHeight() > MAX_HEIGHT) return false; return true; } @Override public void doPly(AbstractPly c) { if (!isLegal(c)) throw new IllegalArgumentException("Coup illégal : " + c); AvalamPly p = (AvalamPly) c; int xF = p.getXFrom(), yF = p.getYFrom(); int xT = p.getXTo(), yT = p.getYTo(); Tower src = grid[xF][yF]; Tower dst = grid[xT][yT]; dst.mergeTower(src); grid[xF][yF] = null; super.doPly(c); gameOver = false; result = null; } @Override public Iterator iterator() { java.util.List moves = new java.util.ArrayList<>(); Player cur = getCurrentPlayer(); for (int r = 0; r < SIZE; r++) { for (int c = 0; c < SIZE; c++) { for (int dr = -1; dr <= 1; dr++) { for (int dc = -1; dc <= 1; dc++) { if (dr == 0 && dc == 0) continue; int nr = r + dr, nc = c + dc; AvalamPly p = new AvalamPly(cur, r, c, nr, nc); if (isLegal(p)) moves.add(p); } } } } return moves.iterator(); } @Override public IBoard safeCopy() { Tower[][] newGrid = new Tower[SIZE][SIZE]; for (int r = 0; r < SIZE; r++) for (int c = 0; c < SIZE; c++) newGrid[r][c] = grid[r][c]; return new AvalamBoard(newGrid, getCurrentPlayer(), gameOver, result); } }