package main;
public class Level {
private int maxwidth = 0;
public char[][] grid;
public boolean[][] targets;
private int playerX;
private int playerY;
private int width;
private int height;
private History history;
static final char WALL = '#';
static final char EMPTY = ' ', TARGET = '.';
static final char PLAYER = '@', PLAYER_ON_TARGET = '+';
static final char BOX = '$', BOX_ON_TARGET = '*';
public Level(String line) {
String[] lines = line.split("\\|");
this.height = lines.length;
for (int i = 0; i < lines.length; i++) {
if (lines[i].length() > maxwidth) {
maxwidth = lines[i].length();
}
}
this.width = maxwidth;
grid = new char[lines.length][maxwidth];
targets = new boolean[lines.length][maxwidth];
for (int i = 0;i<lines.length;i++){
for (int j=0;j<maxwidth;j++){
grid[i][j] = (j < lines[i].length() ? lines[i].charAt(j) : EMPTY);
}
}
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j] == PLAYER) {
playerY = i;
playerX = j;
}
if (grid[i][j] == TARGET) {
targets[i][j] = true;
}
else if (grid[i][j] == PLAYER_ON_TARGET) {
targets[i][j] = true;
}
else if (grid[i][j] == BOX_ON_TARGET) {
targets[i][j] = true;
}
else {
targets[i][j] = false;
}
}
}
history = new History();
}
public int getX() {
return this.playerX;
}
public int getY() {
return this.playerY;
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public int getMoves() {
return history.getMoves();
}
public int getPushes() {
return history.getPushes();
}
public void setCell(int y, int x, char c) {
if (c == BOX && targets[y][x] == true) {
grid[y][x] = BOX_ON_TARGET;
}
else if (c == PLAYER && targets[y][x] == true) {
grid[y][x] = PLAYER_ON_TARGET;
}
else {
grid[y][x] = c;
}
}
public void doMove(int dx, int dy) {
boolean push = true;
if (grid[playerY + dy][playerX + dx] == BOX) {
setCell(playerY + dy, playerX + dx, PLAYER);
setCell(playerY + (dy*2), playerX + (dx*2), BOX);
if (targets[playerY][playerX]) setCell (playerY, playerX, TARGET); else setCell (playerY, playerX, EMPTY);
}
else if (grid[playerY + dy][playerX + dx] == BOX_ON_TARGET) {
setCell(playerY + dy, playerX + dx, PLAYER);
setCell(playerY + (dy*2), playerX + (dx*2), BOX);
if (targets[playerY][playerX]) setCell (playerY, playerX, TARGET); else setCell (playerY, playerX, EMPTY);
}
else {
setCell (playerY + dy, playerX + dx, PLAYER);
push = false;
if (targets[playerY][playerX]) setCell (playerY, playerX, TARGET); else setCell (playerY, playerX, EMPTY);
}
history.add(new Log(playerY, playerX, dy, dx, push));
playerX = playerX + dx;
playerY = playerY + dy;
}
public boolean checkMove (int x, int y) {
boolean move = true;
if (grid[playerY + y][playerX + x] == WALL) {
move = false;
}
else if (grid[playerY+y][playerX+x] == BOX && grid[playerY+(y*2)][playerX+(x*2)] == WALL) {
move = false;
}
else if (grid[playerY+y][playerX+x] == BOX_ON_TARGET && grid[playerY+(y*2)][playerX+(x*2)] == WALL) {
move = false;
}
else if (grid[playerY+y][playerX+x] == BOX && grid[playerY+(y*2)][playerX+(x*2)] == BOX) {
move = false;
}
else if (grid[playerY+y][playerX+x] == BOX && grid[playerY+(y*2)][playerX+(x*2)] == BOX_ON_TARGET) {
move = false;
}
else if (grid[playerY+y][playerX+x] == BOX_ON_TARGET && grid[playerY+(y*2)][playerX+(x*2)] == BOX) {
move = false;
}
else {
move = true;
}
return move;
}
public Log undoMove() {
Log log = history.remove();
if(log != null){
setCell(playerY, playerX, EMPTY);
setCell(playerY - log.getDy(), playerX - log.getDx(), PLAYER);
if (log.getPush()) {
setCell(playerY, playerX, BOX);
setCell(playerY + log.getDy(), playerX + log.getDx(), EMPTY);
}
playerX -= log.getDx();
playerY -= log.getDy();
}
return log;
}
public boolean hasWon() {
boolean hasWon = true;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j] == BOX) {hasWon = false; break;}
}
}
return hasWon;
}
public History getHistory() {
return this.history;
}
public String toString() {
String output="";
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
output += grid[i][j];
}
}
return(output);
}
}