Problem with a loop

Hi i tried to use the code i recieve from my post “a pathfinding solution” to make my creatur find food.

here is the case :
my creatures walk randomly and when they are hungry they go to the closest food, but my foods have a life time so its disapeard after a while. Other foods appear constantly and my creatures eat it when they pass on it.

float currentSmallest;
float dist;
for(int a = herb3f.size()-1; a >= 0; a--){
	Herbivor3F h3f = herb3f.get(a);
	if(h3f.faim() == false){
	h3f.randomMv();
	}
	else{
		PVector target = new PVector(0,0);
		currentSmallest = (parent.height * parent.height) + (parent.width * parent.width);
		while(F2.hasNext()){
			Food2 f = F2.next();
			dist = ((h3f.position.x - f.position.x) * (h3f.position.x - f.position.x)) + ((h3f.position.y - f.position.y) * (h3f.position.y - f.position.y));
			if( dist < currentSmallest){
				currentSmallest = dist;
				target.x = f.position.x;
				target.y = f.position.y;
			}
		}
		h3f.findFood(target);
	}
}

my problem:
Well my creatures dont go to the foods and go on the top left corner on my screen (the currentSmallest) when they are hungry (the condition “faim” is true)
i tried to make loop but every time is bug.

Thanks for yours times and help.

i dont know if i give enough informations, so if you need more just tell me

It seems that you never enter that block:

if( dist < currentSmallest){
	currentSmallest = dist;
	target.x = f.position.x;
	target.y = f.position.y;
}

So target stays (0, 0) and thus your creatures go to the upper left corner.

My guess is that you don’t even enter the while loop. Can you add this line just before you while loop to check that hypothesis:

println(F2.hasNext());
1 Like

Yes i never enter the loop, its say false every time.
But i need my while to point the food or i get an error

We would need to see your Food2 class then.

i tried a do while but i got the exception :

java.util.NoSuchElementException
at java.util.ArrayList$Itr.next(Unknown Source)
at mechanisme.World.run(World.java:338)

the error occur with Food2 f = F2.next();

and here is my food2:

public class Food2 {
	PApplet parent;
	ArrayList<PVector> food2;
	ArrayList<Tree2> tree2;
	float food2live;
	public PVector position;
	
	public Food2(int nombFood2, PApplet p){
		parent = p;
		food2 = new ArrayList<PVector>();
		food2live = 255;
	}
	
	@SuppressWarnings("deprecation")
	public void add(PVector l){
		food2.add(l.get());
	}
	
	public void grow(Tree2 t){
		ArrayList<PVector> tree2 = t.getTree2();
		for(int i = 0; i < tree2.size(); i++){
			if(parent.random(1) < 0.001){
				int nombfood2 = 1;
				for(int a = 0; a < nombfood2; a++){
					food2.add(new PVector(parent.random(tree2.get(i).x -50, tree2.get(i).x +50), parent.random(tree2.get(i).y-50, tree2.get(i).y +50)));
				}
			}
		}	
	}
	
	
	public void run(PApplet p){
		for(PVector f : food2){
			//parent.rectMode(PConstants.CENTER);
			parent.ellipseMode(PConstants.CENTER);
			parent.stroke(0,food2live);
			parent.fill(153,153,0,food2live);
			//parent.rect(f.x, f.y, 8, 8);
			parent.ellipse(f.x, f.y, 8, 8);
		}
	}
	
	public void growOld(Food2 f){
		ArrayList<PVector> food2 = f.getFood2();
		for(int i = food2.size()-1; i >= 0; i--){
			food2live -= 0.06;
		}
	}
	
	public ArrayList<PVector> getFood2(){
		return food2;
	}
	
	public PVector position(){
		return position;
	}
	
	public boolean rotten(){
		if(food2live < 0.0){
			return true;
		}
		else{
			return false;
		}
	}
}

how do you define your F2 variable in your first code?

i did not… thats the error right ?

when i run my food2 in the beginning of my code i do that: (but its not connected)

Iterator<Food2> F2 = food2.iterator();
while(F2.hasNext()){
	Food2 f2 = F2.next();
	f2.run(parent);
	f2.grow(tree2);
	f2.growOld(f2);
	if(f2.rotten()){
		F2.remove();
	}
}

And how do you define food2 in the context of your first code?

i dont know what do you mean by that.

here is my code only for food2

public class World {
	ArrayList<Food2> food2;

	public World(PApplet p){
		parent = p;
		int nombfood2 = 1;
		food2 = new ArrayList<Food2>();
		for(int i = 0; i < nombfood2; i++){
			food2.add(new Food2(nombfood2, p));
		}
	}

	public void run(){
		Iterator<Food2> F2 = food2.iterator();
		while(F2.hasNext()){
			Food2 f2 = F2.next();
			f2.run(parent);
			f2.grow(tree2);
			f2.growOld(f2);
			if(f2.rotten()){
				F2.remove();
			}
		}

	        float currentSmallest;
		float dist;
		for(int a = herb3f.size()-1; a >= 0; a--){
			Herbivor3F h3f = herb3f.get(a);
			if(h3f.faim() == false){
				h3f.randomMv();
			}
			else{
				PVector target = new PVector(0,0);
				currentSmallest = (parent.height * parent.height) + (parent.width * parent.width);
				do{
					Iterator<Food2> F2f = food2.iterator();
					Food2 f = F2f.next();
					dist = ((h3f.position.x - f.position.x) * (h3f.position.x - f.position.x)) + ((h3f.position.y - f.position.y) * (h3f.position.y - f.position.y));
					if( dist < currentSmallest){
						currentSmallest = dist;
						target.x = f.position.x;
						target.y = f.position.y;
					}
				}while(F2.hasNext());
				h3f.findFood(target);
			}
		}
	}
}

sorry for my lack of knowledge.
And i put F2f instead of F2 because its give me an error(duplicate local variable) when i dont change it

Don’t apologize for that, we have all been there and we all lack of knowledge somewhere :wink:

The problem with your last code is that you have already itirated through all of your food with that code:

while(F2.hasNext()){
  Food2 f2 = F2.next();
  f2.run(parent);
  f2.grow(tree2);
  f2.growOld(f2);
  if(f2.rotten()){
    F2.remove();
  }
}

So when you do this:

do{
   ...
}while(F2.hasNext());

You do it only once because it does not have next element anymore.

Try replace that code:

do{
  Iterator<Food2> F2f = food2.iterator();
  Food2 f = F2f.next();
  dist = ((h3f.position.x - f.position.x) * (h3f.position.x - f.position.x)) + ((h3f.position.y - f.position.y) * (h3f.position.y - f.position.y));
  if( dist < currentSmallest){
    currentSmallest = dist;
    target.x = f.position.x;
    target.y = f.position.y;
  }
}while(F2.hasNext());

by this one:

for (Iterator<Food2> i = food2.iterator (); i.hasNext(); ) {
  Food2 f = i.next();

  dist = ((h3f.position.x - f.position.x) * (h3f.position.x - f.position.x)) + ((h3f.position.y - f.position.y) * (h3f.position.y - f.position.y));
  if( dist < currentSmallest){
    currentSmallest = dist;
    target.x = f.position.x;
    target.y = f.position.y;
  }
}

i got an error java.lang.NullPointerException on the line :

dist = ((h3f.position.x - f.position.x) * (h3f.position.x - f.position.x)) + ((h3f.position.y - f.position.y) * (h3f.position.y - f.position.y));

so my code dont know what is “f” now right ?

when i compare it whit my other behavior (find water) the main difference is thats the food2 appear and disappear so the list change all the time

