ArrayIndexOutOfBounds Exception in TicTacToe game - java

I'm getting an error that I don't realy understand why. It is a tictactoe game(n x n)
here is the table class
public class Table {
private int columns;
private int rows;
private int wincells;
private PieceType[][] table;
public Table() {
}
public Table(int rows, int columns, int wins) {
this.columns = columns;
this.rows = rows;
this.wincells = wins;
table = new PieceType[rows][columns];
fillEmpty();
}
public void fillEmpty() {
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < columns; ++j) {
table[i][j] = PieceType.None;
}
}
}
public PieceType getElement(int i, int j) {
return table[i][j];
}
its the getElement() method giving the error after i call the function with
game.move(e.x, e.y);
public void widgetSelected(SelectionEvent e) {
Button button = (Button) e.getSource();
MoveResult moveResult = game.move(e.x, e.y);
if (game.getCurrentPlayer().getPieceType() == PieceType.Cross)
button.setText("x");
else
button.setText("0");
switch (moveResult) {
case ValidMove: {
buttonTable[gridData.horizontalIndent][gridData.verticalIndent]
.setText("X");
game.changePlayer();
}
case WinMatch:
disableButtons();
case Draw:
disableButtons();
}
this is where the x and Y get the value
for (int i = 0; i < rows; ++i)
for (int j = 0; j < cols; ++j) {
gridData.heightHint = 45;
gridData.widthHint = 45;
Button button = new Button(buttonpanel, SWT.PUSH);
button.setLayoutData(gridData);
button.setData(new Cell(i,j));
buttonTable[i][j] = button;
buttonTable[i][j]
.addSelectionListener(new buttSelectionListener());
any ideas on what the problem can be? is it from the game.move(e.x, e.y)? Am I not calling it properly?
StackTrace?:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at backview.Table.getElement(Table.java:42)
at backview.Game.move(Game.java:56)
at frontview.MainGui$buttSelectionListener.widgetSelected(MainGui.java:159)
at org.eclipse.swt.widgets.TypedListener.handleEvent(Unknown Source)
at org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Unknown Source)
at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
at frontview.MainGui.<init>(MainGui.java:55)
at main.Main.main(Main.java:18)
here is the method calling
if(table.getElement(x, y) != PieceType.None) return MoveResult.InvalidMove;

You probably want to get the Cell from the Button data and use the i,j coordinates to call getElement().
Note: A couple of comments on your Table class. The default constructor doesn't make sense if you already know the initial size of the table. If that is the case, make columns, rows and wincells final so they cannot be modified during the game. Also, check that the coordinates provided in getElement() are within the array bounds:
public PieceType getElement(int i, int j) {
if ((i < 0) || (i >= rows) ||
(j < 0) || (j >= columns)) {
return null;
}
return table[i][j];
}

The e.x and e.y of the SelectionEvent e are the coordinate of the click of the mouse, and not the grid. You should get the Cell from the Button data, and then use it for your game move.
You can fix your widgetSelected method like that:
Cell c = (Cell) button.getData();
// Then use i and j of the cell for the game move
game.move(c.i, c.j); // or something similar

import java.util.Scanner;
public class TicTacToe_Game {
public static void main(String[] args) {
Scanner Myinput = new Scanner(System.in);
char[][] board = new char[3][3];
boolean Gameover;
Gameover = CalculateWinner(board);
while(!Gameover){
displayBoard(board);
System.out.println("Enter row and column for player X");
int rowX, columnX;
rowX=Myinput.nextInt();
columnX= Myinput.nextInt();
boolean successX = setMove(rowX , columnX ,board,'X');
while(!successX){
System.out.println("INVALID MOVE FOR PLAYER X");
System.out.println("Re-Enter row and column for player X");
rowX=Myinput.nextInt();
columnX= Myinput.nextInt();
successX = setMove(rowX , columnX ,board,'X');
}
Gameover= CalculateWinner(board);
displayBoard(board);
System.out.println();
System.out.println("Enter row and column for player O");
int rowO, columnO;
rowO=Myinput.nextInt();
columnO= Myinput.nextInt();
boolean successO= setMove(rowO , columnO ,board,'O');
while(!successO){
System.out.println("invalid Move");
System.out.println("Re-Enter row and column for player O");
rowO=Myinput.nextInt();
columnO= Myinput.nextInt();
successO = setMove(rowO , columnO ,board,'0');
}
Gameover=CalculateWinner(board);
}
}
public static boolean setMove(int row, int column,char[][] board,char player){
if(board[row][column]== 'X' || board[row][column]== 'O' ){
return false;
}
else if (player =='X'){
board[row][column] = 'X';
return true;
}
else{
board[row][column] = 'O';
return true;
}
}
public static void displayBoard(char[][]board){
System.out.println("-------------------");
System.out.println("|"+board[0][0]+"|"+board[0][1]+"|"+board[0][2]+"|");
System.out.println("-------------------");
System.out.println("|"+board[1][0]+"|"+board[1][1]+"|"+board[1][2]+"|");
System.out.println("-------------------");
System.out.println("|"+board[2][0]+"|"+board[2][1]+"|"+board[2][2]+"|");
System.out.println("-------------------");
}
public static boolean CalculateWinner(char[][] board){
boolean filled =false;
for(int column=0; column<=2; column++){
for(int row =0; row<=2; row++){
if (board[column][row]!='X'&& board[column][row]!='O'){
filled = false;
}
else
{ filled = true;
}
}
}
if (filled){
return true;
}else {
return false;
}
}
}

Related

Java: Error in code for a Recursive Maze for using Java

this code below is for a maze via recursion and is supposed to solve the maze. There are three different txt files that it reads from S is the start, G is the goal, X is a barrier and O is a free space
GOOOOXO //maze1
XXOXOOX
OXOOOXX
XXXOOXO
XXXXOXX
SOOOOOX
XXXXXXX
XOOOOXO //maze2
XXOXOOG
OXOOOXX
XXXOOOX
XXXXOXX
SOOOOOX
XXXXXXX
XOOOOXO //maze3
XXOXOXG
OXOOOXX
XXXOOOX
XXXXOXX
SOOOOOX
XXXXXXX
These are the mazes. maze1 and maze2 have a solution but every time I run it, it returns "unsolvable". I'm not sure where the error is. Here is the full code:
import java.util.ArrayList;
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class Maze2
{
private static char[][] maze;
private static int startrow, startcol, finishrow, finishcol;
private static ArrayList<String> mazeBuffer;
public static void initializeMaze(String fileName)
{
startrow = startcol = finishrow = finishcol = -1;
mazeBuffer = new ArrayList<String>();
int numcols = 0;
try
{
Scanner file = new Scanner(new File(fileName));
while(file.hasNext())
{
String nextLine = file.nextLine();
mazeBuffer.add(nextLine);
if (nextLine.length() > numcols)
numcols = nextLine.length();
}
}
catch(Exception e)
{
System.out.println(fileName + " has an issue");
}
int numrows = mazeBuffer.size();
maze = new char[numrows][numcols];
for (int r = 0; r < numrows; r ++)
{
String row = mazeBuffer.get(r);
for (int c = 0; c < numcols; c++)
{
if(row.length() >= c)
maze[r][c]=row.charAt(c);
else
maze[r][c]='*';
if (maze[r][c] == 'S')
{
startrow = r;
startcol = c;
}
if (maze[r][c] == 'G')
{
finishrow = r;
finishcol = c;
}
}
}
System.out.println("Maze loaded");
}
public static void printMaze()
{
for (char[] row: maze)
{
for (char c: row)
System.out.print(c);
System.out.println();
}
System.out.println();
}
public static void main (String[] args)
{
initializeMaze("maze3.txt");
printMaze();
if (solveMaze(startrow, startcol))
printMaze();
else
System.out.println("Unsolvable.");
}
public static boolean solveMaze(int r, int c)
{
if(r < 0 || c < 0 || r >= maze.length || c >= maze[0].length)
return false;
if(maze[r][c]=='G')
return true;
if (maze[r][c] != '0'|| maze[r][c] != 'S')
return false;
maze[r][c]='A';
if(solveMaze(r-1,c))
{
maze[r][c]= '#';
return true;
}
if(solveMaze(r+1,c))
{
maze[r][c]='#';
return true;
}
if(solveMaze(r,c-1))
{
maze[r][c]='#';
return true;
}
if(solveMaze(r,c+1))
{
maze[r][c]='#';
return true;
}
else{
return false;
}
}
}
If all is correct, mazes 1 and 2 should be solvable but as of now they are not for some reason. plz help it's a project due soon and I can't figure it out.
The problem lies in the condition if you are on a valid path.
The first error is, that you are checking for the number 0 instead of the capital letter O.
The second error is the combination of the two conditions. If you start at 'S' you are obviously not at an 'O'. So your condition tells you, that you are not on a valid path. The check should be:
if(!(maze[r][c] == 'O'|| maze[r][c] == 'S'))
If you fix this, everything should be working fine.

Java 2D Game NullPointerException [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I am trying to create a 2D game in Java where a user is prompted for a row width and column length. A 'world' object is created that looks like this when printed (where P is the player's character):
P---
----
----
----
The user can then enter up, down, left, right or exit which should move the P around and do nothing if the move would move the character off the map. My issue is after I enter the width and length, I get the following error:
java.lang.NullPointerException
at World.displayWorld(Driver.java:90)
at Driver.main(Driver.java:28)
I believe this means that Java is seeing worldDimensions.length as empty/null?? I thought I was assigning a value to it when the world object is created.. Any guidance is much appreciated!
Here's my code:
import java.util.Scanner;
public class Driver {
public static void main(String args[]) {
//Create a scanner object
Scanner input = new Scanner(System. in );
boolean exit = true;
//Prompt user to enter world width and height
System.out.print("World width: ");
int userWidth = input.nextInt();
System.out.print("World height: ");
int userHeight = input.nextInt();
//Create a world object
World world1 = new World(userWidth, userHeight);
world1.displayWorld();
System.out.println("Possible inputs: up, down, left, right, exit");
while (exit = true) {
//display world
world1.displayWorld();
System.out.print("ACTION > ");
String userAction = input.next();
if (userAction == "up" || userAction == "down" || userAction == "left" || userAction == "right" || userAction == "exit") {
switch (userAction) {
case "up":
world1.moveUp();
break;
case "down":
world1.moveDown();
break;
case "left":
world1.moveLeft();
break;
case "right":
world1.moveRight();
break;
case "exit":
exit = false;
break;
}
} else {
System.out.println("Invalid Input. Possible inputs are: up, down, left, right, or exit.");
}
}
}
}
class World {
static private char[][] worldDimensions;
static private int characterRow;
static private int characterColumn;
public World(int userWidth, int userHeight) {
char[][] worldDimensions = new char[userHeight][userWidth];
int characterRow = 0;
int characterColumn = 0;
for (int row = 0; row < worldDimensions.length; row++) {
for (int column = 0; column < worldDimensions[row].length; column++) {
if (characterRow == row && characterColumn == column) {
worldDimensions[row][column] = (char)
'P';
} else {
worldDimensions[row][column] = (char)
'-';
}
}
}
}
public void displayWorld() {
for (int row = 0; row < worldDimensions.length; row++) {
for (int column = 0; column < worldDimensions[row].length; column++) {
System.out.print(worldDimensions[row][column]);
}
System.out.println();
}
}
public void moveUp() {
if (characterRow - 1 >= 0) {
characterRow--;
}
}
public void moveDown() {
if (characterRow + 1 <= worldDimensions[0].length) {
characterRow++;
}
}
public void moveLeft() {
if (characterColumn - 1 >= 0) {
characterColumn--;
}
}
public void moveRight() {
if (characterRow + 1 <= worldDimensions.length) {
characterRow++;
}
}
}
You're shadowing worldDimensions inside of your constructor. The local declaration does not give you the same field as previously declared.
Simply remove the declaration and you'll be alright (at least for that error):
worldDimensions = new char[userHeight][userWidth];
You're overwriting your class variable worldDimensions. Your World constructor should look like the following
public World(int userWidth, int userHeight)
{
//here is where you were overwriting the global variable, leaving it null
//and populating the local one instead
worldDimensions = new char[userHeight][userWidth];
int characterRow = 0;
int characterColumn = 0;
for (int row = 0; row < worldDimensions.length; row++)
{
for (int column = 0; column < worldDimensions[row].length; column++)
{
if (characterRow == row && characterColumn == column)
{
worldDimensions[row][column] = (char)'P';
}
else
{
worldDimensions[row][column] = (char)'-';
}
}
}
}

CardPile Index Out of bounds

I'm currently trying to convert my code to ArrayList and I can't seem to make it work. I'm running the whole program and it tells me Index out bounds. I'm sure I forgot to add the size of the array for the cards, but I don't know how to add it. Thanks for the help!
Edit: The error I get is at the bottom. Also, it tells me to go to the removeTop method. It looks fine there.
import java.util.Random;
import java.util.List;
import java.util.ArrayList;
public class CardPile {
private ArrayList<Card> cards = new ArrayList<Card>();
private static Random r = new Random(1);
public void addToBottom(Card c) {
if (this.cards.size() == 52) {
System.out.println("The CardPile is full. You cannot add any more Card objects.");
}
this.cards.add(c);
}
public Card removeCard(Card c) {
if (this.cards.contains(c)) {
this.cards.remove(c);
}
return null;
}
public Card removeTop() {
return this.cards.remove(0);
}
public int searchValue(int value) {
int count = 0,
for (int i = 0;i < this.cards.size();i++) {
if (this.cards.get(i).getValue() == value) {
count++;
}
}
//System.out.println("Count = "+count);
return count;
}
public Card[] removeAll(int value)
//System.out.println("(removeAll) cards ="+ cards);
int count = searchValue(value);
Card[] removed = new Card[count];
int deletedCount = 0;
int i = 0;
while (deletedCount < count) {
if (this.cards.get(i).getValue() == value) {
removed[deletedCount] = this.cards.remove(i);
deletedCount++;
} else {
i++;
}
}
return removed;
}
public int getNumberCards() {
return this.cards.size();
}
public String toString() {
if (this.cards.isEmpty()) {
return "";
}
String builder = "";
for (int i = 0;i < this.cards.size() - 1;i++) {
builder = builder + this.cards.get(i) + ", ";
}
builder = builder + this.cards.get(this.cards.size() - 1);
return builder;
}
public void shuffle() {
if (this.cards.isEmpty()) {
return;
}
for (int count = 0; count < 100000;count++) {
int i = r.nextInt(this.cards.size());
int j = r.nextInt(this.cards.size());
Card temp = this.cards.get(i);
this.cards.set(i, this.cards.get(j));
this.cards.set(j, temp);
}
}
public static CardPile makeFullDeck() {
CardPile deck = new CardPile();
for (int suit = 0;suit < 4;suit++) {
for (int value = 1; value <= 13;value++) {
deck.addToBottom(new Card(suit, value));
}
}
deck.shuffle();
return deck;
}
}
**Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.remove(ArrayList.java:492)
at CardPile.removeTop(CardPile.java:40)
at GoFish.dealCards(GoFish.java:112)
at GoFish.main(GoFish.java:13)**
EDIT:
This is the Player class:
public class Player {
private boolean[] books;
private CardPile pile;
private static int MAXIMUM_VALUE_CARD = 13;
public Player()
{
this.pile = new CardPile();
this.books = new boolean[13]; //by default all are false
}
public boolean hasCard(int value)
{
return this.pile.searchValue(value) > 0;
}
public Card[] removeAll(int value)
{
return this.pile.removeAll(value);
}
public void addAll(Card[] cards)
{
for (int i = 0; i < cards.length; i++)
{
this.pile.addToBottom(cards[i]);
}
}
//optional additional method
public void addCard(Card card)
{
this.pile.addToBottom(card);
}
public int getNumberCards()
{
return this.pile.getNumberCards();
}
public int countBooks()
{
int count = 0;
for (int i = 0; i < MAXIMUM_VALUE_CARD; i++)
{
if (books[i])
{
count++;
}
}
return count;
}
public void addBook(int value)
{
this.books[value - 1] = true;
}
public void printHand()
{
System.out.println("Player's hand is " + this.pile);
}
}
And this is the GoFish class:
import java.util.Scanner;
public class GoFish {
private static Scanner reader;
public static void main(String[] args)
{
System.out.println("How many players?");
reader = new Scanner(System.in);
int numberPlayers = reader.nextInt();
Player[] players = createPlayersArray(numberPlayers);
int currentTurn = 0;
CardPile deck = CardPile.makeFullDeck();
dealCards(deck, players);
int maximumRetries = 2;
int numRetries = 0;
while(deck.getNumberCards() > 0 && players[currentTurn].getNumberCards() > 0)
{
updateBooks(players[currentTurn]);
if (numRetries == maximumRetries)
{
numRetries = 0;
currentTurn++;
if (currentTurn == numberPlayers)
{
currentTurn = 0;
}
}
System.out.println("Player " + currentTurn + ", here is your hand. What card would you like to ask for?");
players[currentTurn].printHand();
int queryCard = reader.nextInt();
System.out.println("And from whom would you like to get it from?");
int queryPlayer = reader.nextInt();
if (queryCard < 1 || queryCard > 13 || queryPlayer < 0 || queryPlayer >= numberPlayers || queryPlayer == currentTurn)
{
System.out.println("Invalid entries. Please retry");
numRetries++;
}
else
{
numRetries = 0;
boolean hasCard = players[queryPlayer].hasCard(queryCard);
if (hasCard)
{
System.out.println("Cards found!");
Card[] removed = players[queryPlayer].removeAll(queryCard);
players[currentTurn].addAll(removed);
}
else
{
System.out.println("Go fish!");
Card top = deck.removeTop();
System.out.println("You drew " + top);
players[currentTurn].addCard(top);
//check to make sure this extra card didn't form a book
//Note this could happen even if it doesn't match the card they were asking about
updateBooks(players[currentTurn]);
if (top.getValue() == queryCard)
{
System.out.println("You successfully went fishing!");
}
else
{
currentTurn++;
if (currentTurn == numberPlayers)
{
currentTurn = 0;
}
}
}
}
}
//calculate the winner now
int maxPlayer = 0;
int maxPlayerBooks = players[0].countBooks();
for (int i = 1; i < numberPlayers; i++)
{
int currentBooks = players[i].countBooks();
if (currentBooks > maxPlayerBooks)
{
maxPlayer = i;
maxPlayerBooks = currentBooks;
}
}
System.out.println("Congratulations! Player " + maxPlayer + " you have won the game by accumulating " + maxPlayerBooks + " books!");
}
private static Player[] createPlayersArray(int numPlayers)
{
Player[] players = new Player[numPlayers];
for (int i = 0; i < numPlayers; i++)
{
players[i] = new Player();
}
return players;
}
private static void dealCards(CardPile deck, Player[] players)
{
final int NUMBER_CARDS_PER_PLAYER = 7;
for (int i = 0; i < NUMBER_CARDS_PER_PLAYER * players.length; i++)
{
Card next = deck.removeTop();
players[i % players.length].addCard(next);
}
}
private static void updateBooks(Player player)
{
for (int i = 1; i <= 13; i++)
{
//alternative option would be to modify the hasCard method to return an int instead of boolean. Then we could just count (this is probably better design)
Card[] valued = player.removeAll(i);
if (valued.length == 4)
{
player.addBook(i);
}
else
{
player.addAll(valued);
}
}
}
}

Methods to display different table content, repeating header issue

I need to be able to use different methods in order to print out certain table content such as a sum, multiplication, or random table to name a few. I cannot figure out how to print out this content separate from the row ID. another problem I am having is when I enter "f" to reprint the table the header gets repeated each time I print it which just creates a very long repeating header after a few reprints, could someone help with this?
The original code will be followed by the IntTable class, it is not completely filled out which I am aware of but I want to figure this out before I move on.
import java.util.Scanner;
public class Assignment6{
public static String returnMenu(){
String menu = "Command Options---------------\na: Create a new table\nb: Change the row sizes\nc: Change the column sizes\nd: Change the data types\ne: Chnge the formats\nf: Display the table\ng: Display the log data\n:?: Display this menu\nq: Quit the program\n------------------------------";
return menu;
}
public static void main(String[] arg){
Scanner scan = new Scanner(System.in);
String input = "p";
String output = "NOOOOO!";
IntTable myTable = new IntTable();
while (!input.equals("q")){
System.out.println("Please input a command: ");
input = scan.nextLine();
if (input.equals("a")){
System.out.print("a [Input three integers to initialize table]: ");
myTable.setRow(scan.nextInt()); myTable.setColumn(scan.nextInt()); myTable.setType(scan.nextInt());
scan.nextLine();
myTable.printTable();
}
else if (input.equals("b")){
System.out.print("b [Enter integer to update table row]: ");
myTable.setRow(scan.nextInt());
scan.nextLine();
}
else if (input.equals("c")){
System.out.println("c [Enter integer to update column]: ");
myTable.setColumn(scan.nextInt());
scan.nextLine();
}
else if (input.equals("d")){
System.out.println("d [Enter integer to update data type]: ");
myTable.setType(scan.nextInt());
scan.nextLine();
}
else if (input.equals("e")){
System.out.println("e [Enter integer to update printf format]: ");
}
else if (input.equals("f")){
System.out.println("f [Display table]: ");
myTable.printTable();
}
else if (input.equals("g")){
System.out.println("g [Display data log]: ");
}
else if (input.equals("?")){
System.out.println(Assignment6.returnMenu());
}
else
System.out.println("Invalid: ***Type \"?\" to get the commands***");
}
}
}
public class IntTable{
private int row, column, type;
static String log, tFormat;
final int TYPE_DEFAULT = 0;
final int TYPE_NUMBERS = 1;
final int TYPE_SUM = 2;
final int TYPE_MULTIPLY = 3;
final int TYPE_RANDOM = 4;
final int TYPE_POWER = 5;
final int TYPE_FIBONACCI = 6;
String beginRow = " * |";
String divider = "-------";
int count = 1;
public IntTable(){
}
public IntTable(int row, int column, int type){
}
public int getRow(){
return row;
}
public int getColumn(){
return column;
}
public int getType(){
return type;
}
public void setRow(int newRow){
row = newRow;
}
public void setColumn(int newColumn){
column = newColumn;
}
public void setType(int newType){
type = newType;
}
public void printTable(){
int count = 1;
printTableHeader();
for(int i = 1; i <row+1; i++){
System.out.printf("%4d %4s", i, " |");
for (int j = 1; j < column+1; j++)
{
System.out.printf("%4d", count);
count++;
}
System.out.println();
}
}
private void printTableHeader(){
for(int i = 1; i < column + 1; i++)
{
beginRow+=" "+i;
divider+="-----";
}
System.out.println(beginRow);
System.out.println(divider);
}
private void printTableRowID(int ID){
ID = row;
for(int i = 1; i <ID+1; i++){
System.out.printf("%4d %4s", i, " |");
System.out.print(getElement(i, (row-(row-1))));
System.out.println();
}
}
private int getElement(int c, int r){
if(type == 0)
return 0;
else if(type == 1)
return c+column;
else if(type == 2)
return c+ r;
else if(type == 3)
return c*r;
else if(type == 4)
return (int)(1 + Math.random()*10);
else if(type == 5)
return (int)Math.pow(r, c);
else
return r;
}
private int pow(int one, int two){
return (int)Math.pow(one, two);
}
private int fibonacci(int fib){
return fib;
}
private int sum(int add, int addd){
return add + addd;
}
private int multiply(int prod, int product){
return prod * product;
}
private int random(int what, int huh){
return (int)(what + Math.random()*huh);
}
}
the reason why header repeating is because you do not reinitialize variable(beginRow and divider)
when you call printTable Method, variable String beginRow = " * |"; String divider = "-------"; is redefined
you need to reintialize variable(beginRow, divider)
look fllowing code which i modified
private void printTableHeader()
{
for(int i = 1; i < column + 1; i++)
{
beginRow+=" "+i;
divider+="-----";
}
System.out.println(beginRow);
System.out.println(divider);
beginRow = " * |";
divider = "-------";
}

Program never ends [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm not sure what's going on, but in the console I have a red 'stop' square that i can click to stop my program from running (Eclipse IDE) and my program is just running and the square stays red..?
EDIT:
my maze:
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WSOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOWOOOOOOW
WWOOOOOOOOOOOOOWWWWWWWWWWWWWOOOOOOOOOOWWWWWWWWWWWWWOOOOOOW
WWWWWWOOOOOOOOOOOOWWWWWWWOOOOOOOOOOOOWWWWWWWWWWWWWWWWOOOOW
WOOOOOOWWWWWWWWWWWWWWOOOOOOOOOOOWWWWWWWWOOOOOOOOOOOOOOOWWW
WOOOOWWWWWWWOOOOOOWWWWOOOOOOWWWWWWWWWWWOOOOWWWWWWWWWOWWWWW
WOOOWWWWWWWWWWWWOOWWWWWWWWWWWWOOOOOOOOOOOOWWWWWWWWWOOOOOWW
WOOWWWWWWWWWWWWWOOWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWWOOOW
WOWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWOOW
WOWWWWWWWWWWWWWOOOOOOOOOOOOOOOOOOOOOOOOOOOOWWWWWWWWWWWWOOW
WOOOOOOOOOOOOOOOOWWWWOOOOOOOOWWWWWWWOOOOOOWWWWWWWWWWWWWWFW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
EDIT: here is my code:
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;
nextPoints.push(current);
do {
if(current.y < 11) {
if((mazePoints[current.y + 1][current.x] != ' ') && (mazePoints[current.y + 1][current.x] != 'W') ){ // below direction
nextPoints.push(new Point(current.y + 1, current.x));
mazePoints[current.y + 1][current.x] = ' ';
isTraversable(nextPoints.pop());
}
}
if(current.y > 0){
if (mazePoints[current.y - 1][current.x] != ' ' && mazePoints[current.y - 1][current.x] != 'W' ){ //up dir
nextPoints.push(new Point(current.y - 1, current.x));
mazePoints[current.y - 1][current.x] = ' '; //'X' marks where you've already been
isTraversable(nextPoints.pop());
}
}
if(current.x < 57){
if(mazePoints[current.y][current.x + 1] != ' ' && mazePoints[current.y][current.x + 1] != 'W'){ // to the right
nextPoints.push(new Point(current.y, current.x + 1));
mazePoints[current.y][current.x + 1] = ' ';
isTraversable(nextPoints.pop());
}
}
if(current.x > 0){
if(mazePoints[current.y][current.x - 1] != ' ' && mazePoints[current.y][current.x - 1] != 'W') { // to the left
nextPoints.push(new Point(current.y, current.x - 1));
mazePoints[current.y][current.x - 1] = ' ';
isTraversable(nextPoints.pop());
}
}
if(current.equals(finishPoint)){
isSolvable = true;
System.out.println("MAZE IS SOLVABLE, YAHOOOOOO!!!!");
}
} while(!current.equals('F') && !nextPoints.isEmpty());
return isSolvable;
}
}
As I suggested before, you just need to reconfigure your recursive method. I took the liberty of doing this but if you ever want to learn how to program you'll want to try and solve problems like these on your own. Or try to understand the logic of your solution before you start coding.
Your main problem is that you don't know what direction you want to go in with the method before you just jumped in and that was causing all sorts of errors with different things not being compatible with each other.
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 TestCode {
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);
}
}
}
System.out.println(isTraversable(startPoint));
}
public static boolean isTraversable(Point current){
mazePoints[current.x][current.y] = ' ';
if(current.y < 56 && current.y > 0 && current.x > 0 && current.x < 11){
if (mazePoints[current.x - 1][current.y] == 'O'){ // Up dir
Point upPoint = new Point(current.x-1, current.y);
nextPoints.push(upPoint);
}
if(mazePoints[current.x+1][current.y] == 'O'){ // Down dir
Point downPoint = new Point(current.x+1, current.y);
nextPoints.push(downPoint);
}
if(mazePoints[current.x][current.y + 1] == 'O'){ // to the right
Point rightPoint = new Point(current.x, current.y+1);
nextPoints.push(rightPoint);
}
if(mazePoints[current.x][current.y - 1] == 'O'){ // to the left
Point leftPoint = new Point(current.x, current.y-1);
nextPoints.push(leftPoint);
}
if(mazePoints[current.x - 1][current.y] == 'F' ||
mazePoints[current.x + 1][current.y] == 'F' ||
mazePoints[current.x][current.y - 1] == 'F' ||
mazePoints[current.x][current.y + 1] == 'F'){
System.out.println("MAZE IS SOLVABLE, YAHOOOOOO!!!!");
return true;
}
}
if(nextPoints.isEmpty()){
return false;
}
else{
current = nextPoints.pop();
}
return(isTraversable(current));
}
}
With the maze input:
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WSOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOWOOOOOOW
WWOOOOOOOOOOOOOWWWWWWWWWWWWWOOOOOOOOOOWWWWWWWWWWWWWOOOOOOW
WWWWWWOOOOOOOOOOOOWWWWWWWOOOOOOOOOOOOWWWWWWWWWWWWWWWWOOOOW
WOOOOOOWWWWWWWWWWWWWWOOOOOOOOOOOWWWWWWWWOOOOOOOOOOOOOOOWWW
WOOOOWWWWWWWOOOOOOWWWWOOOOOOWWWWWWWWWWWOOOOWWWWWWWWWOWWWWW
WOOOWWWWWWWWWWWWOOWWWWWWWWWWWWOOOOOOOOOOOOWWWWWWWWWOOOOOWW
WOOWWWWWWWWWWWWWOOWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWWOOOW
WOWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWOOW
WOWWWWWWWWWWWWWOOOOOOOOOOOOOOOOOOOOOOOOOOOOWWWWWWWWWWWWOOW
WOOOOOOOOOOOOOOOOWWWWOOOOOOOOWWWWWWWOOOOOOWWWWWWWWWWWWWOFW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
Yields the following output:
So, you want to know if your maze is solvable.....?
MAZE IS SOLVABLE, YAHOOOOOO!!!!
true
I imported the file a different way, but you can change that back to whatever method you use previously.
Might be that you've started multiple programs and you have the "Show Console When Standard Output Changes" Not sure, but that explains one scenario. If you start task manager and find the program there you could try terminating it that way.
If it's stuck running and never completes you could try running your program in the Eclipse debugger, without any breakpoints.
Open the Debug tab (Open in from Window > Show View > Debug), suspend the thread by right clicking 'Thread [main] (Running)' and selecting 'Suspend'.
Then work your way up from the bottom of the stack, hopefully this will narrow it down enough for you to find where it blocks.
import java.util.Scanner;
import java.util.Stack;
public class test5 {
private int numRows;
private int numCols;
public test5(){
Scanner input = new Scanner(System.in);
System.out.println("Enter number of rows: ");
numRows = input.nextInt();
System.out.println("Enter number of cols: ");
numCols = input.nextInt();
Stack<Point>stack = new Stack<Point>();
stack.push(new Point(0,0));
while(!stack.isEmpty()){
if(currentPath(stack.pop(),stack)){
System.out.println("Maze is solvable");
}
}
}
public static void main(String[]args){
new test5();
}
private boolean currentPath(Point point, Stack<Point>stack){
int currentRow = point.getRow();
int currentCol = point.getCol();
while(currentRow!=numRows-1 || currentCol!=numCols-1){
boolean canGoRight = canGoRight(currentRow,currentCol);
boolean canGoUp = canGoUp(currentRow,currentCol);
boolean canGoDown = canGoDown(currentRow,currentCol);
if(canGoRight){
if(canGoUp){
stack.push(new Point(currentRow-1,currentCol));
}
if(canGoDown){
stack.push(new Point(currentRow+1,currentCol));
}
currentCol = currentCol+1;
}
else{
if(canGoUp){
if(canGoDown){
stack.push(new Point(currentRow+1,currentCol));
}
currentRow = currentRow-1;
}
else if(canGoDown){
currentRow = currentRow+1;
}
else{
return false;
}
}
}
return true;
}
private boolean canGoUp(int row, int col){
return row-1>=0;
}
private boolean canGoRight(int row, int col){
return col+1<numCols;
}
private boolean canGoDown(int row, int col){
return row+1<numRows;
}
class Point{
private int row;
private int col;
public Point(int row, int col){
this.row = row;
this.col = col;
}
public int getRow(){
return row;
}
public int getCol(){
return col;
}
}
}

Categories