/** * @file Supply.java * * @author Christos Choutouridis AEM:8997 * @email cchoutou@ece.auth.gr */ package net.hoo2.auth.labyrinth; /** * @brief * This class is the representation of the supplies in the game * * Supplies are the game "goodies". They placed randomly in the board. * In each tile there can be only one supply. The player has to collect all * of them in order to complete the game successfully. */ class Supply { /** @name Constructors */ /** @{ */ /** * The main constructor of the Supply constructed from (x,y) * * @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 */ protected Supply(int id, int x, int y) { // 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)"; // Initialization this.supplyId =id; this.x =x; this.y =y; this.supplyTileId = Position.toID(x, y); } /** * 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) */ 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)"; // Initialization this.supplyId =id; this.supplyTileId = tileId; this.x = Position.toX(tileId); this.y = Position.toY(tileId); } /** * A deep copy constructor. */ protected Supply (Supply s) { this.supplyId = s.supplyId; this.x = s.x; this.y = s.y; this.supplyTileId = s.supplyTileId; // We achieve deep copy as the members are all primitives. } /** @} */ /** @name Supply's main application interface */ /** @{ */ /** @return the supplyId */ protected int supplyId () { return supplyId; } /** * Set the supplyId * @param sId The Id to set * @return The supplyId * @note This function also returns the supplyId to help in chained expressions. */ protected int supplyId (int sID) { return supplyId = sID; } /** * @return the position of the supply as a Position object * @see Position */ protected Position position () { return new Position (x, y); } /** * 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 * @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) { // 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(); return p; } /** * 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. * @see Position */ protected int 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; } /** @return The supplyTileId */ protected int positionId () { return supplyTileId; } /** @} */ /** * @name Accessor/Mutator interface * @note * Please consider not to use mutator interface. Its the abstraction killer :( * We have added a bit of logic however, in order to make it a bit more safe. */ /** @{ */ protected int getSupplyId () { return supplyId; } protected int getX() { return x; } protected int getY() { return y; } protected int getSupplyTileId(){ return supplyTileId; } 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)"; 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)"; 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)"; this.supplyTileId = tileId; this.x = Position.toX(tileId); this.y = Position.toY(tileId); } /** @} */ /** @name Class data */ /** @{ */ private int supplyId; /**< The unique identifier of the tile. This must not be confused with TileID */ 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 supplyTileId; /**< The Id of the tile on the board, in witch the supply is located */ /** * @warning * We can calculate tileId from (x,y) so having both (x,y) and tile ID is error * prone and not a good practice. Its easy to get them out of sync (code smell). * We implement it just because its in the requirements of the assignment. * @see Tile.tileId */ /** @} */ }