Must qualify the allocation with

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!

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!

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;
  } */
}
2 Likes

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

1 Like

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. java - No enclosing instance is accessible. Must qualify the allocation with an enclosing instance of type (e.g. x.new A() where x is an instance of ) - Stack Overflow

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!

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!

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

EnhancedLoop7

1 Like

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());
}
1 Like

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:

1 Like

Ok Thank u, I got it!

Thank u too for mini correction!

@quark @GoToLoop there is a possibility that you can answer also at my other question in this post?
https://discourse.processing.org/t/neural-network-help/2871
Because I missing something. Of course If you know stuff about Neural Network :smiley:
Thank you anyway for the appreciated help!

Given that the error message that @Manatee is seeing (“Must qualify the allocation …”) is caused by not using an inner class, I’m not sure describing less “fudgy” ways to write code that still won’t work is that useful! :wink:

In the example posted earlier with Snake and Jumble (which I assume should be Jungle?! :smile:), a static Jumble class cannot create a Snake class like that. An inner class has one hidden extra field than a normal class, which is a reference to the enclosing instance - in this case the instance of PApplet. In effect, whenever you create a Snake inside PApplet your call to new Snake() is translated to something like new Snake(this).

Your Jumble class, if it had a reference to a PApplet, could create a Snake using -

PApplet applet;
Snake snake = applet.new Snake();

I had to look that syntax up - it’s there but not something you see very often.

In general, just use inner classes and stop fighting with the type system. If you really want static classes, make them all static and pass the PApplet into them. Don’t have static classes referring to inner classes or you’ll end up in a mess!

2 Likes

Problem solved :smiley: Dont worry

Ok ok, no problem. I will not use instance method at this point, or I will get with a super messy code!
Anyway is Jumble synonymous of a lot of people/stuff/things

1 Like

My research shows that the “Must qualify the allocation…” message is created when trying to instantiate an inner class without qualifying it with an object of the outer class.

If the sole reason of making an inner class static is to make it behave like a top-level class then it is fudgy or more accurately, bad programming practice. The code I presented was not meant to be a solution to his code (we don’t have it all), it simply shows how to create a true top-level class which he could adapt to his own use.

OK I know this is not technically true :grinning: but the whole truth can be confusing :thinking:. For decades it has been good programming practice to name the Java source file after the class. One reason is that It makes it easier to debug large projects.

We don’t teach the truth, we teach what the learner can comprehend.
Quark 2018 :grinning:

2 Likes

Alright! However, avoid using absolute verbs like must, have to, ought to. :unamused:

Go w/ something like should or need to instead. :innocent:

1 Like

Well, yes if you want it to compile! :smile: Although you learn something new every day - never realised it only applied to public classes - and my Java experience is in the decades.

Sorry my mistake, I meant to use the following in my example

public class Population {

in which case it must be in its own file ‘Population.java’