Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - 2D Array Index Manipulation in a Complex Program

Before asking my question I want to make some things clear. First, I am new to Java and programming in general. Second, This is my second post so please go easy on me if I did something wrong. Finally, I would like an explanation as to why what I did was wrong instead of just a pasted solution in any responses to this post. To better understand the issue I will write the assignment information, then the Driver class that is given, then my class code that is accessed by the Driver class.

My question:

How can I get the bottom left of my 'building' to be [0][0] on my 2D array? Here's an example of a for loop that works in changing the bottom left of a 2D array to [0][0], but I tried implementing this into my searchRoom method (where the player character is set to myHidingPlaces index) and I can't get myHidingPlaces[0][0] to be the bottom left of my 2D Array. I believe that i need to edit the toString method somehow with for loops, but I can't figure out how I should do it.

The following is the assignment:

You are to design a class “LostPuppy.java” which represents a puppy lost in a multi-floor building that contains the same number of rooms on each floor. During instantiation (or creation) of an object of this class, each room on each floor will be initialized as empty (you will actually use the space ‘ ‘ character for this purpose) and a random room will be chosen where the puppy is lost. For this purpose, the character “P” will be placed in this random location. Further details on the constructor is listed below.

An object of this class is used as a game for two players to take turns searching for the puppy, one room at a time until the unfortunate little canine is found. The instantiation of this object and the search will be performed by a “driver” program which has been provided to you allowing you to only have to concentrate on developing the class (the driver program is in the file “PuppyPlay.java”)

Fields (of course, all fields are private):

  • A character (char) array named myHidingPlaces. This represents the building where the rows are floors and the columns are rooms on each floor (this building has an unusual numbering system; the floors and rooms both start at zero).

  • Two integers that will hold the floor and room where the puppy is lost, named myFloorLocation and myRoomLocation.

  • A char named myWinner which will be assigned the player’s character when a player finds the puppy (the driver program uses digits ‘1’ and ‘2’ to more clearly distinguish the players from the puppy).

  • A boolean named myFound which is set to true when the puppy is found.

Constructor:

  • Receives two integer parameters as the user’s input for the number of floors and rooms of the building in which the puppy is lost.

  • The constructor instantiates the 2D array “myHidingPlaces” as a character array with the first parameter for the rows (theFloors) and the second parameter as the columns (theRooms).

  • Initialize myHidingPlaces’ cells, each to contain a space ‘ ‘ (done with single quotes)

  • Set myFloorLocation (floor puppy is on) randomly based using the first parameter
  • Set myRoomLocation (room puppy is in) randomly based using the second parameter
  • Set myHidingPlaces[myFloorLocation][myRoomLocation] to the char ‘P’
  • Set myWinner to a single space
  • Set myFound to false

Methods:

  • roomSearchedAlready receives the floor and room to be searched and returns true if the room has already been searched, false otherwise.

  • puppyLocation receives the floor and room to be searched and returns true if the floor and room are where the puppy is lost, false otherwise. This method should NOT change any of the fields.

  • indicesOK receives the floor and room to be searched and returns true if the floor and room values are within the array indices range, false otherwise (used to check that these indices will not cause an error when applied to the array).

  • numberOfFloors returns how many floors are in the building (the first floor starts at zero).

  • numberOfRooms returns how many rooms are on each floor of the building (the first room starts at zero and all floors have the same number of rooms).

  • searchRoom receives the floor and room to be searched and also the current player (as a char type) and returns true if the puppy is found, false otherwise. If the puppy is NOT found searchRoom also sets the myHidingPlaces array at the received floor and room location to the received player value (a ‘1’ or a ‘2’) OR, when found, sets the myWinner field to the current player AND sets myFound to true.

  • toString displays the current hidingPlaces array and it’s contents EXCEPT the location of the puppy which remains hidden until he/she is found at which point toString will be called (by the driver) and both the player who found the puppy and a ‘P’ will be displayed in the same cell….

  • NOW, and perhaps the awkward portion of the toString output. Normally, when displaying a 2D array, the [0][0] cell is displayed in the upper left corner as with matrices. However, because the puppy decided to get lost in a building and not a matrix, it would make more visual sense to have the first floor (row 0) displayed on the bottom, second floor above it… and finally the top floor, well… on top! To save words, look closely at the sample run provided on the next page. Your output should look the same as what is seen on the next page in the sample run.

