Switch case for two INT variables - java

Consider the following code :
if (xPoint > 0 && yPoint > 0) {
m_navigations = Directions.SouthEast;
}
else if (xPoint > 0 && yPoint < 0) {
m_navigations = Directions.NorthEast;
}
else if (xPoint < 0 && yPoint > 0) {
m_navigations = Directions.SouthWest;
}
else if (xPoint < 0 && yPoint < 0) {
m_navigations = Directions.NorthWest;
}
else if (xPoint == 0 && yPoint < 0) {
m_navigations = Directions.North;
}
else if (xPoint == 0 && yPoint > 0) {
m_navigations = Directions.South;
}
else if (xPoint > 0 && yPoint == 0) {
m_navigations = Directions.East;
}
else if (xPoint < 0 && yPoint == 0) {
m_navigations = Directions.West;
}
This is quite ugly , and I want to use switch case , but how can I use switch with 2 variables ?
I thought about something like this - the answer of #Frits van Campen , but I need to use > and < operators ...
Thanks

You can do everything with enums. I created examples for the first two values, you can continue with the rest.
public enum Direction
{
SouthEast(1,1),
NorthEast(1,-1);
int _xPoint, _yPoint;
Direction(int xPoint, int yPoint)
{
_xPoint = xPoint;
_yPoint = yPoint;
}
public static Direction getDirectionByPoints(int xPoint, int yPoint)
{
for (Direction direction : Direction.values())
{
if( Integer.signum(xPoint) == direction._xPoint
&& Integer.signum(yPoint) == direction._yPoint )
{
return direction;
}
}
throw new IllegalStateException("No suitable Direction found");
}
}
So you can just call:
m_navigations = Direction.getDirectionByPoints(xPoint,yPoint);

Use signum to get -1, 0 or 1 on the direction like this:
String direction = Integer.signum(xPoint)+","+Integer.signum(yPoint);
switch(direction){
case "1,1":
m_navigations = Directions.SouthEast;
break;
case "-1,0"
m_navigations = Directions.West;
break;
etc..
}

The simplest and easiest solution is to use multidimensional arrays.
public class CalculateDirections {
private final static Directions DIRECTION_MAP[][] = {
{Directions.NorthWest, Directions.North, Directions.NorthEast},
{Directions.West, null, Directions.East},
{Directions.SouthWest, Directions.South, Directions.SouthEast},
};
public static void main(String[] args) {
int x = Integer.valueOf(args[0]);
int y = Integer.valueOf(args[1]);
int signumX = Integer.signum(x);
int signumY = Integer.signum(y);
Directions direction = DIRECTION_MAP[signumY + 1][signumX + 1];
System.out.println(direction);
}
}
enum Directions {
SouthEast, NorthEast, SouthWest, NorthWest, North, South, East, West
}
There are several advantages:
No if/else cascades which take some runtime and are hard to manage.
No creation of temporary Strings. In a tight game loop this may be important.
No linear search through lists or arrays.

Similar to other answers but without strings. Just for fun :-)
public Directions getDirection(int xPoint, int yPoint) {
int num = 8 * (xPoint == 0 ? 0 : xPoint > 0 ? 1 : 2);
num += yPoint == 0 ? 0 : yPoint > 0 ? 1 : 2;
switch (num) {
case 01:
return Directions.South;
case 02:
return Directions.North;
case 010:
return Directions.East;
case 011:
return Directions.SouthEast;
case 012:
return Directions.NorthEast;
case 020:
return Directions.West;
case 021:
return Directions.SouthWest;
case 022:
return Directions.NorthWest;
}
return Directions.None;
}

boolean xNeg = xPoint < 0;
boolean yNeg = yPoint < 0;
boolean xZero = xPoint == 0;
boolean yZero = yPoint == 0;
We have four bits, we have 2^4 possibilities, an array of Directions may do the rest...
int index =
((xNeg ?1:0)<<3)|
((yNeg ?1:0)<<2)|
((xZero?1:0)<<1)|
((yZero?1:0)<<0);
Directions dir = directions[index];
with directions a static final array of Directions initialized at class loading time.
static final Directions[] directions = {
Direction.NorthEast, // false, false, false, false ==> x > 0 && y > 0
Direction.East, // false, false, false, true ==> x > 0 && y == 0
Direction.North, // false, false, true , false ==> x == 0 && y > 0
...
}
Indexing an array with an integer computed from ternaries, shift and or operators is less CPU consuming than a string concatenation used in a string switch and works well from Java 1.0.

