Created
April 1, 2015 20:05
-
-
Save bluerogue/92e2f694cbc1cf214d3f to your computer and use it in GitHub Desktop.
Generates a 2D grid with randomized integers (ensuring no 3 consecutive values) and performs several functions against the grid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Handles the generation of the randomized grid and associated functions. | |
* | |
* @author Matthew Roberts | |
* matthew.bowen.roberts@gmail.com | |
* matthewroberts.org | |
*/ | |
public class GridGenerator { | |
private static final int MAX_RANDOM = 5; | |
/** | |
* Gets a grid with no 3-in-a-row sequences. | |
* | |
* @param gridSize | |
* the length of the rows and columns of the grid | |
* @param numberBound | |
* the upper bound of the random numbers to use when building the | |
* grid | |
* @return returns a 2D integer array game grid with no 3-in-a-row sequences | |
*/ | |
public static int[][] getGameGrid(int gridSize, int numberBound) { | |
int[][] grid = getRandomGrid(gridSize, numberBound); | |
List<GridPoint> matchingLocations = getMatchingLocations(grid); | |
if (matchingLocations.size() > 0) { | |
while (matchingLocations.size() > 0) { | |
matchingLocations = getMatchingLocations(grid); | |
grid = replaceMatches(grid, matchingLocations); | |
} | |
} | |
return grid; | |
} | |
/** | |
* Replaces only the original instances of matching GridPoints in a | |
* sequence. | |
* | |
* @param grid | |
* a 2D array to perform the operation on | |
* @param matchingLocations | |
* a list of GridPoints to replace | |
* @return returns a new version of the specified grid with points replaced | |
*/ | |
public static int[][] replaceOnlyMatches(int[][] grid, | |
List<GridPoint> matchingLocations) { | |
int[][] updatedGrid = grid; | |
List<GridPoint> newMatchingLocations = matchingLocations; | |
while (newMatchingLocations.size() > 0) { | |
for (GridPoint point : matchingLocations) { | |
updatedGrid[point.getRow()][point.getCol()] = getNumber(MAX_RANDOM); | |
} | |
newMatchingLocations = getMatchingLocations(updatedGrid); | |
} | |
return updatedGrid; | |
} | |
/** | |
* Replaces all instances of matching GridPoints in a sequence. | |
* | |
* @param grid | |
* a 2D array to perform the operation on | |
* @param matchingLocations | |
* a list of GridPoints to replace | |
* @return returns a new version of the specified grid with points replaced | |
*/ | |
public static int[][] replaceMatches(int[][] grid, | |
List<GridPoint> matchingLocations) { | |
int[][] updatedGrid = grid; | |
for (GridPoint point : matchingLocations) { | |
updatedGrid[point.getRow()][point.getCol()] = getNumber(MAX_RANDOM); | |
} | |
return updatedGrid; | |
} | |
/** | |
* Finds and returns all GridPoints that are part of a 3-in-a-row adjacent | |
* sequence including rows, columns, and left and right diagonals. | |
* | |
* @param grid | |
* a 2D array to perform the operation on | |
* @return returns a list of GridPoints that are part of a 3-in-a-row | |
* adjacent sequence | |
*/ | |
public static List<GridPoint> getMatchingLocations(int[][] grid) { | |
List<GridPoint> matchingLocations = new ArrayList<GridPoint>(); | |
/* Used to prevent ArrayOutOfBoundsException */ | |
int safetyBound = grid.length - 2; | |
for (int i = 0; i < grid.length - 1; i++) { | |
for (int j = 0; j < grid.length - 1; j++) { | |
int firstMatch = grid[i][j]; | |
/* Search column for 3 adjacent */ | |
if (i < safetyBound && grid[i + 1][j] == firstMatch | |
&& grid[i + 2][j] == firstMatch) { | |
matchingLocations.add(new GridPoint(i, j)); | |
matchingLocations.add(new GridPoint(i + 1, j)); | |
matchingLocations.add(new GridPoint(i + 2, j)); | |
} | |
/* Search row for 3 adjacent */ | |
if (j < safetyBound && grid[i][j + 1] == firstMatch | |
&& grid[i][j + 2] == firstMatch) { | |
matchingLocations.add(new GridPoint(i, j)); | |
matchingLocations.add(new GridPoint(i, j + 1)); | |
matchingLocations.add(new GridPoint(i, j + 2)); | |
} | |
/* Perform diagonal searches */ | |
if (i < safetyBound && j < safetyBound) { | |
/* Search diagonal right for 3 adjacent */ | |
if (grid[i + 1][j + 1] == firstMatch | |
&& grid[i + 2][j + 2] == firstMatch) { | |
matchingLocations.add(new GridPoint(i, j)); | |
matchingLocations.add(new GridPoint(i + 1, j + 1)); | |
matchingLocations.add(new GridPoint(i + 2, j + 2)); | |
} | |
/* Search diagonal left for 3 adjacent */ | |
if (grid[i][grid.length - (j + 1)] == grid[i + 1][grid.length - (j + 2)] | |
&& grid[i][grid.length - (j + 1)] == grid[i + 2][grid.length - (j + 3)]) { | |
matchingLocations.add(new GridPoint(i, grid.length - (j + 1))); | |
matchingLocations.add(new GridPoint(i + 1, grid.length - (j + 2))); | |
matchingLocations.add(new GridPoint(i + 2, grid.length - (j + 3))); | |
} | |
} | |
} | |
/* Search last row and column */ | |
if (i < safetyBound) { | |
/* Search last row for 3 adjacent */ | |
if (grid[grid.length - 1][i] == grid[grid.length - 1][i + 1] | |
&& grid[grid.length - 1][i + 1] == grid[grid.length - 1][i + 2]) { | |
matchingLocations.add(new GridPoint(grid.length - 1, i)); | |
matchingLocations.add(new GridPoint(grid.length - 1, i + 1)); | |
matchingLocations.add(new GridPoint(grid.length - 1, i + 2)); | |
} | |
/* Search last column for 3 adjacent */ | |
if (grid[i][grid.length - 1] == grid[i + 1][grid.length - 1] | |
&& grid[i + 1][grid.length - 1] == grid[i + 2][grid.length - 1]) { | |
matchingLocations.add(new GridPoint(i, grid.length - 1)); | |
matchingLocations.add(new GridPoint(i + 1, grid.length - 1)); | |
matchingLocations.add(new GridPoint(i + 2, grid.length - 1)); | |
} | |
} | |
} | |
return matchingLocations; | |
} | |
/** | |
* Populates a proportioned 2D array with random integers. | |
* | |
* @param gridSize | |
* the length of the rows and columns of the grid | |
* @param numberBound | |
* the upper bound of the random numbers to use when building the | |
* grid | |
* @return returns a 2D array of specified size populated with random | |
* integers | |
*/ | |
public static int[][] getRandomGrid(int gridSize, int numberBound) { | |
int[][] grid = new int[gridSize][gridSize]; | |
for (int i = 0; i < gridSize; i++) { | |
for (int j = 0; j < gridSize; j++) { | |
grid[i][j] = getNumber(numberBound); | |
} | |
} | |
return grid; | |
} | |
/** | |
* Get a random integer between 1 and a specified upper bound. | |
* | |
* @param upperBound | |
* an int to use a an upper boundary | |
* @return returns a random integer between 1 and the specified upper bound | |
*/ | |
public static int getNumber(int upperBound) { | |
return new Random().nextInt(upperBound) + 1; | |
} | |
/** | |
* Determines if a GridPoint is immediately adjacent to another GridPoint. | |
* | |
* @param origin | |
* the original GridPoint to test | |
* @param destination | |
* the destination GridPoint to test | |
* @return returns true if the GridPoints are immediately adjacent | |
*/ | |
public static boolean isAdjacent(GridPoint origin, GridPoint destination) { | |
boolean isAdjacent = false; | |
int colDiff = Math.abs(origin.getCol() - destination.getCol()); | |
int rowDiff = Math.abs(origin.getRow() - destination.getRow()); | |
if (colDiff == 1 && rowDiff == 0 | |
|| colDiff == 0 && rowDiff == 1) { | |
isAdjacent = true; | |
} | |
return isAdjacent; | |
} | |
} | |
/** | |
* Defines a point on a grid in terms of columns and rows. | |
* | |
* @author Matthew Roberts | |
* matthew.bowen.roberts@gmail.com | |
* matthewroberts.org | |
*/ | |
class GridPoint { | |
private int row, col; | |
public GridPoint(int row, int col) { | |
this.setRow(row); | |
this.setCol(col); | |
} | |
public int getRow() { | |
return row; | |
} | |
public void setRow(int row) { | |
this.row = row; | |
} | |
public int getCol() { | |
return col; | |
} | |
public void setCol(int col) { | |
this.col = col; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment