Files
BUT3ProjetJeuGroupe/fr/iut_fbleau/Avalam/AvalamBoard.java

173 lines
4.8 KiB
Java

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<AbstractPly> 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<AbstractPly> iterator() {
java.util.List<AbstractPly> 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);
}
}