Here is the Driver program:

import java.util.Random;
import java.util.Scanner;

/**
 * This program is used as a driver program to play the game from the
 * class LostPuppy.  Not to be used for grading!
 *
 * A puppy is lost in a multi-floor building represented in the class 
 * LostPuppy.class.  Two players will take turns searching the building
 * by selecting a floor and a room where the puppy might be.
 *
 * @author David Schuessler
 * @version Spring 2015
 */

public class PuppyPlay
{
  /**
   * Driver program to play LostPuppy.
   *
   * @param theArgs may contain file names in an array of type String
   */
  public static void main(String[] theArgs)
  {
    Scanner s = new Scanner(System.in);
    LostPuppy game; 
    int totalFloors;
    int totalRooms;
    int floor;
    int room;
    char[] players = {'1', '2'};
    int playerIndex;
    boolean found = false;
    Random rand = new Random();

    do 
    {
      System.out.print("To find the puppy, we need to know:\n"
                       + "\tHow many floors are in the building\n"
                       + "\tHow many rooms are on the floors\n\n"
                       + "             Please enter the number of floors: ");
      totalFloors = s.nextInt();
      System.out.print("Please enter the number of rooms on the floors: ");
      totalRooms = s.nextInt();
      s.nextLine();    // Consume previous newline character    

      // Start the game: Create a LostPuppy object:
      game = new LostPuppy(totalFloors, totalRooms);

      // Pick starting player
      playerIndex = rand.nextInt(2);

      System.out.println("\nFloor and room numbers start at zero '0'");

      do 
      {

        do 
        {
          System.out.println("\nPlayer " + players[playerIndex]
                             + ", enter floor and room to search separated by a space: ");
          floor = s.nextInt();
          room = s.nextInt();

          //for testing, use random generation of floor and room
          //floor = rand.nextInt(totalFloors);
          //room = rand.nextInt(totalRooms);
        } while (!game.indicesOK(floor, room) 
                 || game.roomSearchedAlready(floor, room));


        found = game.searchRoom(floor, room, players[playerIndex]);
        playerIndex = (playerIndex + 1) % 2;
        System.out.println("\n[" + floor + "], [" + room + "]");
        System.out.println(game.toString());
        s.nextLine();
      } while (!found);

      playerIndex = (playerIndex + 1) % 2;
      System.out.println("Great job player " + players[playerIndex] +"!");
      System.out.println("Would you like to find another puppy [Y/N]? ");
    } 
    while (s.nextLine().equalsIgnoreCase("Y"));
  }
}

Finally, here is my test code:

import java.util.Random;
import java.util.Scanner;

public class LostPuppy
{
   int value;
   char[][] myHidingPlaces;
   int myFloorLocation;
   int myRoomLocation;
   char myWinner;
   boolean myFound;
   Random random = new Random();

   public LostPuppy(int theFloors, int theRooms)
   {
      myHidingPlaces = new char[theFloors][theRooms];

      for (int i = theFloors - 1; i >= 0; i--)
      {
         for (int j = 0; j <= theRooms - 1; j++)
         {
            myHidingPlaces[i][j] = ' ';
         }
      }

      myFloorLocation = random.nextInt(theFloors);
      myRoomLocation = random.nextInt(theRooms);
      myHidingPlaces[myFloorLocation][myRoomLocation] = 'P';
      myWinner = ' ';
      myFound = false;  
   }
   public boolean roomSearchedAlready(int floor, int room)
   {
      return (myHidingPlaces[floor][room] == '1' || 
              myHidingPlaces[floor][room] == '2');
   }

   public boolean puppyLocation(int floor, int room)
   {
      return (myHidingPlaces[floor][room] == 'P');
   }

