Super powerful Boolean expressions
So far, when we’ve used Boolean expressions for our loops or if tests, they’ve been pretty simple. We will be using more powerful boolean expressions in some of the Ready-Bake Code you’re about to see, and even though we know you wouldn’t peek, we thought this would be a good time to discuss how to energize your expressions.
“And” and “Or” Operators ( &&, || )
Let’s say you’re writing a chooseCamera( ) method, with lots of rules about which camera to select. Maybe you can choose cameras ranging from $50 to $1000, but in some cases you want to limit the price range more precisely. You want to say something like:
“If the price range is between $300 and $400, then choose X.”
if (price >= 300 && price < 400) { camera = "X";
}
Let’s say that of the ten camera brands available, you have some logic that applies to only a few of the list:
if (brand.equals("A") || brand.equals("B")) { // do stuff for only brand A or brand B }
Boolean expressions can get really big and complicated:
if ((zoomType.equals("optical") &&
(zoomDegree >= 3 && zoomDegree <= 8)) ||
(zoomType.equals("digital") &&
(zoomDegree >= 5 && zoomDegree <= 12))) { // do appropriate zoom stuff
}
If you want to get really technical, you might wonder about the precedence of these operators. Instead of becoming an expert in the arcane world of precedence, we recommend that you use parentheses to make your code clear.
import java.util.*;
public class GameHelper {
private static final String ALPHABET = "abcdefg";
private static final int GRID_LENGTH = 7;
private static final int GRID_SIZE = 49;
private static final int MAX_ATTEMPTS = 200;
static final int HORIZONTAL_INCREMENT = 1; // A better way to represent these two static final int VERTICAL_INCREMENT = GRID_LENGTH; // things is an enum (see Appendix B) private final int[] grid = new int[GRID_SIZE];
private final Random random = new Random();
private int startupCount = 0;
public String getUserInput(String prompt) { System.out.print(prompt + ": ");
Scanner scanner = new Scanner(System.in);
return scanner.nextLine().toLowerCase();
} //end getUserInput
public ArrayList<String> placeStartup(int startupSize) { // holds index to grid (0 - 48)
int[] startupCoords = new int[startupSize]; // current candidate co-ordinates int attempts = 0; // current attempts counter boolean success = false; // flag = found a good location?
startupCount++; // nth Startup to place
int increment = getIncrement(); // alternate vert & horiz alignment while (!success & attempts++ < MAX_ATTEMPTS) { // main search loop
int location = random.nextInt(GRID_SIZE); // get random starting point for (int i = 0; i < startupCoords.length; i++) { // create array of proposed coords startupCoords[i] = location; // put current location in array location += increment; // calculate the next location }
// System.out.println("Trying: " + Arrays.toString(startupCoords));
if (startupFits(startupCoords, increment)) { // startup fits on the grid?
success = coordsAvailable(startupCoords); // ...and locations aren't taken?
} // end loop } // end while
savePositionToGrid(startupCoords); // coords passed checks, save ArrayList<String> alphaCells = convertCoordsToAlphaFormat(startupCoords);
// System.out.println("Placed at: "+ alphaCells);
return alphaCells;
} //end placeStartup
Ready-Bake Code
This is the helper class for the game. Besides the user input method (that prompts the user and reads input from the command line), the helper’s Big Service is to create the cell locations for the Startups. We tried to keep it fairly small so you wouldn’t have to type so much. And remember, you won’t be able to compile the StartupBust game class until you have this class.
Note: For extra credit, you might try “un-commenting” the System.out.println’s, just to watch it work! These print statements will let you “cheat” by giving you the location of the Startups, but it will help you test it.
Ready-Bake: GameHelper
This is the statement that tells you exactly where the
Ready-Bake
Code GameHelper class code continued...
private boolean startupFits(int[] startupCoords, int increment) { int finalLocation = startupCoords[startupCoords.length - 1];
if (increment == HORIZONTAL_INCREMENT) { // check end is on same row as start
return calcRowFromIndex(startupCoords[0]) == calcRowFromIndex(finalLocation);
} else {
return finalLocation < GRID_SIZE; // check end isn't off the bottom }
} //end startupFits
private boolean coordsAvailable(int[] startupCoords) {
for (int coord : startupCoords) { // check all potential positions if (grid[coord] != 0) { // this position already taken // System.out.println("position: " + coord + " already taken.");
return false; // NO success }
}
return true; // there were no clashes, yay!
} //end coordsAvailable
private void savePositionToGrid(int[] startupCoords) { for (int index : startupCoords) {
grid[index] = 1; // mark grid position as 'used' }
} //end savePositionToGrid
private ArrayList<String> convertCoordsToAlphaFormat(int[] startupCoords) { ArrayList<String> alphaCells = new ArrayList<String>();
for (int index : startupCoords) { // for each grid coordinate String alphaCoords = getAlphaCoordsFromIndex(index); // turn it into an "a0" style alphaCells.add(alphaCoords); // add to a list
}
return alphaCells; // return the "a0"-style coords } // end convertCoordsToAlphaFormat
private String getAlphaCoordsFromIndex(int index) {
int row = calcRowFromIndex(index); // get row value
int column = index % GRID_LENGTH; // get numeric column value String letter = ALPHABET.substring(column, column + 1); // convert to letter return letter + row;
} // end getAlphaCoordsFromIndex
private int calcRowFromIndex(int index) { return index / GRID_LENGTH;
} // end calcRowFromIndex private int getIncrement() {
if (startupCount % 2 == 0) { // if EVEN Startup return HORIZONTAL_INCREMENT; // place horizontally } else { // else ODD
return VERTICAL_INCREMENT; // place vertically }
} //end getIncrement
} //end class
This code, and a basic test, is available in the GitHub
API packages