if-else statements and 2d arrays - java

I am writing a method that checks to see if certain moves of a checkers game are valid by returning true or false. My code works fine when I want to move diagonally (not jumping). However, when I try to see if my piece can jump across another piece, nothing gets returned (no false, no true, no error message, just blank). I have a setLocation method that takes three parameters of the checkers board column, row, and piece color which places a checkers piece at the said location on the board.
How can I get my code to return true or false if I have pieces on the board set and I want to see if a piece can jump over an opposing color piece? curRow and curCol are just the current row and column that the piece is at. destRow and destCol are the destination that I want my piece to go to.
Here's my code:
if (board[curCol][curRow].equals(Piece.WHITE)){
boolean valid=false;
if ((curRow+1==destRow&&curCol+1==destCol)&&board[destRow][destCol].equals(Piece.NONE)){
valid=true;
}else if ((curRow+1==destRow&&curCol-1==destCol)&&board[destRow][destCol].equals(Piece.NONE)){
valid=true;
//jumps up right over piece
}else if ((curRow+2==destRow&&curCol+2==destCol)&&board[destRow-1][destCol-1].equals(Piece.BLACK)){
valid=true;
//jumps up left over piece
else if ((curRow+2==destRow&&curCol-2==destCol)&&(board[destRow-1][destCol+1].equals(Piece.BLACK))){
valid=true;
}else{
return valid;
}
return valid;
}

First of all, Java can't return "blanks". If your method (which you don't show the declaration of) is a boolean method, it MUST return a boolean.
Why not try something like this:
private static board Peice[][] = new Peice[][]
private enum Peice{
BLACK(-1, false),
BLACK_CROWN(-1, true),
WHITE(1, false),
WHITE_CROWN(1, true)
private int direction;
private boolean crowned;
public Peice(int direction, boolean crowned){
this.direction = direction;
this.crowned = crowned;
}
public boolean isLegal(int curRow, int curCol, int destRow, int destCol){
//not valid if the spot is occupied or if the move isn't the same distance each way
if (board[destRow, destCol] != null) || ((Math.abs(destRow - CurRow) != (Math.abs(destCol - curCol)){
return false;
}
if (abs(destRows - curRows) == 1){
return (destRow - curRow == direction) || crowned;
} else if (abs(destRows-curRows) == 2){
return takeMove(curRow, curCol, destRow, destCol);
// anything but 1 or 2 moves diagonal is never ok.
} else{
return false;
}
}
private boolean takeMove(int curRow, int curCol, int destRow, int destCol)
if (!isOpponent(board[(curRow + destRow)/2, (curCol + destCol)/2])){
return false;
}
return (destRow - curRow) * direction > 0 || crowned;
}
private boolean isOpponent(Peice other){
return other.direction != this.direction
}
}

Related

Game score via collision detection increment

So i have a game where if my user collides with an image it will increase the score by 1. However because i use this method of collision detection and an if statement to increment my score, during the duration of the collision the score will go up by about 30 as the collision method detects it colliding multiple times as they pass through each other. How would i stop it from incrementing by more than one each time.
Here is my code:
void draw () {
if (gameMode == Active) {
if(crash() == false) {
drawBackground();
textSize(32);
fill(22,100,8);
text("Score: " + score ,20,40); //calls the drawBackground method
alien1.update();
alien2.update(); //constantly calls the move and render method for the alien and defender
alien3.update();
user1.render();
Burger.update();
if(Bcrash() == true) {
if(Bcrash() == false) {
score = score + 1;
}
}
} else {
gameMode = End;
textSize(32);
fill(22,100,8);
text("Game Over, press 'r' to restart",150,200);
}
}
}
boolean Bcrash() {
return user1.crash(Burger));
}
// Burger.class (Editor's note: I guess it's User.class)
public class User {
boolean crash(Burger A) {
return(abs(x-A.x)<=30) && abs(y-A.y)<=30;
}
}
Check to see if collision is false before allowing it to add another number.
something like:
Boolean collisionInProgress = false;
if(collision == true && collisionInProgress == false){
score = score+1;
collisionInProgess = true;
}
…loop…
if(collision == false){
collisionInProgess = false;
}

Recursively finding a path on a 2d array [Java]

