Hey there. I have working code that reads in a text file into a 2d array. The text file holds symbols that make up a map for a game. I'm trying to assign each of the symbols (like ^, for a mountain) to an object, and store those in the 2d array as well, so that my map is made up of mapspace objects (desert space, mountain space...all of which I have existing classes for). I'm thinking of using if(possibly?) statements to check each character that is stored in the array & instantiate a new mountain/desert object.

I'm not sure how to go about it, though.... Here's what I have so far:

public class Map {
 
     ArrayList array = new ArrayList();
    char [][] linksWorld = null;
 
    public Map(String mapFile) {
        
        try{
                
          BufferedReader in = new BufferedReader(new FileReader(mapFile));
          String data;
                
              //Read from file
              while ((data = in.readLine()) != null)
              {
                //Convert data to char array and add into array
                array.add(data.toCharArray());
              }
                in.close();
 
          //Creating a 2D char array using the arraylist size
          linksWorld = new char [array.size()][];
 
          //Convert array from ArrayList to 2D array
          for (int i=0; i<array.size(); i++){
            linksWorld[i] = (char[])array.get(i);
            
          }
 
          //Test 2d array
          for (int j=0; j<linksWorld.length; j++){
            char [] temp = linksWorld[j];
                for (int x=0; x<temp.length; x++)
                {
                  System.out.print(temp[x]);
                }
                  System.out.println("");
          }
             
        }
        
        catch (Exception ex){
            ex.printStackTrace();
        }
    }//constructor
    
//test
    public static void main(String[] args){
        Map map = new Map("samplemap.txt");
    }
}

Recommended Answers

All 6 Replies

Don't call the class Map, to avoid confusion with the standard library :)

Make it an array of MapSpace objects and store just those, maybe having those have the original character in them somewhere (or better have an enum that maps the characters to symbolic constants).

Think something like

public enum TerrainType {
  MOUNTAIN('^', mypackage.terrain.Mountain.class),
  SEA('~', mypackage.terrain.Sea.class);

  private char type;
  private Class terrainClass;


  TerrainType(char type, Class terrainClass) {
    this.type = type;
    this.terrainClass = terrainClass;
  }

  public String getType() {
     return type;
  }
  
  public Class getTerrainClass() {
    return terrainClass;
  }

}

I'll leave it up to you to add methods to get the enum for a specific terraintype character.

Member Avatar for DaSogo

It seems you'll need to do alot of work to do this with an array. I would suggest using a Map class from java.util. Maps allow you to store a key-value pair.

Map<k,v>

Above is the signature of a Map. It allows you to define the type of parameters that your Map will hold. It's alot more flexible than an array. Map<String,Object>

It also has methods that allow you store, retrieve and delete. Well, that's all that I am able to offer. Please be sure to check out the java api by sun for guidance on using collections.

I unfortunately cannot use Map class, I'm supposed to use a 2d array. :mad: I'm gearing towards this to instantiate my 2d array, hyrule, with MapSpace objects.

//reads in from a text file line by line.
while((s = in.readLine())!= null){
                
               for(int cols = 0; cols<arr.length; cols++){
                    
                       arr1 = s.toCharArray();
                    
                   if(arr1[rows] == '^'){
                  //Make a new Mountain object.
                     hyrule[rows][cols] = new Mountain();
                  }//if
                  
                  else if(arr1[rows] == '#'){
                  //Make a new Desert object.
                     hyrule[rows][cols] =  new Desert();    
                  }//else if
                  
                  
                    for(rows=0;rows<arr1.length;rows++){
                  System.out.println(hyrule[rows][cols]);
                        }
                            
                 rows++;
                cols = arr1.length;
                 
                
                    }//for
                    
            
            
            
            }//while

I also want to be able to get a MapSpace object in the 2d array using a method, but I'm not sure what would go in the body of the method to retrieve the specific element (I know how to retrieve an element in a 1d array, but not a 2d array). The java api wasn't too helpful when trying to get 2d array elements.

public MapSpace getMapSpace(int row, int column){
          //code to retrieve specific element
         return MapSpaceObject;
      }

Any ideas?

Member Avatar for DaSogo

I'm a little confused about your code. It seems to me that you are doing way to much. Then again it could be just me!!! Please help me understand it. I may be just missing the point. It's been awhile since I actually coded and some of the objects and methods in your program, I have never used before.

I'm guessing that each character symbol that represents an object is on its own line in the text file. If this is the case, why to you read only 1 character (string i'm guessing) and convert it to a char array which will have the size of 1 and then store it in an array list or an array. I'm really confused since you changed your variables and the way you are now assigning each char array to what appears to be an array reference variable. Have you ran this code yet or tested it. If so, what error messages are you getting. I'm much better at debugging messages than analyzing code from a web page.

