Recursive Maze Solver Issue - java
I'm making a recursive Java maze program and I'm stuck on the part when it comes to calling to my subroutines goNorth(), goWest(), goEast() and goSouth(). Basically my problem involves the fact that it calls to one subroutine, but within that subroutine it doesn't pick up on my other else if and else statements therefore not making it pick up on the other possibilities. Please assist, I appreciate your upcoming answer.
import java.util.*;
import java.io.*;
public class RecursiveMazeSolverv2 {
static Scanner in;
static int row = 0;
static int col = 0;
static char maze[][];
static int rowSize = 0;
static int colSize = 0;
static boolean success = true;
public static void main(String[] args) {
while (true) {
try {
in = new Scanner(new File("Maze1.txt"));
break;
}
catch (FileNotFoundException e) {
System.out.println("Wrong File");
}
}
rowSize = Integer.parseInt(in.nextLine());
colSize = Integer.parseInt(in.nextLine());
maze = new char[rowSize][colSize];
String lineOfInput = "";
for (int i = 0; i < maze.length; i++) {
lineOfInput = in.nextLine();
for (int j = 0; j < maze.length; j++) {
maze[i][j] = lineOfInput.charAt(j);
}
}
displayGrid();
for (int i = 0; i < maze.length; i++) {
for (int j = 0; j < maze.length; j++) {
if (maze[i][j] == 'S') {
maze[i][j]='+';
System.out.println("Starting coordinates: " + i + ", " + j);
row = i;
col = j;
}
}
}
if (goNorth(row, col))
displayGrid();
else
System.out.println("Impossible!");
}
static Boolean goNorth(int row, int col) {
if (maze[row][col] == '.') {
maze[row][col] = '+';
return goNorth(row -1, col);
}
else if (maze[row][col] == 'G') {
return true;
}
else {
success = goNorth(row, col);
if (success == false) {
success = goWest(row, col -1);
}
if (success == false) {
success = goEast(row, col +1);
}
if (success == false) {
success = goSouth(row +1, col);
}
if (success == false) {
maze[row][col] = '.';
success = false; }
return false;
}
}
static Boolean goWest(int row, int col) {
if (maze[row][col] == '.') {
maze[row][col] = '+';
return goWest(row, col -1);
}
else if (maze[row][col] == 'G') {
return true;
}
else {
success = goWest(row, col);
if (success == false) {
success = goNorth(row -1, col);
}
if (success == false) {
success = goSouth(row +1, col);
}
if (success == false) {
success = goEast(row, col -1);
}
if (success == false) {
maze[row][col] = '.';
success = false; }
return false;
}
}
static Boolean goEast(int row, int col) {
if (maze[row][col] == '.') {
maze[row][col] = '+';
return goEast(row, col +1);
}
else if (maze[row][col] == 'G') {
return true;
}
else {
success = goEast(row, col);
if (success == false) {
success = goNorth(row -1, col);
}
if (success == false) {
success = goSouth(row +1, col);
}
if (success == false) {
success = goWest(row, col -1);
}
if (success == false) {
maze[row][col] = '.';
success = false; }
return false;
}
}
static Boolean goSouth(int row, int col) {
if (maze[row][col] == '.') {
maze[row][col] = '+';
return goSouth(row +1, col);
}
else if (maze[row][col] == 'G') {
return true;
}
else {
success = goSouth(row, col);
if (success == false) {
success = goNorth(row -1, col);
}
if (success == false) {
success = goWest(row, col -1);
}
if (success == false) {
success = goEast(row, col +1);
}
if (success == false) {
maze[row][col] = '.';
success = false; }
return false;
}
}
public static void displayGrid() {
for (int j = 0; j < maze.length; j++) {
for (int k = 0; k < maze.length; k++) {
System.out.print(maze[j][k] + " ");
}
System.out.println();
}
}
}
Sorry, I can't post the actual maze in here, it wont display right.
Problems I see:
As others eluded to, you shouldn't make everything static. Without going into a super long and boring discussion, making everything static means that the values you set in your recursive calls will modify the value for all calls. You are effectively over-writing each recursive call with values you are setting in subsequent recursive calls. You will want to make most of those method-scoped variables so that the value will only be valid in the scope of that method call.
Your recursive calls are not in the same order. You need to do the same calls in the same step each time: Try North, then South, then East, then West. Whatever order you pick, the calls need to be in the same order. In fact, I am not really sure why you decided to have separate methods for each direction...why not have one method called "move" that tries to go North, then recurses, then tries to go South, then recurses, then tries to go East and recurses, then West and recurses. The way you have things coded, there is no telling where the code will go in the maze, and most likely you will end up going around in circles.
This isn't directly linked to why it's not working, but you REALLY need to work on your code formatting, in particular your tabbing. Your code looks like it's all over the place. I can only imagine that that is making it WAY harder to troubleshoot that it needs to be.
Edit - Example
I will try to do this in a way to guide you without giving you a copy/paste answer, so this will be pseudo-code'ish.
/**
* My move recursion
*/
public boolean move(int currRow, int currCol) {
// See if we solved it...
if (solved) {
return true;
}
// Try to go north first...
if (maze[currRow-1][currCol] == '.') {
if (move(int currRow-1, currCol)) {
// Mark this with the "good" path and return true
}
}
// Try to go east next...
if (maze[currRow][currCol+1] == '.') {
if (move(int currRow, currCol+1)) {
// Mark this with the "good" path and return true
}
}
// Try to go south next...
if (maze[currRow+1][currCol] == '.') {
if (move(int currRow+1, currCol)) {
// Mark this with the "good" path and return true
}
}
// Try to go west...
if (maze[currRow][currCol-1] == '.') {
if (move(int currRow, currCol-1)) {
// Mark this with the "good" path and return true
}
}
return false;
}
So, basically we check if we are "solved". If not, see if we can go north. If we can, see if the next call is solved. Repeat for east, south, and west. Eventually one of the recursive calls will get to the solved condition, which will trigger each of the recursive calls to pass the inner if, which marks the maze and returns true, thus creating a chain reaction that ends up popping back up the call stack until you are done with the recursion.
Things to note with recursion:
It typically needs to be a process that can be broken into one or more repeatable, autonomous steps. This doesn't mean it has to be one method, but if it's multiple methods you HAVE to perform things within the method in the same order. Otherwise, your logic get's out of sync.
It typically works best when you can break the "steps" into their smallest, most menial parts. Overly complex recursive methods makes for hard debugging and lots and lots of crazy branching and looping.
You have to have a VERY clear "end", else you will recurse until you blow the stack up.
There should be a very clear distinction between variables/data/information that are "method level" and things that are "global". In your case, the maze is global, the success and current position are not.
Related
Java maze won't print
I have to make a maze for a java assignment, and I was able to finish most of it. I was provided with an outline of the code that had all the methods. Can someone help me? My issue is that the maze wont print out, and I can't figure out why. package maze; public class Maze { private char direction; private int r; // x position of the mouse private int c; //y position of the mouse private boolean exitFound = false; public Maze(int[][] arrMaze) { this.r = arrMaze.length - 1; this.c = 0; } //Prints out the maze without solution public void displayMaze(int[][] arrMaze) { //display the maze putting blank spaces where there are 1's in the array and putting //another symbol where there are 0's to show the maze without the solution for(int i=0; i<arrMaze.length; i++){ System.out.println(" "); for(int j=0; j<arrMaze[i].length; j++){ if(arrMaze[i][j] == 0){ System.out.print("#"); } if(arrMaze[i][j] == 1) { System.out.print(" "); } if(arrMaze[i][j] == 2){ System.out.print("#"); } if(arrMaze[i][j] == 3){ System.out.println("~"); } } } } //displays the Maze with the path taken public void displayPath(int[][] arrMaze) { //show the user how far the mouse has gone since the start. //The path the mouse has gone will be filled in but the path ahead will not. for (int i = 0; i < arrMaze.length; i++) { System.out.println(" "); for (int j = 0; j < arrMaze[i].length; j++) { if (arrMaze[i][j] == 3) { System.out.print("#"); } else if (arrMaze[i][j] == 2) { System.out.print("~"); } else if (arrMaze[i][j] == 0) { System.out.print("#"); } else { } } } } public boolean takeStep(int[][] newMaze) { // moveNorth(newMaze) for (int i = 0; i < newMaze.length; i++) { System.out.println(" "); for (int j = 0; j < newMaze[i].length; j++) { if (newMaze[r][c] == 3) { moveNorth(newMaze); System.out.print("~"); } else if (newMaze[r][c] == 2) { System.out.print("#"); } else { } } } return isAnExit(newMaze); } public void moveNorth(int[][] arrMaze) { //complete the code here /*method will check for a 0 or a 1 in the position above the current position * and then if not a 0 will change the current position to the row above it, but in the same column. */ if (arrMaze[r][c - 1] != 0) { arrMaze[r][c - 1] = 3; arrMaze[r][c + 1] = 2; } else { moveSouth(arrMaze); } displayPath(arrMaze); } public void moveSouth(int[][] arrMaze) { //method will check for a 0 or a 1 in the position below the current position and then if not a 0 //it will change the current position to the row below it, but in the same column. if (arrMaze[r][c + 1] != 0) { arrMaze[r][c + 1] = 3; arrMaze[r][c + 1] = 2; } else { moveNorth(arrMaze); } displayPath(arrMaze); } public void moveEast(int[][] arrMaze) { //method will check for a 0 or a 1 in the position to the right of  the current position and then if //not a 0 will change the current position to the column to the right but the same row. if (arrMaze[r + 1][c] != 0) { arrMaze[r + 1][c] = 3; arrMaze[r - 1][c] = 2; } else { moveWest(arrMaze); } displayPath(arrMaze); } public void moveWest(int[][] arrMaze) { //method will check for a 0 or a 1 in the position to the left of  the current position and then if //not a 0 will change the current position to the column to the left but the same row. if (arrMaze[r - 1][c] != 0) { arrMaze[r - 1][c] = 3; arrMaze[r + 1][c] = 2; } else { } displayPath(arrMaze); } private boolean isAnExit(int[][] arrMaze) { //method will return true if the user arrives into the last column of the array because there is only one //location in the last column that is a 1, so if the user reaches the array[i].length then that means that it found an exit. if (arrMaze[r][c] > arrMaze.length) { exitFound = true; } else { exitFound = false; } return exitFound; } //finds the path without stopping at every step //method will show the complete path from start to finish of the maze and the suggested route to the end. public void findExit(int[][] arrMaze) { if (arrMaze[r][c] > arrMaze.length) { for (int i = 0; i < arrMaze.length; i++) { takeStep(arrMaze); } } } } This is the test code. I was provided the test code, and I haven't changed it. package maze; import java.util.Scanner; public class TestMaze { public static void main(String[] args) { int[][] mazeArray = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0}, {0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1}, {0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0}, {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; Maze myMaze = new Maze(mazeArray); boolean keepAsking = true; Scanner scan = new Scanner(System.in); String input = ""; myMaze.displayPath(mazeArray); System.out.println("Maze"); do { System.out.println("T = Take a step | S = Show path | Q = Quit"); System.out.print("Enter command: "); input = scan.nextLine(); input.trim(); input.toLowerCase(); if(input.equals("t")) { keepAsking = !myMaze.takeStep(mazeArray); System.out.println("Which direction would you like to go? N, S, E, W?"); String direction = scan.nextLine(); if(direction.equalsIgnoreCase("n")) myMaze.moveNorth(mazeArray); if(direction.equalsIgnoreCase("s")) myMaze.moveSouth(mazeArray); if(direction.equalsIgnoreCase("e")) myMaze.moveEast(mazeArray); if(direction.equalsIgnoreCase("w")) myMaze.moveWest(mazeArray); } else if(input.equals("s")) { myMaze.findExit(mazeArray); keepAsking = false; } else if(input.equals("q")) { keepAsking = false; } else { System.out.println("ERR: Invalid input"); } } while(keepAsking); System.out.println("Quitting program..."); scan.close(); } }
You need to call displayMaze() (in displayPath()) to print it. Currently, you're not calling the method, meaning that your code will never print the maze as it's no being instructed to. Also, where are you assigning values to r and c? I think you meant to use i and j in your displayPath() method ([i][j] instead of [r][c]).
I imagine you're throwing an error somewhere because your r and c values are undefined everywhere they are used. Try adding code to initialize and update these values, then you should see your maze print.
Connect 4 right to left diagonal check
There's probably a very simple solution to this but I can't figure out where I'm doing something wrong. I'm making a small game with android studio that is connect 4. There is a 5x7 matrix of single cells, and 5 imageviews above that when clicked on put a fiche in the right place. Up to this point it's all working fine. When I however have to check if someone won, I thought I could break up the process in 4 main functions: one that check horizontally, one vertically, one diagonally left to right and one diagonally right to left. Now they all work perfectly except the right to left one. I'll post the code below: private void checkRightLeftDiagonally() { int winCondition = 0; boolean goingRight = true; int y = 1; int i = 4; int j = 0; while (y < 6 && won == false) { while (i > 0 && j < 7 && won == false) { if (cells[j][i].getFull() == true && players[playerTurn].getFicheColor() == cells[j][i].getFicheColor()) { winCondition++; winningCells.add(cells[j][i]); } else { winCondition = 0; winningCells.clear(); } if (winCondition == 4) { won = true; for (int x = 0; x < 4; x++) { winningCells.get(x).won(); } } i--; j++; } if(goingRight == true) { if(y<=4) { i=4-y; j=0; y++; } else { goingRight = false; y=0; i=0; j=0+y; } } if(goingRight == false) { i=0; j=0+y; y++; } if(won == false) { winCondition = 0; winningCells.clear(); } } if(won == false) { winCondition = 0; winningCells.clear(); } } And here is one of the arrow imageview code: imgArrows[0].setOnClickListener(new View.OnClickListener() { #Override public void onClick(View view) { if(cells[0][0].getFull() == false && won == false) { int i = 0; while(cells[i][0].getFull() == false) { i++; if(i>6) break; } i--; cells[i][0].ficheDown(players[playerTurn]); checkVertically(); checkHorizantally(); checkLeftRightDiagonally(); checkRightLeftDiagonally(); playerTurn++; if(playerTurn==2) { playerTurn = 0; } } } }); I've also made the cell class, which is here if it could help you public class Cell { private boolean full; private Player.FicheColor ficheColor; private ImageView fiche; public Cell(Player currentPlayer, ImageView img) { full = false; ficheColor = currentPlayer.getFicheColor(); fiche = img; img.setAlpha(0f); } public void ficheDown(Player currentPlayer) { full = true; ficheColor = currentPlayer.getFicheColor(); switch(ficheColor) { case red: fiche.setImageResource(R.drawable.redfiche); break; case blue: fiche.setImageResource(R.drawable.bluefiche); break; case green: fiche.setImageResource(R.drawable.greenfiche); break; case white: fiche.setImageResource(R.drawable.whitefiche); break; case black: fiche.setImageResource(R.drawable.whitefiche); break; } fiche.setAlpha(1f); } public Player.FicheColor getFicheColor() { return ficheColor; } public boolean getFull() { return full; } public void won(){ fiche.setColorFilter(Color.GREEN); } public void reset() { fiche.clearColorFilter(); } } Thank a lot, even just for reading
In the end the problem was that in the first paragraph of code the int i needed to be set to 4 and that solved it. Thanks to everyone that tried to help me
Looking for a better java OO approach to a lot of Boolean if else statements
I was given this project by a friend who is coding in school, but I am trying to find a better way to code it. It is calling different Boolean methods, checking if true and adding to a count for latter use. public static void testHand(PokerHand d) { if (d.isRoyalFlush()) { royalFlush++; } else if (d.isStraightFlush()) { straightFlush++; } else if (d.is4OfAKind()) { fourtOfAKind++; } else if (d.isFullHouse()) { fullHouse++; } else if (d.isFlush()) { flush++; } else if (d.isStraight()) { straight++; } else if (d.is3OfAKind()) { threeOfAKind++; } else if (d.is2Pair()) { twoPair++; } else if (d.isPair()) { pair++; } else if(d.isHighCard()){ highCard++; } } The code for PokerHand is as follows: public class PokerHand { private Card[] hand; // the hand of 5 cards // the default constructor public PokerHand() { hand = new Card[5]; } // A constructor to help with testing public PokerHand(Card c0, Card c1, Card c2, Card c3, Card c4) { hand = new Card[5]; hand[0] = c0; hand[1] = c1; hand[2] = c2; hand[3] = c3; hand[4] = c4; } /* This methods fills the hand with cards from the deck. It uses an insertion sort so that the cards are ordered by rank.*/ public void fillHand(Deck deck) { for (int i = 0; i < 5; i++) { int j = i - 1; Card temp = deck.dealCard(); while (j >= 0 && hand[j].getRank() > temp.getRank()) { hand[j + 1] = hand[j]; j--; } hand[j + 1] = temp; } } //PLACE ADDITIONAL METHODS AFTER THIS COMMENT /*Checking for Royal flush by first checking if straight flush and then if highest card is an Ace.*/ public boolean isRoyalFlush() { return (isStraightFlush() && hand[4].getRank() == 14); } //Check for Straight Flush by seeing if it is both a straight and a flush public boolean isStraightFlush() { return (isFlush() && isStraight()); } /*Checking if hand is a Four-of-a-kind. Done by looking at first card and checking if it equals next 3 cards. If not, then checking second card and checking if it equals next three cards.*/ public boolean is4OfAKind() { boolean isFour = false; for (int i = 0; i < hand.length - 3; i++) { int card = hand[i].getRank(); if (card == hand[i + 1].getRank() && card == hand[i + 2].getRank() && card == hand[i + 3].getRank()) { isFour = true; } } return isFour; } //Checking if hand holds a Full House By: public boolean isFullHouse() { //Setting two boolean values boolean a1, a2; //First checking if it is a pair followed by a 3-of-a-kind. a1 = hand[0].getRank() == hand[1].getRank() && hand[2].getRank() ==hand[3].getRank() && hand[3].getRank() == hand[4].getRank(); //Second, checking if it is 3-of-a-cind followed by a pair a2 = hand[0].getRank() == hand[1].getRank() && hand[1].getRank() == hand[2].getRank() && hand[3].getRank() == hand[4].getRank(); //Returns true if it is either. return (a1 || a2); } /*Checking if hand is a Flush by first getting the first card's suit and checking if it is the same for all cards.*/ public boolean isFlush() { String suit = hand[0].getSuit(); return hand[1].getSuit().equals(suit) && hand[2].getSuit().equals(suit) && hand[3].getSuit().equals(suit) && hand[4].getSuit().equals(suit); } /*Checking id hand is a Straight by first getting the rank of the first card, then checking if the following cards are incremented by 1*/ public boolean isStraight() { int card = hand[0].getRank(); return (hand[1].getRank() == (card + 1) && hand[2].getRank() == (card + 2) && hand[3].getRank() == (card + 3) && hand[4].getRank() == (card + 4)); } /*Checking if hand is a Three-of-a-kind. Done by looking at first card and checking if it equals next 2 cards. If not, then checking next card and checking if it equals next 2 cards. This is done three times in total.*/ public boolean is3OfAKind() { boolean threeKind = false; for (int i = 0; i < hand.length - 2; i++) { int card = hand[i].getRank(); if (card == hand[i + 1].getRank() && card == hand[i + 2].getRank()) { threeKind = true; } } return threeKind; } //Checking hand for 2 pairs by: public boolean is2Pair() { int count = 0; // Number of pairs. int firstPair = 0; //If pair found, store rank. //Go through hand for (int i = 0; i < hand.length - 1; i++) { int card = hand[i].getRank(); //Finding pairs. Cannot be same rank pairs. if (card == hand[i + 1].getRank() && card != firstPair) { firstPair = card; count++; } } return count == 2; } /*Checking if hand is a Pair. Done by looking at first card and checking if it equals the next card. If not, then it checks the next card and sees if it equals the next card. This is done four times in total.*/ public boolean isPair() { boolean isPair = false; for (int i = 0; i < hand.length - 1; i++) { int card = hand[i].getRank(); if (card == hand[i + 1].getRank()) { isPair = true; } } return isPair; } //If hand is not equal to anything above, it must be High Card. public boolean isHighCard() { return !(isRoyalFlush() || isStraightFlush() || is4OfAKind() || isFullHouse() || isFlush() || isStraight() || is3OfAKind() || is2Pair() || isPair()); } }
You could use the ternary operator ? : to shorten the code. Like public static void testHand(PokerHand d) { royalFlush += d.isRoyalFlush() ? 1 : 0; straightFlush += d.isStraightFlush() ? 1 : 0; fourtOfAKind += d.is4OfAKind() ? 1 : 0; // <-- this appears to be a typo. fullHouse += d.isFullHouse() ? 1 : 0; flush += d.isFlush() ? 1 : 0; straight += d.isStraight() ? 1 : 0; threeOfAKind += d.is3OfAKind() ? 1 : 0; twoPair += d.is2Pair() ? 1 : 0; pair += d.isPair() ? 1 : 0; highCard += d.isHighCard() ? 1 : 0; } Alternatively, you could encode the hand types with an enum. Give the PokerHand a HandType (or create a factory method). Something like, enum HandType { ROYALFLUSH, STRAIGHTFLUSH, FOUROFAKIND, FULLHOUSE, FLUSH, STRAIGHT, THREEOFAKIND, TWOPAIR, PAIR, HIGHCARD; static HandType fromHand(PokerHand d) { if (d.isRoyalFlush()) { return ROYALFLUSH; } else if (d.isStraightFlush()) { return STRAIGHTFLUSH; } else if (d.is4OfAKind()) { return FOUROFAKIND; } else if (d.isFullHouse()) { return FULLHOUSE; } else if (d.isFlush()) { return FLUSH; } else if (d.isStraight()) { return STRAIGHT; } else if (d.is3OfAKind()) { return THREEOFAKIND; } else if (d.is2Pair()) { return TWOPAIR; } else if (d.isPair()) { return PAIR; } else { return HIGHCARD; } } } Then you can create an array of counts for testHand like private static int[] handCounts = new int[HandType.values().length]; public static void testHand(PokerHand d) { handCounts[HandType.fromHand(d)]++; }
I would suggest you model the potential hands as an enum. They are a good use case because they have a fixed set of members. Something like the following: enum Rank { ROYAL_FLUSH(Hand::isRoyalFlush), FOUR_OF_A_KIND(Hand::isFourOfAKind), ... public static Rank getRank(Hand hand) { for (Rank rank: values()) { if (rank.test.test(hand)) return rank; } throw new IllegalStateException("No rank for hand " + hand.toString()); } private final Predicate<Hand> test; Rank(Predicate<Hand> test) { this.test = test; } } Then all your if statements can be replaced by Rank.getRank(hand).
Maybe the switch statement will suit your needs : switch (d) { case d.isRoyalFlush() : royalFlush++; break; case d.isStraightFlush(): straightFlush++; break; ... ... ... default : do-something(); }
Logical issue with while statement in java method
Background Information : I'm developing a battleship game and in the game I have a 10x10 int[][] (the grid). I've developed a method which trys to hit a cell on that array or grid as long as the same spot hasn't already been tried. (This is for the computer ofcourse playing against me). public boolean randomShot() { int row; int col; boolean wasHit = false; boolean complete = false; while (complete == false) { // Randomly generate a row and column row = randomizer.nextInt(ROW_COUNT); col = randomizer.nextInt(COLUMN_COUNT); if(compShots.contains("" + row + col) == false) { complete = true; if(checkHit(row, col) == true) { wasHit = true; } compShots.add("" + row + col); } } return wasHit; } The above method works fine and i'm happy with it. The problem : I wanted to develop a method that is based off the above method however the computer acts a little smarter in the sense that lets say if he hit row 3 and column 3. Then it would next try to hit row 3 and column 4 etc. however if the next column or row is over the boundary of the board then it would try do it the other way. The while loop is crashing the game at the moment, any idea why? This is the method I have to hit the array with a little more brain so to say public boolean randomShotClever() { int row; int col; boolean wasHit = false; boolean complete = false; while (complete == false) { // Randomly generate a row and column row = randomizer.nextInt(ROW_COUNT); col = randomizer.nextInt(COLUMN_COUNT); if(previousRows.size() == 0 || compShots.contains("" + (previousRows.size() -1) + (previousCols.size() -1) )) { finalRow = previousRows.get(previousRows.size()); if((finalRow + 1) < (ROW_COUNT -1)) { finalRow = finalRow + 1; } else { finalRow = row; } finalCol = previousCols.get(previousCols.size()); if((finalCol + 1) < (COLUMN_COUNT -1 )) { finalCol = finalCol + 1; } else { finalCol = col; } if(compShots.contains("" + finalRow + finalCol) == false) { complete = true; if(checkHit(finalRow, finalCol) == true) { previousCols.add(finalCol); previousRows.add(finalRow); wasHit = true; } compShots.add("" + finalRow + finalCol); } } } return wasHit; } Thanks in advance for any help offered.
Comparison is backwards on if((finalRow + 1) > (ROW_COUNT -1)) { finalRow = finalRow + 1; And again in if((finalCol + 1) > (COLUMN_COUNT -1)) "If I am too big, make me bigger". There may be others like it.
Why do I get "Cannot be Resolved" errors in this code?
I'm trying to check if a move is legal for the game Othello. I'm using a for each loop and once (only once) when I use the variable that it's checking for, it gives me a 'cannot be resolved error'. I have bolded where this occurs. Can anyone help? (Yes I know that the code isn't finished yet, I'm trying to get rid of this error first.) public boolean isLegal(Location loc1) { String currentColor = currentPlayer.getColor(); boolean isLegal = false; int row = loc1.getRow(); int col = loc1.getCol(); if(board.isValid(loc1)) { if(board.get(loc1) == null) { for(Location tempLoc : board.getValidAdjacentLocations(loc1)) { if(!board.get(tempLoc).equals(currentColor)) { int tempRow = tempLoc.getRow(); if((row != tempLoc.getRow()) && (col == tempLoc.getCol())) { //count up column if(**tempLoc.getRow()** < row) { for(int i = row; i > 1;) { Location tempLoc2 = new Location(i-2, col); if(!board.get(tempLoc2).equals(currentColor)) { i--; } else { i=-1; isLegal = true; } } } //count down column else { for(int i = row; i < 6;) { Location tempLoc2 = new Location(i+2, lcol); if(!board.get(tempLoc2).equals(currentColor)) { i++; } else i=9; isLegal = true; } } } else if(col != tempLoc.getCol() && row == tempLoc.getRow()) { //count left/right row if(col > tempLoc.getCol()) { } else } else { //count up/right & down/left diag if(1!=0) { } //count up/left & down/right diag else } } } } } return isLegal; }
The "else" statements without a body at the bottom of your code are confusing the compiler about what counts as inside the loops. If you fix that error, the other one will go away.