float currentSmallest;
float dist;
for(int a = herb3f.size()-1; a >= 0; a--){
	Herbivor3F h3f = herb3f.get(a);
	if(h3f.soif() == false){
		h3f.randomMv();
	}
	else{
		PVector target = new PVector(0,0);
		currentSmallest = (parent.height * parent.height) + (parent.width * parent.width);
		for(int b = lac.size()-1; b >= 0; b--){
			Lac l = lac.get(b);
			dist = ((h3f.position.x - l.position.x) * (h3f.position.x - l.position.x)) + ((h3f.position.y - l.position.y) * (h3f.position.y - l.position.y));
			if( dist < currentSmallest){
				currentSmallest = dist;
				target.x = l.position.x;
				target.y = l.position.y;
			}
		}
		h3f.findWater(target);
	}
}

With all the code you posted I don’t know how everything is working together, if this is all the same piece of code or if this is different parts used at different places…

It is really confusing! :slight_smile:

Is it possible to get your full code with some comments around the part that is causing you the issue?

here is my code for the food2 and the herbivor3F is use now:
sorry its a little bit messy
my world class:

public class World {
	PApplet parent;
	
	Tree2 tree2;
	ArrayList<Food2> food2;
	ArrayList<Herbivor3F> herb3f;
	ArrayList<Lac> lac;
	

	
	public World(PApplet p){
		parent = p;
		
			
		int nombtree2 = 20;
		tree2 = new Tree2();
		for(int i = 0; i < nombtree2; i++){
			tree2.add(new PVector(p.random(p.width-1000, p.width-150), p.random(p.height-700, p.height-150)));
		}
				
		int nombfood2 = 1;
		food2 = new ArrayList<Food2>();
		for(int i = 0; i < nombfood2; i++){
			food2.add(new Food2(nombfood2, p));
		}
		
			
		int nombHerb3f = 10;
		herb3f = new ArrayList<Herbivor3F>();
		for(int i = 0; i < nombHerb3f; i++){
			PVector l = new PVector(p.random(p.width),p.random(p.height));
			DNA2 dna2 = new DNA2(p);
			herb3f.add(new Herbivor3F(l,dna2,p));
		}
		
		
		int nomlac = 3;
		lac = new ArrayList<Lac>();
		for(int i = 0; i < nomlac; i++){
			PVector l = new PVector(p.random(p.width-1000, p.width-150), p.random(p.height-700, p.height-150));
			lac.add(new Lac(p, l));
		}
	
	
	public void run(){
		
		
		////trees and fruits
		tree2.run(parent);
			
			
		if(parent.random(1) < 0.01){
			food2.add(new Food2(0, parent));
		}
		
		Iterator<Food2> F2 = food2.iterator();
		while(F2.hasNext()){
			Food2 f2 = F2.next();
			f2.run(parent);
			f2.grow(tree2);
			f2.growOld(f2);
			if(f2.rotten()){
				F2.remove();
			}
		}
		
		////lac
		for(int i = lac.size()-1; i >= 0; i--){
			Lac l = lac.get(i);
			l.run(parent);
		}
		
			
		////female
		Iterator<Herbivor3F> H3F = herb3f.iterator();
		while(H3F.hasNext()){
			Herbivor3F h3f = H3F.next();
			h3f.run(parent);
			//h3f.randomMv();
			if(h3f.dead()){
				H3F.remove();
			}
		}
		
		for(int a = herb3f.size()-1; a >= 0; a--){
			Herbivor3F h3f = herb3f.get(a);
			for(int i = food2.size()-1; i >= 0; i--){
				Food2 f2 = food2.get(i);
				h3f.eat2(f2);
			}
		}
		
		////drink water
		for(int a = herb3f.size()-1; a >= 0; a--){
			for(int b = lac.size()-1; b >= 0; b--){
				Herbivor3F h3f = herb3f.get(a);
				Lac l = lac.get(b);
				PVector lpos = l.position;
				PVector h3fpos = h3f.position;
				float dist = PVector.dist(lpos, h3fpos);
				if(h3f.getR() > dist){
					h3f.drinkWater();
				}
			}
		}
		
		
		/*
		////find water work great
		if(herb3f.size() > 0){
			float currentSmallest;
			float dist;
			for(int a = herb3f.size()-1; a >= 0; a--){
				Herbivor3F h3f = herb3f.get(a);
				if(h3f.soif() == false){
					h3f.randomMv();
				}
				else{
					PVector target = new PVector(0,0);
					currentSmallest = (parent.height * parent.height) + (parent.width * parent.width);
					for(int b = lac.size()-1; b >= 0; b--){
						Lac l = lac.get(b);
						dist = ((h3f.position.x - l.position.x) * (h3f.position.x - l.position.x)) + ((h3f.position.y - l.position.y) * (h3f.position.y - l.position.y));
						if( dist < currentSmallest){
							currentSmallest = dist;
							target.x = l.position.x;
							target.y = l.position.y;
						}
					}
					h3f.findWater(target);
				}
			}
		}
		*/
		
		
	//////Find food2
		float currentSmallest;
		float dist;
		for(int a = herb3f.size()-1; a >= 0; a--){
			Herbivor3F h3f = herb3f.get(a);
			if(h3f.faim() == false){
				h3f.randomMv();
			}
			else{
				PVector target = new PVector(0,0);
				currentSmallest = (parent.height * parent.height) + (parent.width * parent.width);
				
				for(Iterator<Food2> i = food2.iterator(); i.hasNext();){
					Food2 f = i.next();

                                        ////here i have my error java null pointer execption//////
					dist = ((h3f.position.x - f.position.x) * (h3f.position.x - f.position.x)) + ((h3f.position.y - f.position.y) * (h3f.position.y - f.position.y));


					if(dist < currentSmallest){
						currentSmallest = dist;
						target.x = f.position.x;
						target.y = f.position.y;
					}
				}
				
				h3f.findFood(target);
			}
		}
	}

}

my class Food2:

public class Food2 {
	PApplet parent;
	ArrayList<PVector> food2;
	ArrayList<Tree2> tree2;
	float food2live;
	public PVector position;
	
