import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Random;
public class GameBoard {
private final int rows;
private final int cols;
private final List<MakhlukGame> daftarMakhluk = new ArrayList<>();
private final Random random = new Random();
public GameBoard(int rows, int cols) {
if (rows <= 0 || cols <= 0) {
throw new IllegalArgumentException("Ukuran papan harus lebih besar dari nol");
}
this.rows = rows;
this.cols = cols;
}
public void tambahMakhluk(MakhlukGame makhluk) {
if (!posisiDiDalam(makhluk.getPosisi())) {
throw new IllegalArgumentException("Posisi makhluk berada di luar papan");
}
if (!kosong(makhluk.getPosisi())) {
throw new IllegalArgumentException("Petak sudah terisi makhluk lain");
}
daftarMakhluk.add(makhluk);
}
public void hapusMakhluk(MakhlukGame makhluk) {
daftarMakhluk.remove(makhluk);
}
public void pindahkanMakhluk(MakhlukGame makhluk, Position posisiBaru) {
if (!posisiDiDalam(posisiBaru)) {
return;
}
makhluk.pindahKe(posisiBaru);
}
public boolean posisiDiDalam(Position posisi) {
int r = posisi.getRow();
int c = posisi.getCol();
return r >= 0 && r < rows && c >= 0 && c < cols;
}
public boolean kosong(Position posisi) {
return getMakhlukPada(posisi) == null;
}
public MakhlukGame getMakhlukPada(Position posisi) {
for (MakhlukGame makhluk : daftarMakhluk) {
if (makhluk.getPosisi().equals(posisi)) {
return makhluk;
}
}
return null;
}
public List<MakhlukGame> getMakhluk() {
return Collections.unmodifiableList(daftarMakhluk);
}
public List<Position> tetangga(Position posisi) {
List<Position> hasil = new ArrayList<>();
for (int dr = -1; dr <= 1; dr++) {
for (int dc = -1; dc <= 1; dc++) {
if (dr == 0 && dc == 0) {
continue;
}
Position kandidat = new Position(posisi.getRow() + dr, posisi.getCol() + dc);
if (posisiDiDalam(kandidat)) {
hasil.add(kandidat);
}
}
}
return hasil;
}
public List<Position> tetanggaKosong(Position posisi) {
List<Position> kosong = new ArrayList<>();
for (Position kandidat : tetangga(posisi)) {
if (kosong(kandidat)) {
kosong.add(kandidat);
}
}
return kosong;
}
public Optional<MakhlukGame> cariTerdekat(Class<? extends MakhlukGame> tipe, Position dari) {
MakhlukGame kandidat = null;
int jarakTerdekat = Integer.MAX_VALUE;
for (MakhlukGame makhluk : daftarMakhluk) {
if (tipe.isInstance(makhluk)) {
int jarak = dari.manhattanDistance(makhluk.getPosisi());
if (jarak < jarakTerdekat) {
jarakTerdekat = jarak;
kandidat = makhluk;
}
}
}
return Optional.ofNullable(kandidat);
}
public void jalankanPutaran() {
List<MakhlukGame> iterasi = new ArrayList<>(daftarMakhluk);
Collections.shuffle(iterasi, random);
for (MakhlukGame makhluk : iterasi) {
if (daftarMakhluk.contains(makhluk)) {
makhluk.lakukanLangkah(this);
}
}
}
public void tampilkanPapan() {
char[][] grid = new char[rows][cols];
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
grid[r][c] = '.';
}
}
for (MakhlukGame makhluk : daftarMakhluk) {
Position pos = makhluk.getPosisi();
grid[pos.getRow()][pos.getCol()] = makhluk.getSimbol();
}
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
System.out.print(grid[r][c] + " ");
}
System.out.println();
}
}
public Random getRandom() {
return random;
}
public int hitungMakhluk(Class<? extends MakhlukGame> tipe) {
int total = 0;
for (MakhlukGame makhluk : daftarMakhluk) {
if (tipe.isInstance(makhluk)) {
total++;
}
}
return total;
}
}