WIP: First draft of the board (Need predicate for wall placement decision)
This commit is contained in:
parent
8e3a9a35a8
commit
c4bb683797
@ -1,14 +1,260 @@
|
|||||||
|
/**
|
||||||
|
* @file Board.java
|
||||||
|
*
|
||||||
|
* @author Christos Choutouridis AEM:8997
|
||||||
|
* @email cchoutou@ece.auth.gr
|
||||||
|
*/
|
||||||
|
|
||||||
package net.hoo2.auth.labyrinth;
|
package net.hoo2.auth.labyrinth;
|
||||||
|
|
||||||
|
import java.util.function.IntFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* This class is the representation of the games's board
|
||||||
|
*
|
||||||
|
* The board is the square arrangement of the tiles. This class is also
|
||||||
|
* the owner of the tile and supply objects.
|
||||||
|
*/
|
||||||
public class Board {
|
public class Board {
|
||||||
|
/** @name Constructors */
|
||||||
|
/** @{ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The empty constructor for default initialization
|
||||||
|
*/
|
||||||
|
protected Board() {
|
||||||
|
this.N = this.S = this.W = 0;
|
||||||
|
this.tiles = null;
|
||||||
|
this.supplies =null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main constructor for the application
|
||||||
|
* @param N The size of each edge of the board
|
||||||
|
* @param S The number of supplies on the board
|
||||||
|
* @param W The number of walls on the board
|
||||||
|
*/
|
||||||
|
protected Board(int N, int S, int W) {
|
||||||
|
assert (W>= 4*N-1 && W<=(3*N*N+1)/2 )
|
||||||
|
: "Boards walls has to be in the range [4N-1, (3N^2+1)/2]";
|
||||||
|
|
||||||
|
this.N = Session.boardSize = N;
|
||||||
|
this.S = S;
|
||||||
|
this.W = W;
|
||||||
|
tiles = new Tile[N*N];
|
||||||
|
supplies = new Supply[S];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deep copy constructor
|
||||||
|
* @param b The board to copy
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* The lack of value semantics in java is (in author's opinion) one of the greatest
|
||||||
|
* weakness of the language and one of the reasons why it will never be a language
|
||||||
|
* to care about. To quote Alexander Stepanof's words in "elements of programming" section 1.5:
|
||||||
|
* "Assignment is a procedure that takes two objects of the same type and makes the first
|
||||||
|
* object equal to the second without modifying the second".
|
||||||
|
* In this class we try to cope with this situation knowing that we can not do anything about
|
||||||
|
* assignment operator. We just add value semantics to the copy constructor and go on with our lifes...
|
||||||
|
*/
|
||||||
|
protected Board(Board b) {
|
||||||
|
// Copy primitives
|
||||||
|
this.N = b.N;
|
||||||
|
this.S = b.S;
|
||||||
|
this.W = b.W;
|
||||||
|
// Clone arrays
|
||||||
|
this.tiles = b.tiles.clone();
|
||||||
|
this.supplies = b.supplies.clone();
|
||||||
|
}
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/** @name Supply's main application interface */
|
||||||
|
/** @{ */
|
||||||
|
|
||||||
|
protected void createTiles() {
|
||||||
|
int wallPool = W;
|
||||||
|
wallPool -= createBasicTileWalls ();
|
||||||
|
createInnerWalls(wallPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void createSupplies(int theseusTile, int minotaurTile) {
|
||||||
|
ShuffledRange rand = new ShuffledRange(0, N*N);
|
||||||
|
for (int tileId, i=0 ; i<supplies.length ; ++i) {
|
||||||
|
do
|
||||||
|
tileId = rand.get();
|
||||||
|
while (tileId == theseusTile || tileId == minotaurTile);
|
||||||
|
supplies[i] = new Supply(i, tileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void createBoard(int theseusTile, int minotaurTile) {
|
||||||
|
createTiles();
|
||||||
|
createSupplies(theseusTile, minotaurTile);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String[][] getStringRepresentation(int theseusTile, int minotaurTile) {
|
||||||
|
String[][] frame = new String[2*N+1][N];
|
||||||
|
|
||||||
|
for (int row=0 ; row<N ; ++row) {
|
||||||
|
int col;
|
||||||
|
for (col =0 ; col<N-1 ; ++col)
|
||||||
|
renderTile(frame, row, col, theseusTile, minotaurTile);
|
||||||
|
renderSentinelTile(frame, row, col, theseusTile, minotaurTile);
|
||||||
|
}
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void printBoard (String[][] sBoard) {
|
||||||
|
for (int i=sBoard.length-1 ; i>=0 ; --i) {
|
||||||
|
for (String it : sBoard[i])
|
||||||
|
System.out.print(it);
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int size() { return N; }
|
int size() { return N; }
|
||||||
|
|
||||||
private int N;
|
/** @} */
|
||||||
private int S;
|
|
||||||
private int W;
|
/**
|
||||||
private Tile[] tiles;
|
* @name Accessor/Mutator interface
|
||||||
private Supply[] supplies;
|
* @note
|
||||||
|
* Please consider not to use mutator interface. Its the abstraction killer :(
|
||||||
|
*/
|
||||||
|
/** @{ */
|
||||||
|
protected int getN() { return N; }
|
||||||
|
protected int getS() { return S; }
|
||||||
|
protected int getW() { return W; }
|
||||||
|
/**
|
||||||
|
* @note Use it with care. Any use of this function results to what Sean Parent calls "incidental data-structure".
|
||||||
|
* <a href="https://github.com/sean-parent/sean-parent.github.io/blob/master/better-code/03-data-structures.md"> see also here</a>
|
||||||
|
* @return Reference to inner tiles array.
|
||||||
|
*/
|
||||||
|
protected Tile[] getTiles() { return tiles; }
|
||||||
|
/**
|
||||||
|
* @note Use it with care. Any use of this function results to what Sean Parent calls "incidental data-structure".
|
||||||
|
* <a href="https://github.com/sean-parent/sean-parent.github.io/blob/master/better-code/03-data-structures.md"> see also here</a>
|
||||||
|
* @return Reference to inner supplies array.
|
||||||
|
*/
|
||||||
|
protected Supply[] getSupplies() { return supplies; }
|
||||||
|
|
||||||
|
protected void setN(int N) { this.N = N; }
|
||||||
|
protected void setS(int S) { this.S = S; }
|
||||||
|
protected void setW(int W) { this.W = W; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tiles Reference to tiles that we want to act as replacement for the inner tiles array.
|
||||||
|
* @note Use with care.
|
||||||
|
* Any call to this function will probably add memory for the garbage collector.
|
||||||
|
*/
|
||||||
|
protected void setTiles(Tile[] tiles) { this.tiles = tiles; }
|
||||||
|
/**
|
||||||
|
* @param supplies Reference to supplies that we want to act as replacement for the inner supplies array.
|
||||||
|
* @note Use with care.
|
||||||
|
* Any call to this function will probably add memory for the garbage collector.
|
||||||
|
*/
|
||||||
|
protected void setSupplies(Supply[] supplies) { this.supplies= supplies; }
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
private int createBasicTileWalls () {
|
||||||
|
int tileCount =0;
|
||||||
|
// Create basic tiles and outer walls
|
||||||
|
for (int i =0 ; i< tiles.length ; ++i) {
|
||||||
|
int r = Position.toRow(i);
|
||||||
|
int c = Position.toCol(i);
|
||||||
|
boolean up = (r == N-1) ? true : false;
|
||||||
|
boolean down = (r == 0 && c != 0) ? true : false;
|
||||||
|
boolean left = (c == 0) ? true : false;
|
||||||
|
boolean right = (c == N-1) ? true : false;
|
||||||
|
tileCount += ((up?1:0) + (down?1:0) + (left?1:0) + (right?1:0));
|
||||||
|
tiles[i] = new Tile (i, up, down, left, right);
|
||||||
|
}
|
||||||
|
return tileCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int createInnerWalls (int wallPool) {
|
||||||
|
// Create inner walls for the rest of the desired walls
|
||||||
|
ShuffledRange randTiles = new ShuffledRange(0, N*N);
|
||||||
|
for (int tileId, i =0 ; i<wallPool ; ++i) {
|
||||||
|
// randomly pick a tile with less than 2 walls
|
||||||
|
do {
|
||||||
|
tileId = randTiles.get();
|
||||||
|
if (tileId == Const.noTileId)
|
||||||
|
return 0;
|
||||||
|
} while (tiles[tileId].hasWalls() >= 2); //XXX: Predicate : can put wall
|
||||||
|
// Randomly pick a not used direction in that tile
|
||||||
|
ShuffledRange randDirections = new ShuffledRange(Direction.Begin, Direction.Step, Direction.End);
|
||||||
|
Position tilePos = new Position(tileId);
|
||||||
|
int dir;
|
||||||
|
do
|
||||||
|
dir = randDirections.get();
|
||||||
|
while (tiles[tileId].hasWall(dir));
|
||||||
|
switch (dir) {
|
||||||
|
case Direction.UP:
|
||||||
|
tiles[tileId].setWalls(true, false, false, false);
|
||||||
|
tiles[Position.toID(tilePos.getRow()+1, tilePos.getCol())].setWalls(false, true, false, false);
|
||||||
|
break;
|
||||||
|
case Direction.DOWN:
|
||||||
|
tiles[tileId].setWalls(false, true, false, false);
|
||||||
|
tiles[Position.toID(tilePos.getRow()-1, tilePos.getCol())].setWalls(true, false, false, false);
|
||||||
|
break;
|
||||||
|
case Direction.LEFT:
|
||||||
|
tiles[tileId].setWalls(false, false, true, false);
|
||||||
|
tiles[Position.toID(tilePos.getRow(), tilePos.getCol()-1)].setWalls(false, false, false, true);
|
||||||
|
break;
|
||||||
|
case Direction.RIGHT:
|
||||||
|
tiles[tileId].setWalls(false, false, false, true);
|
||||||
|
tiles[Position.toID(tilePos.getRow(), tilePos.getCol()+1)].setWalls(false, false, true, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTileBody (int row, int col, int theseusTile, int minotaurTile) {
|
||||||
|
int tileId = Position.toID(row, col);
|
||||||
|
boolean T = (tileId == theseusTile) ? true : false;
|
||||||
|
boolean M = (tileId == minotaurTile) ? true : false;
|
||||||
|
int S = tiles[tileId].hasSupply(supplies);
|
||||||
|
|
||||||
|
if (T && !M) return " T ";
|
||||||
|
else if (M && !T) return " M ";
|
||||||
|
else if (T && M) return "T+M";
|
||||||
|
else if (S != Const.noSupply)
|
||||||
|
return String.format("s%02d", S+1);
|
||||||
|
else return " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderTile(String[][] frame, int row, int col, int theseusTile, int minotaurTile) {
|
||||||
|
IntFunction<Integer> toframe = (r)->{ return 2*r+1; };
|
||||||
|
|
||||||
|
int tileId = Position.toID(row, col);
|
||||||
|
frame[toframe.apply(row)+1][col] = tiles[tileId].hasWall(Direction.UP) ? "+---" : "+ ";
|
||||||
|
frame[toframe.apply(row) ][col] = (tiles[tileId].hasWall(Direction.LEFT)? "|" : " ")
|
||||||
|
+ getTileBody(row, col, theseusTile, minotaurTile);
|
||||||
|
frame[toframe.apply(row)-1][col] = tiles[tileId].hasWall(Direction.DOWN) ? "+---" : "+ ";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void renderSentinelTile(String[][] frame, int row, int col, int theseusTile, int minotaurTile ) {
|
||||||
|
IntFunction<Integer> toframe = (r)->{ return 2*r+1; };
|
||||||
|
|
||||||
|
int tileId = Position.toID(row, col);
|
||||||
|
frame[toframe.apply(row)+1][col] = tiles[tileId].hasWall(Direction.UP) ? "+---+" : "+ +";
|
||||||
|
frame[toframe.apply(row) ][col] = (tiles[tileId].hasWall(Direction.LEFT)? "|" : " ")
|
||||||
|
+ getTileBody(row, col, theseusTile, minotaurTile)
|
||||||
|
+ (tiles[tileId].hasWall(Direction.RIGHT)? "|" : " ");
|
||||||
|
frame[toframe.apply(row)-1][col] = tiles[tileId].hasWall(Direction.DOWN) ? "+---+" : "+ +";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @name Class data */
|
||||||
|
/** @{ */
|
||||||
|
private int N; /**< The size of each edge of the board */
|
||||||
|
private int S; /**< The number of the supplies on the board */
|
||||||
|
private int W; /**< The number of walls on the board */
|
||||||
|
private Tile[] tiles; /**< Array to hold all the tiles for the board */
|
||||||
|
private Supply[] supplies; /**< Array to hold all the supplies on the board */
|
||||||
|
/** @} */
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,17 @@
|
|||||||
*/
|
*/
|
||||||
package net.hoo2.auth.labyrinth;
|
package net.hoo2.auth.labyrinth;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
class Const {
|
||||||
|
static final int noSupply =-1;
|
||||||
|
static final int noTileId =-1;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Application wide object to hold settings like values for the session.
|
* Application wide object to hold settings like values for the session.
|
||||||
*/
|
*/
|
||||||
class Defaults {
|
class Session {
|
||||||
static int boardSize = 15; /**@< Default board's size (if no one set it via command line) */
|
static int boardSize = 15; /**@< Default board's size (if no one set it via command line) */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,26 +28,29 @@ class Direction {
|
|||||||
static final int RIGHT =3; /**< East direction */
|
static final int RIGHT =3; /**< East direction */
|
||||||
static final int DOWN =5; /**< South direction */
|
static final int DOWN =5; /**< South direction */
|
||||||
static final int LEFT =7; /**< West direction */
|
static final int LEFT =7; /**< West direction */
|
||||||
|
static final int Begin =1;
|
||||||
|
static final int End =8;
|
||||||
|
static final int Step =2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* An Application wide board position implementation holding just the coordinates
|
* An Application wide board position implementation holding just the id coordinate.
|
||||||
*
|
*
|
||||||
* Position is a helper class to enable us cope with the redundant position data (id and coordinates).
|
* Position is a helper class to enable us cope with the redundant position data (id and coordinates).
|
||||||
* This class provide both static conversion functionalities between id and coordinates
|
* This class provide both static conversion functionalities between id and coordinates
|
||||||
* and data representation in the coordinates system.
|
* and data representation in the coordinates system.
|
||||||
|
* For clarity we adopt a row-column naming convention.
|
||||||
*/
|
*/
|
||||||
class Position {
|
class Position {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic constructor from coordinates
|
* Basic constructor from col-row coordinates
|
||||||
* @param x The x coordinate
|
* @param row The row coordinate
|
||||||
* @param y The y coordinate
|
* @param col The column coordinate
|
||||||
*/
|
*/
|
||||||
protected Position(int x, int y) {
|
protected Position(int row, int col) {
|
||||||
this.x = x;
|
this.id = toID(row, col);
|
||||||
this.y = y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,52 +58,90 @@ class Position {
|
|||||||
* @param tileId The id of tile
|
* @param tileId The id of tile
|
||||||
*/
|
*/
|
||||||
protected Position(int tileId) {
|
protected Position(int tileId) {
|
||||||
this.x = toX(tileId);
|
this.id = tileId;
|
||||||
this.y = toY(tileId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @name non-static API */
|
/** @name non-static API */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
protected int getX() { return x; } /**< Read access to x coordinate */
|
protected int getRow() { return toRow(id); } /**< Read access to virtual row coordinate */
|
||||||
protected int getY() { return y; } /**< Read access to y coordinate */
|
protected int getCol() { return toCol(id); } /**< Read access to virtual column coordinate */
|
||||||
protected int getID(){ return toID(x, y); } /**< Virtual read access to id coordinate */
|
protected int getId() { return id; } /**< Read access to id coordinate */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** @name Static convention utilities */
|
/** @name Static convention utilities */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
/**
|
/**
|
||||||
* Takes x and y coordinates and return the calculated Id coordinate
|
* Takes row and column coordinates and return the calculated Id coordinate
|
||||||
* @param x The x coordinate
|
* @param row The row coordinate
|
||||||
* @param y The y coordinate
|
* @param col The column coordinate
|
||||||
* @return The converted value
|
* @return The converted value
|
||||||
*/
|
*/
|
||||||
protected static int toID(int x, int y) {
|
protected static int toID(int row, int col) {
|
||||||
return y * Defaults.boardSize + x;
|
return row * Session.boardSize + col;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes Id coordinate and return the corresponding x coordinate
|
* Takes Id coordinate and return the corresponding row coordinate
|
||||||
* @param id The id coordinate
|
* @param id The id coordinate
|
||||||
* @return The x coordinate
|
* @return The row coordinate
|
||||||
*/
|
*/
|
||||||
protected static int toX(int id){
|
protected static int toRow(int id){
|
||||||
return id % Defaults.boardSize;
|
return id / Session.boardSize;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Takes Id coordinate and return the corresponding y coordinate
|
* Takes Id coordinate and return the corresponding column coordinate
|
||||||
* @param id The id coordinate
|
* @param id The id coordinate
|
||||||
* @return The y coordinate
|
* @return The column coordinate
|
||||||
*/
|
*/
|
||||||
protected static int toY(int id) {
|
protected static int toCol(int id) {
|
||||||
return id / Defaults.boardSize;
|
return id % Session.boardSize;
|
||||||
}
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** @name private data types */
|
/** @name private data types */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
private int x; /**< The x coordinate of the constructed Position object */
|
private int id; /**< The id coordinate of the constructed Position object */
|
||||||
private int y; /**< The y coordinate of the constructed Position object */
|
|
||||||
/** @} */
|
/** @} */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ShuffledRange {
|
||||||
|
|
||||||
|
ShuffledRange() {
|
||||||
|
numbers = new ArrayList<Integer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShuffledRange(int begin, int end) {
|
||||||
|
numbers = new ArrayList<Integer>();
|
||||||
|
init (begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShuffledRange(int begin, int step, int end) {
|
||||||
|
numbers = new ArrayList<Integer>();
|
||||||
|
init (begin, step, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init (int begin, int end) {
|
||||||
|
numbers.clear();
|
||||||
|
for (int i=begin ; i<end ; ++i)
|
||||||
|
numbers.add(i);
|
||||||
|
Collections.shuffle(numbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init (int begin, int step, int end) {
|
||||||
|
numbers.clear();
|
||||||
|
for (int i=begin ; i<end ; i+=step)
|
||||||
|
numbers.add(i);
|
||||||
|
Collections.shuffle(numbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
int get () {
|
||||||
|
try {
|
||||||
|
return numbers.remove(0);
|
||||||
|
}
|
||||||
|
catch (IndexOutOfBoundsException e) {
|
||||||
|
return Const.noTileId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<Integer> numbers;
|
||||||
|
}
|
||||||
|
@ -15,7 +15,10 @@ public class Game {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
System.out.println("Lets begin");
|
System.out.println("Lets begin");
|
||||||
|
Board board = new Board(7, 3, 42);
|
||||||
|
board.createBoard(0, Position.toID(3, 3));
|
||||||
|
String[][] frame = board.getStringRepresentation(0, Position.toID(3, 3));
|
||||||
|
board.printBoard(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,39 +21,40 @@ class Supply {
|
|||||||
/** @{ */
|
/** @{ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main constructor of the Supply constructed from (x,y)
|
* The main constructor of the Supply constructed from (row,column)
|
||||||
*
|
*
|
||||||
* @param id The Id of the created supply
|
* @param id The Id of the created supply
|
||||||
* @param x The x coordinate to place the supply
|
* @param row The row coordinate to place the supply
|
||||||
* @param y The y coordinate to place the supply
|
* @param col The column coordinate to place the supply
|
||||||
*/
|
*/
|
||||||
protected Supply(int id, int x, int y) {
|
protected Supply(int id, int row, int col) {
|
||||||
// Boundary checks
|
// Boundary checks
|
||||||
assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
|
assert (row >= 0 && row< Session.boardSize) : "Row coordinate must be in the range [0, Session.boardSize)";
|
||||||
assert (x >= 0 && x< Defaults.boardSize) : "Y coordinate must be in the range [0, Defaults.boardSize)";
|
assert (col >= 0 && col< Session.boardSize) : "Column coordinate must be in the range [0, Session.boardSize)";
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
this.supplyId =id;
|
this.supplyId =id;
|
||||||
this.x =x;
|
this.x =col;
|
||||||
this.y =y;
|
this.y =row;
|
||||||
this.supplyTileId = Position.toID(x, y);
|
this.supplyTileId = Position.toID(row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A second constructor of the Supply constructed from supplyTileId
|
* A second constructor of the Supply constructed from supplyTileId
|
||||||
*
|
*
|
||||||
* @param id The Id of the created supply
|
* @param id The Id of the created supply
|
||||||
* @param tileId The linear combination of (x, y)
|
* @param tileId The linear combination of (row, column)
|
||||||
*/
|
*/
|
||||||
protected Supply(int id, int tileId) {
|
protected Supply(int id, int tileId) {
|
||||||
// Boundary check
|
// Boundary check
|
||||||
assert (id >= 0 && id <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1))
|
assert (id >= 0 && id <= Position.toID(Session.boardSize-1, Session.boardSize-1))
|
||||||
: "TileId must be in the range of [0, Defaults.boardSize^2)";
|
: "TileId must be in the range of [0, Session.boardSize^2)";
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
this.supplyId =id;
|
this.supplyId = id;
|
||||||
this.supplyTileId = tileId;
|
this.supplyTileId = tileId;
|
||||||
this.x = Position.toX(tileId);
|
this.x = Position.toCol(tileId);
|
||||||
this.y = Position.toY(tileId);
|
this.y = Position.toRow(tileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,24 +86,25 @@ class Supply {
|
|||||||
* @return the position of the supply as a Position object
|
* @return the position of the supply as a Position object
|
||||||
* @see Position
|
* @see Position
|
||||||
*/
|
*/
|
||||||
protected Position position () { return new Position (x, y); }
|
protected Position position () { return new Position (supplyTileId); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the position of the supply from a (x, y) pair
|
* Set the position of the supply from a (row, column) pair
|
||||||
* @param x The x coordinate of the tile
|
* @param row The row coordinate of the tile
|
||||||
* @param y The y coordinate of the tile
|
* @param col The column coordinate of the tile
|
||||||
* @return the position of the supply as a Position object
|
* @return the position of the supply as a Position object
|
||||||
* @note This function also returns the supplyId to help in chained expressions.
|
* @note This function also returns the Position to help in chained expressions.
|
||||||
* @see Position
|
* @see Position
|
||||||
*/
|
*/
|
||||||
protected Position position (int x, int y) {
|
protected Position position (int row, int col) {
|
||||||
// Boundary checks
|
// Boundary checks
|
||||||
assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
|
assert (row >= 0 && row< Session.boardSize) : "Row coordinate must be in the range [0, Session.boardSize)";
|
||||||
assert (x >= 0 && x< Defaults.boardSize) : "Y coordinate must be in the range [0, Defaults.boardSize)";
|
assert (col >= 0 && col< Session.boardSize) : "Column coordinate must be in the range [0, Session.boardSize)";
|
||||||
Position p = new Position (x, y);
|
|
||||||
this.x = x;
|
Position p = new Position (row, col);
|
||||||
this.y = y;
|
this.x = p.getCol(); // =col;
|
||||||
this.supplyTileId = p.getID();
|
this.y = p.getRow(); // =row;
|
||||||
|
this.supplyTileId = p.getId();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,21 +112,20 @@ class Supply {
|
|||||||
* Set the position of the supply from a tileId
|
* Set the position of the supply from a tileId
|
||||||
* @param tileId The tileId position
|
* @param tileId The tileId position
|
||||||
* @return The position of the supply as Position object
|
* @return The position of the supply as Position object
|
||||||
* @note This function also returns the supplyId to help in chained expressions.
|
* @note This function also returns the Position to help in chained expressions.
|
||||||
* @see Position
|
* @see Position
|
||||||
*/
|
*/
|
||||||
protected int position (int tileId) {
|
protected Position position (int tileId) {
|
||||||
// Boundary check
|
// Boundary check
|
||||||
assert (tileId >= 0 && tileId <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1))
|
assert (tileId >= 0 && tileId <= Position.toID(Session.boardSize-1, Session.boardSize-1))
|
||||||
: "TileId must be in the range of [0, Defaults.boardSize^2)";
|
: "TileId must be in the range of [0, Session.boardSize^2)";
|
||||||
this.x = Position.toX(tileId);
|
|
||||||
this.y = Position.toY(tileId);
|
|
||||||
this.supplyTileId = tileId;
|
|
||||||
return supplyTileId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return The supplyTileId */
|
Position p = new Position (tileId);
|
||||||
protected int positionId () { return supplyTileId; }
|
this.x = p.getCol();
|
||||||
|
this.y = p.getRow();
|
||||||
|
this.supplyTileId = p.getId(); // =tileId;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
@ -142,21 +143,21 @@ class Supply {
|
|||||||
|
|
||||||
protected void setSupplyId(int Id) { supplyId = Id; }
|
protected void setSupplyId(int Id) { supplyId = Id; }
|
||||||
protected void setX(int x) {
|
protected void setX(int x) {
|
||||||
assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
|
assert (x >= 0 && x< Session.boardSize) : "X coordinate must be in the range [0, Session.boardSize)";
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.supplyTileId = Position.toID(this.x, this.y);
|
this.supplyTileId = Position.toID(this.x, this.y);
|
||||||
}
|
}
|
||||||
protected void setY(int y) {
|
protected void setY(int y) {
|
||||||
assert (y >= 0 && y< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
|
assert (y >= 0 && y< Session.boardSize) : "X coordinate must be in the range [0, Session.boardSize)";
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.supplyTileId = Position.toID(this.x, this.y);
|
this.supplyTileId = Position.toID(this.x, this.y);
|
||||||
}
|
}
|
||||||
protected void setSupplyTileId(int tileId) {
|
protected void setSupplyTileId(int tileId) {
|
||||||
assert (tileId >= 0 && tileId <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1))
|
assert (tileId >= 0 && tileId <= Position.toID(Session.boardSize-1, Session.boardSize-1))
|
||||||
: "TileId must be in the range of [0, Defaults.boardSize^2)";
|
: "TileId must be in the range of [0, Session.boardSize^2)";
|
||||||
this.supplyTileId = tileId;
|
this.supplyTileId = tileId;
|
||||||
this.x = Position.toX(tileId);
|
this.x = Position.toCol(tileId);
|
||||||
this.y = Position.toY(tileId);
|
this.y = Position.toRow(tileId);
|
||||||
|
|
||||||
}
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -20,24 +20,24 @@ class Tile {
|
|||||||
/** @{ */
|
/** @{ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main constructor of the Tile constructed from (x,y)
|
* The main constructor of the Tile constructed from (row,column)
|
||||||
*
|
*
|
||||||
* @param x The x coordinate to place the Tile
|
* @param row The row coordinate to place the Tile
|
||||||
* @param y The y coordinate to place the Tile
|
* @param col The column coordinate to place the Tile
|
||||||
* @param up The existence of wall north of the tile
|
* @param up The existence of wall north of the tile
|
||||||
* @param down The existence of wall south of the tile
|
* @param down The existence of wall south of the tile
|
||||||
* @param left The existence of wall left of the tile
|
* @param left The existence of wall left of the tile
|
||||||
* @param right The existence of wall right of the tile
|
* @param right The existence of wall right of the tile
|
||||||
*/
|
*/
|
||||||
protected Tile(int x, int y, boolean up, boolean down, boolean left, boolean right) {
|
protected Tile(int row, int col, boolean up, boolean down, boolean left, boolean right) {
|
||||||
// Boundary checks
|
// Boundary checks
|
||||||
assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
|
assert (row >= 0 && row< Session.boardSize) : "Row coordinate must be in the range [0, Session.boardSize)";
|
||||||
assert (x >= 0 && x< Defaults.boardSize) : "Y coordinate must be in the range [0, Defaults.boardSize)";
|
assert (col >= 0 && col< Session.boardSize) : "Column coordinate must be in the range [0, Session.boardSize)";
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
this.tileId = Position.toID(x, y);
|
this.tileId = Position.toID(row, col);
|
||||||
this.x =x;
|
this.x =col;
|
||||||
this.y =y;
|
this.y =row;
|
||||||
this.up = up;
|
this.up = up;
|
||||||
this.down = down;
|
this.down = down;
|
||||||
this.left = left;
|
this.left = left;
|
||||||
@ -55,12 +55,12 @@ class Tile {
|
|||||||
*/
|
*/
|
||||||
protected Tile(int id, boolean up, boolean down, boolean left, boolean right) {
|
protected Tile(int id, boolean up, boolean down, boolean left, boolean right) {
|
||||||
// Boundary check
|
// Boundary check
|
||||||
assert (id >= 0 && id <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1))
|
assert (id >= 0 && id <= Position.toID(Session.boardSize-1, Session.boardSize-1))
|
||||||
: "TileId must be in the range of [0, Defaults.boardSize^2)";
|
: "TileId must be in the range of [0, Session.boardSize^2)";
|
||||||
// Initialization
|
// Initialization
|
||||||
this.tileId = id;
|
this.tileId = id;
|
||||||
this.x =Position.toX(id);
|
this.x =Position.toCol(id);
|
||||||
this.y =Position.toY(id);
|
this.y =Position.toRow(id);
|
||||||
this.up = up;
|
this.up = up;
|
||||||
this.down = down;
|
this.down = down;
|
||||||
this.left = left;
|
this.left = left;
|
||||||
@ -89,24 +89,25 @@ class Tile {
|
|||||||
* @return the position of the tile as a Position object
|
* @return the position of the tile as a Position object
|
||||||
* @see Position
|
* @see Position
|
||||||
*/
|
*/
|
||||||
protected Position position () { return new Position (x, y); }
|
protected Position position () { return new Position (tileId); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the position of the tile from a (x, y) pair
|
* Set the position of the tile from a (row, column) pair
|
||||||
* @param x The x coordinate of the tile
|
* @param row The row coordinate of the tile
|
||||||
* @param y The y coordinate of the tile
|
* @param col The column coordinate of the tile
|
||||||
* @return the position of the supply as a Position object
|
* @return the position of the supply as a Position object
|
||||||
* @note This function also returns the supplyId to help in chained expressions.
|
* @note This function also returns the supplyId to help in chained expressions.
|
||||||
* @see Position
|
* @see Position
|
||||||
*/
|
*/
|
||||||
protected Position position (int x, int y) {
|
protected Position position (int row, int col) {
|
||||||
// Boundary checks
|
// Boundary checks
|
||||||
assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
|
assert (row >= 0 && row< Session.boardSize) : "Row coordinate must be in the range [0, Session.boardSize)";
|
||||||
assert (x >= 0 && x< Defaults.boardSize) : "Y coordinate must be in the range [0, Defaults.boardSize)";
|
assert (col >= 0 && col< Session.boardSize) : "Column coordinate must be in the range [0, Session.boardSize)";
|
||||||
Position p = new Position (x, y);
|
|
||||||
this.x = x;
|
Position p = new Position (row, col);
|
||||||
this.y = y;
|
this.x = p.getCol(); // =col;
|
||||||
this.tileId = p.getID();
|
this.y = p.getRow(); // =row;
|
||||||
|
this.tileId = p.getId();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,18 +118,17 @@ class Tile {
|
|||||||
* @note This function also returns the supplyId to help in chained expressions.
|
* @note This function also returns the supplyId to help in chained expressions.
|
||||||
* @see Position
|
* @see Position
|
||||||
*/
|
*/
|
||||||
protected int position (int tileId) {
|
protected Position position (int tileId) {
|
||||||
// Boundary check
|
// Boundary check
|
||||||
assert (tileId >= 0 && tileId <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1))
|
assert (tileId >= 0 && tileId <= Position.toID(Session.boardSize-1, Session.boardSize-1))
|
||||||
: "TileId must be in the range of [0, Defaults.boardSize^2)";
|
: "TileId must be in the range of [0, Session.boardSize^2)";
|
||||||
this.x = Position.toX(tileId);
|
|
||||||
this.y = Position.toY(tileId);
|
|
||||||
this.tileId = tileId;
|
|
||||||
return tileId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return The tileId */
|
Position p = new Position (tileId);
|
||||||
protected int positionId () { return tileId; }
|
this.x = p.getCol();
|
||||||
|
this.y = p.getRow();
|
||||||
|
this.tileId = p.getId(); // =tileId;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the tile's walls
|
* Set the tile's walls
|
||||||
@ -141,10 +141,11 @@ class Tile {
|
|||||||
assert (
|
assert (
|
||||||
((up?1:0) + (down?1:0) + (left?1:0) + (right?1:0)) <=2
|
((up?1:0) + (down?1:0) + (left?1:0) + (right?1:0)) <=2
|
||||||
) : "A tile can have at most 2 walls";
|
) : "A tile can have at most 2 walls";
|
||||||
this.up = up;
|
|
||||||
this.down = down;
|
this.up = (up) ? true : this.up;
|
||||||
this.left = left;
|
this.down = (down) ? true : this.down;
|
||||||
this.right = right;
|
this.left = (left) ? true : this.left;
|
||||||
|
this.right = (right)? true : this.right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -162,6 +163,20 @@ class Tile {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the tile has walls and return the number of them
|
||||||
|
* @return The number of walls
|
||||||
|
*/
|
||||||
|
protected int hasWalls () {
|
||||||
|
return ((up?1:0) + (down?1:0) + (left?1:0) + (right?1:0));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int hasSupply (Supply[] supplies) {
|
||||||
|
for (Supply s: supplies)
|
||||||
|
if (s.position().getId() == position().getId())
|
||||||
|
return s.getSupplyId();
|
||||||
|
return Const.noSupply;
|
||||||
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,19 +195,19 @@ class Tile {
|
|||||||
protected boolean getRight () { return right; }
|
protected boolean getRight () { return right; }
|
||||||
|
|
||||||
protected void setTileId(int tileId) {
|
protected void setTileId(int tileId) {
|
||||||
assert (tileId >= 0 && tileId <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1))
|
assert (tileId >= 0 && tileId <= Position.toID(Session.boardSize-1, Session.boardSize-1))
|
||||||
: "TileId must be in the range of [0, Defaults.boardSize^2)";
|
: "TileId must be in the range of [0, Session.boardSize^2)";
|
||||||
this.tileId = tileId;
|
this.tileId = tileId;
|
||||||
this.x = Position.toX(tileId);
|
this.x = Position.toCol(tileId);
|
||||||
this.y = Position.toY(tileId);
|
this.y = Position.toRow(tileId);
|
||||||
}
|
}
|
||||||
protected void setX(int x) {
|
protected void setX(int x) {
|
||||||
assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
|
assert (x >= 0 && x< Session.boardSize) : "X coordinate must be in the range [0, Session.boardSize)";
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.tileId = Position.toID(this.x, this.y);
|
this.tileId = Position.toID(this.x, this.y);
|
||||||
}
|
}
|
||||||
protected void setY(int y) {
|
protected void setY(int y) {
|
||||||
assert (y >= 0 && y< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
|
assert (y >= 0 && y< Session.boardSize) : "Y coordinate must be in the range [0, Session.boardSize)";
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.tileId = Position.toID(this.x, this.y);
|
this.tileId = Position.toID(this.x, this.y);
|
||||||
}
|
}
|
||||||
@ -208,8 +223,8 @@ class Tile {
|
|||||||
* The unique identifier of the tile. This is the linear combination of
|
* The unique identifier of the tile. This is the linear combination of
|
||||||
* x and y coordinates of the tile
|
* x and y coordinates of the tile
|
||||||
*/
|
*/
|
||||||
private int x; /**< The x coordinate of the tile as if the board lies in the 1st quadrant */
|
private int x; /**< The x coordinate(column) of the tile as if the board lies in the 1st quadrant */
|
||||||
private int y; /**< The y coordinate of the tile as if the board lies in the 1st quadrant */
|
private int y; /**< The y coordinate(row) of the tile as if the board lies in the 1st quadrant */
|
||||||
private boolean up; /**< Indicator of a wall in the north side of the tile */
|
private boolean up; /**< Indicator of a wall in the north side of the tile */
|
||||||
private boolean down; /**< Indicator of a wall in the south side of the tile */
|
private boolean down; /**< Indicator of a wall in the south side of the tile */
|
||||||
private boolean left; /**< Indicator of a wall in the left side of the tile */
|
private boolean left; /**< Indicator of a wall in the left side of the tile */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user