package SnakePkg; import java.util.Random; /** * The game's board representation * @author Christos Choutouridis 8997 */ public class Board { /** @name Constructors */ /** @{ */ /** Default ctor */ Board () { N = M =0; tiles = null; snakes = null; ladders = null; apples = null; } /** * Main constructor * We make some simple input checking before memory allocation. * @note * May throw BadBoardInput */ Board (int N, int M, int numOfSnakes, int numOfLadders, int numOfApples) throws BadBoardInput { // Input checking if (numOfApples + numOfLadders*2 + numOfSnakes*2 >= N*M/2) throw new BadBoardInput("Too many Apples, Snakes and ladders"); // Init the board object setN (N); // Input checked version (may throw) setM (M); // Input checked version (may throw) tiles = new int[N][M]; snakes = new Snake[numOfSnakes]; ladders = new Ladder[numOfLadders]; apples = new Apple[numOfApples]; } /** * Copy constructor. We make a deep copy of B and we trust B's * data to be valid * @note We don't use clone as long as we don't inherit Cloneable iface */ Board (Board B) { this.N = B.getN(); this.M = B.getM(); tiles = new int[N][M]; snakes = new Snake[B.getSnakes().length]; ladders = new Ladder[B.getLadders().length]; apples = new Apple[B.getApples().length]; // Copy B's guts for (int i =0 ; i=0 ; --j) tiles[i][j] = tile++; } } } /** * @brief * Place the snakes on the board * The only constrain at this point is that snake tails must be * below heads and in different tiles */ private void _place_snakes () { int [] head = new int [snakes.length]; // temporary place holder for heads int [] tail = new int [snakes.length]; // temporary place holder for tails for (int i =0, tile =0 ; i= 0); head[i] = tile; tail[i] = (int)(Math.random() * (head[i] - head[i]%M)); // Don't use heads row and up for tail snakes[i] = new Snake(i, head[i], tail[i]); // Allocate snake } } /** * @brief * Place apples on the board * At this point we have snakes. The constrains here are * that apples have to lie on different tiles and not in some * snake's head */ private void _place_apples () { int [] apple_tiles = new int [apples.length]; // temporary placeholder for heads int [] snake_tiles = new int [snakes.length]; // array with snake head tiles for (int i =0 ; i= 0) || (_search (snake_tiles, tile) >= 0)); apple_tiles[i] = tile; int points = (int)(Math.random() *10) * 5; // get points boolean red = (boolean)(Math.random() >=0.5); // get color // Allocate apple if (red) apples[i] = new Apple(i, tile, "red", points); else apples[i] = new Apple(i, tile, "black", -points); } } /** * @brief * Place ladders on board * At this point we have snakes and apples. * @note * We add a constrain for ladder so its up-setp has to be different from a * snake's head tile. This ensures the each ladder and snake are independent */ private void _place_ladders () { int [] upstep = new int [ladders.length]; // temporary place holder for up-steps int [] downstep = new int [ladders.length]; // temporary place holder for down-step int [] snake_tiles = new int [snakes.length]; // array with snake head tiles for (int i =0 ; i= 0) || (_search (snake_tiles, tile) >= 0)); upstep[i] = tile; downstep[i] = (int)(Math.random() * (upstep[i] - upstep[i]%M)); //^ Don't use up-step row and up for down-step ladders[i] = new Ladder (i, upstep[i], downstep[i]); // Allocate ladder } } /** * Make element array of snakes * @param elemSnakes */ private void _makeElementSnakes (String[][] elemSnakes) { int [] head_tiles = new int [snakes.length]; // array with snake head tiles int [] tail_tiles = new int [snakes.length]; // array with snake head tiles int sn =-1; // Load snake head tiles for (int i =0 ; i= 0) elemSnakes[i][j] = "SH" + sn; else if ((sn = _search (tail_tiles, tiles[i][j])) >= 0) elemSnakes[i][j] = "ST" + sn; else elemSnakes[i][j] = "___"; } } } /** * Make element array of ladders * @param elemLadders */ private void _makeElementLadders (String[][] elemLadders) { int [] up_tiles = new int [ladders.length]; // array with ladder up-step tiles int [] down_tiles = new int [ladders.length]; // array with ladder down-step tiles int sn =-1; // Load ladder tiles for (int i =0 ; i= 0) elemLadders[i][j] = "LU" + sn; else if ((sn = _search (down_tiles, tiles[i][j])) >= 0) elemLadders[i][j] = "LD" + sn; else elemLadders[i][j] = "___"; } } } /** * Make element array of apples * @param elemApples */ private void _makeElementApples (String[][] elemApples) { int [] red_tiles = new int [apples.length]; // array with red apple tiles int [] black_tiles = new int [apples.length]; // array with black apple tiles int sn =-1; // Load apple tiles for (int i =0 ; i= 0) elemApples[i][j] = "AR" + sn; else if ((sn = _search (black_tiles, tiles[i][j])) >= 0) elemApples[i][j] = "AB" + sn; else elemApples[i][j] = "___"; } } } /** * Print element array * @param elem The element array to print * @param caption The caption * @note * As long as we use tiles[0][0] for first tile, this method * has to print in reverse Y-axis order. For ex: * 16 15 14 13 * 09 10 11 12 * 08 07 06 05 * 01 02 03 04 */ private void _printElement (String[][] elem, String caption) { System.out.print(caption); for (int i=N-1 ; i>=0 ; --i) { System.out.println(""); System.out.print(" "); for (int j =0 ; j=0 Element found */ private int _search (int[] array, int elem) { for (int i=0 ; i