5 Commits
8 changed files with 419 additions and 96 deletions
-1
View File
@@ -1,6 +1,5 @@
*bin/* *bin/*
*doc/* *doc/*
*report/*
*deliverable/* *deliverable/*
*.project *.project
*.classpath *.classpath
BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

@@ -1,7 +1,5 @@
package net.hoo2.auth.dsproject.snake; package net.hoo2.auth.dsproject.snake;
import java.lang.Math;
/** /**
* @class Apple * @class Apple
* @brief Represent an Apple in the Board. * @brief Represent an Apple in the Board.
+6 -5
View File
@@ -223,11 +223,11 @@ public class Board {
* @param tile The tile to check * @param tile The tile to check
* @return The result tile * @return The result tile
*/ */
int checkLadder (int tile) { int checkLadder (int tile, boolean climb) {
for (int i =0 ; i<ladders.length ; ++i) { for (int i =0 ; i<ladders.length ; ++i) {
if (ladders[i].getDownStepId() == tile && if (ladders[i].getDownStepId() == tile &&
ladders[i].getBroken() == false) { ladders[i].getBroken() == false) {
ladders[i].setBroken(true); ladders[i].setBroken(climb);
return ladders[i].getUpStepId(); return ladders[i].getUpStepId();
} }
} }
@@ -239,13 +239,14 @@ public class Board {
* @param tile The tile to check * @param tile The tile to check
* @return The score difference * @return The score difference
*/ */
int checkApple (int tile) { int checkApple (int tile, boolean eat) {
int ds =0; // delta-score int ds =0; // delta-score
for (int i =0 ; i<apples.length ; ++i) { for (int i =0 ; i<apples.length ; ++i) {
if (apples[i].getAppleTileId() == tile) { if (apples[i].getAppleTileId() == tile) {
// eat it
ds = apples[i].getPoints(); ds = apples[i].getPoints();
apples[i].setPoints(0); // eat it
if (eat)
apples[i].setPoints(0);
} }
} }
return ds; return ds;
+133 -46
View File
@@ -2,7 +2,7 @@ package net.hoo2.auth.dsproject.snake;
/** /**
* @mainpage * @mainpage
* @title Snake game project. -- Part 1 -- * @title Snake game project. -- Part 2 --
* *
* This is the code documentation page of the Snake game project. * This is the code documentation page of the Snake game project.
* Listed are: * Listed are:
@@ -13,9 +13,7 @@ package net.hoo2.auth.dsproject.snake;
* @author Christos Choutouridis AEM:8997 * @author Christos Choutouridis AEM:8997
* @email cchoutou@ece.auth.gr * @email cchoutou@ece.auth.gr
*/ */
import java.util.*;
import java.lang.Math;
import java.util.ArrayList;
/** /**
* @class Game * @class Game
@@ -31,40 +29,74 @@ import java.util.ArrayList;
public class Game { public class Game {
/** @name Constants */ /** @name Constants */
/**@{ */ /**@{ */
static final int MAX_PLAYERS = 4; /**< The maximum number of allowed players in the game */ static final int MAX_PLAYERS = 6; /**< The maximum number of allowed players in the game */
static final int MAX_GAME_ROUNDS = 10000; /**< the maximum allowed round of the game */ static final int MAX_GAME_ROUNDS = 1000; /**< the maximum allowed round of the game */
/**@} */ /**@} */
/** @name Private data members */ /** @name Private data members */
/** @{ */ /** @{ */
private int round; /**< The current round of the game */ private int round; /**< The current round of the game */
private Board board; /**< A reference to board */ private Board board; /**< A reference to board */
private ArrayList<Player> players; /**< A reference to players */ private ArrayList<Player> players; /**< A reference to players */
private Map<Integer, Integer> playingOrder; /**< A Map with {PlayerID, Dice-roll} pairs
@note
This way of storing the playing order is unnecessary.
The old style was far more better. We had a turn variable
in each Player and we used to sort the players vector based on
that value. This made the rest of the program simpler, faster, easer.
We have adopt the above approach just because it is one of the
homework requirements.
*/
/** @} */ /** @} */
/** @name private api */ /** @name private api */
/** @{ */ /** @{ */
/** /**
* Dice functionality * Search the players already in the pairs vector and compare their turn to play
* @return An integer in the range [1 .. 6]
*/
private int _dice () {
return (int)(1 + Math.random()*5);
}
/**
* Search the players already in the players vector and compare their turn to play
* with the result of a dice. If there is another one with the same dice result return true. * with the result of a dice. If there is another one with the same dice result return true.
* *
* @param turn The dice result to check in order to find player's turn to play * @param roll The dice result to check in order to find player's turn to play
* @param players Reference to already register players * @param pairs Reference to already register players and their dice result
* @return True if there is another player with the same dice result * @return True if there is another player with the same dice result
*/ */
private boolean _search (int die, ArrayList<Player> players) { private boolean _search (int roll, ArrayList<Integer[]> pairs) {
for (int i =0; i<players.size() ; ++i) for (int i =0; i<pairs.size() ; ++i)
if (players.get(i).getTurn() == die) if (pairs.get(i)[1] == roll)
return true; return true;
return false; return false;
} }
/**
* Sort the pairs vector using second parameter witch represent the
* dice roll. We use bubblesort for the implementation.
* @param pairs A vector with {PlayerId, dice-roll} pairs to sort
*/
private void _sort (ArrayList<Integer[]> pairs) {
Integer[] temp;
for (int i=pairs.size()-1 ; i>0 ; --i) {
for (int j =0 ; j<i ; ++j) {
if (pairs.get(j)[1] > pairs.get(i)[1]) {
temp = pairs.get(i);
pairs.set(i, pairs.get(j));
pairs.set(j, temp);
}
}
}
}
/**
* Helper function to get a player from players vector using it's ID
* @param playerId The player's ID to seek
* @return Reference to Player or null
*/
private Player _getPlayer(int playerId) {
for (Player p : players) {
if (p.getPlayerId() == playerId)
return p;
}
return null;
}
/** @} */ /** @} */
@@ -75,6 +107,8 @@ public class Game {
round = 0; round = 0;
board = new Board(); board = new Board();
players = new ArrayList<>(); players = new ArrayList<>();
playingOrder
= new HashMap<Integer, Integer>();
} }
/** /**
@@ -92,6 +126,8 @@ public class Game {
// delegate constructors // delegate constructors
board = new Board (N, M, numOfSnakes, numOfLadders, numOfApples); board = new Board (N, M, numOfSnakes, numOfLadders, numOfApples);
players = new ArrayList<>(); players = new ArrayList<>();
playingOrder
= new HashMap<Integer, Integer>();
} }
/** @} */ /** @} */
@@ -118,6 +154,12 @@ public class Game {
void setPlayers(ArrayList<Player> players) { void setPlayers(ArrayList<Player> players) {
this.players = players; this.players = players;
} }
/** Get reference to playingOrder Map */
Map<Integer, Integer> getPlayingOrder () { return playingOrder; }
/** Set the playingOrder Map */
void setPlayingOrder (Map<Integer, Integer> playingOrder) {
this.playingOrder = playingOrder;
}
/** @} */ /** @} */
/** @name Public functionality */ /** @name Public functionality */
@@ -134,26 +176,53 @@ public class Game {
players.add(new Player(playerId, name, board)); players.add(new Player(playerId, name, board));
return true; return true;
} }
/**
* Register a heuristic player to the game
* @param playerId The player ID to use
* @param name The player name to use
* @return The status of the operation
*/
boolean registerHeuristicPlayer (int playerId, String name) {
if (players.size() >= MAX_PLAYERS)
return false;
players.add(new HeuristicPlayer(playerId, name, board));
return true;
}
/** /**
* @brief Set the playing order of players * @brief Set the playing order of players
* This function emulates the classic roll of dice to decide which player * This function emulates the classic roll of dice to decide which player
* plays first which second and so on. * plays first which second and so on.
*/ */
void playOrder () { Map<Integer, Integer> setTurns (ArrayList<Player> players) {
int d; int[] pairData = new int[2]; // We use plain int[] to create an Integer[]
for (int i =0 ; i<players.size() ; ++i) { Integer[] PairData; // The Integer[] to push to ArrayList<>
do ArrayList<Integer[]>
// Keep rolling the dice as the die belongs to another user pairList = new ArrayList<>(); // Use use ArrayList before Map in order to sort
d = _dice();
while (_search (d, players));
players.get(i).setTurn(d);
}
// Sort players vector
players.sort((p1, p2) ->
Integer.compare (p1.getTurn(), p2.getTurn())
);
}
for (int d, i =0 ; i<players.size() ; ++i) {
do
// Keep rolling the dice until we get a unique value
d = players.get(i).dice ();
while (_search (d, pairList));
// Make Integer[] pair
pairData[0] = players.get(i).getPlayerId();
pairData[1] = d;
PairData = Arrays.stream(pairData)
.boxed()
.toArray(Integer[]::new);
pairList.add(PairData); // Add to vector
}
// Sort playeingOrger
_sort (pairList);
// Make and return the Map
for (int i =0 ; i<pairList.size() ; ++i) {
playingOrder.put(pairList.get(i)[0], pairList.get(i)[1]);
}
return playingOrder;
}
/** /**
* Sort the players according to their score * Sort the players according to their score
*/ */
@@ -166,19 +235,22 @@ public class Game {
/** /**
* A game round. In each round every player plays when is his turn * A game round. In each round every player plays when is his turn
* *
* @param verbose Flag to indicate how much we print to console
* @return The winner if we have one, or null * @return The winner if we have one, or null
*/ */
Player round () { Player round (boolean verbose) {
int [] mret; int tile;
++round; // keep track of round ++round; // keep track of round
// traverse the players vector and move each player on the board // traverse the players vector and move each player on the board
// using a dice throw // using a dice throw
for (int i =0 ; i<players.size() ; ++i) { for (Integer pid : playingOrder.keySet()) {
mret = players.get(i).move (players.get(i).getTile(), _dice()); Player p = _getPlayer(pid);
if (mret[0]>= board.getN()*board.getM()) tile = p.getNextMove (p.getTile());
p.statistics(verbose, false);
if (tile>= board.getN()*board.getM())
// The first one here is the winner // The first one here is the winner
return players.get(i); return p;
} }
return null; // No one finished yet return null; // No one finished yet
} }
@@ -203,6 +275,7 @@ public class Game {
int numOfLadders = 3; int numOfLadders = 3;
int numOfApples = 6; int numOfApples = 6;
int numOfPlayers = 2; int numOfPlayers = 2;
boolean verbose = false;
// Print caption // Print caption
System.out.println("================== Snake Game =================="); System.out.println("================== Snake Game ==================");
@@ -214,14 +287,18 @@ public class Game {
Game game = new Game (lines, columns, numOfSnakes, numOfLadders, numOfApples); Game game = new Game (lines, columns, numOfSnakes, numOfLadders, numOfApples);
// game.getBoard().createElementBoard(); // Not explicitly required // game.getBoard().createElementBoard(); // Not explicitly required
// Player registration // Player registration, the one is cheater
for (int i=0 ; i<numOfPlayers && i<MAX_PLAYERS; ++i) for (int i=0 ; i<numOfPlayers && i<MAX_PLAYERS; ++i) {
game.registerPlayer(i+1, String.format("Player %d", i+1)); if (i == 0)
game.playOrder(); // Choose play order game.registerHeuristicPlayer(i+1, String.format("Player %d", i+1));
else
game.registerPlayer(i+1, String.format("Player %d", i+1));
}
game.setTurns(game.getPlayers()); // Choose play order
Player winner; Player winner;
do // Keep going until someone finishes do // Keep going until someone finishes
winner = game.round (); winner = game.round (verbose);
while (winner == null while (winner == null
&& game.getRound() < MAX_GAME_ROUNDS); && game.getRound() < MAX_GAME_ROUNDS);
if (game.getRound() == MAX_GAME_ROUNDS) { if (game.getRound() == MAX_GAME_ROUNDS) {
@@ -231,8 +308,10 @@ public class Game {
} }
// Print the results // Print the results
System.out.println("***** Game finished *****"); System.out.println("*** Game finished ***");
System.out.println(""); System.out.println("");
System.out.println("");
System.out.println("*** Game Results ***");
System.out.println("Rounds: " + game.getRound()); System.out.println("Rounds: " + game.getRound());
System.out.println("Winner: " + winner.getName() + " [" + winner.getScore() +" points]"); System.out.println("Winner: " + winner.getName() + " [" + winner.getScore() +" points]");
System.out.println("Score: "); System.out.println("Score: ");
@@ -245,5 +324,13 @@ public class Game {
else else
System.out.println(" " +p.getName() + ": " + p.getScore() +" points"); System.out.println(" " +p.getName() + ": " + p.getScore() +" points");
} }
// Print the extra statistics for the heuristic player only
// We use a little reflection for that
for (Player p : game.getPlayers()) {
if (p.getClass().getSimpleName().equals("HeuristicPlayer"))
p.statistics(verbose, true);
}
} }
} }
@@ -0,0 +1,140 @@
package net.hoo2.auth.dsproject.snake;
import java.util.*;
/**
* @class HeuristicPlayer
* @brief Represent a Heuristic Player in the Game
*
* The players are playing in a round-robin sequence and we keep track
* for each one of them their playing order, score and place on the board.
* This kind of player, is a cheater. He can control the dice. Not fair dude.
*
* @author Christos Choutouridis AEM:8997
* @email cchoutou@ece.auth.gr
*/
public class HeuristicPlayer
extends Player {
/** @name Constructors */
/** @{ */
/** Default doing nothing constructor */
public HeuristicPlayer() {
super ();
path = new ArrayList<Integer[]>();
}
/**
* @brief The main constructor
*
* This creates a player for the game
* @param playerId The player's to create
* @param name The name of the player
* @param board Reference to the board the player will play on.
*/
HeuristicPlayer (int playerId, String name, Board board) {
super (playerId, name, board);
path = new ArrayList<Integer[]>();
}
/* @} */
/** @name Get/Set interface */
/** @{ */
ArrayList<Integer[]> getPath() { return path; }
void setPath (ArrayList<Integer[]> path) {
this.path = path;
}
/** @} */
/**
* Override dice functionality for the player
* @return As this is called from the game only to select playing order
* we cheat and return 1
*/
@Override
int dice () {
return 1;
}
/**
* Override get the next tile after the user's move
* @param tile The initial tile
* @return The tile after the move
*/
@Override
int getNextMove (int tile) {
Map<Integer, Double> moves = new HashMap<Integer, Double>();
double max = Double.NEGATIVE_INFINITY;
double ev = Double.NEGATIVE_INFINITY;
int roll = 0;
// Evaluate each possible dice result and find the better one
for (int r=1 ; r<=6 ; ++r) {
moves.put (new Integer(r), evaluate (tile, r));
if ((ev = moves.get(r)) > max) {
max = ev;
roll = r;
}
}
// Do the move and get the move data
Integer[] move_data = Arrays.stream(move (tile, roll, true))
.boxed()
.toArray(Integer[]::new);
// Store the move data
path.add(move_data);
return tile + roll; // return the new tile position
}
/**
* The Heuristic statistics version
* @param verbose Flag to select the verbosity
* @param sum Flag to select if we need to print a summarize of the user hystory
*/
@Override
void statistics (boolean verbose, boolean sum) {
if (sum) {
// If we run the summarize
int nSnakes =0;
int nLadders =0;
int nRedApples =0;
int nBlackApples =0;
// Calculate frequencies
for (int i=0 ; i<path.size() ; ++i) {
nSnakes += path.get(i)[MOVE_SNAKES_IDX];
nLadders+= path.get(i)[MOVE_LADDERS_IDX];
nRedApples += path.get(i)[MOVE_RED_APPLES_IDX];
nBlackApples += path.get(i)[MOVE_BLACK_APPLES_IDX];
}
// Print the results
System.out.println("");
System.out.println("*** Statistics for " + name + " ***");
System.out.println(" Number of Snake bites : " + nSnakes);
System.out.println(" Number of Ladders used : " + nLadders);
System.out.println(" Number of Red Apples eaten : " + nRedApples);
System.out.println(" Number of Black Apples eaten: " + nBlackApples);
}
else
// Call the base version
super.statistics(verbose, sum);
}
/**
* The main evaluation function
* @param tile The current tile of the player
* @param roll the roll to check
* @return The evaluation of the roll
*/
private double evaluate (int tile, int roll) {
int[] check = new int[MOVE_DATA_SIZE];
check = move(tile, roll, false);
return 0.65*check[MOVE_STEPS_IDX] + 0.35*check[MOVE_POINTS_IDX];
}
/** @name Data members package access only */
/** @{ */
private ArrayList<Integer[]> path; /**< Players history as required */
/** @} */
}
+138 -40
View File
@@ -1,5 +1,8 @@
package net.hoo2.auth.dsproject.snake; package net.hoo2.auth.dsproject.snake;
import java.util.Arrays;
import java.lang.Math;
/** /**
* @class Player * @class Player
* @brief Represent a Player in the Game * @brief Represent a Player in the Game
@@ -11,13 +14,27 @@ package net.hoo2.auth.dsproject.snake;
* @email cchoutou@ece.auth.gr * @email cchoutou@ece.auth.gr
*/ */
public class Player { public class Player {
/** Helper variables to keep track of the move() return values @see move() */
static final int MOVE_DATA_SIZE = 9; /**< The move return data array size */
static final int MOVE_TILE_IDX = 0; /**< The index of tile */
static final int MOVE_INITTILE_IDX = 1; /**< The index of init tile */
static final int MOVE_STEPS_IDX = 2; /**< The index of steps */
static final int MOVE_ROLL_IDX = 3; /**< The index of roll */
static final int MOVE_POINTS_IDX = 4; /**< The index of points */
static final int MOVE_SNAKES_IDX = 5; /**< The index for number of snakes (Always <= 1) */
static final int MOVE_LADDERS_IDX = 6; /**< The index for number of ladders (Always <= 1) */
static final int MOVE_RED_APPLES_IDX = 7; /**< The index for number of red apples (Always <= 1) */
static final int MOVE_BLACK_APPLES_IDX = 8; /**< The index for number of black apples (Always <= 1) */
/** @name Constructors */ /** @name Constructors */
/** @{ */ /** @{ */
/** Default doing nothing constructor */ /** Default doing nothing constructor */
Player () { Player () {
playerId = score = tile = turn = 0; playerId = score = tile = 0;
name = ""; name = "";
board = null; board = null;
lastMove = new int[MOVE_DATA_SIZE];
dryMove = new int[MOVE_DATA_SIZE];
} }
/** /**
* @brief The main constructor * @brief The main constructor
@@ -33,7 +50,8 @@ public class Player {
this.board = board; this.board = board;
score = 0; score = 0;
tile = 0; tile = 0;
turn = 0; lastMove = new int[MOVE_DATA_SIZE];
dryMove = new int[MOVE_DATA_SIZE];
} }
/** @} */ /** @} */
@@ -63,75 +81,155 @@ public class Player {
void setTile (int tile) { void setTile (int tile) {
this.tile = tile; this.tile = tile;
} }
/** Get turn */
int getTurn () { return turn; } /** Get lastMove */
/** Set turn */ int[] getLastMove () { return lastMove; }
void setTurn (int turn) { /** Set lastMove */
this.turn = turn; void setLastMove (int[] lastMove) {
this.lastMove = lastMove;
}
/** Get dryMove */
int[] getDryMove () { return dryMove; }
/** Set dryMove */
void setDryMove (int[] dryMove) {
this.dryMove = dryMove;
} }
/** @} */ /** @} */
/** @name Exposed API members */ /** @name Exposed API members */
/** @{ */ /** @{ */
/**
* Dice functionality for the players
* @return An integer in the range [1 .. 6]
*/
int dice () {
return (int)(1 + Math.random()*5);
}
/**
* Get the next tile after the user's move
* @param tile The initial tile
* @return The tile after the move
* @note
* We add this move() wrapper in order to provide polymorphism to
* Player class hierarchy and to be sure that we are not braking the
* Liskov substitution principle
* @see https://en.wikipedia.org/wiki/Liskov_substitution_principle
*/
int getNextMove (int tile) {
return move (tile, dice(), true)[MOVE_TILE_IDX];
}
/** /**
* @brief Move functionality * @brief Move functionality
* This function prints to stdout various logs about user interaction with elements
* *
* @param tile The initial tile of the player * @param tile The initial tile of the player
* @param die The die to play * @param roll The dice roll to play
* @param run Flag to indicate if we fake the move(dry run) or we do make the move.
* @return * @return
* int[0] tile after move * int[MOVE_TILE_IDX (0)] tile after move
* int[1] number of snake bites * int[MOVE_INITTILE_IDX (1)] tile before move
* int[2] number of ladder used * int[MOVE_STEPS_IDX (2)] number of total steps for the move
* int[3] number of apples eaten * int[MOVE_ROLL_IDX (3)] the roll of the dice
* int[MOVE_POINTS_IDX (4)] the points of the move
* int[MOVE_SNAKES_IDX (5)] number of snake bites
* int[MOVE_LADDERS_IDX (6)] number of ladders used
* int[MOVE_RED_APPLES_IDX (7)] number of red apples eaten
* int[MOVE_BLACK_APPLES_IDX (8)] number of black apples eaten
* @note
* Probably a mutable class like: <pre>
* class MoveData {
* int tile;
* int initTile;
* ...
* }
* </pre>
* for returning value would be better, less error prone, cleaner, etc...
* We could also had members like: <pre> MoveData previous; </pre> to help us further.
* We kept this representation just because it was a requirement.
*/ */
int [] move (int tile, int die) { int [] move (int tile, int roll, boolean run) {
int [] ret = new int[4];
int t; int t;
tile += die; // Initial move Arrays.fill(dryMove, 0);
//System.out.println(name + " +" + die + "->tile: " + tile); //XXX: Debug only dryMove[MOVE_INITTILE_IDX] = tile;
dryMove[MOVE_ROLL_IDX] = roll;
tile += roll; // Initial move
boolean keepGoing; boolean keepGoing;
do { do {
keepGoing = false; keepGoing = false;
// Check apples // Check apples
t = board.checkApple(tile); if ((t = board.checkApple(tile, run)) != 0) {
if (t != 0) { dryMove[MOVE_POINTS_IDX] += t;
score += t; if (t > 0)
++ret[3]; ++dryMove[MOVE_RED_APPLES_IDX];
System.out.println(name + " Apple @" + tile + " " + t + " points"); else
++dryMove[MOVE_BLACK_APPLES_IDX];
} }
// Check ladder // Check ladder
t = board.checkLadder(tile); if ((t = board.checkLadder(tile, run)) != tile) {
if (t != tile) {
System.out.println(name + " Ladder @" + tile + " new position " + t);
tile = t; tile = t;
++ret[2]; ++dryMove[MOVE_LADDERS_IDX];
keepGoing = true; keepGoing = true;
} }
// Check snakes // Check snakes
t = board.checkSnake(tile); if ((t = board.checkSnake(tile)) != tile) {
if (t != tile) {
System.out.println(name + " Ouch!! Snake @" + tile + " new position " + t);
tile = t; tile = t;
++ret[1]; ++dryMove[MOVE_SNAKES_IDX];
keepGoing = true; keepGoing = true;
} }
} while (keepGoing); } while (keepGoing);
ret[0] = this.tile = tile;
return ret; dryMove[MOVE_TILE_IDX] = tile;
dryMove[MOVE_STEPS_IDX]= tile - dryMove[MOVE_INITTILE_IDX];
// Check if we do run the move
if (run) {
lastMove = dryMove.clone();
this.tile = lastMove[MOVE_TILE_IDX];
score += lastMove[MOVE_POINTS_IDX];
}
return dryMove;
}
/**
* The base statistics version
* @param verbose Flag to select the verbosity
* @param sum Flag to select if we need to print a summarize (not used here)
* @note
* We added this function because:
* 1) we need to keep the "Is a" relationship (Liskov substitution principle)
* 2) It help us get rid of the move() console output code
* 3) makes the code smaller
*/
void statistics (boolean verbose, boolean sum) {
int begin = lastMove[MOVE_INITTILE_IDX];
int roll = lastMove[MOVE_ROLL_IDX];
int last = lastMove[MOVE_TILE_IDX];
if (verbose)
System.out.println(name + " +" + roll + "->tile: " + (begin + roll));
if (lastMove[MOVE_RED_APPLES_IDX] > 0)
System.out.println(name + " Apple " + lastMove[MOVE_POINTS_IDX] + " points");
if (lastMove[MOVE_BLACK_APPLES_IDX] > 0)
System.out.println(name + " Apple " + lastMove[MOVE_POINTS_IDX] + " points");
if (lastMove[MOVE_LADDERS_IDX] > 0)
System.out.println(name + " Ladder @" + (begin + roll) + " new position " + last);
if (lastMove[MOVE_SNAKES_IDX] > 0)
System.out.println(name + " Ouch!! Snake @" + (begin + roll) + " new position " + last);
// No use of sum here
} }
/**@} */ /**@} */
/** @name Data members package access only */
/** @name Data members (private) */
/** @{ */ /** @{ */
private int playerId; /**< Player's ID */ int playerId; /**< Player's ID */
private String name; /**< Player's name */ String name; /**< Player's name */
private int score; /**< Player's score */ int score; /**< Player's score */
private Board board; /**< Reference to current board */ Board board; /**< Reference to current board */
private int tile; /**< Player's tile location */ int tile; /**< Player's tile location */
private int turn; /**< Player's turn of playing */ int[] lastMove; /**< move() return data for statistics. These are only valid after a true move */
private int [] dryMove; /**< Fake (dry run) move return buffer */
/** @} */ /** @} */
} }