At the moment :
String direction = Integer.signum(xPoint) + "|" + Integer.signum(yPoint);
switch(direction)
{
case "1|1":
{m_navigations = Directions.SouthEast; break;}
case "1|-1":
{m_navigations = Directions.NorthEast; break;}
case "-1|1":
{m_navigations = Directions.SouthWest; break;}
case "-1|-1":
{m_navigations = Directions.NorthWest; break;}
case "0|-1":
{m_navigations = Directions.North; break;}
case "0|1":
{m_navigations = Directions.South; break;}
case "1|0":
{m_navigations = Directions.East; break;}
case "-1|0":
{m_navigations = Directions.West; break;}
default: break;
}
Now I'll try what #danieln has suggested .

Related

How to navigate a spider in a grid system?

I have a problem where it needs to navigate a spider in a grid system (X, Y co-ordinate) with proper instruction. Initially, the spider is in (0,0) and face towards the positive Y axis.
There are 3 possible instructions for the navigation: 'F' for forward (1 grid in the same direction ), 'R' for right turn (90 degree) and 'L' for left turn (90 degree) and initially, the spider faces towards positive Y axis.
Say, if I pass the direction String of "LFF", the position should be (-2,0). I solve the problem and the current state of code is as following,
public static void spiderNavigator(String str ){
if( str == null || str.length() == 0)
return;
int [] initial = {0,0};
boolean xPos = false, xNeg = false, yPos = true, yNeg = false;
char[] ch = str.toCharArray();
for( char c: ch){
// the initial position of the spider is towards the positive Y axis
if(c == 'L'){
if(xPos){
xPos = false;
yPos = true;
}
else if ( xNeg){
xNeg = false;
yNeg = true;
}
else if(yPos){
xNeg = true;
yPos = false;
}
else if (yNeg){
yNeg = false;
xPos = true;
}
}
else if ( c == 'R'){
if(xPos){
xPos = false;
yNeg = true;
}
else if ( xNeg){
yPos = true;
xNeg = false;
}
else if(yPos){
yPos = false;
xPos = true;
}
else if (yNeg){
yNeg = false;
xNeg = true;
}
}
else if (c == 'F'){
if(xNeg){
initial[0] -= 1;
}
else if (xPos){
initial[0] += 1;
}
else if (yNeg){
initial[1] -=1;
}
else if( yPos){
initial[1] += 1;
}
}
}
System.out.println(Arrays.toString(initial));
}
However, the code feels quite ugly even to me. How can I design the algorithm in better way ?
Here's a shorter and more elegant solution:
public static void spiderNavigator(String str) {
if (str == null || str.length() == 0)
return;
int[] initial = {0, 0};
int angle = 90;
char[] ch = str.toCharArray();
for (char c : ch) {
if (c == 'L') {
angle = (angle + 90) % 360;
} else if (c == 'R') {
angle = (angle - 90) % 360;
} else if (c == 'F') {
initial[0] += (int) Math.cos(Math.toRadians(angle));
initial[1] += (int) Math.sin(Math.toRadians(angle));
}
}
System.out.println(Arrays.toString(initial));
}
Angle represents the direction spider is facing, and using trigonometric functions you can easily calculate where it should move based on current position and an angle it is facing.
Here is how I would approach it.
Have a direction variable spider_dir (where your spider is going to go now). It will store 4 different kind of values (like U, R, D, L).
Have a function change_direction which takes a current direction a and value L or R and returns a new direction. Notice that if L is passed you need to take previous circular value in array of values (['U', 'R', 'D', 'L']) of your previous value. If R than the next circular value.
Have a hash that maps your direction to your steps (assume +x, +y). U will be (0, 1), L will be (-1, 0).
Now that you have this simply iterate through your string and if you see F move add value to your current position depending on your spider_dir. If you see anything else - change your spider_dir depending on where to rotate and spider_dir
Here is a version built on a similar concept to the very nice answer by #MateuszDryzek, but without using trigonometric functions.
public static void spiderNavigator(String str) {
if (str == null || str.isEmpty())
return;
int x = 0, y = 0, dir = 0;
for (char c : str.toCharArray())
if (c == 'R')
dir = (dir + 1) % 4; // dir++: 0 -> 1 -> 2 -> 3 -> 0
else if (c == 'L')
dir = (dir + 3) % 4; // dir--: 3 -> 2 -> 1 -> 0 -> 3
else if (c == 'F')
if (dir == 0)
y++; // 0: Up
else if (dir == 1)
x++; // 1: Right
else if (dir == 2)
y--; // 2: Down
else
x--; // 3: Left
System.out.printf("(%d,%d)%n", x, y);
}

