0

first timer here, got a Java issue while working on a simple strategy game. Here goes:

Trying to save processor time, I used int arrays (multidimensional) as a database interface. Like this:

//database variables
public int mapSize;// amount of tiles along one side of the map
public int[][] map;// [area id] - [resource type] - value

public int[][][] trades;// [trade id] - [sender/recipient] - [resource type] - value

public Object users = new Object(){
    public int usercount;// amount of users in the game
    public int[][] opinion;// [first user id] - [second user id] - value
    public int[][][] resources;// [user id] - [resource type] - [value type] - value
    public int[][] efficiency;// [user id] - [resource type] - value
    public int[][] processes;// [user id] - [resource type] - value
};

//public math function (triangular numbers by iteration)
public int triNum(int i){
    return (int) i*(i+1)/2;
}

As you can see, I used an Object() to store the users data in. Users refers to the player + AI here, not any actual people. I did it this way because I was concerned about memory, since resources takes up much more space than opinion, efficiency, or processes, and definitely more than usercount. This code is located in the class Game. This class is not the main class and does not contain the public static void main(String[] args) method either. This code is not inside any method, but it is inside the class. No errors here.

The problem lies in the void start(Main home, String save) method, which actually fires up a game. The class Game() monitors the currently active game and it's variables and objects, and is always active). In here, after firing up the frame and panels, and generating a map (using a method int[][] generateMap(int size)), I want to fill in the arrays. This is the relevant code:

//DATA VARIABLES
if (save.equals("new")){
    //make map
    mapSize = 9;//placeholder value - retrieve actual value from settings file later
    int mapScale = (int) Math.pow(mapSize, 2);
    map = generateMap(mapSize);//9x9 grid

    //make users
    users.usercount = (int) Math.pow(mapSize / 3, 2);//<--- ERROR HERE
    for (int i = 0; i < users.usercount; i++){//<--- ERROR HERE

    }    

    //make trades
    trades = new int[triNum(users.usercount - 1)][1][8];//<--- ERROR HERE
    for (int[][] trade : trades) {
        //fill array with appropriate values
        for (int j = 0; j < users.usercount; j++) {//<--- ERROR HERE
            for (int k = 0; k < users.usercount; k++) {//<--- ERROR HERE
                if (j < k) {
                    trade[0][0] = j;
                    trade[1][0] = k;
                }
            }
        }
    }
}

The marked locations generate the following NetBeans IDE 8.1 error:

cannot find symbol:
    symbol:   variable usercount
    location: variable users of type Object
----
(Alt-Enter shows hints)

Pressing Alt and Enter simultaneously simply displayed the error even when not hovering over the icon. Pressing the icon made a "cannot do" windows sound (Windows 10).

From what I understand, the compiler cannot access the Object users from the start() method. Is there any way for me to access, from a public method, in a public class, the public variables, in a public object, made in the same public class?


If not, could you be so kind to explain:

A) Why not?

B) What do I not/incorrectly understand?

C) What I can do otherwise?

I understand I could very well just declare those variables separate from any users object. But 1) I want to refer to that set of variables with a single name, and an array would be disproportionally memory-intensive, and 2) my problem will probably arise later in a different setting, and if so I want to know how to deal with it.


I know I am just a Java newbie, but I have tried using google searches, and whereas otherwise they helped me they did not help me here. Maybe I am using the incorrect search terms, but if so just those terms would already be a huge help.

Thanks for reading through this wall of text, and thank you even more if you would be so kind to help me out here.

1
  • 1
    In an attempt to pre-optimize, you have decided not to use classes and made your code completely unreadable. Use classes. Your users object is of type Object. Object doesn't have any field. Define your classes. Choose appropriate data structure. Add readable methods and encapsulate. Commented Mar 7, 2016 at 17:37

1 Answer 1

3

The approach you're using here is not the correct way to do what you want. When you declare users like that, it's what's known as an anonymous class. Basically, it gets turned into a full class declaration with a automatically generated name.

Because of how Java's type system works, you can only (directly) access the fields and methods of an object if they're declared in the type of the reference you use to refer to it. So for example, if you say Object o = "string", you can use any of Object's methods, but you can't call a method that only exists on String, since the compiler doesn't know that what you have is actually a String.

This is a problem for you, because you have no way to convert your object into it's actual type, because the class itself is anonymous. Short of reflection, there's no way to get those fields back out of it, which makes the object effectively useless.

The correct approach is to either put those fields directly into the class where you've declared users, or make a separate class to hold those fields:

class Users {
    public int usercount;
    public int[][] opinion;
    public int[][][] resources;
    public int[][] efficiency;
    public int[][] processes;
};

And then reference it later by that class name:

Users users = new Users();

Since you've now given a name to the class, the compiler can safely know what type it is, and what fields it contains.

As a side note, those arrays are still going to be pretty hard to understand. Don't be scared to declare objects to represent your data in a useful way. The JVM is very good at creating and managing objects, and it's extremely unlikely that the performance gains you're trying to achieve will actually matter. More likely, your program will be confusing enough that you end up writing inefficient code that will be slower than if you'd simply written it to be readable.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.