I want to write a programm in java that finds a path on a 2d Array with recursion.
The 2d Array named "gitter" consists of Objects of the type 'field'.
Every field will be initialized with a random number in the range of 100-999. If a field was initialized with a number, in which one of the digits is a prime, it is a "trap". The fields can be imagined as squares, so i can move only in 4 directions:
public class Field {
int number;
boolean visited;
Field() {
Random rn = new Random();
this.number = rn.nextInt((999+1) - 100) + 100;
this.visited = false;
}
boolean isTrap() {
String str = String.valueOf(number);
if(str.contains("2") | str.contains("3") | str.contains("5") | str.contains("7")) {
return true;
} return false;
}
}
The start-field and the end-field of the path shall have a manhattan-distance of more than 2. The problem so far is the recursion. The more i think about it, the if cases in it are just getting longer and longer. I added also a boolean variable "visited", for not visiting the same field twice, but no success. Is the while-loop necessary for the recursion? If not (what i guess), what is the easiest way to make the recursion stop, after i found a path? i tried it with and without a while-loop, but couldn't find any solution.
public class Gitter {
Field[][] gitter = new Field[10][10];
List<Field> path = new ArrayList<Field>();
public Field[] getStartAndGoal() {
boolean notFound = true;
Field[] startGoal = new Field[2];
while(notFound) {
Random x0 = new Random();
Random y0 = new Random();
Random x1 = new Random();
Random y1 = new Random();
int row0 = x0.nextInt((9)+1);
int line0 = y0.nextInt((9)+1);
int row1 = x1.nextInt((9)+1);
int line1 = y1.nextInt((9)+1);
int distance = Math.abs(row1-row0) + Math.abs(line1-line0);
if(distance>2){
if(gitter[row0][line0].isTrap() == false && gitter[row1][line1].isTrap() ==false) {
notFound = false;
Field start = gitter[row0][line0];
Field goal = gitter[row1][line1];
startGoal[0] = start;
startGoal[1] = goal;
}
}
}
return startGoal;
}
public boolean findPath(Field start, Field goal) {
boolean solved = false;
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
if(gitter[i][j].equals(start)) {
gitter[i][j].visited=true;
while(solved==false){
if((i+1)<10 && gitter[i+1][j].isTrap()==false && gitter[i+1][j].visited == false && findPath(gitter[i+1][j], goal)){
gitter[i+1][j].visited = true;
path.add(gitter[i+1][j]);
return true;
}
if((i-1)>0 && gitter[i-1][j].isTrap()==false && gitter[i-1][j].visited == false && findPath(gitter[i-1][j], goal)){
gitter[i-1][j].visited = true;
path.add(gitter[i-1][j]);
return true;
}
if((j+1)<10 && gitter[i][j+1].isTrap()==false && gitter[i][j+1].visited == false && findPath(gitter[i][j+1], goal)){
gitter[i][j+1].visited = true;
path.add(gitter[i][j+1]);
return true;
}
if((j-1)>10 && gitter[i][j-1].isTrap()==false && gitter[i][j-1].visited == false && findPath(gitter[i][j-1], goal)){
gitter[i][j-1].visited = true;
path.add(gitter[i][j-1]);
return true;
}
for(i=0; i<path.size(); i++) {
if(path.get(i).equals(goal)){
solved = true;
break;
}
}
}
}
}
} return false;
}
Does anybody got a hint for me?
Looking at the problem, there are many variables that aren't necessarily too important to consider yet would allow me to create a simple solution quicker. If you use concepts from my solution, just take notes that there are a variety of restraints completely ignored which can easily be implemented.
Recursion
Typically recursion is used to replace the iterative behaviour of loops. With this problem you want to search every possible path if there exists a path that can take you from point A to point B, or up until you have determined there exists a path.
The more i think about it, the if cases in it are just getting longer and longer
Easy. Create a helper method that does the calculation for you so that you avoid repetitive use of the same code.
Is the while-loop necessary for the recursion?
I'm not entirely sure what you're doing with your loops, but it would definitely be possible (and much more elegant) to do away with loops altogether for this solution.
what is the easiest way to make the recursion stop, after i found a path?
Once you have found a solution, return true. The previous recursive step will receive a true value and then understand that somewhere along the line you have reached the end so it too should return true. This is where the recursive aspect can produce such an elegant solution.
Solution
public static void main (String args[]) {
int n = 10;
int[][] map = new int[n][n]; // Generate random data however you want
boolean[][] visited = new boolean[n][n]; // Defaults to false
int[2] start = new int[]{0,0}; // Top left corner
int[2] end = new int[]{n-1, n-1}; // Bottom right corner
boolean path = pathExists(map, visited, start, end);
}
public static boolean pathExists(int[][] map, boolean[][] visited, int[] current, int[] end) {
int x = current[0];
int y = current[1];
// If not in bounds, not a valid route
if (!inBounds(map, visited, current)) return false;
// If this is the end, return true!
if (current[0] == end[0] && current[1] == end[1]) return true;
// Attempt each cardinal direction. If you find a return, return true
if (pathExists(map, markPresent(visited, current), new int[]{x-1,y}, end)) return true;
if (pathExists(map, markPresent(visited, current), new int[]{x+1,y}, end)) return true;
if (pathExists(map, markPresent(visited, current), new int[]{x,y+1}, end)) return true;
if (pathExists(map, markPresent(visited, current), new int[]{x,y-1}, end)) return true;
// There is no solution down this path
return false;
}
public static boolean[][] markPresent(boolean[][] visited, int[] current) {
// Make a deep copy - Is needed to prevent interferance
boolean[][] copy = new boolean[visited.length][visited[0].length];
for (int i = 0; i < copy.length; i++)
copy[i] = Arrays.copyOf(visited[i], visited[i].length);
// Mark where you currently are
copy[current[0]][current[1]] = true;
return copy;
}
public static boolean inBounds(int[][] map, boolean[][] visited, int[] position) {
int x = position[0];
int y = position[1];
// Make sure it is within the bounds of the map
if (x < 0 || y < 0 || x >= map.length || y >= map.length) return false;
// Check if the current block is a barrier
if (isBarrier(map, position)) return false;
// If you have visited this path before, don't do it again
if (visited[x][y]) return false;
// Otherwise, check the path!
return true;
}
public static boolean isBarrier(int[][] map, int[] position) {
// Return your definition of a barrier (I used modulo 10 for testing
}
I've done minimal testing, so if you can see any glearing issues feel free to leave a comment.
From what I can gather, you are wanting to detect whether a path exists between to points. If you are wanting to detect the shortest distance (using the Manhatten metric), instance of returning boolean values you could return integer value. If you want to find the path itself, you can return an array of points and recursively append all points to another array. Here's a modified version that finds the shortest path:
public static ArrayList<int[]> findDistance(int[][] map, boolean[][] visited, int[] current, int[] end) {
int x = current[0];
int y = current[1];
ArrayList<int[]> ret = new ArrayList<>();
ret.add(current);
if (!inBounds(map, visited, current)) return new ArrayList<>(); // Return empty array
if (current[0] == end[0] && current[1] == end[1]) return ret; // Return current location
ArrayList<ArrayList<int[]>> paths = new ArrayList<>();
paths.add(findDistance(map, markPresent(visited, current), new int[]{x-1,y}, end));
paths.add(findDistance(map, markPresent(visited, current), new int[]{x+1,y}, end));
paths.add(findDistance(map, markPresent(visited, current), new int[]{x,y+1}, end));
paths.add(findDistance(map, markPresent(visited, current), new int[]{x,y-1}, end));
// Find the shortest path that leads somewhere
paths.removeIf((ArrayList<int[]> data) -> data.size() == 0);
paths.sort(Comparator.comparing(ArrayList::size));
// If the size of the paths is 0, no path was found
if (paths.size() == 0) {
return new ArrayList<>();
} else {
//Append the found path to the current location and return the list
ret.addAll(paths.get(0));
return ret;
}
}
EDIT
I had a terrible feeling I had forgotten something obvious - I had. You will need to clone the visited array so that you don't interfere with each recursive step. I've added a method to do that.
Adding some extra things to make things easier:
start and goal are attributes of Gitter class
findPath has been divided in tho methods, one public and another private
Code
public class Gitter {
Field[][] gitter = new Field[10][10];
List<Field> path = new ArrayList<Field>();
private Field start = null;
private Field goal = null;
// i've omited initializing too
public boolean findPath(Field start, Field goal) {
this.start = start;
this.goal = goal;
// Instead of having one recursive method, I divided it in two, one public and another private
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
if(gitter[i][j].equals(start)) {
return findPath(i,j);
}
}
} return false;
}
/*
* Check if available path exist from Field [i][j]
*/
private boolean findPath(int i, int j){
boolean solved = false;
// This check makes if-else chain cleaner
if(i < 0 || i >= 10 || j < 0 || j >= 10){
return false;
}
// Don't check already visited cells
if(!gitter[i][j].visited){
gitter[i][j].visited=true;
// If its possible to have a trap in goal Field, this check must be first
if(gitter[i][j].equals(goal)){
path.add(gitter[i][j]);
return true;
}
// If start Field mustn't be a trap, first condition should be removed
if(!gitter[i][j].equals(start) && gitter[i][j].isTrap()){
return false;
}
// Down
if(findPath(i+1,j)){
solved = true;
}
// Up
else if(findPath(i-1,j)){
solved = true;
}
// Right
else if(findPath(i,j+1)){
solved = true;
}
// Left
else if(findPath(i,j-1)){
solved = true;
}
// If any direction check found a path, this cell is part of that path
if(solved){
path.add(gitter[i][j]);
}
return solved;
}
return false;
}
}
I've tried with small numbers (from 1 to 9) and it should work
This one can not be a perfect nor efficient solution, but I've tried to make code easier to read and understand. I think with this kind of recursive problems that's a point to be highly considered.

