Pimage array: How to avoid OutOfBoundsException


#1

Hello:
I have 16 images in the array repeated 4 times each and I can put them in an 8x8 board without problems. The magic is from anchnk in this link.
I dont understand how but I suppose the expression that makes it possible is at the end of for loop

       count++;
       if(count %imageArray.length == 0)count = 0; 

When I’ve tried to mess up the imageArray with kaos IntList, the system told me OutOfBounds, of course: there are only 16 images, not 64, but How could i do this? .
my purpose is the typical game of memory, what I get is too tidy:

Any ideas about how do I randomize it???
The code:

// https://forum.processing.org/one/topic/pimage-array-problem#25080000000381019.html

int boxsize;
int margin;
int col;
int row;
int count,num;
IntList kosmos,kaos;

PImage[] imageArray;


void setup() {
  size(800, 800);
  background(0);
  
  imageArray = new PImage[16];
  num= 8;
  if(width >= height){  
     boxsize= height/num;
  }else {
     boxsize= width/num;
  }
  
  kosmos= new IntList(64);
  kaos= new IntList(64);
 

  //Load Images in Memory
  for (int i= 0; i < imageArray.length; i++) {
    imageArray[i] = loadImage("imageArray"+(i)+".png");
  }
  
  kosmos= createkosmos(num);
  println(kosmos);
  kaos= createkaos(num);
  println(kaos);
  
  margin = 10;
  count = 0;
 // noLoop();
}

void draw() {
  int center=margin/2;
  background(10);
  
  
 
  
  for (int x=0; x <num; x++) {
    for (int y=0; y <num; y++) {
       // here the OutOfBounds:
      // int temp_i= kaos.get(count);  
      // image(imageArray[temp_i], center+(x*boxsize)-1, center+(y*boxsize)-1, boxsize-margin, boxsize-margin);
      image(imageArray[count], center+(x*boxsize)-1, center+(y*boxsize)-1, boxsize-margin, boxsize-margin);
      count++;
           
      if(count %imageArray.length == 0)count = 0; // the magic!!!
    }
  }
}
  


IntList createkosmos(int num){
  int tileCount= num *num;
  kosmos= new IntList();
  for(int i= 0; i < tileCount; i++){
    kosmos.append(i);
  }
  return kosmos;
}


// *********************************************************

IntList createkaos(int num){
  int tileCount= num *num;
  kaos= new IntList();
  for(int i= 0; i < tileCount; i++){
    kaos.append(i);
  }
  kaos.shuffle(); 
  return kaos;
}

Thanks a lot!!


#2

Since you have got rid of noLoop() you need to initialise count every frame. Also the lines

    count++;
    if(count %imageArray.length == 0)count = 0; 

can be simplified to a single statement.

  count = 0;
  for (int x=0; x <num; x++) {
    for (int y=0; y <num; y++) {
       // here the OutOfBounds:
      // int temp_i= kaos.get(count);  
      // image(imageArray[temp_i], center+(x*boxsize)-1, center+(y*boxsize)-1, boxsize-margin, boxsize-margin);
      image(imageArray[count], center+(x*boxsize)-1, center+(y*boxsize)-1, boxsize-margin, boxsize-margin);
       count = (count + 1) % imageArray.length;
    }
  }

#3

wuau!!! qué bueno!, It’s math, not magic! Thank you quark
Then, I keep the noLoop();
Maybe I could mess it up before the 8 x8, in portions of 16?
It doesn’t make sense, does it? the frequency would repeat itself, right?
Is it possible to attribute 4 different index to the same image? It’s not possible, is it?
a kind of treatment, an agreement…


#4

The solution is to create a grid array of images in setup and then simply draw them like this

int boxsize;
int margin;
int col;
int row;
int count, num;
IntList kosmos, kaos;

PImage[] imageArray;
PImage[] gridArray;

void setup() {
  size(800, 800);
  background(0);

  imageArray = new PImage[16];
  num= 8;
  if (width >= height) {  
    boxsize= height/num;
  } else {
    boxsize= width/num;
  }

  //Load Images in Memory
  for (int i= 0; i < imageArray.length; i++) {
    imageArray[i] = loadImage("imageArray"+(i)+".png");
  }
  // Create grid array of images using the ones loaded
  gridArray = createRandomGrid(imageArray, num * num);

  margin = 10;
  count = 0;
  // noLoop();
}

void draw() {
  int center=margin/2;
  background(10);
  count = 0;
  for (int x=0; x < num; x++) {
    for (int y=0; y < num; y++) {
      image(gridArray[count], center+(x*boxsize)-1, center+(y*boxsize)-1, boxsize-margin, boxsize-margin);
      count++;
    }
  }
}

/**
 Create a PImage array filled with a number of images in a random position.
 An image can appear more than once
 */
PImage[] createRandomGrid(PImage[] image_array, int nbrPositions) {
  IntList list = new IntList();
  int imageIdx = 0;
  for (int i = 0; i < nbrPositions; i++) {
    list.append(imageIdx);
    imageIdx = (imageIdx + 1) % image_array.length;
  }
  // Now shuffle them
  list.shuffle();
  // Now create the grid array
  PImage[] grid = new PImage[nbrPositions];
  for (int i = 0; i < nbrPositions; i++) {
    grid[i] = image_array[list.get(i)];
  }
  return grid;
}

BTW I don’t have the images so although the code is correct on syntax it might not do exactly what you want :slight_smile: