commit 8e3a9a35a8ae9f2440c852bdd3e89a2bbd010585 Author: Christos Choutouridis Date: Sun Oct 18 11:34:15 2020 +0300 Init commit with some seed code diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..596a358 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +bin/ +doc/ +deliverable/ +.classpath +.project diff --git a/ds_project_2020-2021_PartA.pdf b/ds_project_2020-2021_PartA.pdf new file mode 100644 index 0000000..08a1c95 Binary files /dev/null and b/ds_project_2020-2021_PartA.pdf differ diff --git a/src/net/hoo2/auth/labyrinth/Board.java b/src/net/hoo2/auth/labyrinth/Board.java new file mode 100644 index 0000000..585d42d --- /dev/null +++ b/src/net/hoo2/auth/labyrinth/Board.java @@ -0,0 +1,14 @@ +package net.hoo2.auth.labyrinth; + +public class Board { + + + + int size() { return N; } + + private int N; + private int S; + private int W; + private Tile[] tiles; + private Supply[] supplies; +} diff --git a/src/net/hoo2/auth/labyrinth/Common.java b/src/net/hoo2/auth/labyrinth/Common.java new file mode 100644 index 0000000..37494f5 --- /dev/null +++ b/src/net/hoo2/auth/labyrinth/Common.java @@ -0,0 +1,99 @@ +/** + * @file Common.java + * + * @author Christos Choutouridis AEM:8997 + * @email cchoutou@ece.auth.gr + */ +package net.hoo2.auth.labyrinth; + +/** + * Application wide object to hold settings like values for the session. + */ +class Defaults { + static int boardSize = 15; /**@< Default board's size (if no one set it via command line) */ +} + +/** + * Helper C++-like enumerator class to hold direction + */ +class Direction { + static final int UP =1; /**< North direction */ + static final int RIGHT =3; /**< East direction */ + static final int DOWN =5; /**< South direction */ + static final int LEFT =7; /**< West direction */ +} + +/** + * @brief + * An Application wide board position implementation holding just the 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 + * and data representation in the coordinates system. + */ +class Position { + + /** + * Basic constructor from coordinates + * @param x The x coordinate + * @param y The y coordinate + */ + protected Position(int x, int y) { + this.x = x; + this.y = y; + } + + /** + * Basic constructor from Id + * @param tileId The id of tile + */ + protected Position(int tileId) { + this.x = toX(tileId); + this.y = toY(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 */ + /** @} */ + + /** @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 + * @return The converted value + */ + protected static int toID(int x, int y) { + return y * Defaults.boardSize + x; + } + + /** + * Takes Id coordinate and return the corresponding x coordinate + * @param id The id coordinate + * @return The x coordinate + */ + protected static int toX(int id){ + return id % Defaults.boardSize; + } + /** + * Takes Id coordinate and return the corresponding y coordinate + * @param id The id coordinate + * @return The y coordinate + */ + protected static int toY(int id) { + return id / Defaults.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 */ + /** @} */ +} + + diff --git a/src/net/hoo2/auth/labyrinth/Game.java b/src/net/hoo2/auth/labyrinth/Game.java new file mode 100644 index 0000000..a55e0ad --- /dev/null +++ b/src/net/hoo2/auth/labyrinth/Game.java @@ -0,0 +1,21 @@ +/** + * @file Game.java + * + * @author Christos Choutouridis AEM:8997 + * @email cchoutou@ece.auth.gr + */ + +package net.hoo2.auth.labyrinth; + +/** + * + */ +public class Game { + + public static void main(String[] args) { + // TODO Auto-generated method stub + System.out.println("Lets begin"); + + } + +} diff --git a/src/net/hoo2/auth/labyrinth/Player.java b/src/net/hoo2/auth/labyrinth/Player.java new file mode 100644 index 0000000..236f403 --- /dev/null +++ b/src/net/hoo2/auth/labyrinth/Player.java @@ -0,0 +1,5 @@ +package net.hoo2.auth.labyrinth; + +class Player { + +} diff --git a/src/net/hoo2/auth/labyrinth/Supply.java b/src/net/hoo2/auth/labyrinth/Supply.java new file mode 100644 index 0000000..f76828c --- /dev/null +++ b/src/net/hoo2/auth/labyrinth/Supply.java @@ -0,0 +1,178 @@ +/** + * @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 + */ + /** @} */ +} diff --git a/src/net/hoo2/auth/labyrinth/Tile.java b/src/net/hoo2/auth/labyrinth/Tile.java new file mode 100644 index 0000000..0f23ed5 --- /dev/null +++ b/src/net/hoo2/auth/labyrinth/Tile.java @@ -0,0 +1,224 @@ +/** + * @file Tile.java + * + * @author Christos Choutouridis AEM:8997 + * @email cchoutou@ece.auth.gr + */ + +package net.hoo2.auth.labyrinth; + +/** + * @brief + * This class is the representation of the board's tile + * + * Tiles are arranged on the board in square shape and they're identified by + * an ID. This ID is the linear combination of x and y coordinate of the tile. + */ +class Tile { + + /** @name Constructors */ + /** @{ */ + + /** + * The main constructor of the Tile constructed from (x,y) + * + * @param x The x coordinate to place the Tile + * @param y The y 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) { + // 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.tileId = Position.toID(x, y); + this.x =x; + this.y =y; + this.up = up; + this.down = down; + this.left = left; + this.right = right; + } + + /** + * The main constructor of the Tile constructed from tileId + * + * @param id The tileId 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 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)"; + // Initialization + this.tileId = id; + this.x =Position.toX(id); + this.y =Position.toY(id); + this.up = up; + this.down = down; + this.left = left; + this.right = right; + } + + /** + * A deep copy constructor. + */ + protected Tile (Tile t) { + this.tileId = t.tileId; + this.x = t.x; + this.y = t.y; + this.up = t.up; + this.down = t.down; + this.left = t.left; + this.right = t.right; + // We achieve deep copy as the members are all primitives. + } + /** @} */ + + /** @name Supply's main application interface */ + /** @{ */ + + /** + * @return the position of the tile as a Position object + * @see Position + */ + protected Position position () { return new Position (x, y); } + + /** + * 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 + * @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.tileId = p.getID(); + return p; + } + + /** + * Set the position of the tile 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.tileId = tileId; + return tileId; + } + + /** @return The tileId */ + protected int positionId () { return tileId; } + + /** + * Set the tile's walls + * @param up Request for north wall (winter is coming) + * @param down Request for south wall + * @param left Request for west wall + * @param right Request for east wall + */ + protected void setWalls (boolean up, boolean down, boolean left, boolean right) { + 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; + } + + /** + * Checks if the tile has wall in the requested direction + * @param direction The direction to check + * @return True if there is a wall + */ + protected boolean hasWall (int direction) { + switch (direction) { + case Direction.UP: return up; + case Direction.RIGHT: return right; + case Direction.DOWN: return down; + case Direction.LEFT: return left; + } + return false; + } + + /** @} */ + + /** + * @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 getTileId () { return tileId; } + protected int getX () { return x; } + protected int getY () { return y; } + protected boolean getUp () { return up; } + protected boolean getDown () { return down; } + protected boolean getLeft () { return left; } + 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)"; + this.tileId = tileId; + this.x = Position.toX(tileId); + this.y = Position.toY(tileId); + } + 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.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)"; + this.y = y; + this.tileId = Position.toID(this.x, this.y); + } + protected void setUp(boolean up) { this.up = up; } + protected void setDown(boolean down) { this.down = down; } + protected void setRight(boolean right) { this.right = right; } + protected void setLeft(boolean left) { this.left = left; } + /** @} */ + + /** @name Class data */ + /** @{ */ + private int tileId; /**< + * 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 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 */ + private boolean right; /**< Indicator of a wall in the right side of the tile */ + /** + * @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 Supply.supplyTileId + */ +}