0

I am now working on the AI section of my project. I am calling a method from my AI class which is intended to calculate where the Gladiator objects I have drawn need to actually end up. I passed to that method a List containing all my objects I want to place. A previous method from the AI class has determined where they want to be from each other, distance-wise and I have stored it as gladiator[0..1..2..etc].movementGoal.

Although the project is not real time, ie I will want to just "step" through it in the end, I do want simultaneous movement to occur. This means that my standard method of iterating through the list will not work as I need information about the other Gladiator's movement decisions in order to figure out any one Gladiator's actual movement as these decisions interact.

How can I access another specific gladiator's variables when I am outside the class and only have them in List form?

Edit:

I guess I could iterate through and test for a variable gladiatorNumber to be correct, then when it is pull that info? That would be pretty round-about but its all I can think of.

Edit2:

As requested, some code. My method in Ai class looks like this:

public void moveAI(List<Gladiator> gladiators) {

My gladiator is defined as such:

public class Gladiator {

Gladiator class is created as an array then added into a list in a separate main class. I don't really want to include more code than this, as there is a ton of it. Basically it boils down to how can I call gladiator[0] from AI class even though I created said object in the main class and only have them in list form in the AI class. Assume all variables in Gladiator are public. The error I am getting is cannot find symbol referring to gladiator[0...1...2...etc].

5
  • 2
    Can you post some code for us to work with? If you want to access variables that aren't native to the class then you need to declare them as either public or private. Stopping at a given moment will require the implementation of a timer. Commented Jun 4, 2013 at 15:25
  • Do you have a player-class? Or just gladiators vs gladiators? Commented Jun 4, 2013 at 15:34
  • @tdorno Stopping shouldn't require a timer as I am planning to calculate all relative movements beforehand and then move everything at once to where it will end up. I am not looking for smooth, I am looking for almost turn-based. But with simultaneous movement. Commented Jun 4, 2013 at 15:35
  • @aryaq Gladiator vs Gladiator, no input but the spacebar to "step through" Commented Jun 4, 2013 at 15:36
  • @tdorno It should be noted I do in fact have a timer, but it is to have the AI crunch the data and decide, then repaint. Commented Jun 4, 2013 at 15:44

1 Answer 1

1

I think your problem boils down to wanting to pass the arrays of gladiators to another class. That should be fairly easy. If you in your main-class have these two defintions (note you only need one, I recommend the list as it is more versatile, arrays have fixed-length).

You want something like this:

public class Main {
// ....stuff
// This is the main class that keeps the list of gladiators
private List<Gladiator> gladiatorsList;
private Gladiator[] gladiatorsArray;
private MovementAI movementAI;

public Main() {
    // You initialize gladiatorsList and gladiatorsArray as before
    // gladiatorsList = ...
    // gladiatorsArrray = ...
    // Now you want to pass this list/array to another class (the AI), you
    // can do this in the constructor of that class like so:
    movementAI = new MovementAI(gladiatorsList);
}

// ...stuff as before

}

The AI

public class MovementAI {

private List<Gladiator> gladiators;

// Giving the class the list-reference, this list will be the same as the
// list in main, when main-list changes so does this one, they point to the
// same list-object, so the reference is only needed once.
public MovementAI(List<Gladiator> gladiatorsList) {
    this.gladiators = gladiatorsList;
}

// The class already has a reference to the list from its constructor so it
// doesn't need the list again as a parameter
public void moveAI() {

}

// If you don't want to keep a reference to the list in this class but only
// use it in a method (I would not recommend this)
public MovementAI() {

}

// You need to pass it gladiatorsList everytime you call this method.
public void moveAI(List<Gladiator> gladiators) {

}

}

I see in your last comment that you have decided to let the AI decide to repaint if it meets a criteria, that is not recommended, you should keep responsibilities separate in your classes, less error-prone and better development. It is recommended to let the AI change the list of gladiators (move them, kill them etc) and the rendererclass simply paint every gladiator.

It also seems you want to have every gladiator be able to hold another gladiator as a target, it is better for them to hold the target as an Object, this way you don't have to search the entire list to find out which gladiator the gladiatornumber refers to and you don't have to think about ordering in the list. Something like this:

public class Gladiator {
// ..other stuff

private Gladiator target;
public Gladiator getTarget() {
    return target;
}

public void setTarget(Gladiator target) {
    this.target = target;
}
}
Sign up to request clarification or add additional context in comments.

7 Comments

This seems like a considerably better alternative to passing the list every time and I will adopt it. That being said, I still will be stuck with a list I have to iterate through, without being able to pull data from a particular gladiator, won't I?
To give you an example, each Gladiator object has a target, which refers to the gladiator number of whom they are targeting. The first thing I have to do is to figure out if everyone paired off or if there is multiway fights going on, because I have to handle those events differently. How can I use the gladiator number to check to see if they are engaged in a fight already or if they are targeting the first gladiator, too?
You will be able to pull any data that is available in the gladiator object from the list of gladiators, it is just a container. The target should be easily accessible if it is declared, see my edit.
I think maybe you misunderstood. Or maybe I misunderstood your understanding. I create my timer and my ai object in the renderer, then in my actionPerformed for the timer I call my AI methods one by one, then I repaint. That point about storing my target as a gladiator object sounds immensely useful. I will definitely be doing that.
It would be better to call only one AI method in the actionperformed and inside that one AI method call other (private methods), something like aiManager.update(). This way you can change the logic of the AI without having to change the actionlistener.
|

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.