Correct usage of Recursion - java

I am just wondering if my usage of recursion is correct. The code works for the intended purpose; however, I am not sure if it is actually doing recursion. I have tried tracing through my program, but I don't understand why my output is correct. Basically, the program takes in a data file of spaces and blobs of '*' and my program is supposed to recursively calculate the number of blobs given a certain row and column in the array of spaces and blobs. The problem is that I am not sure why exactly when I used variables like north, south, east, west, it would be able to successfully return the values to me, as it seems that during recursion, each variable just exists within that call. Also, I am not sure why exactly north = count(row,col+1) would give a value for north, since everytime I iterate through the recursion of count, it doesn't seem to stop at a definite value for north, as in like it doesn't seem to stop and say to return 1 as north.
public static int count(int row, int col) {
int north = 0, south = 0, east = 0, west = 0;
if (map[row][col] == BLOB) {
map[row][col] = MARKED;
if (map[row][col+1] == BLOB) {
north = count(row,col+1);
}
//Go South
if (map[row][col-1] == BLOB) {
south = count(row, col-1);
}
//Go East
if (map[row+1][col] == BLOB) {
east = count(row+1, col);
}
//Go West
if (map[row-1][col] == BLOB) {
west = count(row-1, col);
}
return (1 + north + south + east + west);
}
return 0;

Recursion is just having a method call its self. Therefore, this is recursion.
You are correct in that each variable only exists in the scope of each call. However, they are being defined based off of the other recursive calls.
It seems that this code is trying to fill in an array (and the end case is when the part of the array is filled in). This would be why it seems like it doesn't stop calling its self (as it would take many recursive calls before end cases are met).

Related

Using if statements

In this program, the user will be asked to input 2 words, (firstWord and secondWord). The two words will automatically appear on the screen once the object is created.
firstWord is set to change its position on the screen via a while loop.
secondWord will stay in a fixed position.
I want the loop to end once the X position or Y position of firstWord is the same as secondWord.
The XY position of secondWord = (155, 361)
So for instance, something like:
if (word1.xPosition = 155) {
break;
}
Obviously, that code is wrong, it is just to give you
an idea of what I want to achieve.
So how would I write this if statement?
My code is pasted below:
public words(String w1, String w2)
{
// initialise instance variables
firstWord = new Text(w1);
firstWord.randomizePosition();
firstWord.changeColor("green");
firstWord.changeSize(48);
firstWord.makeVisible();
secondWord = new Text(w2);
secondWord.setPosition(155, 361);
secondWord.changeColor("orange");
secondWord.changeSize(48);
secondWord.makeVisible();
public void draw()
{
while(true) {
firstWord.randomizePosition();
}
if(firstWord.xPosition = ){
break;
}
}
Replace the if statement
If you want to align both elements on EITHER x OR y, you should change your while loop to:
while(firstWord's X == secondWord's X || firstWord's Y == secondWord's Y)
firstWord.randomizePosition();
According to your description, this should work. Of course, you can always add a small delay to be able to see the animation, if you want to.
I want the loop to end once the X position or Y position of firstWord is the same as secondWord
while (!( firstWord.getXPosition() == secondWord.getXPosition() ||
firstWord.getYPosition() == secondWord.getYPosition())
{
firstWord.randomizePosition();
}
"While the first position doesn't equal the second position's X or Y position, change the first position"
If you are expecting to draw these labels on a GUI, don't expect to see any movement without a Thread that redraws the elements between moves.

For loop and if statements acting odd

I am making a chess game and so far everything is good and I am writing the rules of each piece now. The problem is that a for loop is acting oddly. Its for the bishop so x is going down and y is going up. At this point it acts oddly whenever I try to add the point to a possible move
for (int i = 0; i < 8; i++) {
Point newLoc = new Point(x-i, y+i);
if(team.equals("white")) {
if(containsPiece(newLoc)) {
if(ChessBoard.black.containsKey(newLoc)) {
possibilities.put(newLoc, rating);
break;
}
else {
break;
}
} else
possibilities.put(newLoc, rating);
}
containsPiece() is working just fine and possibilities is the HashMap I am storing the possible moves in.
The way I see it it should be working perfect because if the tile at newLoc is white it shouldn't add it to the possible moves and stop getting any moves after it in that direction. Does anyone see why it seems to abandon all the previous possible moves added to possibilities
i should start in 1, not 0, since when i==0, newLoc is the position of the bishop ((x-0,y+0)), so you break from the loop, since the bishop is a white tile.

Java Rectangle Collision Intersection (Not always working)

I'm currently working on a tile collision system for an RPG style game and it mostly working except for some inconsistency with rectangle intersection.
protected void tileCollision()
{
AnimatedSprite player = findPlayer();
for(int i = 0; i < _sprites.size(); i++)
{
AnimatedSprite spr = _sprites.get(i);
for(int j = 0; j < tileWithinRange.length; j++)
{
Tile tile = tileWithinRange[j];
if(tile != null)
{
if(tile.getBounds().intersects(player.getBounds()))
{
player.setCollided(true);
tileCollision(player, tile, -1, -1);
} else
{
player.setCollided(false);
}
}
}
}
}
When I first collide with a tile upon launching the game, it always returns true, but if I move along a column of tiles, I start getting false returns and then after a while I only get false returns.
Here is an image of the player intersecting with a tile
There is an obvious intersection here, yet in this scenario, the variable collided returned false.
What is going wrong that the intersection isn't always registering?`
There is too little info here to really know what's happening, but something looks fishy here:
if(tile.getBounds().intersects(player.getBounds()))
{
player.setCollided(true);
tileCollision(player, tile, -1, -1);
} else
{
player.setCollided(false);
}
Since you are checking multiple tiles against the player in a loop, what if the player collides with the first tile, but doesn't collide with the second tile? You'd end up calling player.setCollided(false); even though he collided with a former tile, overwriting that true collision state with a false one. That might explain the behavior you're getting where you're getting only false returns after a while (perhaps because of the order in which you are checking the tiles makes it so you keep overwriting true states with false states).
I'm not sure if that's desirable or not to have these kinds of side effects, but it is a bit confusing at the very least to have this kind of collision state first being turned on and then overwritten with off within the same loop. If that's undesirable behavior, perhaps what you're after needs you to break out of the loop if a collision occurs. Or perhaps what you want is something more like this:
player.setCollided(false);
for(int j = 0; j < tileWithinRange.length; j++)
{
Tile tile = tileWithinRange[j];
if(tile != null && tile.getBounds().intersects(player.getBounds()))
{
player.setCollided(true);
tileCollision(player, tile, -1, -1);
}
}
}
Or maybe your bounds/intersection function is genuinely malfunctioning -- it's too hard to tell with so little code/info (we don't know how these are implemented).
It's good to be able to isolate your code and learn how to construct test cases to test out individual functions in little pieces independently. You want to eliminate suspects through a process of elimination with a testing procedure that allows you to figure out, "Okay, this part works perfectly in every case, let's move on to the next thing." Otherwise it becomes a guessing game trying to figure out what went wrong. One of the easiest ways to lose a time of time/productivity in development is to write a bunch of code first and then try to narrow down what went wrong in hindsight, instead of testing each little babystep. Mistakes get more expensive the later you discover them and the more suspects you have to go through in an investigation.
I ended up rewriting the method into a boolean which made it return true when colliding and false when not. Here is the new code.
public boolean tileCollision() {
AnimatedSprite player = findPlayer();
for(int j = 0; j < tileWithinRange.length; j++) {
Tile tile = tileWithinRange[j];
if(tile != null) {
if(tile.getTileBounds().intersects(player.getBounds()) ) {
return true;
}
}
}
return false;
}

Changing the value of a 2d array every x turns?

Im creating an 'Avoid the Blocks' game, and for this i need to move a character around a grid (2D array) using the keys GHKJ. Every x amount of turns (decreasing as the level increases) a shadow must appear, then that shadow becomes a block and if the player moves into that bloack they lose a life.
Most of this is done for me other than the seemingly simple taski of getting the blocks to appear, here is my code so far for the falling blocks:
public void rocked(){
int rockInit = turn;
if(rockInit > 1){
int save = turn;
System.out.println(turn + " ");
B.board[ran.nextInt(12)][ran.nextInt(12)] = shadow;
if(save == turn - 3){
B.board[rockLocX][rockLocY] = rock;
}
}
}
The system.println is simply for debugging purposes, checking the values are being accesed. Turn is increased by 1 for every move the player makes, ran.nextInt(12) is a randomly generated number between 0 and 11, and B.board is the playing board.
It looks like you're never changing "save" after you initialize it to "turn". So then when you check if(save == turn-3), it will always be false, and so never move the block in. If you want to keep track of how many turns have passed, I would recommend a private instance variable "int turnsPassed" that you can increment each turn. Then for each level, you can check if (turnsPassed % x == 0), where x is as you've described it. Hope that helps!

Need help figuring out Basic Chess movement logic

Sorry for wall of text, but currently stumped. I'm not asking to be "spoon feed" since I have the basic idea down for each piece, it's just I'm having a difficult time on how to finish determining my move logic. Allow me to further explain. I'll be posting my code as well for better reference.
I'm coding with a MVC structure. I have a Model which is a 2D array of BoardSquares. Which those BoardSquares keep track of it's location on the board, what piece is in it (if there is one), what color that piece is (if there is one), and if it's empty. Here's the code for it:
public class BoardSquare {
// Private information stored in each BoardSquare
private boolean isSquareEmpty;
private int row;
private int col;
private String space;
private String pColor;
// Constructor to make an empty space on the board
public BoardSquare(int row, int col) {
space = "";
pColor = "";
this.row = row;
this.col = col;
SquareEmpty();
}
//Constructor to get the information of a space with a piece
public BoardSquare(BoardPiece piece, int row, int col) {
this.space = piece.getModelName();
this.pColor = Character.toString((piece.getModelName().charAt(0)));
this.row = row;
this.col = col;
SquareNotEmpty();
}
public String getpColor() {
String temp = getPieceColor(pColor);
return temp;
}
//A bunch of auto generated getters/setters...
// Gets the correct color label for the piece
public String getPieceColor(String info){
String temp;
if(info.equalsIgnoreCase("b")){
temp = "Black";
}
else {
temp = "White";
}
return temp;
}
Currently all my Pieces extend an abstract BoardPiece class which has several abstract methods as well, but my piece knows of it's location on the board, it's name, it's color, and the 2D board array for the way I'm generating the valid moves.
I'm generating them by checking the spaces it can move to and seeing if they are empty and adding them to an ArrayList and comparing and seeing if that list contains the inputted destination.
However I'm having problems thinking of how to stop checking if say Black Rook was on the left side of the board and wanted to move all the way to the Right, but there was a Black Pawn to the right of the Rook preventing it from doing so. I'm trying to generically think of it to make my life easier and I can implement it in the other piece classes as well So here's the Rook's code:
public class Rook extends BoardPiece{
private String name = "Rook";
private String color;
private String modelName;
BoardSquare board[][];
// Both should remain 0 - 7
private int row;
private int col;
public Rook (String modelName, int row, int col, String color, BoardSquare[][] field) {
this.modelName = modelName;
this.row = row;
this.col = col;
this.color = color;
this.board = field;
}
#Override
void move(BoardSquare target) {
if(!getPossibleMove(board).contains(target)){
//Sysout false move
}
}
#Override
Collection<BoardSquare> getPossibleMove(BoardSquare[][] board) {
ArrayList<BoardSquare> validMoves = new ArrayList<BoardSquare>();
for(int i = 0; i < 8; i++){
// Checks every column of the row that the piece is on
if(moveValidator(board[row][i])){
validMoves.add(board[row][i]);
}
// Checks every row of the column that the piece is on
if(moveValidator(board[i][col])){
validMoves.add(board[i][col]);
}
}
return validMoves;
}
#Override
boolean moveValidator(BoardSquare space) {
// Removes the current square the piece is on as a valid move
if(space.getRow() == getRow() && space.getCol() == getCol()){
return false;
}
//Checks if the space is not empty and the piece in the spot is the same color as the piece itself
if(!space.isEmptySquare() && space.getpColor().equalsIgnoreCase(color)){
return false;
}
return true;
}
Like I said any help or push toward the right direction would be appreciated. Sorry for the wall of text but trying to be as clear as I can so that whoever wants to help can fully understand and see my logic.
EDIT: Forgot to note that the Rook has Auto-generated Getters and Setters as well.
I would approach it the most brute-force and intuitive way possible: think of moving the rook one square at a time as it takes its turn and see if it collides with anything. That is, hop it across every square until it gets to the desired spot and check if it's a valid move at each square.
This is a fine approach because
it's easy to understand
it's not expensive until your chess board gets massively huge, so brute force isn't a problem.
it generalizes to all pieces: rooks have to "slide" to their destination, but knights can "jump" or "teleport" over other pieces to their new location, so don't need the intermediate hops.
This sounds close to your current implementation, but you need to stop tracing when you collide. That is, if there is a black pawn in the way, the columns after that pawn are no longer valid spaces, right? In other words, think of the move as an action that the rook takes instead of an independent state space of possible moves, since some spaces are legal moves except that the rook was previously blocked. You need to know where the rook is from and where it is going to determine valid moves, not just if the space is in the same row.
So, reading your code (thanks for posting the context, by the way, it's quite helpful) really all you need to do is not iterate on each square, but iterate moving through each square, and stop the iteration when you get blocked.

Categories

Resources