how to assign a char to an variable on the base of the size of an ArrayList in Java?

I try to make an long if-statement more compact; this is how it is originaly:
char x;
if(list.size()== 1){
x = 'a';
}
if(list.size()== 2){
x = 'b';
}
if(list.size() == 3){
x = 'c';
}
if(list.size() == 4){
x= 'd';
}
Is there a possibility to compact this code?
thanks already,
Jari Van M
As a first step, we refactor the code to an if-else cascade and backup the list size we are going to use often:
1:
int size = list.size();
char x;
if(size == 1) {
x = 'a';
} else if(size == 2) {
x = 'b';
} else if(size == 3) {
x = 'c';
} else if(size == 4) {
x = 'd';
} else {
//undefined
x = '\0';
}
As we compare the list size with constants only in this case, we can further transform this into a switch statement:
2:
char x;
switch (list.size()) {
case 1: x = 'a'; break;
case 2: x = 'b'; break;
case 3: x = 'c'; break;
case 4: x = 'd'; break;
//undefined
default: x = '\0'; break;
}
Assuming this isn't a randomly chosen example but real code, we see that we need a function which takes a number starting from 1 which outputs the alphabet ('a' to 'z') with increasing value:
3:
char x;
if(list.isEmpty()) {
//undefined
x = '\0';
} else {
//our function
x = (char) ('a' + list.size() - 1);
if(x > 'z') {
//undefined
x = '\0';
}
}
You are basically mapping the size to a character. It can be done easier:
x = 'a' + list.size() - 1;
Easier Option:
Use switch case.
Tricker Option:
char x = (char) ('a' + list.size() - 1);
char x;
int size = list.size();
if (size >= 1 && size <= 4) {
x = "zabcd".charAt(size);
}

How do I use the isValid method inside the move method to determine whether a move is legal?