Keeping track of path through a maze

The program is using backtracking to find out a way out of the maze(which it does fine). The problem occurs when I try to print out the correct path I took.
This is my solveMaze() method.
boolean result = false;
while(result==false){
if((row > 29) || (row < 0) || (col > 19) || (col < 0)) //check if position is within the array
return false;
if(maze[row][col].getVar().equals("E")) // check if youre at the exit
return true;
if(maze[row][col].getVar().equals("1")) // check if youre hitting a wall
return false;
if(maze[row][col].position.size() > 2){ // check if youre at an intersection
intersection[numIntersection] = maze[row][col]; // add intersection to intersection array
numIntersection++;
}
//this section does not need to be checked if youve never visited the position before
if(maze[row][col].getVisted() == true && numIntersection > 0){
if(intersection[numIntersection-1] == null)
return false;
else if(intersection[numIntersection-1] != null){ //as you backtrack to the last intersection pick up your "markers"
maze[row][col].setVar("0");
if(maze[row][col].position == intersection[numIntersection-1].position && intersection[numIntersection-1].getVisted()==true){ //remove intersection from the array as you pass back thru
maze[row][col].setVar("+");
intersection[numIntersection-1] = null;
numIntersection--;
}
}
}
if(maze[row][col].position.empty()==true) //check if the stack is empty
return false;
maze[row][col].position.pop();
if(maze[row][col].getVisted() == false)
maze[row][col].setVar("+"); //mark path as you land on unvisted positions
maze[row][col].setVisted(true);
//look north
if(solveMaze(row-1,col)== true)
return true;
//look east
if(solveMaze(row,col+1)== true){
return true;
}
//look west
if(solveMaze(row,col-1)== true){
return true;
}
//look south
if(solveMaze(row+1,col)== true){
return true;
}
}
return false;
}
As I backtrack I am picking back up my markers but it seems to be picking up markers on the correct path also and prints a maze with a broken up path.

