package Base;
import java.awt.Point;
public class YourRiderExecutor implements IRiderExecutor{
IGrid grid;
IRiderStatus riderStatus;
public YourRiderExecutor(IGrid grid){
this.grid = grid;
riderStatus = new IRiderStatus(grid.maxhp);
}
/**
* Will return an object of IGridStatus containing information about the Grid
*/
public IGridStatus getGridStatus() {
return grid.status;
}
/**
* Will return the status of the nodes in the area around a rider
*/
public INodeStatus[][] lookAround() {
INodeStatus[][] area = new INodeStatus[5][5];
IRiderStatus riderStatus = this.status();
for(int x = 0; x<5; x++)
for(int y = 0; y<5; y++){
int i = riderStatus.x-2+x;
int j = riderStatus.y-2+y;
// Check for out of bounds
if(i<0 || j<0 || i>=grid.N || j>=grid.N)
area[x][y] = null;
else
area[x][y] = grid.grid[i][j];
}
return area;
}
/**
* Will move a rider in a given direction
*/
public void move(IDirection d) {
IRiderStatus riderStatus = this.status();
// Default direction is neutral
int xDir = 0;
int yDir = 0;
if(d==IDirection.NORTH)
yDir = -1;
else if(d==IDirection.EAST)
xDir = 1;
else if(d==IDirection.SOUTH)
yDir = 1;
else if(d==IDirection.WEST)
xDir = -1;
int oldX = riderStatus.x;
int oldY = riderStatus.y;
// New coordinates
int newX = oldX+xDir;
int newY = oldY+yDir;
System.out.println("Move to ("+newX+","+newY+")");
// Check for node existance
if(newX>=0 && newY>=0 && newX<grid.N && newY<grid.N && this.grid.grid[newX][newY].wall==null){
// Set wall
this.grid.grid[newX][newY].wall = d;
// Set new rider coordinates
riderStatus.x = newX;
riderStatus.y = newY;
// Set new rided location on grid
this.grid.grid[newX][newY].teamID = this.grid.grid[oldX][oldY].teamID;
}
else
this.handleCollision(riderStatus, d, newX, newY);
try {
Thread.sleep(grid.speed*1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
return;
}
}
private void handleCollision(IRiderStatus riderStatus, IDirection d, int newX, int newY) {
// Get last node where rider was
INodeStatus lastNode = grid.getNodeStatus(riderStatus.x, riderStatus.y);
// Get team ID
int teamID = lastNode.teamID;
// Decrease HP
riderStatus.hp--;
System.out.println("Collision on ("+newX+","+newY+") by rider with team id: "+teamID);
// Get node where collision took place IF that node is within the grid
INodeStatus collisionNode = null;
if(newX>=0 && newY>=0 && newX<grid.N && newY<grid.N){
collisionNode = grid.getNodeStatus(newX, newY);
}
// RemoveWall of the rider
this.removeWall2(lastNode, true, teamID);
// If there is a collision node a force line has to be partially removed
if(collisionNode!=null)
// Only start removing force line isn't already cleared by previous remove action
if(collisionNode.wall!=null){
System.out.println("Collision with other force line on node ("+newX+","+newY+")" +
" with team id "+collisionNode.teamID + " by rider with team id "+teamID);
this.removeWall2(collisionNode, false,teamID);
//System.out.println(collisionNode.teamID + " by rider with team id "+teamID);
}
// If rider still alive, relocate him
if(riderStatus.hp>0)
this.relocateRider(riderStatus, teamID);
else // If rider died, deactivate him
this.deactivateRider(riderStatus);
System.out.println("Done with collision handling on ("+newX+","+newY+")");
}
private void removeWall2(INodeStatus nodeStatus, boolean complete, int teamID) {
/*
* If wall direction is already null it probably has already been cleared by
* it's original owner
*/
if(nodeStatus.wall==null)
return;
System.out.println(nodeStatus.x+"|"+nodeStatus.y+"|"+
nodeStatus.wall+"|"+nodeStatus.teamID+"|"+complete+ "|"+teamID);
synchronized(nodeStatus){
// Clear node if end of force line is reached and complete = true
if(nodeStatus.wall==IDirection.NEUTRAL && complete){
grid.updateNodeStatus(nodeStatus, -1, null);
return;
}
else if(nodeStatus.wall==IDirection.NEUTRAL && !complete){
/* End of force line, but line doesn't have to be
* cleared completely so do nothing
*/
}
else if(nodeStatus.wall!=IDirection.NEUTRAL){
Point p = this.getWallDirection(nodeStatus.wall);
INodeStatus nextNode = grid.getNodeStatus(nodeStatus.x+p.x, nodeStatus.y+p.y);
this.removeWall2(nextNode, true, teamID);
// If complete line has to be removed just clear the node
if(complete)
grid.updateNodeStatus(nodeStatus, -1, null);
// If complete = false than make this node the new end of the line
else
grid.updateNodeStatus(nodeStatus, nodeStatus.teamID, IDirection.NEUTRAL);
}
}
}
private void removeWall(IDirection d, INodeStatus nodeStatus, boolean complete) {
/* If direction is already neutral the rider crashed into the end of a force line,
* which means nothing has to be removed
*/
if(nodeStatus.wall==IDirection.NEUTRAL && !complete)
return;
while(nodeStatus.wall!=IDirection.NEUTRAL){
Point p = this.getWallDirection(nodeStatus.wall);
if(complete)
grid.updateNodeStatus(nodeStatus, -1, null);
else{
grid.updateNodeStatus(nodeStatus, nodeStatus.teamID, IDirection.NEUTRAL);
complete = true;
}
nodeStatus = grid.getNodeStatus(nodeStatus.x+p.x, nodeStatus.y+p.y);
}
grid.updateNodeStatus(nodeStatus, -1, null);
}
/**
* Will relocate a rider after an collision
* @param riderStatus
* @param teamID
*/
private void relocateRider(IRiderStatus riderStatus, int teamID ) {
grid.placeRider(teamID, riderStatus);
}
/**
* Will deactive a rider when he as no hp left
* @param riderStatus
*/
private void deactivateRider(IRiderStatus riderStatus) {
grid.status.numOfRemainingRiders--;
riderStatus.x=-1; riderStatus.y=-1;
System.out.println("Dood!");
}
/**
* Will return the opposite direction of a wall in the form of a point
* @param wall
* @return
*/
private Point getWallDirection(IDirection wall) {
if(wall==IDirection.NORTH)
return new Point(0,1);
if(wall==IDirection.SOUTH)
return new Point(0,-1);
if(wall==IDirection.EAST)
return new Point(-1,0);
if(wall==IDirection.WEST)
return new Point(1,0);
return new Point(0,0);
}
public IRiderStatus status() {
return this.riderStatus;
}
}