I'm making a game for a project due this Tuesday. You're in a dungeon with rows and columns, and for each coordinate there is a cell and there are 3 trap cells that you instantly die from if you walk into them. Also, you die if you hit 3 walls.

For debugging purposes, I worked out a grid printing system, and various things that tell you where the player is, cell #, cell coordinates, player coordinates, etc, so I know exactly where everything is. In the final version, there will be no grid and none of that.

Everything ATM, works how I want it to, except for ONE thing. If a trap or the player gets placed in Column 0, Row 4 its cell number gets increased by anywhere from 1 to 3, sharing a cell number with another one of the cells, and I have no idea why this happens. I've tried putting in countermeasures for this, but they don't seem to take effect.

I used to have a working system where it displayed on the grid the character's position every time I moved and all of the traps' positions, but now it only displays either if it's in the glitched cell.

Here is the entire program, 5 files zipped up in a .rar:

http://www.sendspace.com/file/t3rsxj

The problem files are DungeonMaze.java, Player.java and Cells.java. I apologize if it's messy. Also, ignore the various profanities placed about, it's from anger. They're not gonna be there when I turn this in. :P

I'm in desperate need of help, guys. I'm VERY beginner with Java (since our teacher "teaches" us jack squat) so there may be some very noobish mistakes. Anything is appreciated! Thank you!

This program does not compile for me. Below is the code for StartGame.

import java.util.Scanner;

public class StartGame {

	public void StartGame(String name, int r, int c) {

		Scanner input = new Scanner(System.in);

		Player player1 = new Player();
		DungeonMaze dungeon = new DungeonMaze();
		Cells[] cellArray = new Cells[r*c];
		dungeon.populateGrid(r,c, cellArray);
		cellArray = dungeon.getCellArray();
		player1.setCell(dungeon.getNumCells()); //Place player in a random cell
		player1.setPlayerPosX(cellArray);
		player1.setPlayerPosY(cellArray);

		dungeon.printGrid(r,c,(player1.getPlayerPosX()),(player1.getPlayerPosY()));
		System.out.print("\nPlayer's current position = Col " + (player1.getPlayerPosX()) + ", Row " + (player1.getPlayerPosY()));
 		dungeon.printCoords(r,c,(player1.getPlayerPosX()),(player1.getPlayerPosY()));

		System.out.println("\nPlayer's coordinates = (" + player1.getPlayerPosX() + ", " + player1.getPlayerPosY() + ")");
		System.out.print("\nWhich cell do you want to find the value of?: ");
		int choice = input.nextInt();

			while(choice > r*c || r <= 0) {

						System.out.print("Please enter a cell between 1-" + r*c + ": ");
						choice = input.nextInt();

				}

		System.out.println("\nCell " + choice + " is Cell #" + dungeon.CellArrayTester(cellArray, choice));

	}

}

Problem lines are 18 and 20. Error messages are below:

Compiling 6 source files...
StartGame.java:18: printGrid(int,int,int,int,Player,Cells[]) in DungeonMaze cannot be applied to (int,int,int,int)
dungeon.printGrid(r,c,(player1.getPlayerPosX()),(player1.getPlayerPosY()));
^
StartGame.java:20: cannot find symbol
symbol : method printCoords(int,int,int,int)
location: class DungeonMaze
dungeon.printCoords(r,c,(player1.getPlayerPosX()),(player1.getPlayerPosY()));
^
2 errors

The error in line 18 is spelled out in the error message. Your function takes six parameters (see red above). You only provide four parameters in the function call (see line 18 and green above).

Line 20 - Where is the printCoords function?

OH, crap I didn't know that file was still in the .rar. Delete StartGame.java, it's an old file that's useless now.

OH, crap I didn't know that file was still in the .rar. Delete StartGame.java, it's an old file that's useless now.

OK, it runs now. Here's a run:

run:
Please enter your name: Bob
How many rows? (1-20): 5
How many columns? (1-20): 3
Please specifff.........you fall asleep.

Cell Array size = 15
Cell #s: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Giving traps cell numbers from 0 to 14...
REROLLING
Giving traps cell numbers from 0 to 14...
Giving traps cell numbers from 0 to 14...

=====TRAP POSITIONS=====
Trap 0 : CellNo = 8, Col 2, Row = 2
Trap 1 : CellNo = 11, Col 2, Row = 3
Trap 2 : CellNo = 12, Col 0, Row = 4

0[0]1[1]2[2] ;Row #0 NumCells = 3 NLC LR
3[0]4[1]5[2] ;Row #1 NumCells = 6 NLC LR
6[0]7[1]8[2] ;Row #2 NumCells = 9 NLC LR
9[0]10[1]11[2] ;Row #3 NumCells = 12 NLC LR
12[T]13[1]14[2] ;Row #4 NumCells = 15 LCLR

Player's current cell number = 4
Player's current position = Col 1, Row 1

Which cell do you want to find the coordinates of? (0-14):

Everything ATM, works how I want it to, except for ONE thing. If a trap or the player gets placed in Column 0, Row 4 its cell number gets increased by anywhere from 1 to 3, sharing a cell number with another one of the cells, and I have no idea why this happens. I've tried putting in countermeasures for this, but they don't seem to take effect.

I think you are going to explain what all this means and what it should look like versus what it looks like. There is a trap at row 4, column 0, as you mention in your first post (see red). But what are we looking at here?

>_<

Another thing I forgot. I've been using a 5 by 5 grid this whole time. Sorry I left that out, I was just so used to it being 5 x 5 I forgot about the additional possibilities.

I don't know how you got the trap cell number right, though. I tried the exact same values and got:

=====TRAP POSITIONS=====
Trap 0 : CellNo = 6, Col 0, Row = 2
Trap 1 : CellNo = 13, Col 0, Row = 4
Trap 2 : CellNo = 5, Col 2, Row = 1

0[0]1[1]2[2] ;Row #0 NumCells = 3 NLC LR
3[0]4[1]5[2] ;Row #1 NumCells = 6 NLC LR
6[0]7[1]8[2] ;Row #2 NumCells = 9 NLC LR
9[0]10[1]11[2] ;Row #3 NumCells = 12 NLC LR
13[T]13[1]14[2] ;Row #4 NumCells = 15 LCLR

That first 13 should be a 12.

Oh, also, from your post you can see that the player is in Cell 4, which is in row 1 column 1, but it's supposed to print out an [X] there instead of the [1]. And notice how it's not printing out the location of the other 2 traps. It's not doing that anymore, which is also another bug.

I can't make heads or tails of your printGrid function. I'm not 100% sure what it's supposed to display, but if it's supposed to do what I think it's supposed to do, when I rewrote printGrid, it appears to give the right values (again, that's if I understand it correctly).

run:
Please enter your name: Bob
How many rows? (1-20): 5
How many columns? (1-20): 6
Please specifff.........you fall asleep.

Cell Array size = 30
Cell #s: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Giving traps cell numbers from 0 to 29...
Giving traps cell numbers from 0 to 29...
Giving traps cell numbers from 0 to 29...

=====TRAP POSITIONS=====
Trap 0 : CellNo = 13, Col 1, Row = 2
Trap 1 : CellNo = 15, Col 3, Row = 2
Trap 2 : CellNo = 17, Col 5, Row = 2

0[0]1[1]2[2]3[3]4[4]5[5]
6[0]7[1]8[2]9[3]10[4]11[5]
12[0]13[T]14[X]15[T]16[4]17[T]
18[0]19[1]20[2]21[3]22[4]23[5]
24[0]25[1]26[2]27[3]28[4]29[5]

Player's current cell number = 14
Player's current position = Col 2, Row 2

Which cell do you want to find the coordinates of? (0-29):

Is this the proper run?

:O

Yes! That's a perfect run!

I'd like to know very much what you did there. :O

Also, if you're feeling ambitious, you could uncomment the call for the MoveCharacter method and move to the bottom left cell and see if your X moves where it's supposed to go when trying to move AWAY from the bottom left cell. Valid directions for the method are any words starting with N,S,E,W (North, South, East, West), case doesn't matter.

:O

Yes! That's a perfect run!

I'd like to know very much what you did there. :O

Well, you said that the grid was only for debugging purposes and you were going to get rid of it later, so I guess it's OK to give the revised code to you. I think the code you had was overly-complicated before. All that is needed is a nested for-loop and some if statements. Here's the printGrid function that I used. Replace yours with it.

public void printGrid(int numRows2, int numCols2, int p1posx, int p1posy, Player player1, Cells[] trap)
    {
        for (int y = 0; y < numRows2; y++)
        {
            for (int x = 0; x < numCols2; x++)
            {
                System.out.print (y * numCols2 + x);

                if (x == p1posx && y == p1posy)
                    System.out.print ("[X]");
                else if (y == trap[0].getCellPosY() && x == trap[0].getCellPosX())
                    System.out.print ("[T]");
                else if (y == trap[1].getCellPosY() && x == trap[1].getCellPosX())
                    System.out.print ("[T]");
                else if (y == trap[2].getCellPosY() && x == trap[2].getCellPosX())
                    System.out.print ("[T]");
                else
                    System.out.print ("[" + x + "]");
            }

            System.out.println ("");
        }
    }

*facepalm*

Holy crap that's simple. Thanks for introducing me to a new concept. I never would have guessed that a double for loop could be the solution. Thanks so much! :D

EDIT: Ok, weird new problem. I pasted over my whole print grid method with your new one, and it works great now. But I ran into a weird issue. This:

=====TRAP POSITIONS=====
Trap 0 : CellNo = 22, Col 0, Row = 4
Trap 1 : CellNo = 21, Col 0, Row = 4
Trap 2 : CellNo = 23, Col 0, Row = 4

0[0]1[1]2[2]3[3]4[4]
5[0]6[1]7[2]8[3]9[4]
10[0]11[1]12[2]13[3]14[4]
15[0]16[X]17[2]18[3]19[4]
20[T]21[1]22[2]23[3]24[4]

For some reason, it made all of the traps' coordinates the bottom left cell, but they all had different cell numbers. And get this: I COULD ENTER THE BOTTOM LEFT CELL AND NOTHING WOULD HAPPEN! However, going into cell 21 resulted in death!

Also, I enabled my MoveCharacter method, and did a new run where there was no trap in the bottom left cell, but when I stepped south into the bottom RIGHT cell then tried to move WEST, it rocketed me all the way over to the bottom left cell.

ALSO, I did another run of the program, and the player got set into the bottom left cell (cell 20), but it says he's in cell 24! WTF!

0[0]1[1]2[2]3[3]4[4]
5[0]6[1]7[T]8[3]9[4]
10[0]11[1]12[2]13[T]14[4]
15[0]16[1]17[T]18[3]19[4]
20[X]21[1]22[2]23[3]24[4]

Player's current cell number = 24
Player's current position = Col 0, Row 4

What the heck is happening here?

Best guess, and it's only a guess, is that in the DungeonMaze.setTraps function, you are "rerolling" because you have some collision (i.e. a trap is picked randomly to be at the same spot as another trap or the same as the player position). You then "reroll" and change the cell number, but you DON'T change the row and column.

If you insist on storing both the cell number and the cell's position, make sure that when you set one, you set the other. You might want to have a function that calculates the cell number from the row and column and number of columns (you may have that already) and a function that checks to make sure everything checks out:

// these functions inside Cells class

public int calculateCellNumber (int numCols)
{
    return posy * numCols + posx;
}

public boolean checkValidity (int numCols)
{
    if (this.calculateCellNumber (numCols) == cellNumber)
        return true;
    
    return false;
}

You can check your traps:

for (int i = 0; i < 3; i++)
{
    if (!trap[i].checkValidity (numCols))
        System.out.println ("Problem!");
}

As I said, that's my guess of what's going on. cellNumber is changing, but posx an posy are not changing with it, or vice versa. Your setTraps function looks overly complicated to me. I'm guessing that the problem is in there.

One way to get a hint is to see how often this occurs. Make a big grid (20 x 20) and a small grid (4 x 4) and count how many times this bug occurs. If it happens much more often in the small grid, then it's probably a collision issue (you're picking 4 spaces out of 16 randomly rather than 4 spaces out of 400). You would expect many more collisions picking 4 out of 16 than picking 4 out of 400.

Comments
That's an intelligent suggestion.

Damn, thanks for all the help, Vernon! I couldn't have done this without you!

I took your advice and rewrote the set traps method, and with a LOOOOT of tweaking, everything prints correctly and everything operates the way it's supposed to, and my program finally works the way my teacher intended. There's a prize system now and you can win the game! :D HOWEVER!

I added a basic little thing to set a "mode". However, setting this mode breaks the program for some reason. :S The problem is in the Game class. Here's the whole Game class:

import java.util.Scanner;

public class Game {

	public void StartGame(String name, int r, int c) {

		Scanner input = new Scanner(System.in);

		Player player1 = new Player();
		DungeonMaze dungeon = new DungeonMaze();
		Cells[] cellArray = new Cells[r*c];
		Cells[] trap = new Cells[3];
		Cells[] prize = new Cells[3];

		dungeon.populateGrid(r,c,cellArray,player1); //Makes the cell array, creates all cells

		cellArray = dungeon.getCellArray();

		player1.setArray(cellArray); //Give player same array for reference
		player1.setRandomCell(dungeon.getNumCells()); //Place player in a random cell
		player1.setPlayerPosX(cellArray);
		player1.setPlayerPosY(cellArray);

		dungeon.setTraps(player1); //Set traps
		trap = dungeon.getTrapArray(); //Get trap array

		dungeon.setPrizes(player1); //Set prizes
		trap = dungeon.getPrizeArray(); //Get prizes array

		System.out.print("\nSet mode difficulty (1: SUPER EASY - Grid display) (2: NIGHTMARE MODE - No grid display): ");
		int grid = input.nextInt();

			while(grid > 2 || grid < 1) {

				System.out.print("Please enter either 1 or 2: ");
				grid = input.nextInt();

			}


		if (grid == 1) dungeon.printGrid(r,c,player1.getPlayerPosX(),player1.getPlayerPosY(), player1, dungeon.getTrapArray(), dungeon.getPrizeArray());
		//System.out.println("\nPlayer's current cell number = " + player1.getCellNumber());
		//System.out.println("Player's current position = Col " + (player1.getPlayerPosX()) + ", Row " + (player1.getPlayerPosY()));

		//System.out.println("\nPlayer's coordinates = (" + player1.getPlayerPosX() + ", " + player1.getPlayerPosY() + ")");

		MoveCharacter(input, dungeon, player1, r, c, grid, cellArray);

	}

	public void MoveCharacter(Scanner input, DungeonMaze dungeon, Player player1, int r, int c, int grid, Cells[] cell) {

		int wallHits = 0;

		while (wallHits < 3 && !(cell[player1.getCellNumber()].hasTrap) && !(player1.winGame())) {

			/*System.out.print("\nWhich cell do you want to find the coordinates of? (0-" + ((r*c) - 1) + "): ");
			int choice = input.nextInt();

				while(choice >= r*c || r < 0) {

					System.out.print("Please enter a cell between 0-" + ((r*c) - 1) + ": ");
					choice = input.nextInt();

				}

			System.out.println("Cell " + choice + " is at (" + cell[choice].getCellPosX() + ", " + cell[choice].getCellPosY() + ")");*/

			System.out.print("\nWhich direction would you like to move?: ");
			String dir = input.nextLine();

			char d = dir.charAt(0);
			dir = Character.toString(d);
			//System.out.println("Direction = " + dir);

			if (dir.equals("e") || dir.equals("E") || dir.equals("w") || dir.equals("W")) player1.MoveX(dir,r,c);

			if (dir.equals("n") || dir.equals("N") || dir.equals("s") || dir.equals("S")) player1.MoveY(dir,r,c);

			if (grid == 1) dungeon.printGrid(r,c,(player1.getPlayerPosX()),(player1.getPlayerPosY()), player1, dungeon.getTrapArray(), dungeon.getPrizeArray());
			//System.out.println("Player's current cell number = " + player1.getCellNumber());
			//System.out.println("Player's current position = Col " + (player1.getPlayerPosX()) + ", Row " + (player1.getPlayerPosY()));
			wallHits = player1.getWallHits();
			System.out.println("Wall hits = " + wallHits);

		}

		if (wallHits == 3) {
		System.out.println("HITTING YOUR HEAD ON SO MANY WALLS CAUSES YOU TO PASS OUT.");
		System.out.println("THE ALLIGATOR EVENTUALLY FINDS YOU EATS YOU.");
		}

		if (player1.winGame()) {

			System.out.println("");
			System.out.println("--!!CONGRATULATIONS!!--");
			System.out.println("You've collected all 3 prizes, and you illuminate the path to the way out!");
			System.out.println("YOU WIN!!");
			System.out.println("");
		}

		else System.out.println("------- GAME OVER -------");

	}

}

This section for the "mode" is this:

System.out.print("\nSet mode difficulty (1: SUPER EASY - Grid display) (2: NIGHTMARE MODE - No grid display): ");
int grid = input.nextInt();

while(grid > 2 || grid < 1) {

System.out.print("Please enter either 1 or 2: ");
grid = input.nextInt();

}

and this:

System.out.print("\nWhich direction would you like to move?: ");
String dir = input.nextLine();

char d = dir.charAt(0);
dir = Character.toString(d);

is what I believe to be causing the problem. The program compiles and runs, but right after the direction question, it gives me this error:

Which direction would you like to move?: Exception in thread "main" java.lang.StringIndexOutOfBounds
Exception: String index out of range: 0
at java.lang.String.charAt(String.java:687)
at Game.MoveCharacter(Game.java:72)
at Game.StartGame(Game.java:47)
at Main.main(Main.java:35)

No idea what's causing this. Probably something above my head.

Which direction would you like to move?: Exception in thread "main" java.lang.StringIndexOutOfBounds

The fact that the error is in the same line as the question display suggests that there is no pause for user input (whether there is or not is important information that you should include in your post in the future). input is probably reading in an empty string and not pausing for the user because it doesn't think it needs to. It reads the next integer from the stream and there is still the carriage return left over that the user entered. Try adding another input.nextLine() command in there that will eat up that carriage return and wait for user input.

System.out.print("\nWhich direction would you like to move?: ");

// two nextLine commands.
input.nextLine(); // clear excess carriage return
String dir = input.nextLine(); // read user input

char d = dir.charAt(0);
dir = Character.toString(d);

See if this is the issue. I am assuming that I am correct that there is no pause for user input.

And that did it! I put that input.nextLine(); right before the MoveCharacter() call, and my program runs flawless now!

Thanks for everything Vernon! Couldn't have done it without you! I believe I can finally mark this as solved!

See you later! :D

This question has already been answered. Start a new discussion instead.