I am kinda new to Java. Currently, I'm busy with a project. The goal is to create a virtual 2D world with living entities (people) and non-living entitities (for instance vulcanos). People should be able to move each time step (only to the adjacent cells) and can be killed or affected in other ways by the non-living entities.
I thought it was a good idea to start with creating a person class and to put them in the grid. These are my classes so far. However, I am struggling with storing people in the grid (It should be possible to store multiple people in one cell).
This is my person class:
public void setName (String name) {//give the person a name
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {// give the person an age
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) { // set gender of the person
this.gender = gender;
}
public String getSexualPreference() {
return sexualPreference;
}
public void setSexualPreference(String sexualPreference) { // set sexual preference of the person
this.sexualPreference = sexualPreference;
}
public String getLifeGoals() {
return lifeGoals;
}
public void setLifeGoals(String lifeGoals) { // set lifegoals of the person
this.lifeGoals = lifeGoals;
}
public boolean isMarried() {
return isMarried;
}
public void setMarried(boolean isMarried) {
this.isMarried = isMarried;
}
public int getAgressionLevel() {
return agressionLevel;
}
public void setAgressionLevel(int agressionLevel) {
this.agressionLevel = agressionLevel;
}
public Terrain get_terrain(){// specify terrain in which the person lives.
return (Terrain) get_terrain();
}
public Person(boolean randomAge){ //creates a person with a random age and a agression level.
if(randomAge==true){
setAge(ThreadLocalRandom.current().nextInt(0,max_age +1));// this gives the person a random age between 0 and the chosen maximum age.
setAgressionLevel(ThreadLocalRandom.current().nextInt(0,max_agressionLevel +1));//this gives the person a random agression level, scaled from 0-10.
}else{
setAge(0);
}
}
public void act(){ // this method specifies what a person can do all the time
increaseAge();
if(isAlive() == true)
{
int births = reproduce();
for(int b = 0; b < births; b++)
{
Location place = get_terrain().random_space(getX(), getY());
if(place != null)
{
Person newpers = new Person(false);
get_terrain().addObject(newpers, place.getX(), place.getY());
}
}
}
}
private int reproduce(){
int births = 0;
if(canReproduce() && isMarried() && Math.random()*100 <= reproducing_prob){
births +=1;
} return births;
}
private void increaseAge(){// increases the person's age, this can result in its dead
setAge(getAge() + 1);
if(getAge() > max_age)
{
setDead();
}
}
private boolean canReproduce(){
return getAge() >= adultAge;
}
public String toString()
{
return "Person, age " + getAge();
This is my terrain class. I am trying to put elements in random places.
import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom;
public class Terrain {
private static int width;
private static int height;
private final static int nrOfPersons = 200;
public Terrain()
{
addPerson(null, null, null);
}
public static void addPerson(Person p, Location x){ //adds the persons to the terrain
ArrayList<Person> listOfPersons = new ArrayList<Person>();
Terrain.addPerson(p, x);
}
public Location random_space(int x, int y){
int x1 = ThreadLocalRandom.current().nextInt(0, width +1);
int y1 = ThreadLocalRandom.current().nextInt(0, height +1);
if(x1 < 0 || x1 >= width || y1 < 0 || y1 >= height) //check if the location is within the terrain
{
System.out.println("Your location is not within the boundaries of the world");
}
return random_space(x1, y1);
}
And this is my lovation class:
public class Location { //corresponds to a place on the terrain
private int x; //horizontal coordinate
private int y; //vertical coordinate
/**
* Constructor for objects of class place
*/
public Location(int x, int y)
{
this.x = x;
this.y = y;
}
public boolean equals(Object obj)
{
if(obj instanceof Location)
{
Location other = (Location)obj;
return x == other.getX() && y == other.getY();
}
else
{
return false;
}
}
public int getX() //return x coordinate
{
return x;
}
public int getY() //return y cordinate
{
return y;
}
}
The addPerson
method should be an instance method on the Terrain class rather than a static
method. Also, it should act on a field of the class rather than a local variable of the method.
You'll also need a means of connecting a person to a location - that could be many things, a 2-D array representing the entire grid, a map from coordinates to person objects, or a location
field on the person object. Let's say you use a Map, then it would look like this...
public class Terrain {
private static int width;
private static int height;
private final Map<Location, Person> personAtLocation = new HashMap<>();
public void addPerson(Person p, Location x){
personAtLocation.put(x, p);
}
...
}
The best mechanism for connecting a Person to a Location is really going to be dependent on what you're trying to achieve in the rest of your program.
This is certainly false:
public static void addPerson(Person p, Location x){ //adds the persons to the terrain
ArrayList<Person> listOfPersons = new ArrayList<Person>();
Terrain.addPerson(p, x);
}
You should not recreate listOfPersons each time: it clears and destroys it at end: then you keep nothing.
1 Do it in your constructor:
List<Person> listOfPersons = new ArrayList<Person>();
public Terrain()
{
// WHAT ?
// addPerson(null, null, null);
}
2 addPerson=>addPerson does an infinite loop
You have to keep this information too.
The simplest way is a Map: Location => person
Map<Location,Person> grid=new HashMap<Location,Person>();
you put like that:
grid.put(one_location,one_person);
you test like that:
grid.contains(one_location); => get true/false
you get like that:
grid.get(one_location); => get one_person
Important thing: you can have only one person at one place, with a Map. with that, your overwrite old person.
by the way, you dont need anymore listOfPersons.
Other strategies to keep multiple persons at the same location:
get a Map: Person => location. When you will need persons at some place, you have to iterate.
Other possibiliy: keep also a Map< Location,Set< Person>> : for each location, you have a set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With