Calling a method from arraylist - java

For a turn-based game I want to make a build queue for a planet. User puts items to build in a queue and then, when turn is generated, everything in a queue is being built.
Right now I have a Planet class which has an ArrayList. An object of type Planet is created for each planet the player owns. The array list contains everything user has ordered this planet to build. It also contains 3 variables that store the resources currently present on the planet and 3 variables that store total number of buildings that are currently on the planet.
Every building type is also a class (because building types costs differ), I plan to put objects of corresponding type into the planets queue. I suppose that each building class should have its own building method .build();
I want to cycle through each item in the queue of the planet and launch something like .buld() method.
Building an object means subtracting some resources from the planets resource variables and adding number of buildings built to total number of buildings on a planet.
The trouble is that I don't understand the main idea, how to achieve this.
The Planet class:
public class Planet extends WorldObject implements Serializable {
private int defenses;
private int mines;
private int factories;
//it also has 3 variables from WorldObject class:
int iron;
int bor;
int ger;
ArrayList<Installation> queue;
private void build(){
for ( int i = 0; i < queue.size()-1; i++ )
{
queue.get(i).build();
}
}
}
One of the building classes:
public class Factory extends Installation {
int costIron = 10;
int costGer = 50;
public build(int amt) {
//build itself, remove res from planet, add number built to planet factory list
}
}
If I'm doing this totally wrong, I would be thankful if you say in which "direction" should I look for information.

It sounds like Planet should have a Resources object that encapsulates the resources, and that could be passed to Installation.build(). Then Installation.build() could return a object that describes what was built.
Edit: here's an example:
public class MineFactory extends Installation {
private final Resources cost;
public MineFactory(Resources cost) {
this.cost = cost.clone();
}
#Override
public Result build(Resources availableResources) {
if (!availableResources.remove(cost)) {
return Result.empty();
}
return Result.mines(2);
}
}

You need to either pass your Planet object to build as an argument so that it has access to resources, or, alternatively, do the "building" in the Panet code itself, and just have getCost on the building, that you'd call yo find out how much resources to subtract.
Personally, I'd know kinda prefer the latter approach, but that's more of a question if taste than anything else.

Related

General questions + How: object that can copy another object's values?