	public Food2(int nombFood2, PApplet p){
		parent = p;
		food2 = new ArrayList<PVector>();
		food2live = 255;
	}
	
	@SuppressWarnings("deprecation")
	public void add(PVector l){
		food2.add(l.get());
	}
	
	public void grow(Tree2 t){
		ArrayList<PVector> tree2 = t.getTree2();
		for(int i = 0; i < tree2.size(); i++){
			if(parent.random(1) < 0.001){
				int nombfood2 = 1;
				for(int a = 0; a < nombfood2; a++){
					food2.add(new PVector(parent.random(tree2.get(i).x -50, tree2.get(i).x +50), parent.random(tree2.get(i).y-50, tree2.get(i).y +50)));
				}
			}
		}	
	}
	
	
	public void run(PApplet p){
		for(PVector f : food2){
			//parent.rectMode(PConstants.CENTER);
			parent.ellipseMode(PConstants.CENTER);
			parent.stroke(0,food2live);
			parent.fill(153,153,0,food2live);
			//parent.rect(f.x, f.y, 8, 8);
			parent.ellipse(f.x, f.y, 8, 8);
		}
	}
	
	public void growOld(Food2 f){
		ArrayList<PVector> food2 = f.getFood2();
		for(int i = food2.size()-1; i >= 0; i--){
			food2live -= 0.06;
		}
	}
	
	public ArrayList<PVector> getFood2(){
		return food2;
	}
	
	public PVector position(){
		return position;
	}
	
	public boolean rotten(){
		if(food2live < 0.0){
			return true;
		}
		else{
			return false;
		}
	}
}

its too messy or its ok ?

It makes more sense now, thanks :slight_smile:

Is there a reason why you wouold want to use an iterator?
Why don’t you use the same template as with the water?

Also you never initialize the position variable in your Food2 class. I think this is why you get the nullPointerException. It is not because the food does not exists but because position does not exist

public Food2(int nombFood2, PApplet p){
  parent = p;
  food2 = new ArrayList<PVector>();
  food2live = 255;
}

Also you don’t need this function:

public PVector position(){
  return position;
}

That’s because you have set your position variable as public so you can access it directly:

public PVector position;

One last thing: can you explain what this arrayList: ArrayList&lt;PVector&gt; food2; is used for? I think you are mixing some things up here.