From c4bb683797c50a2ebe618f26af79f45a16912d19 Mon Sep 17 00:00:00 2001 From: Christos Choutouridis Date: Sun, 18 Oct 2020 22:21:53 +0300 Subject: [PATCH] WIP: First draft of the board (Need predicate for wall placement decision) --- src/net/hoo2/auth/labyrinth/Board.java | 256 +++++++++++++++++++++++- src/net/hoo2/auth/labyrinth/Common.java | 104 +++++++--- src/net/hoo2/auth/labyrinth/Game.java | 5 +- src/net/hoo2/auth/labyrinth/Supply.java | 91 ++++----- src/net/hoo2/auth/labyrinth/Tile.java | 107 +++++----- 5 files changed, 438 insertions(+), 125 deletions(-) diff --git a/src/net/hoo2/auth/labyrinth/Board.java b/src/net/hoo2/auth/labyrinth/Board.java index 585d42d..d77abbb 100644 --- a/src/net/hoo2/auth/labyrinth/Board.java +++ b/src/net/hoo2/auth/labyrinth/Board.java @@ -1,14 +1,260 @@ +/** + * @file Board.java + * + * @author Christos Choutouridis AEM:8997 + * @email cchoutou@ece.auth.gr + */ + 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 { + /** @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=0 ; --i) { + for (String it : sBoard[i]) + System.out.print(it); + System.out.println(); + } + } int size() { return N; } - private int N; - private int S; - private int W; - private Tile[] tiles; - private Supply[] supplies; + /** @} */ + + /** + * @name Accessor/Mutator interface + * @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". + * see also here + * @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". + * see also here + * @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= 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 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 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 */ + /** @} */ } diff --git a/src/net/hoo2/auth/labyrinth/Common.java b/src/net/hoo2/auth/labyrinth/Common.java index 37494f5..d05e017 100644 --- a/src/net/hoo2/auth/labyrinth/Common.java +++ b/src/net/hoo2/auth/labyrinth/Common.java @@ -6,10 +6,17 @@ */ 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. */ -class Defaults { +class Session { 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 DOWN =5; /**< South direction */ static final int LEFT =7; /**< West direction */ + static final int Begin =1; + static final int End =8; + static final int Step =2; } /** * @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). * This class provide both static conversion functionalities between id and coordinates * and data representation in the coordinates system. + * For clarity we adopt a row-column naming convention. */ class Position { /** - * Basic constructor from coordinates - * @param x The x coordinate - * @param y The y coordinate + * Basic constructor from col-row coordinates + * @param row The row coordinate + * @param col The column coordinate */ - protected Position(int x, int y) { - this.x = x; - this.y = y; + protected Position(int row, int col) { + this.id = toID(row, col); } /** @@ -48,52 +58,90 @@ class Position { * @param tileId The id of tile */ protected Position(int tileId) { - this.x = toX(tileId); - this.y = toY(tileId); + this.id = tileId; } /** @name non-static API */ /** @{ */ - protected int getX() { return x; } /**< Read access to x coordinate */ - protected int getY() { return y; } /**< Read access to y coordinate */ - protected int getID(){ return toID(x, y); } /**< Virtual read access to id coordinate */ + protected int getRow() { return toRow(id); } /**< Read access to virtual row coordinate */ + protected int getCol() { return toCol(id); } /**< Read access to virtual column coordinate */ + protected int getId() { return id; } /**< Read access to id coordinate */ /** @} */ /** @name Static convention utilities */ /** @{ */ /** - * Takes x and y coordinates and return the calculated Id coordinate - * @param x The x coordinate - * @param y The y coordinate + * Takes row and column coordinates and return the calculated Id coordinate + * @param row The row coordinate + * @param col The column coordinate * @return The converted value */ - protected static int toID(int x, int y) { - return y * Defaults.boardSize + x; + protected static int toID(int row, int col) { + 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 - * @return The x coordinate + * @return The row coordinate */ - protected static int toX(int id){ - return id % Defaults.boardSize; + protected static int toRow(int id){ + 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 - * @return The y coordinate + * @return The column coordinate */ - protected static int toY(int id) { - return id / Defaults.boardSize; + protected static int toCol(int id) { + return id % Session.boardSize; } /** @} */ /** @name private data types */ /** @{ */ - private int x; /**< The x coordinate of the constructed Position object */ - private int y; /**< The y coordinate of the constructed Position object */ + private int id; /**< The id coordinate of the constructed Position object */ /** @} */ } +class ShuffledRange { + + ShuffledRange() { + numbers = new ArrayList(); + } + + ShuffledRange(int begin, int end) { + numbers = new ArrayList(); + init (begin, end); + } + + ShuffledRange(int begin, int step, int end) { + numbers = new ArrayList(); + init (begin, step, end); + } + void init (int begin, int end) { + numbers.clear(); + for (int i=begin ; i numbers; +} diff --git a/src/net/hoo2/auth/labyrinth/Game.java b/src/net/hoo2/auth/labyrinth/Game.java index a55e0ad..900da80 100644 --- a/src/net/hoo2/auth/labyrinth/Game.java +++ b/src/net/hoo2/auth/labyrinth/Game.java @@ -15,7 +15,10 @@ public class Game { public static void main(String[] args) { // TODO Auto-generated method stub 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); } } diff --git a/src/net/hoo2/auth/labyrinth/Supply.java b/src/net/hoo2/auth/labyrinth/Supply.java index f76828c..684a1cb 100644 --- a/src/net/hoo2/auth/labyrinth/Supply.java +++ b/src/net/hoo2/auth/labyrinth/Supply.java @@ -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 x The x coordinate to place the supply - * @param y The y coordinate to place the supply + * @param row The row 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 - assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)"; - assert (x >= 0 && x< Defaults.boardSize) : "Y 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 (col >= 0 && col< Session.boardSize) : "Column coordinate must be in the range [0, Session.boardSize)"; // Initialization - this.supplyId =id; - this.x =x; - this.y =y; - this.supplyTileId = Position.toID(x, y); + this.supplyId =id; + this.x =col; + this.y =row; + this.supplyTileId = Position.toID(row, col); } /** * A second constructor of the Supply constructed from supplyTileId * * @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) { // Boundary check - assert (id >= 0 && id <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1)) - : "TileId must be in the range of [0, Defaults.boardSize^2)"; + assert (id >= 0 && id <= Position.toID(Session.boardSize-1, Session.boardSize-1)) + : "TileId must be in the range of [0, Session.boardSize^2)"; + // Initialization - this.supplyId =id; + this.supplyId = id; this.supplyTileId = tileId; - this.x = Position.toX(tileId); - this.y = Position.toY(tileId); + this.x = Position.toCol(tileId); + this.y = Position.toRow(tileId); } /** @@ -85,24 +86,25 @@ class Supply { * @return the position of the supply as a Position object * @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 - * @param x The x coordinate of the tile - * @param y The y coordinate of the tile + * Set the position of the supply from a (row, column) pair + * @param row The row coordinate of the tile + * @param col The column coordinate of the tile * @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 */ - protected Position position (int x, int y) { + protected Position position (int row, int col) { // Boundary checks - assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)"; - assert (x >= 0 && x< Defaults.boardSize) : "Y coordinate must be in the range [0, Defaults.boardSize)"; - Position p = new Position (x, y); - this.x = x; - this.y = y; - this.supplyTileId = p.getID(); + assert (row >= 0 && row< Session.boardSize) : "Row coordinate must be in the range [0, Session.boardSize)"; + assert (col >= 0 && col< Session.boardSize) : "Column coordinate must be in the range [0, Session.boardSize)"; + + Position p = new Position (row, col); + this.x = p.getCol(); // =col; + this.y = p.getRow(); // =row; + this.supplyTileId = p.getId(); return p; } @@ -110,21 +112,20 @@ class Supply { * Set the position of the supply from a tileId * @param tileId The tileId position * @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 */ - protected int position (int tileId) { + protected Position position (int tileId) { // Boundary check - assert (tileId >= 0 && tileId <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1)) - : "TileId must be in the range of [0, Defaults.boardSize^2)"; - this.x = Position.toX(tileId); - this.y = Position.toY(tileId); - this.supplyTileId = tileId; - return supplyTileId; - } + assert (tileId >= 0 && tileId <= Position.toID(Session.boardSize-1, Session.boardSize-1)) + : "TileId must be in the range of [0, Session.boardSize^2)"; - /** @return The supplyTileId */ - protected int positionId () { return supplyTileId; } + Position p = new Position (tileId); + 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 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.supplyTileId = Position.toID(this.x, this.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.supplyTileId = Position.toID(this.x, this.y); } protected void setSupplyTileId(int tileId) { - assert (tileId >= 0 && tileId <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1)) - : "TileId must be in the range of [0, Defaults.boardSize^2)"; + assert (tileId >= 0 && tileId <= Position.toID(Session.boardSize-1, Session.boardSize-1)) + : "TileId must be in the range of [0, Session.boardSize^2)"; this.supplyTileId = tileId; - this.x = Position.toX(tileId); - this.y = Position.toY(tileId); + this.x = Position.toCol(tileId); + this.y = Position.toRow(tileId); } /** @} */ diff --git a/src/net/hoo2/auth/labyrinth/Tile.java b/src/net/hoo2/auth/labyrinth/Tile.java index 0f23ed5..8e67601 100644 --- a/src/net/hoo2/auth/labyrinth/Tile.java +++ b/src/net/hoo2/auth/labyrinth/Tile.java @@ -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 y The y coordinate to place the Tile + * @param row The row 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 down The existence of wall south of the tile * @param left The existence of wall left 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 - assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)"; - assert (x >= 0 && x< Defaults.boardSize) : "Y 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 (col >= 0 && col< Session.boardSize) : "Column coordinate must be in the range [0, Session.boardSize)"; // Initialization - this.tileId = Position.toID(x, y); - this.x =x; - this.y =y; + this.tileId = Position.toID(row, col); + this.x =col; + this.y =row; this.up = up; this.down = down; this.left = left; @@ -55,12 +55,12 @@ class Tile { */ protected Tile(int id, boolean up, boolean down, boolean left, boolean right) { // Boundary check - assert (id >= 0 && id <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1)) - : "TileId must be in the range of [0, Defaults.boardSize^2)"; + assert (id >= 0 && id <= Position.toID(Session.boardSize-1, Session.boardSize-1)) + : "TileId must be in the range of [0, Session.boardSize^2)"; // Initialization this.tileId = id; - this.x =Position.toX(id); - this.y =Position.toY(id); + this.x =Position.toCol(id); + this.y =Position.toRow(id); this.up = up; this.down = down; this.left = left; @@ -89,24 +89,25 @@ class Tile { * @return the position of the tile as a Position object * @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 - * @param x The x coordinate of the tile - * @param y The y coordinate of the tile + * Set the position of the tile from a (row, column) pair + * @param row The row coordinate of the tile + * @param col The column coordinate of the tile * @return the position of the supply as a Position object * @note This function also returns the supplyId to help in chained expressions. * @see Position */ - protected Position position (int x, int y) { + protected Position position (int row, int col) { // Boundary checks - assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)"; - assert (x >= 0 && x< Defaults.boardSize) : "Y coordinate must be in the range [0, Defaults.boardSize)"; - Position p = new Position (x, y); - this.x = x; - this.y = y; - this.tileId = p.getID(); + assert (row >= 0 && row< Session.boardSize) : "Row coordinate must be in the range [0, Session.boardSize)"; + assert (col >= 0 && col< Session.boardSize) : "Column coordinate must be in the range [0, Session.boardSize)"; + + Position p = new Position (row, col); + this.x = p.getCol(); // =col; + this.y = p.getRow(); // =row; + this.tileId = p.getId(); return p; } @@ -117,18 +118,17 @@ class Tile { * @note This function also returns the supplyId to help in chained expressions. * @see Position */ - protected int position (int tileId) { + protected Position position (int tileId) { // Boundary check - assert (tileId >= 0 && tileId <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1)) - : "TileId must be in the range of [0, Defaults.boardSize^2)"; - this.x = Position.toX(tileId); - this.y = Position.toY(tileId); - this.tileId = tileId; - return tileId; - } + assert (tileId >= 0 && tileId <= Position.toID(Session.boardSize-1, Session.boardSize-1)) + : "TileId must be in the range of [0, Session.boardSize^2)"; - /** @return The tileId */ - protected int positionId () { return tileId; } + Position p = new Position (tileId); + this.x = p.getCol(); + this.y = p.getRow(); + this.tileId = p.getId(); // =tileId; + return p; + } /** * Set the tile's walls @@ -141,10 +141,11 @@ class Tile { assert ( ((up?1:0) + (down?1:0) + (left?1:0) + (right?1:0)) <=2 ) : "A tile can have at most 2 walls"; - this.up = up; - this.down = down; - this.left = left; - this.right = right; + + this.up = (up) ? true : this.up; + this.down = (down) ? true : this.down; + this.left = (left) ? true : this.left; + this.right = (right)? true : this.right; } /** @@ -162,6 +163,20 @@ class Tile { 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 void setTileId(int tileId) { - assert (tileId >= 0 && tileId <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1)) - : "TileId must be in the range of [0, Defaults.boardSize^2)"; + assert (tileId >= 0 && tileId <= Position.toID(Session.boardSize-1, Session.boardSize-1)) + : "TileId must be in the range of [0, Session.boardSize^2)"; this.tileId = tileId; - this.x = Position.toX(tileId); - this.y = Position.toY(tileId); + this.x = Position.toCol(tileId); + this.y = Position.toRow(tileId); } 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.tileId = Position.toID(this.x, this.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.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 * 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 y; /**< The y 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(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 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 */