package gui;
import java.util.ArrayList;
import BasicDataType.MapUpdate;
/**
* Representation of a map.
* @author Dennis Sandmark & Torbjörn Svangård
*
*/
public class Map {
// Identifiers for the status of a square.
public static final byte UNEXPLORED = 0;
public static final byte OCCUPIED = 1;
public static final byte EMPTY = -1;
/**
*
* Representation of a square in the map.
* Contains two counters, one for occupied propagations and another for empty propagations.
*
*/
private class Square {
byte nrOccupied;
byte nrEmpty;
public Square() {
nrOccupied = 0;
nrEmpty = 0;
}
public void propagateOccupied() {
// Make sure that the value do not exceed the maximum value for a signed byte.
if(nrOccupied >= 127)
return;
nrOccupied++;
}
public void propagateEmpty() {
// Make sure that the value do not exceed the maximum value for a signed byte.
if(nrEmpty >= 127)
return;
nrEmpty++;
}
public byte getDiff() {
// If square is not visited
if(nrOccupied == 0 && nrEmpty == 0)
return UNEXPLORED;
// If the difference is positive then the square is occupied
else if (nrOccupied - nrEmpty >= 0)
return OCCUPIED;
// If the difference is negative then the square is empty
return EMPTY;
}
/**
* Return ratio of nr of empty propagations vs nr of occupied propagations.
* Value is certainty factor between 0 and 100 where 100 means that every robot that
* has visited has propagated the same exploration value.
* @return The method returns ratio between amount of propagations.
*/
public byte getRatio() {
if(nrOccupied >= nrEmpty)
return (byte) (nrOccupied * 100 / (nrOccupied + nrEmpty));
else
return (byte) (nrEmpty * 100 / (nrOccupied + nrEmpty));
}
/**
* The method returns the number of visits at this square).
* @return The method returns the number of visits at this square.
*/
public byte getVisits(){
return (byte)(nrOccupied + nrEmpty < 100 ? nrOccupied + nrEmpty : 100);
}
}
private Square[][] grid;
private byte mapSize;
/**
* All squares in the map is set as unexplored on initialization.
* @param size The width and height of the square map.
*/
public Map(byte size){
mapSize = size;
grid = new Square[mapSize][mapSize];
for(int x=0; x < mapSize; x++){
for(int y=0; y < mapSize; y++){
grid[x][y] = new Square();
}
}
}
/**
* Generates an ArrayList of visited Squares
* @return ArrayList of MapUpdates containing every visited square
*/
synchronized public ArrayList<MapUpdate> getVisitedSquares(){
ArrayList<MapUpdate> visitedSquares = new ArrayList<MapUpdate>();
/*
* Iterate through entire map and add visited squares to the ArrayList
*/
for(int x=0; x < mapSize; x++)
for(int y=0; y < mapSize; y++)
if(grid[x][y].getVisits() != 0)
visitedSquares.add(new MapUpdate(grid[x][y].getDiff(), (byte)x, (byte)y));
return visitedSquares;
}
/**
* Set a square in the map as occupied.
* @param x The x coordinate of the square.
* @param y The y coordinate of the square.
*/
public void propagateOccupied(byte x, byte y){
assert y < 0 : "y-value is below zero";
assert x < 0 : "x-value is below zero";
assert x >= mapSize : "x-value is greater than mapSize";
assert y >= mapSize : "y-value is greater than mapSize";
//Propagate the square at location (x, y) as Occupied.
grid[x][y].propagateOccupied();
}
/**
* Set a square in the map as empty.
* @param x The x coordinate of the square.
* @param y The y coordinate of the square.
*/
public void propagateEmpty(byte x, byte y){
assert y < 0 : "y-value is below zero";
assert x < 0 : "x-value is below zero";
assert x >= mapSize : "x-value is greater than mapSize";
assert y >= mapSize : "y-value is greater than mapSize";
// Propagate the square at location (x, y) as Empty.
grid[x][y].propagateEmpty();
}
/**
* Retrieves the difference of propagations of a square in the map.
* @param x The x coordinate of the square.
* @param y The y coordinate of the square.
* @return The method returns 0 if the square is unexplored.
* A positive value if the square is occupied.
* A negative value if the square is empty.
*/
public byte getSquareDifference(byte x, byte y){
assert y < 0 : "y-value is below zero";
assert x < 0 : "x-value is below zero";
assert x >= mapSize : "x-value is greater than mapSize";
assert y >= mapSize : "y-value is greater than mapSize";
return grid[x][y].getDiff();
}
/**
* Return ratio of nr of empty propagations vs nr of occupied propagations.
* Value is certainty factor between 0 and 100 where 100 means that every robot that
* has visited has propagated the same exploration value.
* @param x The x coordinate of the square.
* @param y The y coordinate of the square.
* @return The method returns ratio between amount of propagations.
*/
public byte getSquareRatio(byte x, byte y) {
assert y < 0 : "y-value is below zero";
assert x < 0 : "x-value is below zero";
assert x >= mapSize : "x-value is greater than mapSize";
assert y >= mapSize : "y-value is greater than mapSize";
return (byte)grid[x][y].getRatio();
}
/**
* The method returns the number of visits at square (x, y).
* @param x The x coordinate of the square.
* @param y The y coordinate of the square.
* @return The method returns the number of visits at square (x, y).
*/
public byte getSquareVisits(byte x, byte y) {
assert y < 0 : "y-value is below zero";
assert x < 0 : "x-value is below zero";
assert x >= mapSize : "x-value is greater than mapSize";
assert y >= mapSize : "y-value is greater than mapSize";
return (byte)grid[x][y].getVisits();
}
/**
* Tool for displaying the map in the console.
* Outputs the map and its corresponding explorationvalues as text in the console.
* The point (0,0) is in the low left corner.
*/
public void showMap() {
for(byte x=0; x<mapSize; x++) {
for(byte y=0; y<mapSize; y++)
System.out.print(getSquareDifference((byte)(mapSize-x-1),y) + " ");
System.out.println("");
}
}
}