@@ -126,6 +126,58 @@ class Board { | |||
System.out.println(); | |||
} | |||
} | |||
/** | |||
* Predicate to check if a direction is Walkable | |||
* @param tileId The starting tileId. | |||
* @param direction The desired direction. | |||
* @return True if it is walkable. | |||
*/ | |||
boolean isWalkable(int tileId, int direction) { | |||
return !tiles[tileId].hasWall(direction) | |||
&& !(tileId == 0 && direction == Direction.DOWN); | |||
} | |||
/** | |||
* Predicate to check if a direction is Walkable | |||
* @param row Row position of the starting tile. | |||
* @param column Column position of the starting tile. | |||
* @param direction The desired direction. | |||
* @return True if it is walkable. | |||
*/ | |||
boolean isWalkable(int row, int col, int direction) { | |||
return !tiles[Position.toID(row, col)].hasWall(direction) | |||
&& !(Position.toID(row, col) == 0 && direction == Direction.DOWN); | |||
} | |||
/** | |||
* Try to pick supply from a tile. If succeed it also erases the | |||
* supply from the board. | |||
* | |||
* @param tileId The tile to check | |||
* @return The id of supply. | |||
* @arg Const.noSupply if there is none | |||
* @arg The ID of supply if there is one. | |||
*/ | |||
int tryPickSupply(int tileId) { | |||
int supplyId = tiles[tileId].hasSupply(supplies); | |||
if (supplyId != Const.noSupply) { | |||
tiles[tileId].pickSupply(supplies, supplyId); | |||
} | |||
return supplyId; | |||
} | |||
/** | |||
* A plain fair dice functionality provided by the board. | |||
* @return A random direction; | |||
*/ | |||
int dice () { | |||
ShuffledRange d = new ShuffledRange(Direction.Begin, Direction.End, Direction.Step); | |||
return d.get(); | |||
} | |||
/** @return the size of each site of the board. */ | |||
int size () { return N; } | |||
/** @} */ | |||
/** | |||
@@ -178,7 +178,10 @@ class Range { | |||
} | |||
} | |||
/** @name protected data types */ | |||
/** @{ */ | |||
protected ArrayList<Integer> numbers; /**< handle to range */ | |||
/** @} */ | |||
} | |||
/** | |||
@@ -8,21 +8,74 @@ | |||
package net.hoo2.auth.labyrinth; | |||
/** | |||
* | |||
* Main application class. This class is the only public interface of | |||
* the entire game. | |||
*/ | |||
public class Game { | |||
Game() {} /**< An empty constructor */ | |||
/** | |||
* @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 getRound() { return round; } | |||
void setRound (int round) { this.round = round; } | |||
/** @} */ | |||
/** @name Game's data */ | |||
/** @{ */ | |||
private int round; | |||
/** @} */ | |||
/** | |||
* Main game loop | |||
*/ | |||
public static void main(String[] args) { | |||
try { | |||
Board board = new Board(7, 3, 60); | |||
board.createBoard(0, Position.toID(3, 3)); | |||
String[][] frame = board.getStringRepresentation(0, Position.toID(3, 3)); | |||
board.printBoard(frame); | |||
// Create a game, a board and 2 players. | |||
Game game = new Game(); | |||
Board board = new Board(11, 4, 82); | |||
Player T = new Player(1, "Theseus", board, 0); | |||
Player M = new Player(2, "Minotaur", board, Position.toID(3, 3)); | |||
// Populate data to the board | |||
board.createBoard(T.playerTileId(), M.playerTileId()); | |||
while (true) { | |||
int[] m; | |||
System.out.println(); | |||
System.out.println("Round: " + (game.getRound()+1)); | |||
m = T.move(T.playerTileId()); | |||
System.out.println(T.getName() + ":\t tileId =" + m[0] + " (" + m[1] + ", " + m[2] + ")"); | |||
m = M.move(M.playerTileId()); | |||
System.out.println(M.getName() + ":\t tileId =" + m[0] + " (" + m[1] + ", " + m[2] + ")"); | |||
board.printBoard( | |||
board.getStringRepresentation(T.playerTileId(), M.playerTileId()) | |||
); | |||
// Termination cases | |||
if (T.getScore() == 4) { | |||
System.out.println(T.getName() + " Wins!!! Score =" + T.getScore()); | |||
System.exit(0); | |||
} | |||
if (M.getScore() == 4 || M.playerTileId() == T.playerTileId()) { | |||
System.out.println(M.getName() + " Wins!!! Score =" + M.getScore()); | |||
System.exit(0); | |||
} | |||
game.setRound(game.getRound()+1); | |||
if (!(game.getRound() < 100)) { | |||
System.out.println("New day has come... Tie!!!"); | |||
System.exit(0); | |||
} | |||
} | |||
} | |||
catch (Exception e) { | |||
System.out.println(e.getMessage()); | |||
System.exit(1); | |||
} | |||
} | |||
} |
@@ -6,8 +6,86 @@ package net.hoo2.auth.labyrinth; | |||
* This class represents the game's player | |||
*/ | |||
class Player { | |||
/** @name Contructors */ | |||
/** @{ */ | |||
/** | |||
* Create a new player and put him at the row-column coordinates | |||
* @param id The id of the player | |||
* @param name The name of the player | |||
* @param board Reference to the board of the game | |||
*/ | |||
Player(int id, String name, Board board, int row, int column) { | |||
this.playerId = id; | |||
this.name = name; | |||
this.board = board; | |||
this.score = 0; | |||
this.x = column; | |||
this.y = row; | |||
} | |||
/** | |||
* Create a new player and put him at the row-column coordinates | |||
* @param id The id of the player | |||
* @param name The name of the player | |||
* @param board Reference to the board of the game | |||
*/ | |||
Player(int id, String name, Board board, int tileId) { | |||
this.playerId = id; | |||
this.name = name; | |||
this.board = board; | |||
this.score = 0; | |||
this.x = Position.toCol(tileId); | |||
this.y = Position.toRow(tileId); | |||
} | |||
/** @} */ | |||
/** @name Player main application interface */ | |||
/** @{ */ | |||
/** | |||
* Player's move. | |||
* | |||
* A player first throw a dice to get a random direction. Then checks if the direction | |||
* is walkable. If it is, then goes to that tile, pick up a possible supply on the tile | |||
* and update player's data. | |||
* | |||
* @param id The id of the starting tile. | |||
* @return An array containing player's final position and possible supply of that position. | |||
* The array format is: | |||
* <ul> | |||
* <li> int[0]: The tileId of the final player's position. | |||
* <li> int[1]: The row of the final player's position. | |||
* <li> int[2]: The column of the final player's position. | |||
* <li> int[1]: The supplyId in case player picked one (Const.noSupply otherwise). | |||
* </ul> | |||
*/ | |||
int[] move(int id) { | |||
// Init return array with the current data | |||
int[] ret = {id, Position.toRow(id), Position.toCol(id), Const.noSupply}; | |||
int diceDirection = board.dice(); // throw the dice | |||
if (board.isWalkable(id, diceDirection)) { // The result is walkable | |||
// Get next tile | |||
Position next = new Position(Position.toRow(id), Position.toCol(id), diceDirection); | |||
ret[0] = next.getId(); // Update player's and return data | |||
ret[1] = y = next.getRow(); | |||
ret[2] = x = next.getCol(); | |||
if ((ret[3] = board.tryPickSupply(next.getId())) != Const.noSupply) { | |||
++score; // keep score | |||
System.out.println(name + ":\t*Found a supply. [score: " + score + "]"); | |||
} | |||
} | |||
else | |||
System.out.println(name + ":\t*Can not move."); | |||
return ret; | |||
} | |||
int playerTileId() { return Position.toID(y, x); } | |||
int playerRow() { return y; } | |||
int playerCol() { return x; } | |||
/** @} */ | |||
/** | |||
* @name Accessor/Mutator interface | |||
* @note | |||
@@ -126,6 +126,11 @@ class Supply { | |||
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; } | |||
/** @} */ | |||
/** | |||
@@ -179,12 +179,28 @@ class Tile { | |||
return ((up?1:0) + (down?1:0) + (left?1:0) + (right?1:0)); | |||
} | |||
/** | |||
* Utility to check if the tile has a supply. | |||
* @param supplies Reference to supply array to check. | |||
* @return Const.noSupply if there is no supply or the supplyId if succeed. | |||
*/ | |||
int hasSupply (Supply[] supplies) { | |||
for (Supply s: supplies) | |||
if (s.position().getId() == position().getId()) | |||
return s.getSupplyId(); | |||
return Const.noSupply; | |||
} | |||
/** | |||
* Utility to find a supply in the supplies array and removes it. | |||
* @param supplies Reference to supply array to check | |||
* @param supplyId The supplyId to search. | |||
*/ | |||
void pickSupply (Supply[] supplies, int supplyId) { | |||
for (Supply s: supplies) | |||
if (s.getSupplyId() == supplyId) | |||
s.removeSupply(); | |||
} | |||
/** @} */ | |||
/** | |||
@@ -244,4 +260,5 @@ class Tile { | |||
* We implement it just because its in the requirements of the assignment. | |||
* @see Supply.supplyTileId | |||
*/ | |||
/** @} */ | |||
} |