@@ -126,6 +126,58 @@ class Board { | |||||
System.out.println(); | 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 */ | protected ArrayList<Integer> numbers; /**< handle to range */ | ||||
/** @} */ | |||||
} | } | ||||
/** | /** | ||||
@@ -8,21 +8,74 @@ | |||||
package net.hoo2.auth.labyrinth; | package net.hoo2.auth.labyrinth; | ||||
/** | /** | ||||
* | |||||
* Main application class. This class is the only public interface of | |||||
* the entire game. | |||||
*/ | */ | ||||
public class 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) { | public static void main(String[] args) { | ||||
try { | 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) { | catch (Exception e) { | ||||
System.out.println(e.getMessage()); | System.out.println(e.getMessage()); | ||||
System.exit(1); | System.exit(1); | ||||
} | } | ||||
} | } | ||||
} | } |
@@ -6,8 +6,86 @@ package net.hoo2.auth.labyrinth; | |||||
* This class represents the game's player | * This class represents the game's player | ||||
*/ | */ | ||||
class 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 | * @name Accessor/Mutator interface | ||||
* @note | * @note | ||||
@@ -126,6 +126,11 @@ class Supply { | |||||
this.supplyTileId = p.getId(); // =tileId; | this.supplyTileId = p.getId(); // =tileId; | ||||
return p; | 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)); | 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) { | int hasSupply (Supply[] supplies) { | ||||
for (Supply s: supplies) | for (Supply s: supplies) | ||||
if (s.position().getId() == position().getId()) | if (s.position().getId() == position().getId()) | ||||
return s.getSupplyId(); | return s.getSupplyId(); | ||||
return Const.noSupply; | 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. | * We implement it just because its in the requirements of the assignment. | ||||
* @see Supply.supplyTileId | * @see Supply.supplyTileId | ||||
*/ | */ | ||||
/** @} */ | |||||
} | } |