Skip to content

Instantly share code, notes, and snippets.

@bluerogue
Created April 1, 2015 20:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bluerogue/92e2f694cbc1cf214d3f to your computer and use it in GitHub Desktop.
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
/**
* 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