DEV: An extra closed room preventing algorithm added.
This commit is contained in:
parent
79bb675c94
commit
5a3c8c5413
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
bin/
|
bin/
|
||||||
doc/
|
doc/
|
||||||
|
out/
|
||||||
deliverable/
|
deliverable/
|
||||||
.classpath
|
.classpath
|
||||||
.project
|
.project
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
package net.hoo2.auth.labyrinth;
|
package net.hoo2.auth.labyrinth;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.function.IntFunction;
|
import java.util.function.IntFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,26 +25,27 @@ class Board {
|
|||||||
* The empty constructor for default initialization
|
* The empty constructor for default initialization
|
||||||
*/
|
*/
|
||||||
Board() {
|
Board() {
|
||||||
this.N = this.S = this.W = 0;
|
this.N = 0;
|
||||||
this.tiles = null;
|
this.S = 0;
|
||||||
this.supplies =null;
|
this.W = 0;
|
||||||
|
tiles = null;
|
||||||
|
supplies =null;
|
||||||
|
walls = new ArrayList<Edge>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main constructor for the application
|
* The main constructor for the application
|
||||||
* @param N The size of each edge of the board
|
* @param N The size of each edge of the board
|
||||||
* @param S The number of supplies on the board
|
* @param S The number of supplies on the board
|
||||||
* @param W The number of walls on the board
|
|
||||||
*/
|
*/
|
||||||
Board(int N, int S, int W) {
|
Board(int N, int S) {
|
||||||
assert (W>= 4*N-1 && W<=(3*N*N+1)/2 )
|
assert (N%2 != 0) : "Board's size has to be an odd number.";
|
||||||
: "Boards walls has to be in the range [4N-1, (3N^2+1)/2]";
|
|
||||||
|
|
||||||
this.N = Session.boardSize = N;
|
this.N = Session.boardSize = N;
|
||||||
this.S = S;
|
this.S = S;
|
||||||
this.W = W;
|
this.W = 0;
|
||||||
tiles = new Tile[N*N];
|
tiles = new Tile[N*N];
|
||||||
supplies = new Supply[S];
|
supplies = new Supply[S];
|
||||||
|
walls = new ArrayList<Edge>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,6 +69,7 @@ class Board {
|
|||||||
// Clone arrays
|
// Clone arrays
|
||||||
this.tiles = b.tiles.clone();
|
this.tiles = b.tiles.clone();
|
||||||
this.supplies = b.supplies.clone();
|
this.supplies = b.supplies.clone();
|
||||||
|
this.walls = b.walls;
|
||||||
}
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
@ -79,7 +82,7 @@ class Board {
|
|||||||
* @param theseusTile
|
* @param theseusTile
|
||||||
* @param minotaurTile
|
* @param minotaurTile
|
||||||
*/
|
*/
|
||||||
void createBoard(int theseusTile, int minotaurTile) throws Exception {
|
void createBoard(int theseusTile, int minotaurTile) {
|
||||||
createTiles();
|
createTiles();
|
||||||
createSupplies(theseusTile, minotaurTile);
|
createSupplies(theseusTile, minotaurTile);
|
||||||
}
|
}
|
||||||
@ -220,6 +223,15 @@ class Board {
|
|||||||
void setSupplies(Supply[] supplies) { this.supplies= supplies; }
|
void setSupplies(Supply[] supplies) { this.supplies= supplies; }
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
|
/** @name Sentinel predicates */
|
||||||
|
/** @{ */
|
||||||
|
private boolean isLeftSentinel (int tileId) { return (Position.toCol(tileId) == 0); }
|
||||||
|
private boolean isRightSentinel (int tileId) { return (Position.toCol(tileId) == N-1); }
|
||||||
|
private boolean isUpSentinel (int tileId) { return (Position.toRow(tileId) == N-1); }
|
||||||
|
private boolean isDownSentinel (int tileId) { return (Position.toRow(tileId) == 0); }
|
||||||
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name private functionality of the object
|
* @name private functionality of the object
|
||||||
*/
|
*/
|
||||||
@ -228,11 +240,11 @@ class Board {
|
|||||||
/**
|
/**
|
||||||
* This function creates randomly all the tiles of the board
|
* This function creates randomly all the tiles of the board
|
||||||
*/
|
*/
|
||||||
private void createTiles() throws Exception {
|
private void createTiles() {
|
||||||
int wallPool = W;
|
int wallCount;
|
||||||
wallPool -= createBasicTileWalls (); // First create tiles with outer walls
|
wallCount = createBasicTileWalls (); // First create tiles with outer walls
|
||||||
if (createInnerWalls(wallPool) > 0) // Create inner walls with the rest of the requested walls
|
wallCount += createInnerWalls(); // Greedy create as many inner walls we can
|
||||||
throw new Exception("Can not create the requested number of walls");
|
W = wallCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -254,13 +266,43 @@ class Board {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @name Sentinel predicates */
|
/**
|
||||||
/** @{ */
|
* Predicate to check if a wall creates a closed room.
|
||||||
private boolean isLeftSentinel (int tileId) { return (Position.toCol(tileId) == 0); }
|
*
|
||||||
private boolean isRightSentinel (int tileId) { return (Position.toCol(tileId) == N-1); }
|
* This algorithm has a complexity of O(N^2) where N represents the total
|
||||||
private boolean isUpSentinel (int tileId) { return (Position.toRow(tileId) == N-1); }
|
* number of tiles it should be used with care.
|
||||||
private boolean isDownSentinel (int tileId) { return (Position.toRow(tileId) == 0); }
|
*
|
||||||
/** @} */
|
* @param tileId The tileId of the wall where the wall is.
|
||||||
|
* @param direction The wall's relative direction from the tile.
|
||||||
|
* @return True if the wall creates a closed room, false otherwise.
|
||||||
|
*/
|
||||||
|
private boolean createsClosedRoom (int tileId, int direction) {
|
||||||
|
// Get a snapshot of the current walls
|
||||||
|
ArrayList<Edge> w = new ArrayList<Edge>();
|
||||||
|
for (Edge it : walls)
|
||||||
|
w.add(new Edge(it));
|
||||||
|
// Create a graph from the current wall(edge)
|
||||||
|
// and populate the graph with all the edges we can attach.
|
||||||
|
Graph g = new Graph(new Edge(tileId, direction));
|
||||||
|
int size;
|
||||||
|
do {
|
||||||
|
size = w.size();
|
||||||
|
for (int i =0, S=w.size() ; i<S ; ++i)
|
||||||
|
if (g.attach(w.get(i))) {
|
||||||
|
w.remove(i);
|
||||||
|
--i; --S;
|
||||||
|
}
|
||||||
|
} while (size != w.size());
|
||||||
|
|
||||||
|
// Search if a vertex is attached more than once.
|
||||||
|
// This means that there is at least 2 links to the same node
|
||||||
|
// so the graph has a closed loop
|
||||||
|
for (Edge it : walls) {
|
||||||
|
if (g.count(it.getV1()) > 1) return true;
|
||||||
|
if (g.count(it.getV2()) > 1) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Predicate to check if a tile direction is `Wallable`.
|
* Predicate to check if a tile direction is `Wallable`.
|
||||||
@ -270,6 +312,7 @@ class Board {
|
|||||||
* <li>The wall is not the DOWN wall from tile (0, 0).
|
* <li>The wall is not the DOWN wall from tile (0, 0).
|
||||||
* <li>There is not already a wall in the desired direction. (Implies no sentinel tile).
|
* <li>There is not already a wall in the desired direction. (Implies no sentinel tile).
|
||||||
* <li>The neighbor in this direction has at most `Const.maxTileWalls -1` walls.
|
* <li>The neighbor in this direction has at most `Const.maxTileWalls -1` walls.
|
||||||
|
* <li>The wall does not create a closed room (Optional requirement).
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @note
|
* @note
|
||||||
@ -286,12 +329,22 @@ class Board {
|
|||||||
if (tiles[tileId].hasWall(direction))
|
if (tiles[tileId].hasWall(direction))
|
||||||
return false;
|
return false;
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case Direction.UP: return (tiles[upTileId.apply(tileId)].hasWalls() < Const.maxTileWalls);
|
case Direction.UP:
|
||||||
case Direction.DOWN: return (tiles[downTileId.apply(tileId)].hasWalls() < Const.maxTileWalls);
|
if (tiles[upTileId.apply(tileId)].hasWalls() >= Const.maxTileWalls) return false;
|
||||||
case Direction.LEFT: return (tiles[leftTileId.apply(tileId)].hasWalls() < Const.maxTileWalls);
|
break;
|
||||||
case Direction.RIGHT:return (tiles[rightTileId.apply(tileId)].hasWalls() < Const.maxTileWalls);
|
case Direction.DOWN:
|
||||||
|
if (tiles[downTileId.apply(tileId)].hasWalls() >= Const.maxTileWalls) return false;
|
||||||
|
break;
|
||||||
|
case Direction.LEFT:
|
||||||
|
if (tiles[leftTileId.apply(tileId)].hasWalls() >= Const.maxTileWalls) return false;
|
||||||
|
break;
|
||||||
|
case Direction.RIGHT:
|
||||||
|
if (tiles[rightTileId.apply(tileId)].hasWalls() >= Const.maxTileWalls) return false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
if (Session.loopGuard && createsClosedRoom(tileId, direction))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -326,16 +379,22 @@ class Board {
|
|||||||
* @return The number of walls created from the utility.
|
* @return The number of walls created from the utility.
|
||||||
*/
|
*/
|
||||||
private int createBasicTileWalls () {
|
private int createBasicTileWalls () {
|
||||||
int tileCount =0;
|
int wallCount =0;
|
||||||
for (int i =0 ; i< tiles.length ; ++i) {
|
for (int i =0 ; i< tiles.length ; ++i) {
|
||||||
boolean up = isUpSentinel(i);
|
boolean up = isUpSentinel(i);
|
||||||
boolean down = isDownSentinel(i) && (i != 0);
|
boolean down = isDownSentinel(i) && (i != 0);
|
||||||
boolean left = isLeftSentinel(i);
|
boolean left = isLeftSentinel(i);
|
||||||
boolean right = isRightSentinel(i);
|
boolean right = isRightSentinel(i);
|
||||||
tileCount += ((up?1:0) + (down?1:0) + (left?1:0) + (right?1:0));
|
wallCount += ((up?1:0) + (down?1:0) + (left?1:0) + (right?1:0));
|
||||||
tiles[i] = new Tile (i, up, down, left, right);
|
tiles[i] = new Tile (i, up, down, left, right);
|
||||||
|
if (Session.loopGuard) {
|
||||||
|
if (up) walls.add(new Edge(i, Direction.UP));
|
||||||
|
if (down) walls.add(new Edge(i, Direction.DOWN));
|
||||||
|
if (left) walls.add(new Edge(i, Direction.LEFT));
|
||||||
|
if (right) walls.add(new Edge(i, Direction.RIGHT));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return tileCount;
|
return wallCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -352,6 +411,8 @@ class Board {
|
|||||||
Position neighbor = new Position(Position.toRow(tileId), Position.toCol(tileId), dir);
|
Position neighbor = new Position(Position.toRow(tileId), Position.toCol(tileId), dir);
|
||||||
tiles[tileId].setWall(dir);
|
tiles[tileId].setWall(dir);
|
||||||
tiles[neighbor.getId()].setWall(Direction.opposite(dir));
|
tiles[neighbor.getId()].setWall(Direction.opposite(dir));
|
||||||
|
if (Session.loopGuard)
|
||||||
|
walls.add(new Edge(tileId, dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -360,23 +421,23 @@ class Board {
|
|||||||
* @param walls The number of walls to create
|
* @param walls The number of walls to create
|
||||||
* @return The number of walls failed to create.
|
* @return The number of walls failed to create.
|
||||||
*/
|
*/
|
||||||
private int createInnerWalls (int walls) {
|
private int createInnerWalls () {
|
||||||
ShuffledRange randTiles = new ShuffledRange(0, N*N);
|
ShuffledRange randTiles = new ShuffledRange(0, N*N);
|
||||||
for (int tileId, i =0, shuffleMark =0 ; i<walls ; ++i) {
|
for (int tileId, i =0, walls =0, shuffleMark =0 ; true ; ) {
|
||||||
// randomly pick a wallable tile.
|
// randomly pick a wallable tile.
|
||||||
do {
|
do {
|
||||||
if ((tileId = randTiles.get())== Const.noTileId) {
|
if ((tileId = randTiles.get())== Const.noTileId) {
|
||||||
if (i == shuffleMark) // Wallable tiles exhausted.
|
if (i == shuffleMark) // Wallable tiles exhausted.
|
||||||
return walls - i;
|
return walls;
|
||||||
else { // Re-shuffle and continue.
|
else { // Re-shuffle and continue.
|
||||||
randTiles = new ShuffledRange(0, N*N);
|
randTiles = new ShuffledRange(0, N*N);
|
||||||
shuffleMark =i;
|
shuffleMark =i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (!isWallable(tileId));
|
} while (!isWallable(tileId));
|
||||||
|
++walls;
|
||||||
createInnerWall(tileId);
|
createInnerWall(tileId);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -456,10 +517,14 @@ class Board {
|
|||||||
|
|
||||||
/** @name Class data */
|
/** @name Class data */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
private int N; /**< The size of each edge of the board */
|
private int N; /**< The size of each edge of the board */
|
||||||
private int S; /**< The number of the supplies on the board */
|
private int S; /**< The number of the supplies on the board */
|
||||||
private int W; /**< The number of walls 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 Tile[] tiles; /**< Array to hold all the tiles for the board */
|
||||||
private Supply[] supplies; /**< Array to hold all the supplies on the board */
|
private Supply[] supplies; /**< Array to hold all the supplies on the board */
|
||||||
|
private ArrayList<Edge> walls; /**<
|
||||||
|
* Array to hold all the walls using the edge representation
|
||||||
|
* required by the closed room preventing algorithm.
|
||||||
|
*/
|
||||||
/** @} */
|
/** @} */
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,11 @@ class Const {
|
|||||||
* Application wide object to hold settings like values for the session.
|
* Application wide object to hold settings like values for the session.
|
||||||
*/
|
*/
|
||||||
class Session {
|
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) */
|
||||||
static int supplySize = 4; /**< Default board's supply size (if no one set it via command line) */
|
static int supplySize = 4; /**< Default board's supply size (if no one set it via command line) */
|
||||||
static int wallSize = 4*15-1; /**< Default board's wall size (if no one set it via command line) */
|
static int maxRounds = 100; /**< Default number of rounds per game (if no one set it via command line) */
|
||||||
|
static boolean loopGuard = false; /**< When true a wall creation guard is added to prevent closed rooms inside the board */
|
||||||
|
static boolean interactive = false; /**< When true each round of the game requires user input */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -209,3 +211,179 @@ class ShuffledRange extends Range {
|
|||||||
Collections.shuffle(numbers);
|
Collections.shuffle(numbers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* A utility class used for room prevent algorithm.
|
||||||
|
*
|
||||||
|
* This class is the wall representation we use in the room preventing algorithm.
|
||||||
|
* In this algorithm we represent the crosses between tiles as nodes (V) of a graph and the
|
||||||
|
* walls as edges. So for example:
|
||||||
|
*
|
||||||
|
* _ V = 15
|
||||||
|
* /
|
||||||
|
* +---+---+---+ We have a 4x4=16 vertices board(nodes) and 14 edges(walls).
|
||||||
|
* | | To represent the vertices on the board we use the
|
||||||
|
* + +---+ + same trick as the tileId.
|
||||||
|
* | | | The edges are represented as vertices pairs.
|
||||||
|
* + + + + <.
|
||||||
|
* | | | \_ V = 7
|
||||||
|
* + +---+---+
|
||||||
|
* ^ ^
|
||||||
|
* V = 0 V = 3
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* Beside the fact that we prefer this kind of representation of the walls in
|
||||||
|
* the application we use the one that is suggested from the assignment. This is
|
||||||
|
* used only in room preventing algorithm.
|
||||||
|
* @note
|
||||||
|
* Using this kind of representation we don't have any more the "problem"
|
||||||
|
* of setting the wall in both neighbor tiles.
|
||||||
|
*/
|
||||||
|
class Edge {
|
||||||
|
/**
|
||||||
|
* This constructor as as the interface between the application's wall
|
||||||
|
* representation and the one based on graph.
|
||||||
|
* @param tileId The tile id of the wall.
|
||||||
|
* @param direction The direction of the tile where the wall should be.
|
||||||
|
*/
|
||||||
|
Edge(int tileId, int direction) {
|
||||||
|
int N = Session.boardSize +1;
|
||||||
|
switch (direction) {
|
||||||
|
case Direction.UP:
|
||||||
|
v1= (Position.toRow(tileId) + 1)*N + Position.toCol(tileId);
|
||||||
|
v2= (Position.toRow(tileId) + 1)*N + Position.toCol(tileId) + 1;
|
||||||
|
break;
|
||||||
|
case Direction.DOWN:
|
||||||
|
v1= (Position.toRow(tileId))*N + Position.toCol(tileId);
|
||||||
|
v2= (Position.toRow(tileId))*N + Position.toCol(tileId) + 1;
|
||||||
|
break;
|
||||||
|
case Direction.LEFT:
|
||||||
|
v1= (Position.toRow(tileId))*N + Position.toCol(tileId);
|
||||||
|
v2= (Position.toRow(tileId) + 1)*N + Position.toCol(tileId);
|
||||||
|
break;
|
||||||
|
case Direction.RIGHT:
|
||||||
|
v1= (Position.toRow(tileId))*N + Position.toCol(tileId) + 1;
|
||||||
|
v2= (Position.toRow(tileId) + 1)*N + Position.toCol(tileId) +1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** A deep copy contructor */
|
||||||
|
Edge(Edge e) {
|
||||||
|
v1 = e.getV1();
|
||||||
|
v2 = e.getV2();
|
||||||
|
}
|
||||||
|
/** Access of the first node of the edge */
|
||||||
|
int getV1() { return v1; }
|
||||||
|
/** Access of the second node of the edge */
|
||||||
|
int getV2() { return v2; }
|
||||||
|
|
||||||
|
private int v1; /**< First vertex of the edge */
|
||||||
|
private int v2; /**< Second vertex of the edge */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Provides a graph functionality for the room preventing algorithm.
|
||||||
|
* We use a graph to represent the wall structure of the walls. This way
|
||||||
|
* is easy to find any closed loops. Using graph we transform the problem
|
||||||
|
* of the closed room in the problem of finding a non simple graph.
|
||||||
|
*
|
||||||
|
* If the board has non connected wall structure then we need more than
|
||||||
|
* one graph to represent it.
|
||||||
|
*
|
||||||
|
* An example graph from a board, starting from V=1 is:
|
||||||
|
* <pre>
|
||||||
|
* 6---7 8 (1)
|
||||||
|
* | | / \
|
||||||
|
* 3 4 5 (4) (2)
|
||||||
|
* | | | \
|
||||||
|
* 0 1---2 (5)--(8)
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
class Graph {
|
||||||
|
/**
|
||||||
|
* Constructs a node of the graph using the value of a vertex(node).
|
||||||
|
* @param v The verteg to attach.
|
||||||
|
*/
|
||||||
|
Graph (int v) {
|
||||||
|
V = v;
|
||||||
|
E = new ArrayList<Graph>();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Constructor that transform an edge into graph.
|
||||||
|
* @param e The edge to transform.
|
||||||
|
*/
|
||||||
|
Graph (Edge e) {
|
||||||
|
V = e.getV1();
|
||||||
|
E = new ArrayList<Graph>();
|
||||||
|
E.add(new Graph(e.getV2()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Access to the current vertex */
|
||||||
|
int getV() { return V; }
|
||||||
|
/** Access to the links of the current vertex */
|
||||||
|
ArrayList<Graph> getE() { return E; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach an edge into a graph IFF the graph already has a vertex
|
||||||
|
* with the same value of one of the vertices of the edge.
|
||||||
|
* @param e The edge to attach.
|
||||||
|
* @return The status of the operation.
|
||||||
|
* @arg True on success
|
||||||
|
* @arg False on failure
|
||||||
|
*/
|
||||||
|
boolean attach (Edge e) {
|
||||||
|
return tryAttach(e, 0) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts the number of vertices on the graph with the value of `v`
|
||||||
|
* @param v The vertex to count
|
||||||
|
* @return The number of vertices with value `v`
|
||||||
|
*/
|
||||||
|
int count (int v) {
|
||||||
|
return tryCount (v, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive algorithm that tries to attach an edge into a graph
|
||||||
|
* IFF the graph already has a vertex.
|
||||||
|
* with the same value of one of the vertices of the edge.
|
||||||
|
* @param e The edge to attach.
|
||||||
|
* @param count An initial count value to feed to the algorithm.
|
||||||
|
* @return The status of the operation.
|
||||||
|
* @arg True on success
|
||||||
|
* @arg False on failure
|
||||||
|
*/
|
||||||
|
private int tryAttach (Edge e, int count) {
|
||||||
|
for (Graph n: E)
|
||||||
|
count += n.tryAttach (e, count);
|
||||||
|
if (V == e.getV1()) {
|
||||||
|
E.add(new Graph(e.getV2()));
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
if (V == e.getV2()) {
|
||||||
|
E.add(new Graph(e.getV1()));
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive algorithm that tries to count the number of vertices
|
||||||
|
* on the graph with the value of `v`
|
||||||
|
* @param v The vertex to count
|
||||||
|
* @param count An initial count value to feed to the algorithm.
|
||||||
|
* @return The number of vertices with value `v`
|
||||||
|
*/
|
||||||
|
private int tryCount (int v, int count) {
|
||||||
|
for (Graph n: E)
|
||||||
|
count = n.tryCount (v, count);
|
||||||
|
if (V == v)
|
||||||
|
return ++count;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
private int V; /**< The value of the current vertex/node */
|
||||||
|
private ArrayList<Graph> E; /**< A list of all the child nodes */
|
||||||
|
}
|
||||||
|
@ -68,33 +68,44 @@ public class Game {
|
|||||||
Session.boardSize = Integer.parseInt(args[++i]);
|
Session.boardSize = Integer.parseInt(args[++i]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "-w":
|
|
||||||
case "--walls":
|
|
||||||
if (i+1 < args.length)
|
|
||||||
Session.wallSize = Integer.parseInt(args[++i]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "-s":
|
case "-s":
|
||||||
case "--suplies":
|
case "--suplies":
|
||||||
if (i+1 < args.length)
|
if (i+1 < args.length)
|
||||||
Session.supplySize = Integer.parseInt(args[++i]);
|
Session.supplySize = Integer.parseInt(args[++i]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "-r":
|
||||||
|
case "--rounds":
|
||||||
|
if (i+1 < args.length)
|
||||||
|
Session.maxRounds = Integer.parseInt(args[++i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "--norooms":
|
||||||
|
Session.loopGuard = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "-i":
|
||||||
|
case "--interactive":
|
||||||
|
Session.interactive = true;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
case "-h":
|
case "-h":
|
||||||
case "--help":
|
case "--help":
|
||||||
System.out.println("Labyrinth Game");
|
System.out.println("Labyrinth Game");
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
System.out.println("Usage:");
|
System.out.println("Usage:");
|
||||||
System.out.println("labyrinth [-b|--board <Num>] [-w|--walls <Num>] [-s|--supplies <Num>]");
|
System.out.println("labyrinth [-b|--board <Num>] [-s|--supplies <Num>] [-r|--rounds <Num>] [--norooms] [-i|--interactive]");
|
||||||
System.out.println("or");
|
System.out.println("or");
|
||||||
System.out.println("labyrinth -h|--help");
|
System.out.println("labyrinth -h|--help");
|
||||||
System.out.println("");
|
System.out.println("\nOptions\n");
|
||||||
System.out.println("\t-b | --board: Sets the size of board's edge.");
|
System.out.println("-b | --board:\n Sets the size of board's edge.\n");
|
||||||
System.out.println("\t-w | --walls: Sets the number of walls on the board.");
|
System.out.println("-s | --supplies:\n Sets the number of supplies on the board.\n");
|
||||||
System.out.println("\t-s | --supplies: Sets the number of supplies on the board.");
|
System.out.println("-r | --rounds:\n Sets the maximum number of rounds of the game.\n");
|
||||||
System.out.println("\t-h | --help: Print this and exit");
|
System.out.println("--norooms:\n Prevents the creation of closed rooms inside the board.\n");
|
||||||
break;
|
System.out.println("-i | --interactive:\n Each round requires user input in order to continue.\n");
|
||||||
|
System.out.println("-h | --help:\n Print this and exits.");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -111,9 +122,9 @@ public class Game {
|
|||||||
|
|
||||||
// Create a game, a board and 2 players.
|
// Create a game, a board and 2 players.
|
||||||
Game game = new Game();
|
Game game = new Game();
|
||||||
Board board = new Board(Session.boardSize, Session.supplySize, Session.wallSize);
|
Board board = new Board(Session.boardSize, Session.supplySize);
|
||||||
Player T = new Player(1, "Theseus", board, 0);
|
Player T = new Player(1, "Theseus", true, board, 0);
|
||||||
Player M = new Player(2, "Minotaur", board, Position.toID(Session.boardSize/2, Session.boardSize/2));
|
Player M = new Player(2, "Minotaur", false, board, Position.toID(Session.boardSize/2, Session.boardSize/2));
|
||||||
|
|
||||||
// Populate data to the board
|
// Populate data to the board
|
||||||
board.createBoard(T.playerTileId(), M.playerTileId());
|
board.createBoard(T.playerTileId(), M.playerTileId());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user