I am new to inheritance in java and I have the folowing problem. My base class is Plane, its child class is PlaneComponent and PlaneComponent's child class is PassengerCompartment. My program consists of 11 classes, when I ignore the PassengerCompartment class everythig's right. But when I run the whole program I get this message: at Plane.<init>(Plane.java:14)
at PlaneComponent.<init>(PlaneComponent.java:1)
at PassengerCompartment.<init>(PassengerCompartment.java:11)
which is printed repeatedly for so many times that I cannot see the top line of the error. The lines includes in error messages are the bold lines (here printed between ** **).
Plane:
import java.util.*;
public class Plane
{
int cap;
int pl;
public Plane()
{
String desc = "Plane Description";
String title = "Boeing 747";
Random rand = new Random();
cap = rand.nextInt(100) + 51; //initialize cap with 50<value<100
**PassengerCompartment a8 = new PassengerCompartment();**
pl = cap / a8.cap2; // pl = sum of Passenger Compartments
if (cap % a8.cap2 != 0)
{
pl = pl - (cap % a8.cap2) + 1;
}
}
public boolean ready_check()
{
CargoBay a6 = new CargoBay();
a6.ready_check();
for (int i = 0 ; i < 3 ; i++)
{
EquipmentCompartment a7 = new EquipmentCompartment();
a7.ready_check();
}
for(int i = 0; i < pl; i++)
{
PassengerCompartment a8 = new PassengerCompartment();
a8.ready_check();
}
System.out.println("Plane OK!");
return true;
}
public void process(String e)
{
if(e == "SecurityEmployee")
{
SecurityEmployee a14 = new SecurityEmployee();
a14.workOn();
}
if(e == "MaintenanceEmployee")
{
MaintenanceEmployee a15 = new MaintenanceEmployee();
a15.workOn();
}
if(e == "CleaningEmployee")
{
CleaningEmployee a16 = new CleaningEmployee();
a16.workOn();
}
}
public void values()
{
System.out.println("Would you like more info about the plane's capacity? type Y or N");
Scanner input = new Scanner(System.in);
String inp = input.nextLine();
while (!(inp.equals("Y")) && !(inp.equals("N")))
{
System.out.println("Wrong input, please type again");
inp = input.nextLine();
}
if ( inp.equals("Y"))
{
PassengerCompartment a8 = new PassengerCompartment();
System.out.println("Plane's capacity: " + cap);
System.out.println("PassComp's capacity: " + a8.cap2);
System.out.println("Number ofPassenger Compartments " + pl);
}
}
}
PlaneComponent:
**public class PlaneComponent extends Plane**
{
public boolean ready_check()
{
return true;
}
public void process(String desc)
{
Employee.workOn(desc);
}
}
PassengerCompartment:
import java.util.*;
public class PassengerCompartment extends PlaneComponent
{
Random rand = new Random();
boolean inner = rand.nextBoolean();
int cap2;
String desc;
public PassengerCompartment()
**{**
desc = "Passenger Compartment";
cap2 = rand.nextInt(50) + 21; //initialize cap with 20<value<50
}
public boolean ready_check()
{
System.out.println(desc);
if (super.ready_check() == true)
{
System.out.println("Passenger Compartment OK!");
if (inner == true)
{
desc = "Inner Compartment";
System.out.println(desc);
if (super.ready_check() == true)
{
System.out.println("Inner Compartment OK!");
}
}
}
return true;
}
public void process(String desc)
{
super.process(desc);
}
}
You have a circular-inheritance-kind-of-situation (which probably creates a StackOverflow exception):
You instantiate PassengerCompartment a8 = new PassengerCompartment(); in the constructor of Plane.
PassengerCompartment extends PlaneComponent, so the constructor of PlaneComponent is called implicitly (super()), which inherit from Plane. In Plane's constructor you have the mentioned instantiation of PassengerCompartment and so on... So I would strongly advise to not instantiate classes that inherit from your class in the constructor of said class.
I would recommend reading my Q/A on this very topic here.
Your issue is with your inheritance structure.
In Planes constructor, you create an instance of PassengerCompartment.
PassengerCompartment extends PlaneCompartment. PlaneCompartment extends `Plane'. So, you are in a circle.
I don't think it makes sense for PlaneCompartment to extends Plane.
What you have is a 'has-a' relationship. So, Plane has a PlaneCompartment but neither extends each other.
Related
I'm new to Java, and i'm trying to create an automatic working shift schedule.
I want the code to mix four different employees to handle a morning shift and afternoon shift every work day.
I have made some code that just pick a random employee into a shift:
import java.util.Arrays;
import java.util.Random;
public class CreateNewShift {
public static void main(String[] args) {
int startWeek = 30; //Which week would start from?
int endWeek = 32; //which week will you end on?
generateShift(startWeek, endWeek);
}
private static void generateShift(int startWeek, int endWeek) {
String Employees[] = {"Employee1", "Employee2", "Employee3", "Employee4"};
String morningShift;
String afternoonShift;
for (int x = 0; x <= (endWeek - startWeek); x++) { //This is counting the number of weeks
System.out.println("\nWeek: " + (startWeek+x));
for (int i = 1; i <= 5; i++) { //this is finding the next working shift day
morningShift = p.chooseRandomEmployee(Employees);
afternoonShift = p.chooseRandomEmployee(Employees);
if (i == 1) {
System.out.println("Mon: " + morningShift + " + " + afternoonShift);
}
else if (i == 2) {
System.out.println("Tue: " + morningShift + " + " + afternoonShift);
}
else if (i == 3) {
System.out.println("Wed: " + morningShift + " + " + afternoonShift);
}
else if (i == 4) {
System.out.println("Thu: " + morningShift + " + " + afternoonShift);
}
else {
System.out.println("Fri: " + morningShift + " + " + afternoonShift);
}
}
}
}
public class Employee {
public String chooseRandomEmployee(String[] Employees) {
Random r = new Random();
int randomNumber = r.nextInt(Employees.length);
return Employees[randomNumber];
}
}
However, I now want the code to handle more restictions.
So i'm currently trying to add the option for the employees to choose some specific days that they dont want to have a shift. I have done this by adding this code to the Employee class:
public class Employee {
boolean monShift = true;
boolean tueShift = true;
boolean wedShift = true;
boolean thuShift = true;
boolean friShift = true;
public String chooseRandomEmployee(String[] Employees) {
Random r = new Random();
int randomNumber = r.nextInt(Employees.length);
return Employees[randomNumber];
}
}
And then i had tried to create new objects in my main class:
private static void generateShift(int startWeek, int endWeek) {
Employee Employee1 = new Employee("Employee1");
Employee Employee2 = new Employee("Employee2");
Employee Employee3 = new Employee("Employee3");
Employee Employee4 = new Employee("Employee4");
String Employees[] = {"Employee1", "Employee2", "Employee3", "Employee4"};
String morningShift;
String afternoonShift;
....
Quetions:
How can I improve my code in the Employee class to do a check if the random chosen employee have
monShift = true;
I have tried something like this, but i know it will not work, (and does not work either):
import java.util.Random;
public class Employee {
public String chooseRandomEmployee(String[] Employees) {
Random r = new Random();
int randomNumber = r.nextInt(Employees.length);
**if (("Employee" + randomNumber).monShift == false) {**
// Go back and try find a new random employee
}
else {
return Employees[randomNumber];
}
}
}
So i need a way to make my code dynamic to know which object (employee) it has to check if they are available that specific day or not.
Feel free to ask for a deepening if my question is not clear.
Since this i my first question on this forum, I also appriciate feedback if my question and thoughts are too long, or any other comments.
I dont think that putting the chooseRandomEmployee() function inside the Employee object is a good idea beacuse is not a part of the employee, is not an "action" of it. I think you shiudl put it outside but I want to respect your decision so shoudl check the do while loop.
import java.util.Random;
public class Employee {
public String chooseRandomEmployee(String[] Employees) {
int randomNumber;
do {
//Generate a new random number
Random r = new Random();
randomNumber = r.nextInt(Employees.length);
//The line under is the same that saying "If monSift == false return to
//the beginning and start again generating a new number"
} while ("Employee" + randomNumber).monShift == false);
return Employees[randomNumber];
}
}
I am programming a very basic bot for planet wars in java and I cant seem to find the errors in my code. I am receiving a few different error messages but the main issue for me is the error: class, interface, or enum expected. Ive checked my brackets about a thousand times. Any help would be appreciated. Here's my bot code:
import java.util.List;
import java.util.Random;
import shared.Planet;
import shared.PlanetWars;
public class MyNewBot {
public static void doTurn(PlanetWars pw) {
// (1) If we currently have a fleet in flight, then do nothing until
// it arrives.
if (pw.myFleets().size() >= 10) {
return;
}
// (2) Pick one of my planets based on the number of ships
Planet source = null;
int largestForce = 0;
for (Planet p : pw.myPlanets()){
int force = pw.numShips();
if( force > largestForce){
largestForce = force;
source = p;
}
}
// (3) Pick a target planet at random.
Planet dest = null;
int highestGrowthRate = 0;
int shortestDistance = 9999;
for (Planet p = pw.notMyPlanets()){
int growthRate = pw.growthRate();
if( growthRate > highestGrowthRate){
highestGrowthRate = growthRate;
dest = p;
}else if (growthRate == highestGrowthRate){
int distance = pw.distance(source,p);
if (distance < shortestDistance){
shortestDistance = distance;
dest = p;
}
}
}
// (4) Send half the ships from source to destination.
if (source != null && dest != null) {
int numShips = source.numShips() / 2;
pw.issueOrder(source, dest, numShips);
}
}
// Ignore the main method unless you know what you're doing.
// Refer to the doTurn function to code your bot.
public static void main(String[] args) {
String line = "";
String message = "";
int c;
try {
while ((c = System.in.read()) >= 0) {
switch (c) {
case '\n':
if (line.equals("go")) {
PlanetWars pw = new PlanetWars(message);
doTurn(pw);
pw.finishTurn();
message = "";
} else {
message += line + "\n";
}
line = "";
break;
default:
line += (char) c;
break;
}
}
} catch (Exception e) {
// Owned.
}
}
}
and the supporting class files:
package shared;
public class Planet implements Cloneable {
private int planetID;
private int owner;
private int numShips;
private int growthRate;
private double x, y;
public Planet(int planetID, int owner, int numShips, int growthRate,
double x, double y) {
this.planetID = planetID;
this.owner = owner;
this.numShips = numShips;
this.growthRate = growthRate;
this.x = x;
this.y = y;
}
public int planetID() {
return planetID;
}
public int owner() {
return owner;
}
public int numShips() {
return numShips;
}
public int growthRate() {
return growthRate;
}
public double x() {
return x;
}
public double y() {
return y;
}
public void owner(int newOwner) {
this.owner = newOwner;
}
public void numShips(int newNumShips) {
this.numShips = newNumShips;
}
public void addShips(int amount) {
numShips += amount;
}
public void removeShips(int amount) {
numShips -= amount;
}
private Planet(Planet _p) {
planetID = _p.planetID;
owner = _p.owner;
numShips = _p.numShips;
growthRate = _p.growthRate;
x = _p.x;
y = _p.y;
}
public Object clone() {
return new Planet(this);
}
}
package shared;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class PlanetWars {
// Constructs a PlanetWars object instance, given a string containing a
// description of a game state.
public PlanetWars(String gameStateString) {
planets = new ArrayList<Planet>();
fleets = new ArrayList<Fleet>();
parseGameState(gameStateString);
}
// Returns the number of planets. Planets are numbered starting with 0.
public int numPlanets() {
return planets.size();
}
// Returns the planet with the given planet_id. There are NumPlanets()
// planets. They are numbered starting at 0.
public Planet getPlanet(int planetID) {
return planets.get(planetID);
}
// Returns the number of fleets.
public int numFleets() {
return fleets.size();
}
// Returns the fleet with the given fleet_id. Fleets are numbered starting
// with 0. There are NumFleets() fleets. fleet_id's are not consistent from
// one turn to the next.
public Fleet getFleet(int fleetID) {
return fleets.get(fleetID);
}
// Returns a list of all the planets.
public List<Planet> planets() {
return planets;
}
// Return a list of all the planets owned by the current player. By
// convention, the current player is always player number 1.
public List<Planet> myPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() == 1) {
r.add(p);
}
}
return r;
}
// Return a list of all neutral planets.
public List<Planet> neutralPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() == 0) {
r.add(p);
}
}
return r;
}
// Return a list of all the planets owned by rival players. This excludes
// planets owned by the current player, as well as neutral planets.
public List<Planet> enemyPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() >= 2) {
r.add(p);
}
}
return r;
}
// Return a list of all the planets that are not owned by the current
// player. This includes all enemy planets and neutral planets.
public List<Planet> notMyPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() != 1) {
r.add(p);
}
}
return r;
}
// Return a list of all the fleets.
public List<Fleet> fleets() {
List<Fleet> r = new ArrayList<Fleet>();
for (Fleet f : fleets) {
r.add(f);
}
return r;
}
// Return a list of all the fleets owned by the current player.
public List<Fleet> myFleets() {
List<Fleet> r = new ArrayList<Fleet>();
for (Fleet f : fleets) {
if (f.owner() == 1) {
r.add(f);
}
}
return r;
}
// Return a list of all the fleets owned by enemy players.
public List<Fleet> enemyFleets() {
List<Fleet> r = new ArrayList<Fleet>();
for (Fleet f : fleets) {
if (f.owner() != 1) {
r.add(f);
}
}
return r;
}
// Returns the distance between two planets, rounded up to the next highest
// integer. This is the number of discrete time steps it takes to get
// between the two planets.
public int distance(int sourcePlanet, int destinationPlanet) {
Planet source = planets.get(sourcePlanet);
Planet destination = planets.get(destinationPlanet);
double dx = source.x() - destination.x();
double dy = source.y() - destination.y();
return (int) Math.ceil(Math.sqrt(dx * dx + dy * dy));
}
// Returns the distance between two planets, rounded up to the next highest
// integer. This is the number of discrete time steps it takes to get
// between the two planets.
public int distance(Planet source, Planet destination) {
double dx = source.x() - destination.x();
double dy = source.y() - destination.y();
return (int) Math.ceil(Math.sqrt(dx * dx + dy * dy));
}
// Sends an order to the game engine. An order is composed of a source
// planet number, a destination planet number, and a number of ships. A
// few things to keep in mind:
// * you can issue many orders per turn if you like.
// * the planets are numbered starting at zero, not one.
// * you must own the source planet. If you break this rule, the game
// engine kicks your bot out of the game instantly.
// * you can't move more ships than are currently on the source planet.
// * the ships will take a few turns to reach their destination. Travel
// is not instant. See the Distance() function for more info.
public void issueOrder(int sourcePlanet, int destinationPlanet, int
numShips) {
System.out.println("" + sourcePlanet + " " + destinationPlanet + " "
+ numShips);
System.out.flush();
}
// Sends an order to the game engine. An order is composed of a source
// planet number, a destination planet number, and a number of ships. A
// few things to keep in mind:
// * you can issue many orders per turn if you like.
// * the planets are numbered starting at zero, not one.
// * you must own the source planet. If you break this rule, the game
// engine kicks your bot out of the game instantly.
// * you can't move more ships than are currently on the source planet.
// * the ships will take a few turns to reach their destination. Travel
// is not instant. See the Distance() function for more info.
public void issueOrder(Planet source, Planet dest, int numShips) {
System.out.println("" + source.planetID() + " " + dest.planetID() + " "
+ numShips);
System.out.flush();
}
// Sends the game engine a message to let it know that we're done sending
// orders. This signifies the end of our turn.
public void finishTurn() {
System.out.println("go");
System.out.flush();
}
// Returns true if the named player owns at least one planet or fleet.
// Otherwise, the player is deemed to be dead and false is returned.
public boolean isAlive(int playerID) {
for (Planet p : planets) {
if (p.owner() == playerID) {
return true;
}
}
for (Fleet f : fleets) {
if (f.owner() == playerID) {
return true;
}
}
return false;
}
// If the game is not yet over (ie: at least two players have planets or
// fleets remaining), returns -1. If the game is over (ie: only one player
// is left) then that player's number is returned. If there are no
// remaining players, then the game is a draw and 0 is returned.
public int winner() {
Set<Integer> remainingPlayers = new TreeSet<Integer>();
for (Planet p : planets) {
remainingPlayers.add(p.owner());
}
for (Fleet f : fleets) {
remainingPlayers.add(f.owner());
}
switch (remainingPlayers.size()) {
case 0:
return 0;
case 1:
return ((Integer) remainingPlayers.toArray()[0]).intValue();
default:
return -1;
}
}
// Returns the number of ships that the current player has, either located
// on planets or in flight.
public int numShips(int playerID) {
int numShips = 0;
for (Planet p : planets) {
if (p.owner() == playerID) {
numShips += p.numShips();
}
}
for (Fleet f : fleets) {
if (f.owner() == playerID) {
numShips += f.numShips();
}
}
return numShips;
}
// Returns the production of the given player.
public int production(int playerID) {
int prod = 0;
for (Planet p : planets) {
if (p.owner() == playerID) {
prod += p.growthRate();
}
}
return prod;
}
// Parses a game state from a string. On success, returns 1. On failure,
// returns 0.
private int parseGameState(String s) {
planets.clear();
fleets.clear();
int planetID = 0;
String[] lines = s.split("\n");
for (int i = 0; i < lines.length; ++i) {
String line = lines[i];
int commentBegin = line.indexOf('#');
if (commentBegin >= 0) {
line = line.substring(0, commentBegin);
}
if (line.trim().length() == 0) {
continue;
}
String[] tokens = line.split(" ");
if (tokens.length == 0) {
continue;
}
if (tokens[0].equals("P")) {
if (tokens.length != 6) {
return 0;
}
double x = Double.parseDouble(tokens[1]);
double y = Double.parseDouble(tokens[2]);
int owner = Integer.parseInt(tokens[3]);
int numShips = Integer.parseInt(tokens[4]);
int growthRate = Integer.parseInt(tokens[5]);
Planet p = new Planet(planetID++, owner, numShips, growthRate,
x, y);
planets.add(p);
} else if (tokens[0].equals("F")) {
if (tokens.length != 7) {
return 0;
}
int owner = Integer.parseInt(tokens[1]);
int numShips = Integer.parseInt(tokens[2]);
int source = Integer.parseInt(tokens[3]);
int destination = Integer.parseInt(tokens[4]);
int totalTripLength = Integer.parseInt(tokens[5]);
int turnsRemaining = Integer.parseInt(tokens[6]);
Fleet f = new Fleet(owner, numShips, source, destination,
totalTripLength, turnsRemaining);
fleets.add(f);
} else {
return 0;
}
}
return 1;
}
// Store all the planets and fleets. OMG we wouldn't wanna lose all the
// planets and fleets, would we!?
private ArrayList<Planet> planets;
private ArrayList<Fleet> fleets;
}
package shared;
public class Fleet implements Comparable<Fleet>, Cloneable {
private int owner;
private int numShips;
private int sourcePlanet;
private int destinationPlanet;
private int totalTripLength;
private int turnsRemaining;
public Fleet(int owner, int numShips, int sourcePlanet,
int destinationPlanet, int totalTripLength, int turnsRemaining) {
this.owner = owner;
this.numShips = numShips;
this.sourcePlanet = sourcePlanet;
this.destinationPlanet = destinationPlanet;
this.totalTripLength = totalTripLength;
this.turnsRemaining = turnsRemaining;
}
public Fleet(int owner, int numShips) {
this.owner = owner;
this.numShips = numShips;
this.sourcePlanet = -1;
this.destinationPlanet = -1;
this.totalTripLength = -1;
this.turnsRemaining = -1;
}
public int owner() {
return owner;
}
public int numShips() {
return numShips;
}
public int sourcePlanet() {
return sourcePlanet;
}
public int destinationPlanet() {
return destinationPlanet;
}
public int totalTripLength() {
return totalTripLength;
}
public int turnsRemaining() {
return turnsRemaining;
}
public void removeShips(int amount) {
numShips -= amount;
}
// Subtracts one turn remaining. Call this function to make the fleet get
// one turn closer to its destination.
public void TimeStep() {
if (turnsRemaining > 0) {
--turnsRemaining;
} else {
turnsRemaining = 0;
}
}
#Override
public int compareTo(Fleet f) {
return this.numShips - f.numShips;
}
private Fleet(Fleet _f) {
owner = _f.owner;
numShips = _f.numShips;
sourcePlanet = _f.sourcePlanet;
destinationPlanet = _f.destinationPlanet;
totalTripLength = _f.totalTripLength;
turnsRemaining = _f.turnsRemaining;
}
public Object clone() {
return new Fleet(this);
}
}
for (Planet p = pw.notMyPlanets()){ should be for (Planet p : pw.notMyPlanets()){.
You've not posted the Fleet class, so as it is the code won't compile for me. However, the above is the only other error I could see.
I am creating a program in Java to simulate evolution. The way I have it set up, each generation is composed of an array of Organism objects. Each of these arrays is an element in the ArrayList orgGenerations. Each generation, of which there could be any amount before all animals die, can have any amount of Organism objects.
For some reason, in my main loop when the generations are going by, I can have this code without errors, where allOrgs is the Organism array of the current generation and generationNumber is the number generations since the first.
orgGenerations.add(allOrgs);
printOrgs(orgGenerations.get(generationNumber));
printOrgs is a method to display an Organism array, where speed and strength are Organism Field variables:
public void printOrgs(Organism[] list)
{
for (int x=0; x<list.length; x++)
{
System.out.println ("For organism number: " + x + ", speed is: " + list[x].speed + ", and strength is " + list[x].strength + ".");
}
}
Later on, after this loop, when I am trying to retrieve the data to display, I call this very similar code:
printOrgs(orgGenerations.get(0));
This, and every other array in orgGenerations, return a null pointer exception on the print line of the for loop. Why are the Organism objects loosing their values?
Alright, here is all of the code from my main Simulation class. I admit, it might be sort of a mess. The parts that matter are the start and simulator methods. The battle ones are not really applicable to this problem. I think.
import java.awt.FlowLayout;
import java.util.*;
import javax.swing.JFrame;
public class Simulator {
//variables for general keeping track
static Organism[] allOrgs;
static ArrayList<Organism[]> orgGenerations = new ArrayList <Organism[]>();
ArrayList<Integer> battleList = new ArrayList<Integer>();
int deathCount;
boolean done;
boolean runOnce;
//setup
Simulator()
{
done = false;
Scanner asker = new Scanner(System.in);
System.out.println("Input number of organisms for the simulation: ");
int numOfOrgs = asker.nextInt();
asker.close();
Organism[] orgArray = new Organism[numOfOrgs];
for (int i=0; i<numOfOrgs; i++)
{
orgArray[i] = new Organism();
}
allOrgs = orgArray;
}
//graphsOrgs
public void graphOrgs() throws InterruptedException
{
JFrame f = new JFrame("Evolution");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(1000,500);
f.setVisible(true);
Drawer bars = new Drawer();
//System.out.println(orgGenerations.size());
for (int iterator=0;iterator<(orgGenerations.size()-1); iterator++)
{
printOrgs(orgGenerations.get(0));
//The 0 can be any number, no matter what I do it wont work
//System.out.println("first");
f.repaint();
bars.data = orgGenerations.get(iterator);
f.add(bars);
//System.out.println("before");
Thread.sleep(1000);
//System.out.println("end");
}
}
//prints all Orgs and their statistics
public void printOrgs(Organism[] list)
{
System.out.println("Number Of Organisms: " + list.length);
for (int x=0; x<list.length; x++)
{
System.out.println ("For organism number: " + x + ", speed is: " + list[x].speed + ", and strength is " + list[x].strength + ".");
}
System.out.println();
}
//general loop for the organisms lives
public void start(int reproductionTime) throws InterruptedException
{
int generationNumber = 0;
orgGenerations.add(allOrgs);
printOrgs(orgGenerations.get(0));
generationNumber++;
while(true)
{
deathCount = 0;
for(int j=0; j<reproductionTime; j++)
{
battleList.clear();
for(int m=0; m<allOrgs.length; m++)
{
if (allOrgs[m].alive == true)
oneYearBattleCheck(m);
}
battle();
}
reproduction();
if (done == true)
break;
orgGenerations.add(allOrgs);
printOrgs(orgGenerations.get(generationNumber));
generationNumber++;
}
printOrgs(orgGenerations.get(2));
}
//Checks if they have to fight this year
private void oneYearBattleCheck(int m)
{
Random chaos = new Random();
int speedMod = chaos.nextInt(((int)Math.ceil(allOrgs[m].speed/5.0))+1);
int speedSign = chaos.nextInt(2);
if (speedSign == 0)
speedSign--;
speedMod *= speedSign;
int speed = speedMod + allOrgs[m].speed;
if (speed <= 0)
speed=1;
Random encounter = new Random();
boolean battle = false;
int try1 =(encounter.nextInt(speed));
int try2 =(encounter.nextInt(speed));
int try3 =(encounter.nextInt(speed));
int try4 =(encounter.nextInt(speed));
if (try1 == 0 || try2 == 0 || try3 == 0 || try4 == 0 )
{
battle = true;
}
if(battle == true)
{
battleList.add(m);
}
}
//Creates the matches and runs the battle
private void battle()
{
Random rand = new Random();
if (battleList.size()%2 == 1)
{
int luckyDuck = rand.nextInt(battleList.size());
battleList.remove(luckyDuck);
}
for(int k=0; k<(battleList.size()-1);)
{
int competitor1 = rand.nextInt(battleList.size());
battleList.remove(competitor1);
int competitor2 = rand.nextInt(battleList.size());
battleList.remove(competitor2);
//Competitor 1 strength
int strengthMod = rand.nextInt(((int)Math.ceil(allOrgs[competitor1].strength/5.0))+1);
int strengthSign = rand.nextInt(2);
if (strengthSign == 0)
strengthSign--;
strengthMod *= strengthSign;
int comp1Strength = strengthMod + allOrgs[competitor1].strength;
//Competitor 2 strength
strengthMod = rand.nextInt(((int)Math.ceil(allOrgs[competitor2].strength/5.0))+1);
strengthSign = rand.nextInt(2);
if (strengthSign == 0)
strengthSign--;
strengthMod *= strengthSign;
int comp2Strength = strengthMod + allOrgs[competitor2].strength;
//Fight!
if (comp1Strength>comp2Strength)
{
allOrgs[competitor1].life ++;
allOrgs[competitor2].life --;
}
else if (comp2Strength>comp1Strength)
{
allOrgs[competitor2].life ++;
allOrgs[competitor1].life --;
}
if (allOrgs[competitor1].life == 0)
{
allOrgs[competitor1].alive = false;
deathCount++;
}
if (allOrgs[competitor2].life == 0)
{
allOrgs[competitor2].alive = false;
deathCount ++ ;
}
}
}
//New organisms
private void reproduction()
{
//System.out.println("Number of deaths: " + deathCount + "\n");
if (deathCount>=(allOrgs.length-2))
{
done = true;
return;
}
ArrayList<Organism> tempOrgs = new ArrayList<Organism>();
Random chooser = new Random();
int count = 0;
while(true)
{
int partner1 = 0;
int partner2 = 0;
boolean partnerIsAlive = false;
boolean unluckyDuck = false;
//choose partner1
while (partnerIsAlive == false)
{
partner1 = chooser.nextInt(allOrgs.length);
if (allOrgs[partner1] != null)
{
if (allOrgs[partner1].alive == true)
{
partnerIsAlive = true;
}
}
}
count++;
//System.out.println("Count 2: " + count);
partnerIsAlive = false;
//choose partner2
while (partnerIsAlive == false)
{
if (count+deathCount == (allOrgs.length))
{
unluckyDuck=true;
break;
}
partner2 = chooser.nextInt(allOrgs.length);
if (allOrgs[partner2] != null)
{
if (allOrgs[partner2].alive == true)
{
partnerIsAlive = true;
}
}
}
if (unluckyDuck == false)
count++;
//System.out.println("count 2: " + count);
if (unluckyDuck == false)
{
int numOfChildren = (chooser.nextInt(4)+1);
for (int d=0; d<numOfChildren; d++)
{
tempOrgs.add(new Organism(allOrgs[partner1].speed, allOrgs[partner2].speed, allOrgs[partner1].strength, allOrgs[partner2].strength ));
}
allOrgs[partner1] = null;
allOrgs[partner2] = null;
}
if (count+deathCount == (allOrgs.length))
{
Arrays.fill(allOrgs, null);
allOrgs = tempOrgs.toArray(new Organism[tempOrgs.size()-1]);
break;
}
//System.out.println(count);
}
}
}
Main method:
public class Runner {
public static void main(String[] args) throws InterruptedException {
Simulator sim = new Simulator();
int lifeSpan = 20;
sim.start(lifeSpan);
sim.graphOrgs();
}
}
Organism class:
import java.util.Random;
public class Organism {
static Random traitGenerator = new Random();
int life;
int speed;
int strength;
boolean alive;
Organism()
{
speed = (traitGenerator.nextInt(49)+1);
strength = (50-speed);
life = 5;
alive = true;
}
Organism(int strength1, int strength2, int speed1, int speed2)
{
Random gen = new Random();
int speedMod = gen.nextInt(((int)Math.ceil((speed1+speed2)/10.0))+1);
int speedSign = gen.nextInt(2);
if (speedSign == 0)
speedSign--;
speedMod *= speedSign;
//System.out.println(speedMod);
int strengthMod = gen.nextInt(((int)Math.ceil((strength1+strength2)/10.0))+1);
int strengthSign = gen.nextInt(2);
if (strengthSign == 0)
strengthSign--;
strengthMod *= strengthSign;
//System.out.println(strengthMod);
strength = (((int)((strength1+strength2)/2.0))+ strengthMod);
speed = (((int)((speed1+speed2)/2.0))+ speedMod);
alive = true;
life = 5;
}
}
The problem lies in the graphOrgs class when I try to print to check if it is working in preparation for graphing the results. This is when it returns the error. When I try placing the print code in other places in the Simulator class the same thing occurs, a null pointer error. This happens even if it is just after the for loop where the element has been established.
You have code that sets to null elements in your allOrgs array.
allOrgs[partner1] = null;
allOrgs[partner2] = null;
Your orgGenerations list contains the same allOrgs instance multiple times.
Therefore, when you write allOrgs[partner1] = null, the partner1'th element becomes null in all the list elements of orgGenerations, which is why the print method fails.
You should create a copy of the array (you can use Arrays.copy) each time you add a new generation to the list (and consider also creating copies of the Organism instances, if you want each generation to record the past state of the Organisms and not their final state).
I'm trying to make a 2d array of an object in java. This object in java has several private variables and methods in it, but won't work. Can someone tell me why and is there a way I can fix this?
This is the exeception I keep getting for each line of code where I try to initialize and iterate through my 2d object.
"Exception in thread "main" java.lang.NullPointerException
at wumpusworld.WumpusWorldGame.main(WumpusWorldGame.java:50)
Java Result: 1"
Here is my main class:
public class WumpusWorldGame {
class Agent {
private boolean safe;
private boolean stench;
private boolean breeze;
public Agent() {
safe = false;
stench = false;
breeze = false;
}
}
/**
* #param args
* the command line arguments
* #throws java.lang.Exception
*/
public static void main(String [] args) {
// WumpusFrame blah =new WumpusFrame();
// blah.setVisible(true);
Scanner input = new Scanner(System.in);
int agentpts = 0;
System.out.println("Welcome to Wumpus World!\n ******************************************** \n");
//ArrayList<ArrayList<WumpusWorld>> woah = new ArrayList<ArrayList<WumpusWorld>>();
for (int i = 0 ; i < 5 ; i++) {
WumpusWorldObject [] [] woah = new WumpusWorldObject [5] [5];
System.out.println( "*********************************\n Please enter the exact coordinates of the wumpus (r and c).");
int wumpusR = input.nextInt();
int wumpusC = input.nextInt();
woah[wumpusR][wumpusC].setPoints(-3000);
woah[wumpusR][wumpusC].setWumpus();
if ((wumpusR <= 5 || wumpusC <= 5) && (wumpusR >= 0 || wumpusC >= 0)) {
woah[wumpusR][wumpusC].setStench();
}
if (wumpusC != 0) {
woah[wumpusR][wumpusC - 1].getStench();
}
if (wumpusR != 0) {
woah[wumpusR - 1][wumpusC].setStench();
}
if (wumpusC != 4) {
woah[wumpusR][wumpusC + 1].setStench();
}
if (wumpusR != 4) {
woah[wumpusR + 1][wumpusC].setStench();
}
System.out.println( "**************************************\n Please enter the exact coordinates of the Gold(r and c).");
int goldR = input.nextInt();
int goldC = input.nextInt();
woah[goldR][goldC].setGold();
System.out.println("***************************************\n How many pits would you like in your wumpus world?");
int numPits = input.nextInt();
for (int k = 0 ; k < numPits ; k++) {
System.out.println("Enter the row location of the pit");
int r = input.nextInt();
System.out.println("Enter the column location of the pit");
int c = input.nextInt();
woah[r][c].setPit();
if ((r <= 4 || c <= 4) && (r >= 0 || c >= 0)) {
woah[r][c].setBreeze();
}
if (c != 0) {
woah[r][c - 1].setBreeze();
}
if (r != 0) {
woah[r - 1][c].setBreeze();
}
if (c != 4) {
woah[r][c + 1].setBreeze();
}
if (r != 4) {
woah[r + 1][c].setBreeze();
}
}
for (int x = 0 ; x < 4 ; x++) {
int j = 0;
while (j < 4) {
agentpts = agentpts + woah[x][j].getPoints();
Agent [] [] k = new Agent [4] [4];
if (woah[x][j].getWumpus() == true) {
agentpts = agentpts + woah[x][j].getPoints();
System.out.println("You just got ate by the wumpus!!! THE HORROR!! Your score is " + agentpts);
}
if (woah[x][j].getStench() == true) {
k[x][j].stench = true;
System.out.println("You smell something funny... smells like old person.");
}
if (woah[x][j].getBreeze() == true) {
k[x][j].breeze = true;
System.out.println("You hear a breeze. yeah");
}
if (woah[x][j].getPit() == true) {
agentpts = agentpts + woah[x][j].getPoints();
System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH! you dumb bith, your dead now.");
}
// if breeze or stench, if breeze and stench, if nothing, etc then move.
k[x][j].safe = true;
// if(k[i][j].isSafe()!=true){
// } else { }
}
}
}
}
}
Here is my class object that I'm trying to implement:
package wumpusworld;
/**
*
* #author Jacob
*/
public class WumpusWorldObject {
private boolean stench;
private boolean breeze;
private boolean pit;
private boolean wumpus;
private boolean gold;
private int points;
private boolean safe;
public WumpusWorldObject(){
}
public boolean getPit() {
return pit;
}
public void setPit() {
this.pit = true;
}
public boolean getWumpus() {
return wumpus;
}
public void setWumpus() {
this.wumpus = true;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
public boolean getStench() {
return stench;
}
public void setStench() {
this.stench = true;
}
public boolean getBreeze() {
return breeze;
}
public void setBreeze() {
this.breeze = true;
}
public boolean getSafe() {
return safe;
}
public void setSafe() {
this.safe = true;
}
public void setGold(){
this.gold=true;
}
}
Creating array doesn't mean it will be automatically filled with new instances of your class. There are many reasons for that, like
which constructor should be used
what data should be passed to this constructor.
This kind of decisions shouldn't be made by compiler, but by programmer, so you need to invoke constructor explicitly.
After creating array iterate over it and fill it with new instances of your class.
for (int i=0; i<yourArray.length; i++)
for (int j=0; j<yourArray[i].length; j++)
yourArray[i][j] = new ...//here you should use constructor
AClass[][] obj = new AClass[50][50];
is not enough, you have to create instances of them like
obj[i][j] = new AClass(...);
In your code the line
woah[wumpusR][wumpusC].setPoints(-3000);
must be after
woah[wumpusR][wumpusC] = new WumpusWorldObject();
.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
public static void main(String[] args) {
Scanner data = new Scanner(System.in);
double low = data.nextDouble();
Attacker type = new Attacker();
type.setLow(low);
Defender fight = new Defender();
fight.result();
}
Defender class
private int ATKvalue;
public void result() {
Attacker xxx = new Attacker();
ATKvalue = xxx.ATKtype();
}
Attacker Class
public Attacker() {
double low = 0
}
public void setLow(double lowpercent) {
low = lowpercent;
}
public int ATKtype() {
System.out.println(low);
}
I simplified my code, but it is the same idea. When I run it, low is equal to 0 instead of the user input. How can I change it equal to user input?
my code :
import java.util.Random;
public class Attacker {
public double low, med, genPercent;
private int lowtype, medtype, hightype;
public Attacker() {
low = 0;
lowtype = 0;
medtype = 1;
hightype = 2;
}
public void setLow(double low) {
this.low = low;
}
public double getLow(){
return(low);
}
public void setMed(double med) {
this.med = med;
}
public int ATKtype() {
System.out.println(low);
Random generator = new Random();
genPercent = generator.nextDouble() * 100.0;
System.out.println(genPercent);
System.out.println(low);
if ( genPercent <= low ) {
System.out.println("low");
return (lowtype);
}
else if ( genPercent <= med + low ) {
System.out.println("med");
return (medtype);
}
else {
System.out.println("high");
return (hightype);
}
}
}
import java.util.Random;
public class Defender {
private int lowtype, medtype, hightype, DEFvalue, ATKvalue;
private double genPercent;
public Defender() {
lowtype = 0;
medtype = 1;
hightype = 2;
}
public int getDEFtype() {
Random generator = new Random();
genPercent = generator.nextDouble() ;
if ( genPercent <= 1d/3d ) {
return (lowtype);
}
else if ( genPercent <= 2d/3d ) {
return (medtype);
}
else {
return (hightype);
}
}
public void result() {
Manager ATK = new Manager();
Defender DEF = new Defender();
DEFvalue = DEF.getDEFtype();
ATKvalue = ATK.getATKtype();
System.out.println(DEFvalue);
System.out.println(ATKvalue);
if ( ATKvalue == DEFvalue ) {
System.out.println("block");
}
else {
System.out.println("hit");
}
}
}
import java.util.Scanner;
public class Manager {
public int getATKtype() {
Attacker genType = new Attacker();
int attack = genType.ATKtype();
return (attack);
}
public static void main(String[] args) {
System.out.print("Number of attack rounds: " );
Scanner data = new Scanner(System.in);
int round = data.nextInt();
System.out.println("Enter percentages for the number of attacks that will be "
+ "directed: low, medium, high. The total of the three percentages "
+ "must sum to 100%");
System.out.print("Percentage of attacks that will be aimed low: ");
double low = data.nextDouble();
System.out.print("Percentage of attacks that will be aimed at medium height: ");
double med = data.nextDouble();
System.out.print("Percentage of attacks that will be aimed high: ");
double high = data.nextDouble();
if ( low + med + high != 100 ){
System.out.println("The sum is not 100%. Equal probablilty will be used.");
low = med = high = 100d/3d ;
}
Attacker type = new Attacker();
type.setLow(low);
type.setMed(med);
System.out.print(type.getLow());
for ( int i = 0 ; i < round ; i++) {
Defender fight = new Defender(Attacker type);
fight.result();
}
}
}
Old answer.
You are recreating instances of your Attacker class and the problem with that is the low value is associated with only that specific instance. So when you create a new one after the fact in Defender, you lose the value. I've also separated Attacker and Defender completely and created a Battle class that will take instances of Attacker and Defender and decide which one wins. That class is a face off of instances. This improves readability, logic, etc. It's a better design. Yours is sort of a mess with not much structure (no offense - just learning):
Main class:
public static void main(String args[])
{
Scanner input = new Scanner(System.in);
System.out.println("Enter attack low: ");
double low = input.nextDouble();
Attacker attacker = new Attacker();
attacker.setLow(low);
Defender defender = new Defender();
Battle battle = new Battle(attacker, defender);
battle.result();
}
Attacker class:
import java.util.Random;
public class Attacker {
public double low = 0;
public void setLow(double low) {
this.low = low;
}
public double getATKtype() {
double genPercent = new Random().nextDouble() * 100.0;
System.out.println(low);
if ( genPercent <= low ) {
System.out.println("Attack: low");
return 0; // low type
}
else if ( genPercent <= 1 + low ) { // genPercent <= medium + low
System.out.println("Attack: medium");
return 1; // medium type
}
else {
System.out.println("Attack: high");
return 2; // high type
}
}
}
Defender class:
import java.util.Random;
public class Defender {
public double getDEFtype() {
double genPercent = new Random().nextDouble();
if ( genPercent <= 1d/3d ) {
System.out.println("Defense: low");
return 0; // low type
}
else if ( genPercent <= 2d/3d ) {
System.out.println("Defense: medium");
return 1; // medium type
}
else {
System.out.println("Defense: high");
return 2; // high type
}
}
}
And finally, Battle class:
public class Battle {
private double attackValue = 0;
private double defenseValue = 0;
public Battle (Attacker attacker, Defender defender) {
attackValue = attacker.getATKtype();
defenseValue = defender.getDEFtype();
}
public void result() {
if (attackValue == defenseValue) {
System.out.println("Block");
} else if (attackValue > defenseValue) {
System.out.println("Hit");
} else { // attack is lower than defense
// do what you need for that
}
}
}
To pass a value into another class you will need to pass it as a parameter either of the other class's constructor or a setter method.
So if you give Attacker a setLow(int low) method, you can pass in the information.
public void setLow(int low) {
this.low = low;
}
And then call the method when needed.