(Java) - I have written out a lengthy, if incomplete, isValid method to determine whether moves in a game of chess are legal, but I have no idea how to embed the code into the move method so that if moves are entered that are illegal, the program prints a message to say the moves aren't valid and requests input again.
import java.util.Scanner;
public class Virtual_Chessboard {
public enum Chessmen {
WHITE_KING, WHITE_QUEEN, WHITE_ROOK, WHITE_BISHOP, WHITE_KNIGHT, WHITE_PAWN, BLACK_KING, BLACK_QUEEN, BLACK_ROOK, BLACK_BISHOP, BLACK_KNIGHT, BLACK_PAWN, EMPTY
}
public static Chessmen[][] chessboard = new Chessmen[8][8];
public static void createBoard() {
int rows = 8;
int columns = 8;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if ((i == 0 && j == 0) || (i == 0 && j == 7)) {
chessboard[i][j] = Chessmen.BLACK_ROOK;
} else if ((i == 0 && j == 1) || (i == 0 && j == 6)) {
chessboard[i][j] = Chessmen.BLACK_KNIGHT;
} else if ((i == 0 && j == 2) || (i == 0 && j == 5)) {
chessboard[i][j] = Chessmen.BLACK_BISHOP;
} else if (i == 0 && j == 3) {
chessboard[i][j] = Chessmen.BLACK_KING;
} else if (i == 0 && j == 4) {
chessboard[i][j] = Chessmen.BLACK_QUEEN;
} else if ((i == 7 && j == 0) || (i == 7 && j == 7)) {
chessboard[i][j] = Chessmen.WHITE_ROOK;
} else if ((i == 7 && j == 1) || (i == 7 && j == 6)) {
chessboard[i][j] = Chessmen.WHITE_KNIGHT;
} else if ((i == 7 && j == 2) || (i == 7 && j == 5)) {
chessboard[i][j] = Chessmen.WHITE_BISHOP;
} else if (i == 7 && j == 3) {
chessboard[i][j] = Chessmen.WHITE_KING;
} else if (i == 7 && j == 4) {
chessboard[i][j] = Chessmen.WHITE_QUEEN;
} else if (i == 1) {
chessboard[i][j] = Chessmen.BLACK_PAWN;
} else if (i == 6) {
chessboard[i][j] = Chessmen.WHITE_PAWN;
} else {
chessboard[i][j] = Chessmen.EMPTY;
}
}
}
}
public static void printBoard(Chessmen[][] chessboard) {
int k = 8;
System.out.print(" " + "\t" + "a" + "\t" + "b" + "\t" + "c" + "\t"
+ "d" + "\t" + "e" + "\t" + "f" + "\t" + "g" + "\t" + "h");
for (int i = 0; i < 8; i++) {
System.out.print("\n" + k);
k--;
for (int j = 0; j < 8; j++) {
System.out.print("\t");
switch (chessboard[i][j]) {
case WHITE_KING:
System.out.print("\u2654");
break;
case WHITE_QUEEN:
System.out.print("\u2655");
break;
case WHITE_ROOK:
System.out.print("\u2656");
break;
case WHITE_BISHOP:
System.out.print("\u2657");
break;
case WHITE_KNIGHT:
System.out.print("\u2658");
break;
case WHITE_PAWN:
System.out.print("\u2659");
break;
case BLACK_KING:
System.out.print("\u265A");
break;
case BLACK_QUEEN:
System.out.print("\u265B");
break;
case BLACK_ROOK:
System.out.print("\u265C");
break;
case BLACK_BISHOP:
System.out.print("\u265D");
break;
case BLACK_KNIGHT:
System.out.print("\u265E");
break;
case BLACK_PAWN:
System.out.print("\u265F");
break;
case EMPTY:
System.out.print("");
break;
} // switch
} // / j for
} // i for
}
public static void move(Chessmen[][] chessboard, String move) {
char newj = move.charAt(6);
int newi = Integer.parseInt(move.substring(7, 8));
newi = -newi + 8;
char oldj = move.charAt(0);
int oldi = Integer.parseInt(move.substring(1, 2));
oldi = -oldi + 8;
switch (newj) {
case 'a':
newj = (int) 0;
break;
case 'b':
newj = (int) 1;
break;
case 'c':
newj = (int) 2;
break;
case 'd':
newj = (int) 3;
break;
case 'e':
newj = (int) 4;
break;
case 'f':
newj = (int) 5;
break;
case 'g':
newj = (int) 6;
break;
case 'h':
newj = (int) 7;
break;
}
switch (oldj) {
case 'a':
oldj = (int) 0;
break;
case 'b':
oldj = (int) 1;
break;
case 'c':
oldj = (int) 2;
break;
case 'd':
oldj = (int) 3;
break;
case 'e':
oldj = (int) 4;
break;
case 'f':
oldj = (int) 5;
break;
case 'g':
oldj = (int) 6;
break;
case 'h':
oldj = (int) 7;
break;
}
chessboard[newi][newj] = chessboard[oldi][oldj]; // Move
// piece
// to
// new
// position
chessboard[oldi][oldj] = Chessmen.EMPTY;
}
public static boolean isValid(Chessmen[][] chessboard, int oldi,int oldj, int newi, int newj) {
switch (chessboard[oldi][oldj]) {
case WHITE_ROOK:
if (oldi == newi || oldj == newj) {
return true;
}
case BLACK_ROOK :
if(oldi == newi || oldj == newj){
return true;
}
case WHITE_KNIGHT :
if((newi==oldi-1 && newj==oldj+1)|| (newi==oldi-2 && newj==oldj-1)||(newi==oldi-2 && newj==oldj+1)
||(newi==oldi-1 && newj==oldj+2)||(newi==oldi+1 && newj==oldj+2)||(newi==oldi+2 && newj==oldj+1)||
(newi==oldi+2 && newj==oldj-1)||(newi==oldi+1 && newj==oldj-2)){
return true;
}
case BLACK_KNIGHT :
if((newi==oldi-1 && newj==oldj+1)|| (newi==oldi-2 && newj==oldj-1)||(newi==oldi-2 && newj==oldj+1)
||(newi==oldi-1 && newj==oldj+2)||(newi==oldi+1 && newj==oldj+2)||(newi==oldi+2 && newj==oldj+1)||
(newi==oldi+2 && newj==oldj-1)||(newi==oldi+1 && newj==oldj-2)){
return true;
}
case WHITE_BISHOP :
for(int x =0;x<8;x++){
if(newi==oldi+x && newj==oldj+x || newi==oldi-x && newj==oldj-x || newi==oldi+x && newj==oldj-x || newi==oldi-x && newj==oldj+x){
return true;
}
}
case BLACK_BISHOP :
for(int x =0;x<8;x++){
if(newi==oldi+x && newj==oldj+x || newi==oldi-x && newj==oldj-x || newi==oldi+x && newj==oldj-x || newi==oldi-x && newj==oldj+x){
return true;
}
}
case WHITE_KING :
if((newi==oldi+1 && newj==oldj) ||
(newi==oldi+1 && newj==oldj+1) ||
(newi==oldi && newj==oldj+1) ||
(newi==oldi-1 && newj==oldj) ||
(newi==oldi-1 && newj==oldj-1) ||
(newi==oldi && newj==oldj-1) ||
(newi==oldi-1 && newj==newj+1) ||
(newi==oldi-1 && newj==newj+1) ){
return true;
}
case BLACK_KING :
if((newi==oldi+1 && newj==oldj) ||
(newi==oldi+1 && newj==oldj+1) ||
(newi==oldi && newj==oldj+1) ||
(newi==oldi-1 && newj==oldj) ||
(newi==oldi-1 && newj==oldj-1) ||
(newi==oldi && newj==oldj-1) ||
(newi==oldi-1 && newj==newj+1) ||
(newi==oldi-1 && newj==newj+1) ){
return true;
}
case WHITE_PAWN :
if(oldi==6 && newi<=4){
return true;
}
else if(newi==oldi-1){
return true;
}
case BLACK_PAWN :
if(oldi==1 && newi<=3){
return true;
}
else if(oldi==newi-1){
return true;
}
default: return false;
}
}
public static void main(String[] args) {
createBoard();
Scanner in = new Scanner(System.in);
String command;
while (!in.equals("exit")) {
printBoard(chessboard);
System.out.println("Please enter a move.");
command = in.nextLine();
move(chessboard, command);
}
}
}
Move might look something like:
if (isValid(...)) {
chessboard[newi][newj] = chessboard[oldi][oldj];
chessboard[oldi][oldj] = Chessmen.EMPTY;
} else {
throw new IllegalMoveException();
}
and then in your main function:
while (!in.equals("exit")) {
printBoard(chessboard);
System.out.println("Please enter a move.");
command = in.nextLine();
try {
move(chessboard, command);
} catch (IllegalMoveException e) {
System.out.println("Illegal Move!");
continue;
}
}
If rewriting your entire code isn't an issue, I would recommend use a more object-oriented approach for this.
Ej. create a Board class with an array or 8x8 Square class instances, each of which, can contain an instance of a Piece class instance. Then, since the movements are made in the Board, you can implement a boardInstance.movePiece(Piece pieceToMove, Square destinationSquare) in which every Piece class should contain its movement rules so the Board instance knows if the Piece is movable to the destination Square instance.

