Must qualify the allocation with


#1

I google this problem but otehr one sort out!
I cannot create a new instance of one of my class, here is the main:

Snake snake;
A tmp;

int frameSpeed = 1;//the frame rate
int score = 0;
//int bestScore = 0;
int attempts = 1;
Population pop;
int amountOfSnakes = 200;

void setup()
{//on startup
  size(600, 800);
  frameRate(frameSpeed);  
  tmp = new A();
  snake = new Snake();  
  pop = new Population(amountOfSnakes);// create new population of size 200  
}

void draw() {
  background(40);
  fill(255);
etc...
etc...
etc...

Well, A and Snake class had been created with no error but new Population not!
Snake and A are non-statich class, Population is a static class!!!
Help, im struggling with no clue or result!


#2

Can you please post a small example program that demonstrates the problem? Note that this should not be your full sketch, but it should be enough for us to copy and paste to see ourselves.

You can find more info in this guide:


#3

Can we see the population class–or at least the most important bits.


#4

We also need to know the actual error message provided by Processing.


#5

EDIT

I’m sorry I did not see that you had declared it already! I will continue looking at your code, but I’ll keep my original explanation in case if someone else has a sort of similar problem :sweat_smile:

As of now, I would like to also ask that you post a little more about your problem, so that we could help out further!

Original Response:

From what you posted, take a look at the top of your code:

Snake snake;
A tmp;

Looks like A and Snake are the only ones working, because it seems that those are the only ones that you actually declared :smiley:

Just add this to the top of your code:

Population pop;

To match what you have here in setup() :

pop = new Population(amountOfSnakes);

You need to make sure you declare a variable or class before you can actually try to use it and such. If Processing is saying something like “Must qualify the allocation” that means that you are trying to initialize a variable, in this case: pop, and you didn’t even allocate any memory to it by declaring it yet! It’s easy to forget especially if you build the class first, but yes always remember to declare your objects up top, trust me- I’ve been there too :joy:

Hope that clears it up!

EnhancedLoop7


#6

He had it all along!


#7

Why is Population static and the others not? Does it work if it isn’t static?


#8

Give me some times, Im working on to reply to all of you!


#9

I apologize with everybody!
I solved my problem adjusting the folder name with the class that hold the “main” structurre (setup() and draw()) and now it starts to work again!
So the problem was 75% a folder problem solved changed main class name and folder name!
Thank you all for fast reply and super help!


#10

It works yes with static and not.
I need it static because there a instance class that allow me to do that:

Snake child = new Snake();
child = Population.crossover(father, mother);

instead of:

Snake child = new Snake();
child = father.crossover(mother);

It looks more readable because Im god and I play doing crossover, so I made a child using crossover between 2 params! :smiley:


#11

Now I lost the error cause I got some others in the old files, but It was something related to instance of main class Snakefield correlated to population!


#12

I certainly do!
I was so tired last night and I create a real no clue post. Sorry, I will do next ones in the right way!


#13

Yeah sure. I fixed the problem but I post it anyway!

static class Jumble
{
  Snake snakes[]; //All Snakes part of snakes

  int bestScore; //Best score ever achieved
  int bestFitness; //Best fitness ever achieved
  float mutationRate; //Global mutation rate
  int maxPopulation; //Max number of population
  int generation;

  Jumble(float MutationRate, int MaxPopulation)
  {
    mutationRate = MutationRate;
    maxPopulation = MaxPopulation;
    snakes = new Snake[MaxPopulation];
  }

  Jumble(int MaxPopulation)
  {
    snakes = new Snake[MaxPopulation];
    //Be God, create all the Snakes
    for (int i = 0; i < snakes.length; i++)
    {
      snakes[i] = new Snake();
    }
  }

//------------------------------------------------------------------------------------------------------------------

  //Calculates fitness of every snake
  void calcFitness()
  {
    for (int i = 0; i < snakes.length; i++)
    {
      snakes[i].calcFitness();
    }
  }

  //Let's play Noah's Ark
  void naturalSelection()
  {
    Snake[] newGeneration = new Snake[snakes.length]; //next generation of snakes

    for (int i = 0; i < newGeneration.length; i++)
    {      
      //select 2 parents based on fitness
      Snake mother = choseSnake();
      Snake father = choseSnake();
      
      //crossover the 2 snakes to create the child
      Snake child = Population.crossover(motehr, father); //TODO
      //Snake child = parent1.crossover(parent2); //You have could use Instance method of a class
      
      //mutate the child (weird thing to type)
      child.mutate(globalMutationRate);
      //add the child to the next generation
      newGeneration[i] = child;
      
      //newGeneration[i] = selectSnake().clone().mutate(globalMutationRate); //uncomment this line to do natural selection without crossover
    }
  }

  //-----------------------------------------------------------------------------------------------

  Snake choseSnake()
  {
    /*
    This function take all percentage of the snaked and transform into a POOL (array)
    subdivided by the percentage of the snake
    i.e. 
    A=50
    B=30
    C=10
    D=10

    Pool [A|A|A|A|A|B|B|B|C|D];

    Then convert the percentage before insert the snake into array using sigmoid()
    So I get value between 0 and 1 and finally take the best creating new Population
     */
    float[] allFitness = new float[maxPopulation];
    
    //Insert all fitness into array
    for(int i = 0; i < snakes.length; i++)
    {
      allFitness[i] = snakes[i].getFitness();
      //Convert fitness into value between 0<->1
      allFitness[i] *= 100;
      //Make it to percentage
      //NOT SURE TODO, test it until insert fitness!
    }
  }

//-------------------------------------------------------------------------------------------------------

  //Create next Population
  /* void nextGeneration()
  {
    for(int i = 0; i < maxPopulation; i++)
    {
      Snake mother = floor(random())//Fish into the pool
      Snake father = floor(random())//Fish into the pool
      Snake child = Population.crossover(mother, father); //Crossover daddy and mommy
      child.mutate(this.mutationRate);//Mutate the child
      this.snakes[i] = child;//Inser him in the new Jumble
    }
    generation += 1;
  } */
}

#14

Thank you for long reply but was my stupid mistake!
Sorry for your time wasted!


#15

Fair enough. Odd reason! And you shouldn’t need the Population field in that case?!

The error message you quoted is caused by trying to reference a non-static inner class from a static nested class - see eg. https://stackoverflow.com/questions/47541459/no-enclosing-instance-is-accessible-must-qualify-the-allocation-with-an-enclosi


#16

Well I definitively have some similar problem now!
This is the error:

No enclosing instance of type Main is accessible. Must qualify the allocation with an enclosing instance of type Main (e.g. x.new A() where x is an instance of Main).

Here is the class involved:
Main


int FPS = 1;//the frame rate
int score = 0;
int bestScore = 0;
int attempts = 1;
int jumbleSize = 200;

Jumble jumble;
Snake snake;

void setup()
{
  //on startup
  size(600, 800);
  frameRate(FPS);      
  snake = new Snake();  
  jumble = new Jumble();// create new population of size 200  
}

void draw()
{
  background(40);
  fill(255);
  stroke(255);
  line(0, 600, 600, 600);
  textSize(30);
  text("Score: " + score, 10, 640);
  text("Length: " + snake.len, 10, 680);
  text("Attempts: " + attempts, 360, 640);
  text("Speed: " + FPS, 360, 680);
  
  textSize(20);
  text("Control Snake using 'wasd'", 100, 725);
  text("Increase/Decrease speed using + or -", 100, 750);
  text("Enable/Disable wall using L " + "(" + snake.getWall() + ")", 100, 775);
  //pos = pos.add(vel);//accelera :D
  //rect(pos.x, pos.y, 10, 10);
  if(snake.getAlive())
  {
    snake.show();
    snake.move();
    // snake.look();//Print what he should see
  }
  else
  {
    redraw();
    snake.reset();
    attempts += 1;        
  } 
}

//---------------------------------------------------------------------------------------------------------------------------------------------------------  

void keyPressed()
{
  switch(key)
  {
  case 'w'://toggle show all  
    snake.turn(1);//Up
    break;
  case 'a'://toggle show all    
    snake.turn(2);//Left
    break;
  case 's'://toggle show all    
    snake.turn(3);//Down
    break;
  case 'd'://toggle show all    
    snake.turn(4);//Right
    break;
  case '+'://speed up frame rate
    FPS += 10;
    frameRate(FPS);
    break;
  case '-'://slow down frame rate
    if (FPS > 10) //Check framerate > 10
    {
      FPS -= 10;
      frameRate(FPS);
    }
    break;
  case 'l':
    snake.triggerWall();
    break;
  case 'c'://Enable cheat, gnam gnam
    //Food food0 = new Food(100, 100);
    //food0.show();
    //Food food1 = new Food(120, 100);
    //food1.show();
    break;
  }  
}

Jumble

static class Jumble
{
  Snake snakes[]; //All Snakes part of snakes

  int bestScore; //Best score ever achieved
  int bestFitness; //Best fitness ever achieved
  float mutationRate; //Global mutation rate
  int maxPopulation; //Max number of population
  int generation;

  Jumble()
  {      
    int bestScore = 0; //Best score ever achieved
    int bestFitness = 0; //Best fitness ever achieved
    float mutationRate = 0; //Global mutation rate
    int maxPopulation = 0; //Max number of population
    int generation = 0;  
  }

  Jumble(float MutationRate, int MaxPopulation)
  {
    mutationRate = MutationRate;
    maxPopulation = MaxPopulation;
    snakes = new Snake[MaxPopulation];
  }

  Jumble(int MaxPopulation)
  {
    snakes = new Snake[MaxPopulation];
    //Be God, create all the Snakes
    for (int i = 0; i < snakes.length; i++)
    {
      snakes[i] = new Snake(); //HERE GET THE ERROR
    }
  }

Now I tried put the class Jumble non-static and I have no error, probably I am doing the same thing as last time where @quark and @neilcsmith help me!


#17

Well u re right!
I think I have to adapt to don’t have static class and use Random class and avoid instance method… So sad about this, I really like instance methods!


#18

Oh no it’s not a problem at all, we both made mistakes :smiley:

EnhancedLoop7


#19

The main problem is that any class defined in the main window is treated as an Inner Class, one way to make it a top level class is to declare it as static. This is a fudge and generally should be avoided.

In Processing the only true way to make a top level class is to declare it in its own .java tab named after the class. For instance your Population class would be in a tab called Population.java.

IMPORTANT the tab name must be exactly the same as the class name including case followed by “.java” otherwise it won’t work.

Here is a Population class (true top-level class)

// This is in a tab called 'Population.java'

import processing.core.*;

class Population {
  private PApplet app;
  private int nbrSnakes;
  
  public Population(PApplet papp, int nbrOfSnakes){
    app = papp;
    nbrSnakes = nbrOfSnakes;
  }
  
  public void setNbrSnakes(int nos){
    nbrSnakes = nos;
  }
  
  public int getNbrSnakes(){
    return nbrSnakes;
  }
    
}

and in the main tab use this to test it.

Population p;

void setup(){
  p = new Population(this, 40);
  println(p.getNbrSnakes());
}

#20

That’s not necessarily true! As long as a “.java” file doesn’t have any class or interface declared as public, it can have any name! :stuck_out_tongue:

Although true, declaring a nested class as static makes it behave pretty much as a top level class as well. :sunglasses: