maggie
maggie

Reputation: 59

simple maze game in java

I am creating a simple maze game in java. The code reads a data file and assigns it to a String array. The player inputs what direction he or she would like to go in and each position contains a certain number of points (0, 1, or 2) that corresponds to the obstacleNumber (0, 1, or 2). I want to keep track of the points as well as the number of times the player has moved but I cannot figure out where to call my methods to make sure that the counting is correct. I'm sorry if this is a really stupid question but I am new to java!

The array is being filled correctly but I cannot count the moves and points.

    import java.util.*; 
    import java.io.File;

    public class Program12
     {

 static public void main( String [ ] args ) throws Exception
 {

     if(args.length != 1) {
         System.out.println("Error -- usage is: java Lab11 roomData.txt"); 
         System.exit(0); 
     }

    File newFile = new File(args[0]); 
    Scanner inputFile = new Scanner(newFile);       

    int numberOfRows = inputFile.nextInt();
    int numberOfColumns = inputFile.nextInt();  

    Room[][] game; 

    game = new Room[numberOfRows][numberOfColumns]; 
    int rowNumber = 0; 
    int columnNumber = 0; 

    int moves = 0;
    int points = 0;


    for(int i = 0; i < numberOfRows; i++) 
    {
        for (int j = 0; j < numberOfColumns; j++) 
        {
            String obstacle = inputFile.nextLine(); 
            int obstacleNumber = inputFile.nextInt(); 

            Room room = new Room(obstacle, obstacleNumber); 

            game[i][j] = room;

        }
        System.out.println(); 
        countPoints(obstacleNumber, points);

    }


    while(true) 
    {
        printPlayerLocation(numberOfRows, numberOfColumns, rowNumber, columnNumber);

        System.out.println();
        System.out.print("Enter up, down, left, or right to move:  ");
        Scanner userInput = new Scanner(System.in);
        String in = userInput.nextLine();
        if(in.equals("left") || in.equals("right") || in.equals("up") || in.equals("down"))
        {
            if (in.equalsIgnoreCase("up"))  
            { 
                rowNumber = rowNumber - 1; 
            } 

            if (in.equalsIgnoreCase("down")) 
            {           
                rowNumber = rowNumber + 1; 
            } 

            if (in.equalsIgnoreCase("left"))  
            {   
                columnNumber = columnNumber - 1;  
            } 

            if (in.equalsIgnoreCase("right"))  
            {   
                columnNumber = columnNumber + 1; 
            }
        }
        else
        {
            System.out.println("Input invalid! Please enter up, down, left, or right.");
        }

        try 
        {
            System.out.println(game[columnNumber][rowNumber].toString());
        }

        catch (ArrayIndexOutOfBoundsException e)
        {
            System.out.println("You cannot leave the boardwalk during the hunt! Please start over.");
            System.exit(0);     
        }

        countMoves(in, moves);
        //countPoints(obstacleNumber, points);
    }        
}

    public static void printPlayerLocation(int numberOfRows, int numberOfColumns, int rowNumber, int columnNumber)
    {
        System.out.println();
        System.out.print("***** PLAYER LOCATION *****");
        String[][] game = new String[numberOfRows][numberOfColumns];
        for (int i = 0; i < numberOfRows; i++)
        {
            for (int j = 0; j < numberOfColumns; j++)
            {
                game[i][j] = "*";
            }   
        }

        game[rowNumber][columnNumber] = "P";

        for (int i = 0; i < numberOfRows; i++)
        {
            System.out.println();
            for (int j = 0; j < numberOfColumns; j++)
            {
                System.out.printf("%-5s", game[i][j]);
            }   
        }
        System.out.println();
    }

    //doesn't correctly count the moves
    public static void countMoves(String in, int moves)
    {
        if(in.equals("left") || in.equals("right") || in.equals("up") || in.equals("down"))
        {
            moves++;
        }
        System.out.println("You have used " + moves + " moves.");
    }

    //doesn't correctly count the points
    public static void countPoints(int obstacleNumber, int points)
    {
        if(obstacleNumber == 0)
        {
            points = points;
        }
        if(obstacleNumber == 1)
        {
            points++;
        }
        if(obstacleNumber == 2)
        {
            points = points + 2;
        }
        System.out.println("You have obtained " + points + " points so far. Keep hunting!");
    }

The data file has the size of the array (4 4) and an obstacleNumber and obstacle

    0 this obstacleNumber would award 0 points
    1 this obstacleNumber would award 1 point
    2 this obstacleNumber would award 2 points

16 times to fill the array.

I would like the sample output to print the player location (which it does correctly), ask the user to input a direction (which it does correctly), print the text in the data file (again already done) and then print the number of moves already used and the amount of points the player has gained so far.

How do you correctly calculate the number of times the user typed "up, down, right, or left" and how many points does the user have so far? Thank you in advance for your help I sincerely appreciate your time.

Upvotes: 0

Views: 12300

Answers (3)

patrick.elmquist
patrick.elmquist

Reputation: 2140

I might be wrong here (early in the morning...) but I'm guessing you always get the same moves and points value? This is because you are not increasing the values of the actual moves and points. When you send an Int as a parameter to a method you are not sending a pointer to the Int but a copy of it which will be used by the method and then removed when leaving it. You need to either return moves and points after increasing the values or put them as static attributes. Try doing it this way instead:

...
moves = countMoves(String in, int moves);
...

public static int countMoves(String in, int moves) {
    if(in.equals("left") || in.equals("right") || in.equals("up") || in.equals("down")) {
        moves++;
    }
    System.out.println("You have used " + moves + " moves.");
    return moves;
}

Or you could increase them when identifying the moving direction (which is more efficient since you don't have to redo the check if the move was valid):

if (in.equalsIgnoreCase("up")) { 
    rowNumber = rowNumber - 1; 
    moves++;
}
...

EDIT
Points Problem:
Since you didn't post how Room is implemented I just improvise, but I figure it should look something like this:

...  
points = countPoints(game[rowNumber][columnNumber].getObstacleNumber(), points);
...

and change countPoints() to:

public static int countPoints(int obstacleNumber, int points) {
        if(obstacleNumber == 0) points = points;
        if(obstacleNumber == 1) points++;
        if(obstacleNumber == 2) points += 2;

        System.out.println("You have obtained " + points + " points so far. Keep hunting!");
        return points;
    }

or just (provided you know that the input is correct):

public static int countPoints(int obstacleNumber, int points) {
        points += obstableNumber;
        System.out.println("You have obtained " + points + " points so far. Keep hunting!");
        return points;
    }

Upvotes: 1

juanmirocks
juanmirocks

Reputation: 6181

In Java, arguments to methods are always passed by value. It can get confusing with objects though. But with primitive types like int it's very simple. To the functions countMoves and countPoints you are only giving the value of the moves and points, respectively, but not their reference. That is, the methods are working in fact with another variable. This variable is initialized to the value you give in and you can change it as you want, but the changes made to this variable are only visible to the method. Therefore in order to make the changes visibile to the outer variables you must reset their values. For instance you could do this:

public static int countMoves(String in, int moves) {
       //... change the value of moves as you want
       return moves; //return the new value
}

And then use the method like:

moves = countMoves(in, moves);

Where the set variable is the one you define in main. Analogously for countPoints. Another possibility would be to define moves and points in the class Program12 and make the methods count methods modify these variables directly without passing them, like:

public static void countMoves(String in) {
    moves = ...
}

In this case the moves moves defined in Program12 is visible to the countMoves and so you are changing directly the variable you want; there is no need to reset it.

--

But big but. The code you have is rather spaghetti. You should think how to better structure and compartmentalize the code into closely-related logical units. In object-oriented programming you do it with classes. For example, you could define a class called GameState that keeps the variables moves and points or anything else shall you need it, and define there the count methods or other methods to modify the statistics of the game. Don't make the main method define the logic of the program. It should merely be used to read the input to initialize some sort of class Game and write to output the results of the Game.

Upvotes: 1

Lazy Senior
Lazy Senior

Reputation: 171

The moves arent count right, because countMoves doesnt increment the Variable moves from the main function. If you do :

System.out.println(moves);
countMoves(in, moves);
System.out.println(moves);

You will see that the value didnt changed. So you could add a return value to countMoves and assingn moves with it :

moves = countMoves(in,moves);

Or you could increment the moves here :

if(in.equals("left") || in.equals("right") || in.equals("up") || in.equals("down"))
    {
        moves++;
        if (in.equalsIgnoreCase("up"))  
        {

            rowNumber = rowNumber - 1; 
        } 

        if (in.equalsIgnoreCase("down")) 
        {           
            rowNumber = rowNumber + 1; 
        } 

        if (in.equalsIgnoreCase("left"))  
        {   columnNumber = columnNumber - 1;  
        } 

        if (in.equalsIgnoreCase("right"))  
        {   columnNumber = columnNumber + 1; 
        }
    }

The same with Points i think. The line

points = points;

Would only make sense if you have a classvariable that would get the point value but assign a variable with its own value doenst make sense .

So maybe add a return to the countPoints and assign points with it :

points = countPoints(obstacleNumber, points);

Upvotes: 2

Related Questions