   public boolean indicesOK(int floor, int room)
   {
      return (floor <= myHidingPlaces.length && room <= myHidingPlaces[0].length);
   }

   public int numberOfFloors()
   {
      return myHidingPlaces.length - 1;
   }
   public int numberOfRooms()
   {
      return myHidingPlaces[0].length - 1;
   }

   public boolean searchRoom(int floor, int room, char player)
   {
      if (puppyLocation(floor, room))
      {
         myFound = true;
         myWinner = player;
         return true;
      }
      else
      {
         myHidingPlaces[floor][room] = player;
         return false;
      }
   }

   public String toString()
   {
      int rooms = myHidingPlaces[0].length;
      int floors = myHidingPlaces.length;

      System.out.print(" ");
      for (int x = 0; x < rooms; x++)
      {
         System.out.print("___");
      }

      for (int y = 0; y < rooms - 1; y++)
      {
         System.out.print("_");
      }
      System.out.print("\n");

      for (int r = 0; r < floors; r++)
      {
         System.out.print("| ");
         for (int c = 0; c < rooms; c++)
         {

            if (myHidingPlaces[r][c] == 'P' && myFound)
            {
               System.out.print("" + myWinner + "" + myHidingPlaces[r][c] + "| ");
            }
            else if (myHidingPlaces[r][c] == 'P' && !myFound)
            {
               System.out.print("  | ");
            }
            else
            {
               System.out.print(myHidingPlaces[r][c] + " | ");
            }

            //System.out.print(myHidingPlaces[r][c] + " | ");

         }
         System.out.print("\n");
         for (int i = 0; i < rooms; i++)
         {
            System.out.print("|___");
         }
         System.out.print("|\n");
      }
      return "";

   }

}
like image 758
Trafton Avatar asked Jul 15 '15 04:07

Trafton


People also ask

How are 2D arrays indexed in Java?

Two-dimensional (2D) arrays are indexed by two subscripts, one for the row and one for the column. Each element in the 2D array must by the same type, either a primitive type or object type.

How do you modify a 2D array in Java?

In Java, elements in a 2D array can be modified in a similar fashion to modifying elements in a 1D array. Setting arr[i][j] equal to a new value will modify the element in row i column j of the array arr .

How do I find the index of a 2D array?

Indexing a Two-dimensional Array To access elements in this array, use two indices. One for the row and the other for the column. Note that both the column and the row indices start with 0. So if I need to access the value '10,' use the index '3' for the row and index '1' for the column.

How do you initialize a 2D array in Java with values?

Here is how we can initialize a 2-dimensional array in Java. int[][] a = { {1, 2, 3}, {4, 5, 6, 9}, {7}, }; As we can see, each element of the multidimensional array is an array itself. And also, unlike C/C++, each row of the multidimensional array in Java can be of different lengths.


1 Answers

There is no way you can make a reversed array in Java, but you don't need it. You need to think of the building and operate with it just like you would do it with matrices. However you need to print it upside-down. Also there is no changing of position in array by the link you provided, it is just an array traversal from last index to first.

So you need to print array upside-down and this is pretty easy. You need to change one line in your toString method, change

for (int r = 0; r < floors; r++)

to

for (int r = floors - 1; r >= 0; r--)

And you will get correct result!

Also in this case you don't need to fill array from last to first (at least because you fill it with the same value), like you do

for (int i = theFloors - 1; i >= 0; i--) {
    for (int j = 0; j <= theRooms - 1; j++) {
        ...
    }
}

It will be better if you do it like this (just better to read your code)

for (int i = 0; i < theFloors; i++) {
    for (int j = 0; j < theRooms; j++) {
        ...
    }
}

As @Dante said you also need to correct indicesOK method because last index of array is its length - 1, so when you access myHidingPlaces.length or myHidingPlaces[i].length element the exception ArrayIndexOutOfBoundsException will be thrown.

public boolean indicesOK(int floor, int room) {
    return (floor < myHidingPlaces.length && room < myHidingPlaces[0].length);
}
like image 133
Nikolay K Avatar answered Sep 29 '22 17:09

Nikolay K