How do we simplify this kind of code in Java? Something like macros in C?

public static boolean diagonals(char[][] b, int row, int col, int l) {
int counter = 1; // because we start from the current position
char charAtPosition = b[row][col];
int numRows = b.length;
int numCols = b[0].length;
int topleft = 0;
int topright = 0;
int bottomleft = 0;
int bottomright = 0;
for (int i=row-1,j=col-1;i>=0 && j>=0;i--,j--) {
if (b[i][j]==charAtPosition) {
topleft++;
} else {
break;
}
}
for (int i=row-1,j=col+1;i>=0 && j<=numCols;i--,j++) {
if (b[i][j]==charAtPosition) {
topright++;
} else {
break;
}
}
for (int i=row+1,j=col-1;i<=numRows && j>=0;i++,j--) {
if (b[i][j]==charAtPosition) {
bottomleft++;
} else {
break;
}
}
for (int i=row+1,j=col+1;i<=numRows && j<=numCols;i++,j++) {
if (b[i][j]==charAtPosition) {
bottomright++;
} else {
break;
}
}
return topleft + bottomright + 1 >= l || topright + bottomleft + 1 >= l; //in this case l is 5
}
After I was done posting the code above here, I couldn't help but wanted to simplify the code by merging the four pretty much the same loops into one method.
Here's the kind of method I want to have:
public int countSteps(char horizontal, char vertical) {
}
Two parameters horizontal and vertical can be either + or - to indicate the four directions to walk in. What I want to see if possible at all is i++; is generalized to i horizontal horizontal; when horizontal taking the value of +.
What I don't want to see is if or switch statements, for example:
public int countSteps(char horizontal, char vertical) {
if (horizontal == '+' && vertical == '-') {
for (int i=row-1,j=col+1;i>=0 && j<=numCols;i--,j++) {
if (b[i][j]==charAtPosition) {
topright++;
} else {
break;
}
}
} else if (horizontal == '+' && vertical == '+') {
for (int i=row+1,j=col+1;i>=0 && j<=numCols;i++,j++) {
if (b[i][j]==charAtPosition) {
topright++;
} else {
break;
}
}
} else if () {
} else {
}
}
Since it is as tedious as the original one. Note also that the comparing signs for the loop condition i>=0 && j<=numCols; for example, >= && <= have correspondence with the value combination of horizontal and vertical.
Sorry for my bad wording, please let me know if anything is not clear.
You can easily convert the loops to something like:
int doit(int i_incr, int j_incr) {
int cornerIncrement = 0;
for (int i=row+i_incr, j=col+j_incr; i>=0 && j>=0; i+=i_incr, j+=j_incr) {
if (b[i][j]==charAtPosition) {
cornerIncrement++;
} else {
break;
}
}
return cornerIncrement;
}
And then repeat 4 times...
int increment = doit(+1, -1); // Or (-1, +1) etc
topLeft += increment; // Or bottomLeft/topRight/bottomRight
So you have these two loops:
for (int i=row-1,j=col-1;i>=0 && j>=0;i--,j--) {
if (b[i][j]==charAtPosition) {
topleft++;
} else {
break;
}
}
for (int i=row-1,j=col+1;i>=0 && j<=numCols;i--,j++) {
if (b[i][j]==charAtPosition) {
topright++;
} else {
break;
}
}
First, turn your counters into an array, i.e. topleft -> counter[0] and topright -> counter[1]
Then, turn the difference between the code into variables, so you have:
for(direction = 0; direction < 2; direction++) {
int offset = direction * 2 - 1; // This is what I mean by doing some math
for(int i=row-1,j=col+offset;i>=0 && -j*offset>=-numCols*direction;i--,j+=offset) {
if (b[i][j]==charAtPosition) {
counter[direction]++;
// etc.
The math can get ugly sometimes, or you can do it in a separate line. Look at my other post on this question for an elegant way to do the math in this particular problem using ? : syntax.

Maze recursion - going wrong for few inputs (likely error in the logic)

I am a beginner in java.
I have been working on an maze problem trying it solve it by recursion.
I have written the code which seems to work on few inputs and not others.
The input is a maze consisting of 0's and 1's. # is the start and # is the exit.0 is wall and 1's are open.The output will be the hops from # to #.
Though i am solving the problem by recursion,I must be going wrong with the logic.
Please let me know where I am wrong.
Class practisenumwords
import java.util.Scanner;
class practisenumwords {
public static void main(String[] args){
Scanner in=new Scanner(System.in);
int r=in.nextInt();
int c=in.nextInt();
maze maz=new maze(r,c); /*input in string copied to array*/
char[] ch;
ch = "00000000111111101111011001101##11100".toCharArray();
int l=0;
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++) /*initialising the maze elements*/
{
maz.m[i][j]=new cells();
maz.m[i][j].c=ch[l];
maz.m[i][j].row=i;
maz.m[i][j].col=j;
l++;
}
}
for(int i=0;i<r;i++) /*print the input maze */
{
for(int j=0;j<c;j++)
{
System.out.print(""+maz.m[i][j].c);
}
System.out.println();
}
maz.escape();
maz.find(maz.startx,maz.starty,maz.hops);
}
}
Class cells
class cells {
char c;
int row;
int col;
boolean done=false; /*initially all cells are unvisited*/
}
Class maze
class maze{
maze (int a,int b){
rows=a;
cols=b;
m=new cells[rows][cols];
}
int rows;
int cols;
cells[][] m;
int startx,starty;
int hops=0;
void escape()
{
for(int i=0;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
if(m[i][j].c=='#')
{
startx=i;
starty=j;
System.out.println(startx+" "+starty);
}
}
}
}
void find(int x,int y,int h)
{
if ((x+1<rows && m[x+1][y].c=='#' && m[x+1][y].done!=true)
||(x-1>=0 && m[x-1][y].c=='#' && m[x-1][y].done!=true)
||(y+1<cols && m[x][y+1].c=='#' && m[x][y+1].done!=true)
||(y-1>=0 && m[x][y-1].c=='#' && m[x][y-1].done!=true)){
h++;
System.out.println(h);
}
else
{
if(x-1>=0 && m[x-1][y].c=='1' && m[x-1][y].done!=true){ /*north cell*/
m[x][y].done=true;
h++;
find(x-1,y,h);
}
if(x+1<rows && m[x+1][y].c=='1' && m[x+1][y].done!=true){ /*south cell*/
m[x][y].done=true;
h++;
find(x+1,y,h);
}
if(y+1<cols && m[x][y+1].c=='1' && m[x][y+1].done!=true){ /*east cell*/
m[x][y].done=true;
h++;
find(x,y+1,h);
}
if(y-1>=0 && m[x][y-1].c=='1' && m[x][y-1].done!=true){ /*west cell*/
m[x][y].done=true;
h++;
find(x,y-1,h);
}
}
}
}
Now,i get the right output for the inputs as the 1 in program.
000000
001111
111011
110110
01101#
#11100
output- 12 (obtaining right output)
00#000
001111
111011
110110
011011
#11100
output- 7 (obtaining right output)
BUT NOT FOR OTHER INPUTS like
0 0 0 0 # 0
0 1 0 1 1 0
1 1 1 1 0 1
0 1 0 1 0 0
0 0 # 1 1 1
0 1 1 0 0 1
correct output - 6 output obtained -7
Also the output changes with the order in which the adjacent cells are checked.
Honestly, I'd implement your recursive function a little differently:
And there's no need to check whether a bool value is != true, !boolValue is fine.
int find(int x,int y,int h)
{
int result = -1;
if ((x+1<rows && m[x+1][y].c=='#' && !m[x+1][y].done)
||(x-1>=0 && m[x-1][y].c=='#' && !m[x-1][y].done)
||(y+1<cols && m[x][y+1].c=='#' && !m[x][y+1].done)
||(y-1>=0 && m[x][y-1].c=='#' && !m[x][y-1].done)){
return h + 1;
}
else
{
if(x-1>=0 && m[x-1][y].c=='1' && !m[x-1][y].done){ /*north cell*/
m[x][y].done=true;
result = find(x-1,y,h + 1)
if (result > -1) {
return result;
}
m[x][y].done=false;
}
Implement the other three directions the same way, then result should still be -1 if no solution was found.
return result;
}
In a fast reading I notice:
if(...) {
...
h++;
find(x-1,y,h);
}
For each if-block.
Inside second if-block h == h+2 when first if-condition is satisfied and the same goes for third and fourth if-block
Maybe you should write:
if(...) {
...
// h++;
find(x-1,y,h+1);
}
int find(int x, int y, int h) {
if ((x + 1 < rows && m[x + 1][y].c == '#' && m[x + 1][y].done != true)
|| (x - 1 >= 0 && m[x - 1][y].c == '#' && m[x - 1][y].done != true)
|| (y + 1 < cols && m[x][y + 1].c == '#' && m[x][y + 1].done != true)
|| (y - 1 >= 0 && m[x][y - 1].c == '#' && m[x][y - 1].done != true)) {
h++;
finish = true;
return h;
} else {
if (x - 1 >= 0 && m[x - 1][y].c == '1' && m[x - 1][y].done != true
&& !finish) { /* north cell */
m[x][y].done = true;
int temp = find(x - 1, y, h);
if (temp != 0)
h = temp + 1;
return h;
}
if (x + 1 < rows && m[x + 1][y].c == '1'
&& m[x + 1][y].done != true && !finish) { /* south cell */
m[x][y].done = true;
int temp = find(x + 1, y, h);
if (temp != 0)
h = temp + 1;
return h;
}
if (y + 1 < cols && m[x][y + 1].c == '1'
&& m[x][y + 1].done != true && !finish) { /* east cell */
m[x][y].done = true;
int temp = find(x, y + 1, h);
if (temp != 0)
h = temp + 1;
return h;
}
if (y - 1 >= 0 && m[x][y - 1].c == '1' && m[x][y - 1].done != true
&& !finish) { /* west cell */
m[x][y].done = true;
int temp = find(x, y - 1, h);
if (temp != 0) {
h = temp + 1;
}
return h;
}
return 0;
}
}
Also include a boolean finish = false; in your maze class.
and also change the return of the main function
maz.hops = maz.find(maz.startx, maz.starty, maz.hops);
System.out.println(maz.hops);

Categories