I can't figure this out, my dungeon is printing improperly(question and output at bottom). This is going to be a bit of code, but it's all necessary.
here's the dungeon constructor:
public Dungeon ( )
{
Random r = new Random();
int determinedDungeonSize = r.nextInt(10-5) + 5;
int weaponRandom = r.nextInt(determinedDungeonSize);
dungeon = new ArrayList<String>(determinedDungeonSize);
String cell = ("|____| ");
char[] cellArray = cell.toCharArray();
for(int i=0; i<determinedDungeonSize ;i++)
{
int randomProbability = r.nextInt(10000);
if(randomProbability < 5000)
{
cellArray[2] = 'M';
}
if(i == weaponRandom)
{
if(randomProbability < 5000)
{
cellArray[3] = 'S';
cellArray[4] = 'w';
}
else
{
cellArray[3] = 'S';
cellArray[4] = 't';
}
}//end if
cell = String.valueOf(cellArray);
dungeon.add(cell);
}//end for
}//end Dungeon()
toString for the Dungeon:
public String toString()
{
String dungeonString = "";
for(int i = 0; i < dungeon.size(); i++)
{
dungeonString += dungeon.get(i);
}
return dungeonString;
}
Now here's the problem. I'm printing off the dungeon in the driver class with this statement-> System.out.print(d.toString());, where d is just a Dungeon object created w/ Dungeon d = new Dungeon()
And the console is outputting(Here's a bad case):
|_M__| |_M__| |_M__| |_MSt| |_MSt| |_MSt| |_MSt|
The probability of a Monster, denoted 'M', being in a cell is 50/50. The probability for a Weapon(Stick('St') or Sword('Sw')) to exist is ONE WEAPON PER DUNGEON(only one weapon in any given dungeon, cell must be random). The constructor should be doing all this just fine, I have no idea what is going wrong here and I have been trying to solve this for 6 hours now.
EDIT: EXPECTED OUTPUT: |M_| |M_| |_| |_St_| |M| |_| |M| |___|
Your problem is that you never refresh the value of cellArray to be a "new" cell at the end of your for loop. You just write on top of the existing cell. This means that if an M appears in the very first cell, it will appear in every cell. Furthermore, the weapon will appear in every cell after the first time it appears. To fix this, you need to re-initialize cell each time you run the for loop. Just move the initialization to inside the loop:
for(int i=0; i<determinedDungeonSize ;i++)
{
//just move these to the inside of the loop
//so they are fresh each time
String cell = ("|____| ");
char[] cellArray = cell.toCharArray();
int randomProbability = r.nextInt(10000);
if(randomProbability < 5000)
{
cellArray[2] = 'M';
}
if(i == weaponRandom)
{
if(randomProbability < 5000)//this does mean that if the weapon is in the same room as a monster, it will always be Sw. Consider generating a new random value
{
cellArray[3] = 'S';
cellArray[4] = 'w';
}
else
{
cellArray[3] = 'S';
cellArray[4] = 't';
}
}//end if
cell = String.valueOf(cellArray);
dungeon.add(cell);
}//end for
Related
The purpose of this project is to make a pokedex that adds and holds all the pokemon passed in by user input. When the user inputs a pokemon that is already stored in the pokedex the word "duplicate" is supposed to be printed to the console. The word duplicate is printed even though there are no actual duplicates within the object array. Here is my output from the console :
Welcome to your new PokeDex!
How many Pokemon are in your region?: 3
Your new Pokedex can hold 3 Pokemon. Let's start using it!
List Pokemon
Add Pokemon
Check a Pokemon's Stats
Sort Pokemon
Exit
What would you like to do? 2
Please enter the Pokemon's Species: red
Duplicate
Now here is all the code used that could possibly be making this error
import java.util.Scanner;
public class Project4 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Welcome to your new PokeDex!");
System.out.print("How many Pokemon are in your region?: ");
int size = input.nextInt();
Pokedex pokedex = new Pokedex(size);
System.out.println("\nYour new Pokedex can hold " + size + " Pokemon. Let's start using it!");
int choice = 0;
boolean done = false;
while (!done) {
System.out.println("\n1. List Pokemon\n2. Add Pokemon\n3. Check a Pokemon's Stats" + "\n4. Sort Pokemon\n5. Exit");
System.out.print("\nWhat would you like to do? ");
choice = input.nextInt();
switch (choice) {
case 1:
String[] pokemonList = pokedex.listPokemon();
if (pokemonList == null)
System.out.println("Empty");
else
for (int i = 0; i < pokemonList.length; i++) {
System.out.println((i + 1) + ". " + pokemonList[i]);
}
break;
case 2:
System.out.print("\nPlease enter the Pokemon's Species: ");
String species = input.next();
pokedex.addPokemon(species);
break;
}
}
}
}
In the following class I have the actual method that adds the pokemon and the constructor for Pokedex
public class Pokedex {
Pokemon[] pokedex;
String pokeArray[];
public Pokedex(int size) {
pokedex = new Pokemon[size];
pokeArray = new String[size];
}
public boolean addPokemon(String species) {
Pokemon stuff = new Pokemon(species);
for (int i = 0; i < pokedex.length; i++) {
if (pokedex[i] == null) {
pokedex[i] = stuff;
}
else if (i < pokedex.length && pokedex[i] != null) {
System.out.println("Max");
}
if (pokedex[i].getSpecies().equalsIgnoreCase(species)) {
System.out.print("Duplicate");
break;
}
}
return false;
}
}
Sorry for the mass amounts of code I just need help tracing where this unexpected result is coming from.
The reason it's doing that is because of this bit of code here:
public boolean addPokemon(String species)
{
Pokemon stuff = new Pokemon(species);
for (int i = 0; i < pokedex.length; i++)
{
if (pokedex[i] == null)
pokedex[i] = stuff;
else if (i < pokedex.length && pokedex[i] !=null)
System.out.println("Max");
if(pokedex[i].getSpecies().equalsIgnoreCase(species))
{
System.out.print("Duplicate");
break;
}
}
return false;
}
The problem is just a little bit of syntax missing. In your for loop, you check to see if
A) there are any empty spots in the array
B) if every element in the array up to the user inputted size is full
and C) if any element in the array matches the one we're trying to add.
The problem you're encountering is because your C is an if instead of an else if. Because A sees the index is null, it assigns the new Pokemon to the Pokedex. Then because C is an if instead of an else if, it runs after you assign the new Pokemon and sees the Pokemon we just added and says it's a duplicate. Changing it to an else if would fix this.
Also, since there was no break; in A, it would assign every element of the array to the first one entered, causing any further additions to call Max. I edited the code and this is what I had that worked for me:
public boolean addPokemon(String species)
{
Pokemon stuff = new Pokemon(species);
for (int i = 0; i < pokedex.length; i++)
{
if(pokedex[i] !=null && pokedex[i].getSpecies().equalsIgnoreCase(species))
{
System.out.println("Duplicate");
break;
}
else if (pokedex[i] == null)
{
pokedex[i] = stuff;
break;
}
else if(i + 1 == pokedex.length)
{
System.out.println("Max");
break;
}
}
return false;
}
Also, out of curiosity, why is the addPokemon() function a boolean? You return a value (albeit arbitrarily) and then never do anything with that value. You could just make it a void, have it return nothing, and it would work just as fine.
The for loop in the backEnd class - CompareGuess method is not working.
....................................................................................................................................................
public class frontEnd
{
public static void main (String args[])
{
int GetGuess = 0;
backEnd e1 = new backEnd();
e1.InitializeArray();
while(e1.chanceCounter<3)
{
System.out.println("Enter a number");
GetGuess = (int)(Math.random()*6);
System.out.println(GetGuess);
e1.UserGuess(GetGuess);
e1.CompareGuess();
if(e1.suc!=1)
{
System.out.println("It is a miss");
}
}
System.out.println("Sorry, no chances left");
}
}
class backEnd
{
int Guess;
int HitCounter=0;
int[] abc = new int[7] ;
int chanceCounter=0;
int suc = 0;
int x =0;
public void InitializeArray()
{
abc[1]= 3;
abc[2] = 5;
abc[4] = 1;
}
public void UserGuess(int guess)
{
Guess = guess;
}
public void CompareGuess()
{
for(x=0; x<=6; x++ )
{
if (abc[x] == Guess)
{
System.out.println("It is a hit");
chanceCounter = chanceCounter + 1;
suc = 1;
}
break;
}
}
}
The problems seems to be here:
for(x=0; x<=6; x++ )
{
if (abc[x] == Guess)
{
System.out.println("It is a hit");
chanceCounter = chanceCounter + 1;
suc = 1;
}
break; //Here
}
Look what your code does:
Your for loop makes the first iteration, taking x = 0
If abc[x] it's equals to Guess then your program executes the code inside the if statement. After, the break statement will be executed.
If not, it just execute the break statement
So, in both cases, the break statement it's going to be executed in the first iteration (therefore, your program will go out of the for loop).
Look that your program only will execute your first iteration but not the rest (x = 1, x = 2 [....] x =6).
If you want that your for loop go through all the iterations you have to remove your break statement from your code.
I expect it will be helpful for you!
Since your game is all about guessing. I took a guess at what it's supposed to do then I rewrote your code, because I couldn't bear to leave it as it was. I left it as similar to your as I can cope with:
public class FrontEnd
{
public static void main (String args[])
{
int getGuess = 0;
BackEnd e1 = new BackEnd();
e1.initializeArray();
int totalChances = 3;
while(e1.chanceCounter < totalChances)
{
System.out.println("Enter a number");
getGuess = (int)(Math.random()*6);
System.out.println(getGuess);
e1.userGuess(getGuess);
e1.compareGuess();
if(!e1.suc)
{
System.out.println("It is a miss");
}
e1.suc = false;
e1.chanceCounter++;
}
System.out.println("Sorry, no chances left");
System.out.println("you scored " + e1.hitCounter + " out of " + totalChances);
}
}
class BackEnd
{
int guess;
int hitCounter = 0;
int[] abc = new int[7] ;
int chanceCounter = 0;
boolean suc = false;
public void initializeArray()
{
abc[1] = 3;
abc[2] = 5;
abc[4] = 1;
}
public void userGuess(int guess)
{
this.guess = guess;
}
public void compareGuess()
{
for( int x = 0; x <= 6; x++ )
{
if (abc[x] == guess)
{
System.out.println("It is a hit");
hitCounter++;
suc = true;
break;
}
}
}
}
As others have said the break statement is supposed to be inside the conditional block. Also it looks like you were forgetting to reset the suc variable after each guess. Also you weren't using hitCounter at all. I assumed it's for counting correct guesses, which left me wondering when to update chanceCounter: either after each guess or after each wrong guess. I didn't know if the guesser was supposed to run out of chances after 3 guesses, or after 3 wrong guesses. I went with the former and update the chanceCounter after every guess.
guesses of 0 are considered correct because they match with all the entries in the abc array that are not initialised.
This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 7 years ago.
I am writing a basic Tic-Tac-Toe Single player game using basic swing graphics. I completed the game, but there is a weird problem I am facing. At one place, I used a while loop with a SOP statement. If I omit this statement, program works differently and nothing happens (like some kind of infinite loop), and if I keep it, it works just fine. I don't know what's happening in the code. Please help.
Below is the source code which causing problem. Sorry for my amateur coding style.
import java.util.Random;
public class SinglePlayer implements Runnable{
public final int MINIMUM = -1000000;
private GameBoard game;
public SinglePlayer(){
game = new GameBoard("Single Player");
}
public static void main(String[] args){
SinglePlayer gameSingle = new SinglePlayer();
gameSingle.run();
}
public void run(){
boolean machinePlayed = true, userPlayed = false;
// Outer loop is to maintain re-match option of program
while(this.game.quitTwoPlayer == false){
// Inner loop is a single game b/w user and machine
while(this.game.GameQuitStatus() == false){
/* I kept two conditions to switch b/w machine and user mode
* of game and they just keep changing to simulate the game
* b/w machine and user.
*/
if(machinePlayed == false && userPlayed){
try {
MachineMove("O");
} catch (CloneNotSupportedException e) {
e.printStackTrace();
break;
}
this.game.ChangePlayerLabels();
machinePlayed = true;
userPlayed = false;
}
else if(machinePlayed && userPlayed == false){
int earlierCount = this.game.CountSteps();
/* THIS IS THE WHILE LOOP I AM TALKING ABOUT.
* If I omit the print statement inside the body of loop,
* program behaves differently, but when I keep it,
* it working just fine.
* */
while(earlierCount == this.game.CountSteps()){
System.out.println("Player User thinking");
}
this.game.ChangePlayerLabels();
machinePlayed = false;
userPlayed = true;
}
this.game.DeclareResult();
}
this.game.dispose();
}
}
public void MachineMove(String player) throws CloneNotSupportedException{
/* If board is empty, play at center of the board */
if(this.game.CountSteps() == 0){
this.game.MakeMove(1, 1);
}
/* If center is blank, play it there. Otherwise, pick a corner randomly */
else if(this.game.CountSteps() == 1){
if(this.game.IsEmpty(1, 1))
this.game.MakeMove(1, 1);
else{
Random randomNum = new Random();
int num = randomNum.nextInt(4);
if(num == 0)
this.game.MakeMove(0, 0);
else if(num == 1)
this.game.MakeMove(2, 0);
else if(num == 2)
this.game.MakeMove(0, 2);
else if(num == 3)
this.game.MakeMove(2, 2);
}
}
else{
/* If the next move is such that it should be taken, otherwise opponent will win */
String opponent = "";
if(this.game.GetCurrentPlayer().equals("O"))
opponent = "X";
else
opponent = "O";
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
if(this.game.IsEmpty(i,j)){
GameBoard tempGame = new GameBoard(this.game, "Single Player");
tempGame.MakePossibleMove(i, j, opponent);
if(tempGame.GameWinner().equals(opponent + " wins")){
this.game.MakeMove(i,j);
return;
}
}
}
}
/* If the next move is not such that if missed, game is lost, then play most optimal move towards winning */
Move tempMove = new Move(MINIMUM, 0, 0);
Move bestMove = new Move(MINIMUM, 0, 0);
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
if(this.game.IsEmpty(i,j)){
GameBoard tempGame = new GameBoard(this.game, "Single Player");
tempMove = MakeMoves(tempGame, i, j);
if(tempMove.score > bestMove.score){
bestMove.row = tempMove.row;
bestMove.col = tempMove.col;
bestMove.score = tempMove.score;
}
}
}
}
this.game.MakeMove(bestMove.row, bestMove.col);
}
}
public Move MakeMoves(GameBoard tempGame, int row, int col){
String player = tempGame.GetCurrentPlayer();
tempGame.MakeMove(row, col);
if(tempGame.GameWinner().equals("Match Draw")){
return new Move(0, row, col);
}
else if(tempGame.GameWinner().equals("X wins")){
if(player.equals("X")){
return new Move(1, row, col);
}
else{
return new Move(-1, row, col);
}
}
else if(tempGame.GameWinner().equals("O wins")){
if(player.equals("O")){
return new Move(1, row, col);
}
else{
return new Move(-1, row, col);
}
}
else{
Move bestMove = new Move(MINIMUM, 0, 0);
Move tempBestMove = new Move(0, 0, 0);
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
if(tempGame.IsEmpty(i,j)){
GameBoard newGame = new GameBoard(tempGame, "Single Player");
tempBestMove = MakeMoves(newGame, i, j);
if(tempBestMove.score > bestMove.score)
bestMove = tempBestMove;
}
}
}
return bestMove;
}
}
}
class Move{
public int score;
public int row;
public int col;
public Move(int score, int row, int col){
this.score = score;
this.row = row;
this.col = col;
}
}
Your loop is likely typing up your processor, and the SOP slows the loop enough to allow other processes to occur. But regardless and most importantly, you don't want to have this loop present in the first place. You state that you have a,
Tic-Tac-Toe Single player game using basic swing graphics
Remember that Swing is an event driven GUI library, so rather than loop as you would in a linear console program, let events occur, but respond to them based on the state of the program.
In other words, give your class several fields including a boolean variable that tells whose turn it is, such as boolean playersTurn, a boolean variable gameOver, ..., and change the state of these variables as the game is played, and base the games behavior depending on these states. For instance the game would ignore the player's input if it was not his turn.
I am making a simple 2d game in java and i am trying to get fighting to work. I am going to do pokemon-style fighting, so what i am doing is when i press the spacebar, it checks if i am colliding with an enemy, finds that enemy in an arrayList, and then executes the fight method using that enemy. This works most of the time, but sometimes it can't seem to find the enemy in the ArrayList. My code for checking this is:
if (space) {
for (Rectangle collideable : Enemy.ens) {
if (intersects(playerR, collideable)) {
System.out.println("Colliding with Enemy!");
x = locx;
y = locy;
playerR.setLocation(x, y);
for (int i = 0; i < Game.enemies.size(); i++) {
if (Enemy.ens.get(i).equals(collideable)) {
System.out.println("Can't find enemy to fight");
System.out.println(Game.enemies.get(i).getName());
fightQuestion(Game.enemies.get(i), i);
break;
}
}
break;
}
}
}
Enemy.ens is created when i render each enemy. Game.enemies is created when I read in all of the enemy stats, and then i add each enemy to that ArrayList. For every enemy i try to fight, it is getting to the point where it prints out that it is colliding, but not always to the fight part. Any ideas as to why this is happening would be fantastic!
EDIT
Code for when Game.Enemies is filled:
public static void loadEnemies() {
im = getImageManager();
Scanner qwe;
try {
qwe = new Scanner(new File("enemyStats.txt"));
while (qwe.hasNextLine()) {
String name = qwe.nextLine();
String origin = qwe.nextLine();
String weapon = qwe.nextLine();
String gear = qwe.nextLine();
String spec = qwe.nextLine();
int hp = qwe.nextInt();
int att = qwe.nextInt();
int def = qwe.nextInt();
int randX = (int) (Math.random()*(18*SCALE*TILESIZE)); //Give random x coordinate
int randY = (int) (Math.random()*(18*SCALE*TILESIZE)); //Give random y coordinate
if(qwe.hasNextLine()){
qwe.nextLine();
}
enemies.add(new Enemy(randX,randY,im,name,origin,weapon,gear,spec,hp,att,def)); //adds enemy into arrayList
int randI = (int) (Math.random()*enemies.size());
for(int i = 0; i < 4;i++){ //adds enemy to arrayList to be rendered
enemiestoRend.add(enemies.get(randI) );
}
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Why do you execute the statement:
System.out.println("Can't find enemy to fight");
for each iteration in the second loop, regardless of checking a condition first? And why does the second loop check:
i < Game.enemies.size();
instead of:
i < Enemy.ens.size();
So we are given a maze with walls(W) open path(O) a start pt (S) and a finish pt (F).
I am trying to write an algorithm that takes the maze file and then turns it into a 2D array of points to make a grid.
Once I have the grid, I want to start on the 'S' character in the maze and try to find whether or not it is possible to traverse through the O's to get to the F. (Return a boolean true/false)
I know that this maze is solvable, so why am I getting a StackOverFlowError..?
Here is the Maze1.txt file:
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WSOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOWOOOOOOW
WWOOOOOOOOOOOOOWWWWWWWWWWWWWOOOOOOOOOOWWWWWWWWWWWWWOOOOOOW
WWWWWWOOOOOOOOOOOOWWWWWWWOOOOOOOOOOOOWWWWWWWWWWWWWWWWOOOOW
WOOOOOOWWWWWWWWWWWWWWOOOOOOOOOOOWWWWWWWWOOOOOOOOOOOOOOOWWW
WOOOOWWWWWWWOOOOOOWWWWOOOOOOWWWWWWWWWWWOOOOWWWWWWWWWOWWWWW
WOOOWWWWWWWWWWWWOOWWWWWWWWWWWWOOOOOOOOOOOOWWWWWWWWWOOOOOWW
WOOWWWWWWWWWWWWWOOWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWWOOOW
WOWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWOOW
WOWWWWWWWWWWWWWOOOOOOOOOOOOOOOOOOOOOOOOOOOOWWWWWWWWWWWWOOW
WOOOOOOOOOOOOOOOOWWWWOOOOOOOOWWWWWWWOOOOOOWWWWWWWWWWWWWOFW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
Here is my code(new attempt):
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Stack;
import java.awt.Point;
public class MazeExplorer {
static Point startPoint = new Point();
static Point finishPoint = new Point();
final static int mazeHeight = 12;
final static int mazeWidth = 58;
static char[][] mazePoints = new char[mazeHeight][mazeWidth];
Stack<Point> pointsNotTraversed = new Stack<Point>();
Point pt = new Point();
static HashSet<Point> previousLocations = new HashSet<Point>();
static Stack<Point> nextPoints = new Stack<Point>();
public static void main(String[] args) throws FileNotFoundException{
System.out.println("Please enter the file name of your Maze");
Scanner console = new Scanner(System.in);
File f = new File(console.nextLine());
Scanner sc = new Scanner(f);
if(!sc.hasNextLine()){
System.out.println("Sorry, please enter a file name with the extension, that contains a maze!");
}
System.out.println("So, you want to know if your maze is solvable.....?");
for (int row = 0; row < mazeHeight && sc.hasNext(); row++) {
final String mazeRow = sc.next(); //Get the next row from the scanner.
mazePoints[row] = mazeRow.toCharArray(); //Convert the row into a char[].
}
//identify the finish point
for(int i = 0; i < mazeHeight; i++){
for(int j = 0; j<mazeWidth; j++){
if(mazePoints[i][j] == 'F'){
finishPoint = new Point(i, j);
}
}
}
// Identify the start point
for(int i = 0; i< mazeHeight; i++){
for(int j = 0; j < mazeWidth; j++){
if(mazePoints[i][j] == 'S'){
startPoint = new Point(i , j);
}
}
}
isTraversable(startPoint);
}
public static boolean isTraversable(Point current){
boolean isSolvable = false;
do {
mazePoints[current.x][current.y] = ' ';
if (mazePoints[current.y - 1][current.x] == 'O'){ //up dir
nextPoints.push(new Point(current.y - 1, current.x));
mazePoints[current.y - 1][current.x] = ' '; //'X' marks where you've already been
}
if(mazePoints[current.y + 1][current.x] == 'O'){ // below direction
nextPoints.push(new Point(current.y + 1, current.x));
mazePoints[current.y + 1][current.x] = ' ';
}
if(mazePoints[current.y][current.x + 1] == 'O'){ // to the right
nextPoints.push(new Point(current.y, current.x + 1));
mazePoints[current.y][current.x + 1] = ' ';
}
if(mazePoints[current.y][current.x - 1] == 'O'){ // to the left
nextPoints.push(new Point(current.y, current.x - 1));
mazePoints[current.y][current.x - 1] = ' ';
}
if(mazePoints[current.y][current.x] == 'F'){
isSolvable = true;
System.out.println("MAZE IS SOLVABLE, YAHOOOOOO!!!!!!");
}
current = nextPoints.peek();
nextPoints.pop();
isTraversable(current);
} while(!current.equals('F') && !nextPoints.isEmpty());
return isSolvable;
}
}
You're getting the stack overflow error for the following reason:
public static boolean isTraversable(Point current){
boolean isSolvable = false;
Stack<Point> dumbPoints = new Stack<>(); // visited
dumbPoints.push(current); // pt is now visited
previousLocations.add(startPoint); // starts with the 'S' point
while(!dumbPoints.isEmpty()){
Point test = dumbPoints.pop();
if(previousLocations.contains(test)){
continue; // This gets called, and while loop skips to next iteration
}
/* None of this code matters right now, it never gets looked at */
} // End of while loop
isTraversable(current);
return isSolvable;
}
You send startPoint into the isTraversable() method. Inside the method its referred to as current. You then push current AKA startPoint into the stack and then add startPoint to the previousLocations set.
The while loop runs because dumbPoints is not empty (you put current AKA startPoint in there).
Inside the while loop you make a new point test and set it equal to the top item in the stack (which is current, AKA startPoint).
You check to see if(previousLocations.contains(test)) is true, and it is. You added startPoint to the previousLocations set 3 lines up. Since it does contain startPoint it continues on to the next iteration of the while loop.
The next time into the while loop the stack is empty because you popped out the only item that was in it (test). So this time the while loop does not get executed.
We then skip down to the very next line after the while loop:
isTraversable(current);
Which starts everything I just stated all over again. This runs forever until your computer runs out of memory. Hence your error.
Suggestion
I would suggest trying a different approach. You asked a question about this problem yesterday I believe and someone else suggested pushing all neighboring points into the stack. I think this is a good idea. Instead of pushing the current item into the stack you can push all neighboring O's into the stack and then recursively call the isTraversable method on those points. This would continue until a true or false is returned and you'll have your answer.
This is probably one of the cleaner approaches that you could use that isn't all that far off from the code you have already created.