General part first:
This is for my Java 1 final: I need to make an NFL playoff simulator. So, I would make a "Team" object that holds values for "Offense" and whatnot. I would need a method that holds an algorithm to calculate who wins each matchup. However, I don't know how to go about applying the method to the appropriate teams..
I was going to make another object called "Matchup" which would hold 2 "Team" objects, then comparing the 2 teams' values with the algorithm method. But, I don't think you can use objects inside another object, to my knowledge... Therefore, I've just been trying to hard-code everything in an ugly way.
Would anyone point me in the right direction of forming such a program?
Anyway, on to my immediate issue:
Here is my small bit of code thus far..
public class Final_Larrabee {
static Team pit = new Team("Steelers", "AFC", 3, 75, 70);
static Team bal = new Team("Ravens", "AFC", 6, 70, 80);
static String teamA1 = "bal";
public static void main(String[] args) {
System.out.println(+teamA1.seed);
}
}
And my other class:
package final_larrabee;
public class Team {
String name;
String conference;
int seed;
int offense;
int defense;
boolean wcWin;
boolean divWin;
boolean conWin;
boolean alive;
public Team(String n, String c, int s, int o, int d) {
name = n;
conference = c;
seed = s;
offense = o;
defense = d;
wcWin = false; // these wins will be used in the betting part
divWin = false;
conWin = false;
alive = true; // determines if team is out of playoffs or not
}
public String getName(){
return this.name;
}
public void setName(String n){
name = n;
}
public int getConference(){
return this.seed;
}
public void setConference(String c){
conference = c;
}
public int getSeed(){
return this.seed;
}
public void setSeed(int s){
seed = s;
}
public int getOffense(){
return this.offense;
}
public void setOffense(int o){
offense = o;
}
public int getDefense(){
return this.defense;
}
public void setDefense(int d){
defense = d;
}
}
I realize this won't work, because it is trying to access teanA1's seed value (which doesn't exist of course). But, what I wanted was to simply call the bal.seed value. I wanted to do it this way so that later, I can use teamA1 and teamA2 variables for the 2 teams in a given matchup. Is there a way to do it this way?
If not, perhaps ideally, it would be best to create a Team object called teamA1 which holds the values of whatever team I need at the time. It would need to change like a variable instead of make a million objects every time I need it (ideally..) I found the method 'clone' but I'm not sure this is what I want?
Any help, be it to my immediate question, or the general layout of my program, would be much appreciated. Thanks!
make team implements comparable this will give you the ability to write compareTo method and then you can put you win condition based
Just as your class Final_Larrabee holds 2 team objects in your code, your matchup class can also hold other objects.
Yes, you're on the right track with the idea of creating a matchup class which holds instances of team objects.
Inside your main class you can initialize 2 team objects. I would then create a matchup object, which gets passed the 2 team objects you have previously created and do some functionality.
Inside your team class you could implement a method, which returns a score based on the teams stats. For example it could calculate the offense * defence * seed or something like and return it that and then inside your match class, you can then implement a method such as playGame() which calls the getScore() method of each object and compares the values and then returns the winner (or prints them out for simplicity).
As regards your code, you're using the keyword static. Static is a keyword which changes a variable/object/method to a class variable/object/method. This means that every instance of the class shares this variable. I would not use it for creating the teams. An example of where to use static (a very basic example), would be if for some reason you needed to keep track of the amount of team objects you created. You could implement a static COUNT variable inside the team object and increase it by one every time the constructor is called. This could also be used for assigning IDs to the teams.
static int TEAM_COUNT = 0;
public Team()
{
this.id = ++TEAM_COUNT;
}
This would make the TEAM_COUNT be a value which shared by all instances of the class team. If you were to call
teamA.setTeamCount(0);
Then every other instance of Team would also be reset to 0.
Edit: With regards to your playoffs
public static void main(String args[])
{
Team team1 = new Team("parameters required here");
Team team2 = new Team("parameters required here");
Playoff p = new Playoff();
p.add(team1);
p.add(team2);
p.startPlayoffs();
}
If you create all of the objects inside the main class, then they are available to that method as they are local. When you call p.add(), you can add them to an array or collection, which is inside the Playoff class. Your startPlayoffs() method can then process the array of objects already stored inside the class.

Unknown parent variable issue in java

Recently I asked a question about why all my variables in spawned items were being set to the same damage value (Java switch statements outputting the same numbers) and that code wasn't to blame, however after some deep debugging i've found that when an item is spawned it randomises the damage and then for some reason sets that damage to every previously created item of the same type.
I have 'dagger' and 'sword' classes which extend my 'item' class. This is how I set the damage:
case 3: {Sword sword = new Sword(); World[X][Y].treasureName = "sword"; sword.setDamage(4); returnItem = sword; break;}
And this is my item class:
public abstract class Item {
//How much damage is added to the players attack.
static int damage = 0;
static int defence = 0;
public int getDefence() {
return defence;
}
public void setDefence(int defenceValue) {
defence = defenceValue;
}
public int getDamage() {
return damage;
}
public void setDamage(int damageValue) {
damage = damageValue;
}
}
And my sword class:
public class Sword extends Item {
//How much damage is added to the players attack.
static int damage = 0;
static int defence = 0;
public int getDefence() {
return defence;
}
public void setDefence(int defenceValue) {
defence = defenceValue;
}
public int getDamage() {
return damage;
}
public void setDamage(int damageValue) {
damage = damageValue;
}
}
I'm not sure what this problem is called and not sure what to google being fairly new still. I tried to override the item class but that didn't change anything and i've read about inheritance and I don't understand which part is setting every other weapon instance to the same damage. I wanted to remove the methods in the 'Item' class to see if that would fix it, however other code causing errors prevented me to do this when checking and adding together the damage of all the children of 'Item' - this required a cast of (Item) and i'm not sure of what else I can use as a cast.
Here are the referrals to the 'Item' method:
if (((Item) World[k][i].treasure).getDamage() > 9)
{
Without the cast the error is: getDamage() is undefined for the type Object.
and:
//Recalculates the players damage for recently equipped items.
for (int i = 0; i < numItems; i++) {
itemdamage += items[i].getDamage();
System.out.println("You have a " + itemNames[i] + " giving you " + items[i].getDamage() + " extra damage.");
}
What's wrong? I want to understand this so links to helpful information on why, and what i'm doing wrong would be good. Thanks.
static int damage = 0;
Having a static member means that all objects of the class same the same value. If you remove the static keyword, each object will be able to have a different value for damage.
As to the required cast, it seems that World is an array of Object type. Therefore World[k][i] is of Object type, and you can only call methods of the base Object class on it. If you want to call a method defined in the Item class, you must cast the Object to an Item (assuming the runtime type of that Object is an Item).
Your damage and defense variables should not be static. A static variable is tied to the whole class, not to any one instance of the class. As such, when you call setDamage(), even though the method is an instance method, it updates a static variable which is shared by every existing instance.
Remove the static (did you mean to use protected?) and you won't see the "for some reason sets that damage to every previously created item of the same type" behavior anymore.
See What does the 'static' keyword do in a class? for more. Here's the official Java Language Specification on static fields, as well.
You set the variables damage and defence (spelling mistake here - by the way) to be static. Which means that there's only one copy of each variables for the entire class.
Remove the static keyword before the declaration of both variables - and it'll make any new sword instance (object) - carry its own damage and defence.
Heyhey Fluidic,
I'm still fairly new to Java myself, but I think your problem is that your damage variables are set to static (and I would assume the problem would persist across your defence stats as well!)
I had this problem while learning to develop in C++. I would change a value of one of my constructors which referenced a static variable, and all of the instances would change. It's a constant belonging to the class itself, not the object.
So what's happening, is when you change the damage value; all references that use that static damage variable are being changed.
This site gives a bit of an insight on static variables!
http://www.javatpoint.com/static-keyword-in-java
Lemme know if that helps!
Andy
According to the error :
getDamage() is undefined for the type Object
I think you World array, is an array of Object instead of Item
Could you show us how you manage the World array ?

Accessing subclass method from other class

so I'm making a card game.
I have an arrayList of type player in my main, and I have filled it with a certain type of player (in this case, a good player - good player being a subclass of player with a couple of additional methods)
I may just be brain dead from looking at this for too long however heres my code.
I create 4 good players - again - goodPlayer extends player
ArrayList<Player> players = new ArrayList<>();
for (int i = 0; i < 4; i++)
{
goodPlayer gp = new goodPlayer();
players.add(gp);
}
Then after a couple of methods are called I want to call a method from goodPlayer called count, on each of the goodPlayers in players arrayList
for (Player p : players)
{
count(p.getHand());
}
what am I doing wrong as what I currently have is incorrect, unless I make count static and call goodPlayer.count however I do not want the class to act in a static context.
Thanks.
Why don't you use type casting? You don't need to make count method a static one to use it. If you are 100% sure that all players in that list will be from GoodPlayer class (by convention, class names start with a capital), then just cast it as
((GoodPlayer) player).count();
If you're not sure if all players will be from the class GoodPlayer, then add a test to avoid a runtime error:
if (player instanceof GoodPlayer) {
((GoodPlayer) player).count();
}
A solution would be to add a method on your abstract player class and implement that differently in your derived types of player. For example:
public abstract class Player
{
public abstract int count();
}
public class GoodPlayer extends Player
{
public int count()
{
return totalHandsPlayed * 3; //Or something meaningful;
}
}
This example is showing the you have a base class that asks any inherited classes to implement the methods defined as abstract. (in this case count).
If your players list is always going to hold GoodPlayer objects, then it would be best to have it as a a list of GoodPlayers
Otherwise, the answer given by user mehmetakcay best suits your purpose.
though the information you have provided seems to be little bit abstract but you can do in following manner (using downcasting, though its not recommended):
for(Player p:players){
GoodPlayer gp=(GoodPlayer)p;
gp.count();
}

java object arraylist index

I am running following code in java and have some questions.
I am calling following line in a Test class:
building.floor(3).waitForElevator();
My Building class has following method which returns the floor object from an array (floors) for given floorNumber.
ArrayList<Floor> floors = new ArrayList<Floor>();
public Floor floor(int floorNumber) {
return floors.get(floorNumber);
}
My Floor class has waitForElevator() method. In my Floor class I also have an array of length 7 called passengerWaiting. Whenever waitForElevator() is called, I would like to access the correct floorNumber in passengerWaiting array and change its value.
What I am struggling with is when building.floor(3).waitForElevator() is called, how do I access the index (3 in this example) from Floor class.
Thanks for all the help in advance.
You could store the value in a class instance variable and make it accessible via an accessor.
public class Building{
private int floor = 0;
private ArrayList<Floor> floors = new ArrayList<Floor>();
public Buliding(){
Floor floor1 = new Floor(this);
this.floors.add(floor1);
}
public Floor floor(int floorNumber) {
this.floor = floorNumber;
return floors.get(floorNumber);
}
public int getFloor(){
return floor;
}
}
If you add a constructor for Floor that accepts an instance of building and stores it as an instance variable you can access floor at any time.
public class Floor{
private Building building;
public Floor(Building building){
this.building = building;
}
public void waitForElevator(){
int floor = this.building.getFloor();
}
}
Another Solution
Simply pass the int to waitForElevator as an argument.
public class Floor{
public void waitForElevator(int floor){
System.out.println(floor);
}
}
//Usage
building.floor(3).waitForElevator(3);
Note This solution is not as great because the client could invoke as building.floor(3).waitForElevator(4);
To solve your current problem, I would suggest having each floor keep an int of which floor it is.
However, that seems like code smell to me, so I must ask why you need to do it this way. Could you possibly implement it such that you could just call building.waitForElevator(3)? Another refactoring would be to, rather than have one passengerWaiting ArrayList, have an int value for passengerWaiting in the Floor class, and just change that on each call to waitForElevator.
If you would post your full problem, I could give more helpful of suggestions, I'm guessing here based on the snippets you posted.

Not getting the correct values for variables in extended class

Just doing a quick edit up at the top of my post.
The question is if i extend a class and both classes have the same variable why is the extended class getting the original classes value.
This has been answered but would be more than happy to read more information about this.
Polymorphism isn't a strong suit of my so i'm having to relearn this stuff after not using it for months.
So i'm trying to program a game and one of the requirements is some type of list of object that can be scanned in a loop. The trouble starts with my test of ArrayList. I have 3 classes i made to be added in to my array list. Entities, Monster extends Entities, and Character extends Entities. do note Monster and Character both extends Entities class.
I decided that i should make the ArrayList and added new objects directly in to each element(the word element is normally used with array not ArrayList correct?) and use a log function i programmed to note down values of the objects in the ArrayList.
I made a for loop and ran both Monster and Character .getHP() method that they inherited from Entities and the results was the HP from Entities not Monster or Character unless i added a new value to the classes HP using the setHP(int i) method also inherited Entities.
Since my program requires most of the classes and we only need about 99% i decided to make a test project to basically do the above in a smaller form since i don't want to be copying pasting 20 or more .java files here. Anyways here's my test classes and results.
import java.util.ArrayList;
// class to test interactions between Extended classes
public class testHP {
ArrayList<Entities> ent = new ArrayList<Entities>();
public static void main(String[] args) {
///make reference varaible so i don't have to make test() and ent static.
testHP hp = new testHP();
hp.test();
}
void test(){
/// the 3 classes to the arraylist. I could of made a reference variable but didn't.
this.ent.add(new Character());
this.ent.add(new Monster());
this.ent.add(new NPC());
///prints out whats in the array list so i know that i have the correct objects.
System.out.println(this.ent);
/// this prints out { ent(i) HP "is" i } to tell which class is being called and it's HP at this point.
for(int i=0; i<ent.size();i=i+1) {System.out.println(this.ent.get(i).getHP() +" is "+ this.ent.get(i));}
/// this adds i plus 10 then does the same as the last for loop.
for(int i=0; i<ent.size();i=i+1) {
this.ent.get(i).gainHP(i+10);
System.out.println(this.ent.get(i).getHP() +" is "+ this.ent.get(i));}
}
}
abstract public class Entities {
private int HP = 1;
int getHP(){
return HP;
}
void gainHP(int hp){
HP = this.HP + hp;
}
}
///Character is to show what happens when i change the value and make it static.
public class Character extends Entities {
private static int HP = 4;
}
///monster is to show a changed variable from the super which is entities.
public class Monster extends Entities {
private int HP = 4;
}
/// NPC is a class that just to have variables from entities class that aren't edited or made static.
public class NPC extends Entities {
}
here is my results with these files as they are above. I should have put HP next to the number to the left but you get the idea.
[Character#67f1fba0, Monster#3fbefab0, NPC#133c5982]
1 is Character#67f1fba0
1 is Monster#3fbefab0
1 is NPC#133c5982
11 is Character#67f1fba0
12 is Monster#3fbefab0
13 is NPC#133c5982
My test class for the original ArrayList looks like this.
import java.util.ArrayList;
public class AreaMap extends Map {
String CLASS = "Area Map";///log requires.
ArrayList<Entities> ent = new ArrayList<Entities>();
AreaMap(){
Log.Logging(CLASS,"Testing arrayList");
//random text added to the array.
ent.add(new Character());
ent.add(new Monster());
Log.Logging(CLASS, "ent 1 has " +ent+ " in it");
for(int i=0; i < ent.size();i = i+1){
Log.Logging(CLASS, "ArrayList " + this.ent.get(i).getHealth() +" i="+i);
}
for(int i=0; i < ent.size();i = i+1){
this.ent.get(i).setHP(10+i);
Log.Logging(CLASS, "ArrayList " + this.ent.get(i).getHealth() +" i="+i);
}
}
}
And here are my result from that.
[Area Map]##[Testing arrayList]
[Area Map]##[ent 1 has [Character#2bd1e730, Monster#61a116c9] in it]
[Area Map]##[ArrayList 0 i=0]
[Area Map]##[ArrayList 0 i=1]
[Area Map]##[ArrayList 10 i=0]
[Area Map]##[ArrayList 11 i=1]
Do note that "Log" is a class i made and the method is "static Logging(String origin, String Action){System.out.println([origin]+"##"+[Action]);"
origin is always the class not that it has to be.
Sorry if this isn't clear. If you need more information to help me i'm more than willing to answer.
Basically the problem is that you're trying to declare extra variables in subclasses as if they can "override" the variable in the superclass. Variables don't work that way - they're not polymorphic.
If you need to give each class a different starting number of hit points, I suggest you create a protected constructor in Entities (which should be renamed, btw - e.g. AbstractEntity) to take the initial value of HP (which should probably be renamed hitPoints). Then each subclass would have a public constructor to call the superconstructor with an appropriate value.
For example:
public abstract class AbstractEntity {
private int hitPoints;
protected AbstractEntity(int initialHitPoints) {
this.hitPoints = initialHitPoints;
}
public int getHitPoints(){
return hitPoints
}
void gainHitPoints(int amount) {
hitPoints += amount;
}
}
public class Monster extends AbstractEntity {
public Monster() {
// Every monster starts off with 4 hit points
super(4);
}
}
Now that's just a matter of changing the initial state. If you wish the different entities to behave differently, you should override the abstract class methods within the subclasses.
I believe your problem is scoping. The HP that Entities* is accessible from your getHP, but your HP in Character and Monster are different variables that happen to have the same name. Additionally, marking HP as private means that subclasses can't access that variable - I think you have protected.
What is probably the correct solution to get rid of HP in Monster and Character, make HP in Entities protected, and set the default HP in the default constructor for Monster and Character.
* It's good style to name your objects in the singular, so this is better named as Entity.
If I understand it correctly, the problem is as follows:
You declared the attribute HP as private in class Entities and declared a new(!) variable in the subclass (see the other answers).
You can resolve the behavior by setting HP by a constructors, e. g.,
class Entitites {
private int HP;
public Entities(int hp) {
this.HP = hp;
}
}
class Monster extends Entities {
public Monster() {
super(4);
}
}

Categories