Weird java recursion nullpointerexception on a method

Hi I'm writing a checkers engine and defining a canEat(Point1,Point2) method for player class which returns true or false based on if player can eat eat the piece at the specified points by checking if the pieces and landing path is on board, if the two pieces belong to the same player or not and also considering the king/super status of piece.
Anyways it works pretty pleasantly without recursion, but without recursion method must get points of the pieces instead of the landing piece which is okay if I manage the recursion. But I want the method to also consider if it gets the landing point instead of piece location. When I run the code it fixes the location and calls itself again there is no problem with that but. I get NullPointerException on
caneat = Checker2.isAlive() ? true : false; because Checker2 is null. My pointToChecker method returns null on this guy so Checker2 is null. What is causing this I'm new to recursion, even OOP to be honest and
Here is my code and console error log
public boolean canEat(Point Piece, Point target)
{
//INITIALIZING
//POINT1 & CHECKER1-> piece which eats
//POINT2 & CHECKER2-> piece to eat
//POINT3 & CHECKER3-> landing path
if (samePoint(Piece, target))
return false;
boolean caneat = true;
boolean king1 = false;
Point Point1,Point2,Point3;
Checker Checker1,Checker2,Checker3;
int ownerID, victimID,axis;
axis = getDirection(Piece, target);
//CHECK IF PLAYER POINTED THE SQUARE AHEAD TARGET PIECE OR THE PIECE TO EAT
int distance = getStep(Piece, target);
if(distance == 2)
{
boolean resolution;
System.err.println("Recoordinated target");
Point fixed = getBackwards(target, axis);
System.err.println("Fixed is: " + Piece + " " + fixed);
resolution = canEat(Piece, fixed);
return resolution;
}
Point1 = Piece;
Point2 = target;
Point3 = findMovePosition(target, axis);
if(!inBoard(Point1) || !inBoard(Point2) || !inBoard(Point3))
{
System.err.println("Error: Invalid Move --> Thinking outside the box");
return false;
}
Checker1 = PointToPiece(Point1);
Checker2 = PointToPiece(Point2);
Checker3 = PointToPiece(Point3);
//CHECK IF PIECES ARE ALIVE
caneat = Checker1.isAlive() ? true : false;
caneat = Checker2.isAlive() ? true : false;
if(!Checker2.isAlive())
{
return false;
}
//THERE SHOULD BE TARGET AND VICTIM PIECES AND AN EMPTY LANDING POINT
if(!isOccupied(Piece))
{
System.err.println("#OccupyChecker invalid piece to move");
return false;
}
if(!isOccupiedbyEnemy(target))
{
System.err.println("#OccupyChecker invalid piece to eat");
return false;
}
if(!(Checker3 == null))
{
System.err.println("#OccupyChecker landing piece error");
return false;
}
ownerID = Checker1.getOwner().getID();
victimID = Checker2.getOwner().getID();
if(ownerID == victimID)
{
System.err.println("owner ID: " + ownerID + " victimID: " + victimID);
System.err.println("#OCCUPY identity");
return false;
}
if(ownerID == 1 && king1)
{
if(axis == 3 || axis == 4)
System.err.println("#OccupyPoint wrong axis");
caneat = false;
}
if(ownerID == 2 && king1)
{
if(axis == 1 || axis == 2)
System.err.println("#OccupyPoint wrong axis");
caneat = false;
}
return caneat;
}
Checker PointToPiece(Point piece)
{
Checker[] allPieces = allPieces();
Checker found = null;
for(Checker k : allPieces)
{
if(samePoint(k.getPosition(), piece))
found = k;
}
return found;
}