//reads in from a text file line by line.
while((s = in.readLine())!= null){
 
for(int cols = 0; cols<arr.length; cols++){
 
arr1 = s.toCharArray();
 
if(arr1[rows] == '^'){
//Make a new Mountain object.
hyrule[rows][cols] = new Mountain();
}//if

Yes, you're right, I have a text file that is about 6x8 and is full of # and ^ characters that are supposed to represent objects (each with their respective classes, Desert and Mountain). Here's a bit more of my code, including the way I input each line of from the text file. I want to fill my 2d array with the correct Mountain or Desert object, and then be able to call a method that will return the right mapspace (mountain or desert) when given coordinates. However, when I fill the body of the getMapSpace() method and call it on my Map object, it gives me a NullPointerException. If I remember correctly, this means that my array hasn't been instantiated, right?

public class NewMap{

private int height;
private int cols;
private int rows;
private MapSpace[][] hyrule;
private int width;
private String s;
private char [] arr1;

//Constructor
public Map(){
      
         try{
         
            BufferedReader in = new BufferedReader(new FileReader("sampleMap.txt"));
            Random rdm = new Random();
             
            while((s = in.readLine())!= null){

                arr1 = s.toCharArray();

               for(int cols = 0; cols<arr1.length; cols++){
                    for(int rows=0; rows<arr1.length; rows++){
                   if(arr1[rows] == '^'){
                  //Make a new Mountain object.
                     hyrule[rows][cols] = new Mountain();
                  }//if
                  
                  else if(arr1[rows] == '#'){
                  //Make a new Desert object.
                     hyrule[rows][cols] =  new Desert();    
                  }//else if
       
                    
                 rows++;
                cols = arr1.length;
                 
                }//for
                    }//for
                    
            
            
            
            }//while
         
         
            in.close();
         
         }//try
         
             catch(IOException io){
               System.out.println(io);
               io.printStackTrace();
            
            }//catch
}//constructor

then, as stated in my last post, call the getMapSpace() method on the Map object.

Member Avatar for DaSogo

Yes, you're right, I have a text file that is about 6x8 and is full of # and ^ characters that are supposed to represent objects (each with their respective classes, Desert and Mountain).

paste the contents of your text file here so that I may view it. It looks like you are doing alot of work which is not neccessary. 6x8 is too general of a description. I need to know how many symbols per line and does one line represent the contents of 1 object.

However, when I fill the body of the getMapSpace() method and call it on my Map object, it gives me a NullPointerException. If I remember correctly, this means that my array hasn't been instantiated, right?

No, instantiated in a way means to bring an object too life by using the new keyword. You received a nullpointer exception because the element that you were trying to access at hyrule[row][col] was not present. In other words, a value was not assigned to it. I believe you performed that operation in your for loop during the read. That's why I need to see the structure of sampleMap.txt. I see you have gotten rid of the arraylist...good!!!!

public class NewMap{
 
private int height;
private int cols;
private int rows;
private MapSpace[][] hyrule;
private int width;
private String s;
private char [] arr1;
 
//Constructor
public Map(){
 
         try{
 
            BufferedReader in = new BufferedReader(new FileReader("sampleMap.txt"));
            Random rdm = new Random();
 
            while((s = in.readLine())!= null){
 
                arr1 = s.toCharArray();//don't think this is working right because arr1 is a variable that holds the bit pattern to where the char array is actually stored in memory.  Also arr1 was never initialized, meaning it wasn't given a size and an index to store the the input from the text file.
 
if 1 character equals 1 object, then in the textfile, only have 1 column of data.  This will allow 1 character to be read at a time into a string variable.  while the symbol is stored in the the variable, you can go straight to the if statements and compare.  You wouldn't need the for loop since the file will repeat until end of file.  If it turns out that you will need the char array because of its scope, you can assign the character after it passes through the if statements.
 
               for(int cols = 0; cols<arr1.length; cols++){
                    for(int rows=0; rows<arr1.length; rows++){
                   if(arr1[rows] == '^'){
                  //Make a new Mountain object.
                     hyrule[rows][cols] = new Mountain();
                  }//if
 
                  else if(arr1[rows] == '#'){
                  //Make a new Desert object.
                     hyrule[rows][cols] =  new Desert();    
                  }//else if
 
 
                 rows++;
                cols = arr1.length;
 
                }//for
                    }//for
 
 
 
 
            }//while
 
 
            in.close();
 
         }//try
 
             catch(IOException io){
               System.out.println(io);
               io.printStackTrace();
 
            }//catch
}//constructor

then, as stated in my last post, call the getMapSpace() method on the Map object.

Once I have the the contents of the textfile as they are positioned, It will be alot clearer.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.