From 8037833cb9213ae1d14aa43c782113072b3eeded Mon Sep 17 00:00:00 2001 From: Karl Wang Date: Tue, 27 Feb 2018 21:27:28 -0800 Subject: [PATCH 1/3] fix comment --- .../cs56/projects/games/flood_it/view/FloodItController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java b/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java index 65f2505..3591da9 100644 --- a/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java +++ b/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java @@ -76,7 +76,7 @@ public int[][] populateGridEasy(int dimension, int numColors) { } /** - * populateGridEasy populates a medium grid of a given size + * populateGridMedium populates a medium grid of a given size * * @param dimension the grid will be dimension x dimension * @param numColors the number of colors in the grid @@ -94,7 +94,7 @@ public int[][] populateGridMedium(int dimension, int numColors) { /** - * populateGridEasy populates a hard grid of a given size + * populateGridHard populates a hard grid of a given size * * @param dimension the grid will be dimension x dimension * @param numColors the number of colors in the grid From 5a4c412cfc5b4b991000adf26a0da63234dd901a Mon Sep 17 00:00:00 2001 From: Karl Wang Date: Tue, 27 Feb 2018 21:30:06 -0800 Subject: [PATCH 2/3] adjust movesLeft --- .../cs56/projects/games/flood_it/view/FloodItController.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java b/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java index 3591da9..68383ec 100644 --- a/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java +++ b/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java @@ -27,9 +27,12 @@ public FloodItController(int dimension, int numColors, int difficultyLevel) { this.numColors = numColors; this.difficultyLevel = difficultyLevel; populateGrid(dimension, numColors, difficultyLevel); + //set MovesLeft (scales number of moves based on number of colors and dimension //selected using 25 moves for a 6 color, 14x14 grid as a baseline. - movesLeft = (int) Math.floor(dimension * numColors * 25 / 84); + int row = dimension; + int col = dimension; + movesLeft = (int) Math.floor( 25 * (row + col) * numColors / (14 + 14) * 6 ); if (difficultyLevel == 1) movesLeft = (int) Math.floor(movesLeft * .8); if (difficultyLevel == 3) movesLeft = (int) Math.floor(movesLeft * 2.33); } From 51b2d74618edb1c2f07928764d4a812d6bedcc70 Mon Sep 17 00:00:00 2001 From: Karl Wang Date: Wed, 28 Feb 2018 00:00:50 -0800 Subject: [PATCH 3/3] fixed moves left algorithm --- .../flood_it/view/FloodItController.java | 104 +++++++++++++++--- 1 file changed, 91 insertions(+), 13 deletions(-) diff --git a/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java b/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java index 68383ec..a7ef06a 100644 --- a/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java +++ b/src/edu/ucsb/cs56/projects/games/flood_it/view/FloodItController.java @@ -1,5 +1,8 @@ package edu.ucsb.cs56.projects.games.flood_it.view; +import java.util.Collections; +import java.util.Arrays; + /** * Class for Flood it game Controller * @@ -27,14 +30,13 @@ public FloodItController(int dimension, int numColors, int difficultyLevel) { this.numColors = numColors; this.difficultyLevel = difficultyLevel; populateGrid(dimension, numColors, difficultyLevel); - - //set MovesLeft (scales number of moves based on number of colors and dimension - //selected using 25 moves for a 6 color, 14x14 grid as a baseline. - int row = dimension; - int col = dimension; - movesLeft = (int) Math.floor( 25 * (row + col) * numColors / (14 + 14) * 6 ); - if (difficultyLevel == 1) movesLeft = (int) Math.floor(movesLeft * .8); - if (difficultyLevel == 3) movesLeft = (int) Math.floor(movesLeft * 2.33); + + if (difficultyLevel == 1) + this.movesLeft = (int) (calculateBaselineMovesLeft(dimension * dimension, dimension)); + if (difficultyLevel == 2) + this.movesLeft = (int) (calculateBaselineMovesLeft(dimension * dimension, dimension / 2)); + if (difficultyLevel == 3) + this.movesLeft = (int) (calculateBaselineMovesLeft(dimension * dimension, 1)); } /** @@ -127,6 +129,41 @@ public int[][] populateGridHard(int dimension, int numColors) { return result; } + /** + * calculates the number of moves given to the player + * by running random simulations on the grid + * the average of the top results is provided as the recommended number of moves + * + * @return recommended number of moves, not adjusted for difficulty + */ + private double calculateBaselineMovesLeft(int iterations, int tops){ + if(tops > iterations){ + throw new IllegalArgumentException("requesting the average of more result than that is generated"); + } + int[] testResults = new int[iterations]; //the choice of 30 iterations is completely arbitrary. Feel free to change it. + + for(int i = 0; i < testResults.length; i++){ + int[][] testGrid = gridCopy(this.grid); + int movesUsed = 0; + while(!checkWin(testGrid)){ + int newColor; + do{ + newColor = (int) (Math.random() * numColors); + }while(newColor == testGrid[0][0]); + floodIt(0, 0, newColor, testGrid[0][0], testGrid); + movesUsed++; + } + testResults[i] = movesUsed; + } + + Arrays.sort(testResults); + + int sum = 0; + for (int i = 0; i < tops; i++) { + sum += testResults[i]; + } + return (double)sum / tops; + } /** * floodIt redraws the matrix after the player makes a move @@ -138,13 +175,30 @@ public int[][] populateGridHard(int dimension, int numColors) { * @param oldColor the color to be repainted */ public void floodIt(int x, int y, int newColor, int oldColor) { + floodIt(x, y, newColor, oldColor, this.grid); + } + + /** + * floodIt redraws the matrix after the player makes a move + * it is adapted from Wikipedia's algorithm: en.wikipedia.org/wiki/Flood_fill + * + * @param x the x location in the matrix + * @param y the y location in the matrix + * @param newColor the new color being painted + * @param oldColor the color to be repainted + * @param grid the grid to be worked on + */ + private void floodIt(int x, int y, int newColor, int oldColor, int[][] grid) { + if(newColor == oldColor){ + throw new IllegalArgumentException("newColor and oldColor should not be the same!"); + } if (x < 0 || y < 0 || x >= grid.length || y >= grid.length) return; if (grid[x][y] != oldColor) return; grid[x][y] = newColor; - floodIt(x, y + 1, newColor, oldColor); - floodIt(x, y - 1, newColor, oldColor); - floodIt(x + 1, y, newColor, oldColor); - floodIt(x - 1, y, newColor, oldColor); + floodIt(x, y + 1, newColor, oldColor, grid); + floodIt(x, y - 1, newColor, oldColor, grid); + floodIt(x + 1, y, newColor, oldColor, grid); + floodIt(x - 1, y, newColor, oldColor, grid); return; } @@ -154,11 +208,20 @@ public void floodIt(int x, int y, int newColor, int oldColor) { * @return true if win, false if not. */ public boolean checkWin() { + return checkWin(this.grid); + } + + /** + * checkWin checks if the player has won the game + * + * @return true if win, false if not. + * @param grid the grid to be worked on + */ + private boolean checkWin(int[][] grid) { for (int i = 0; i < grid.length; i++) for (int j = 0; j < grid.length; j++) if (grid[i][j] != grid[0][0]) return false; return true; - } public int getDifficultyLevel() { @@ -184,4 +247,19 @@ public Integer getMovesLeft() { public void setMovesLeft(int movesLeft) { this.movesLeft = movesLeft; } + + /** + * utility method for copying a grid + * to be used in calculateMovesLeft() + * + * @return a copy of the provided grid + * @param grid the grid to be worked on + */ + private int[][] gridCopy(int[][] grid){ + int [][] newGrid = new int[grid.length][]; + for(int i = 0; i < grid.length; i++){ + newGrid[i] = grid[i].clone(); + } + return newGrid; + } }