Boolean Value Confusion when it is local, open and recursive in Java

I am a beginner and really confused with this code as what happens to boolean value, "done". I have spent two hours understanding this code and I am very frustrated.
public boolean traverse(int row, int column){
boolean done = false;
if(row == grid.length-1 && column == grid[0].length-1)
done = true;
else{
done = traverse(row + 1. column); //down
if(!done) done = traverse (row, column+1)//right
}
if (done) grid[row][column] = PATH;
}
return done;
}
First, "done" is declared FALSE. Then it moves to an if and else statement and becomes local to it.Now, outside the IF and ELSE statement, when it says if(done) do something, it is when done is FALSE or TRUE? Also while in the ELSE statement does (!done) mean that it is FALSE as it is declared TRUE in IF ELSE statement?
In simple words, when you use an IF, IF and ELSE statement with a boolean in it, does it mean it has to be TRUE?
For instance:
boolean love = false;
if(love) do this;
Now, does it mean "do this" when love is false?
The ! operator negotiates the boolean value. That means a statement becomes true if the boolean variable is false. So, for your example this won't be executed:
boolean love = false;
if(love) do this; //not executed
But with a ! it would be executed:
boolean love = false;
if(!love) do this; //executed
In the other case this wouldn't be executed:
boolean love = true;
if(!love) do this; //not executed
EDIT:
For further explanations on if-Statements maybe you will have a look on the official docs by oracle:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/if.html
EDIT 2:
Maybe if you write your code this way it is more understandable for you:
public boolean traverse(int row, int column){
boolean done = false;
if(row == grid.length-1 && column == grid[0].length-1) {
done = true;
}else{
done = traverse(row + 1. column); //down
if(!done) {
done = traverse (row, column+1)//right
}
}
if (done) {
grid[row][column] = PATH;
}
return done;
}

Categories