/** * @file Supply.java * * @author * Anastasia Foti AEM:8959 * * * @author * Christos Choutouridis AEM:8997 * */ package host.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 (row,column) * * @param id The Id of the created supply * @param row The row coordinate to place the supply * @param col The column coordinate to place the supply */ Supply(int id, int row, int col) { // Boundary checks 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 =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 (row, column) */ Supply(int id, int tileId) { // Boundary check 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.supplyTileId = tileId; this.x = Position.toCol(tileId); this.y = Position.toRow(tileId); } /** * A deep copy constructor. */ 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 */ 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. */ int supplyId (int sID) { return supplyId = sID; } /** * @return the position of the supply as a Position object * @see Position */ Position position () { return new Position (supplyTileId); } /** * 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 Position to help in chained expressions. * @see Position */ Position position (int row, int col) { // Boundary checks 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; } /** * 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 Position to help in chained expressions. * @see Position */ Position position (int tileId) { // Boundary check assert (tileId >= 0 && tileId <= Position.toID(Session.boardSize-1, Session.boardSize-1)) : "TileId must be in the range of [0, Session.boardSize^2)"; Position p = new Position (tileId); this.x = p.getCol(); this.y = p.getRow(); this.supplyTileId = p.getId(); // =tileId; return p; } /** * Marks the supply removed. This usually mean the supply is picked up by a user. */ void removeSupply () { this.supplyId = Const.noSupply; } /** @} */ /** * @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. */ /** @{ */ int getSupplyId () { return supplyId; } int getX() { return x; } int getY() { return y; } int getSupplyTileId(){ return supplyTileId; } void setSupplyId(int Id) { supplyId = Id; } void setX(int x) { assert (x >= 0 && x< Session.boardSize) : "X(column) coordinate must be in the range [0, Session.boardSize)"; this.x = x; this.supplyTileId = Position.toID(this.x, this.y); } void setY(int y) { assert (y >= 0 && y< Session.boardSize) : "Y(row) coordinate must be in the range [0, Session.boardSize)"; this.y = y; this.supplyTileId = Position.toID(this.x, this.y); } void setSupplyTileId(int tileId) { 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.toCol(tileId); this.y = Position.toRow(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 */ /** @} */ }