Is it possible to nest multiple versions of a 2D array in another array?

edited April 2014 in Questions about Code

Hi,

I'm a processing newbie so please forgive any misuse of terminology in trying to explain my question.

I can't quite get my head around the code that would allow multiple configurations of a 2D array to be nested in another array so that they could be individually called upon and drawn. For instance, in the code below I've commented out two additional array configurations that I'd like to be able to swap out with the one that loads at the end of setup.

Any help would be much appreciated.

Many thanks, Daniel

void setup() {
  size(500, 300); // manually defined size based on intended grid

  // define grid to be a 2D array
  int[][] grid;

  // specify size of the array in rows 1st and columns 2nd
  grid = new int[3][5];

  // set the dimensions of square grid units
  int unitSize = 100;
  // variable for the number of units in the grid rows  
  int rows = grid.length;
  // variable for the number of units in the grid columns
  int cols = grid[0].length;

  // define palette
  int white = 255;
  int gray1 = 238;
  int gray2 = 222;
  int gray3 = 202;
  int gray4 = 178;
  int gray5 = 146;
  int gray6 = 108;
  int gray7 = 64;
  int black = 0;

  noStroke();
  background(white);

  // default grid (#1 of 3 possible) 
  // column 0 
  grid[0][0] = white;
  grid[1][0] = gray3;
  grid[2][0] = gray4;
  // column 1
  grid[0][1] = white;
  grid[1][1] = black; 
  grid[2][1] = gray1;
  // column 2
  grid[0][2] = gray7;
  grid[1][2] = gray1;
  grid[2][2] = white;
  // column 3
  grid[0][3] = gray3;
  grid[1][3] = gray1;
  grid[2][3] = white;
  // column 4
  grid[0][4] = white;
  grid[1][4] = gray6;
  grid[2][4] = white; // end of initial grid (#1 of 3)

  //  // grid #2 of 3 possible 
  //  // column 0 
  //  grid[0][0] = gray2;
  //  grid[1][0] = gray2;
  //  grid[2][0] = white;
  //  // column 1
  //  grid[0][1] = gray2;
  //  grid[1][1] = gray5; 
  //  grid[2][1] = gray5;
  //  // column 2
  //  grid[0][2] = white;
  //  grid[1][2] = gray2;
  //  grid[2][2] = gray2;
  //  // column 3
  //  grid[0][3] = white;
  //  grid[1][3] = gray2;
  //  grid[2][3] = white;
  //  // column 4
  //  grid[0][4] = gray2;
  //  grid[1][4] = gray2;
  //  grid[2][4] = white; // end grid (#2 of 3)

  //  // grid #3 of 3 possible 
  //  // column 0 
  //  grid[0][0] = white;
  //  grid[1][0] = white;
  //  grid[2][0] = gray3;
  //  // column 1
  //  grid[0][1] = white;
  //  grid[1][1] = gray3; 
  //  grid[2][1] = gray3;
  //  // column 2
  //  grid[0][2] = white;
  //  grid[1][2] = gray3;
  //  grid[2][2] = gray3;
  //  // column 3
  //  grid[0][3] = white;
  //  grid[1][3] = gray3;
  //  grid[2][3] = black;
  //  // column 4
  //  grid[0][4] = white;
  //  grid[1][4] = gray3;
  //  grid[2][4] = gray4; // end grid (#3 of 3)

  // draw initial grid
  for (int i=0; i<rows; i++) {
    for (int j=0; j<cols; j++) {
      fill(grid[i][j]);
      pushMatrix();
      translate(j*unitSize, i*unitSize);
      rect(0, 0, unitSize, unitSize);
      popMatrix();
    }
  }
} // end setup()

void draw() {
} // end draw()

Answers

  • Sure, you can use an array of 2D arrays.

    You could also use an ArrayList that holds 2D arrays.

    You might also want to look at encapsulating your data inside an object instead of a bunch of arrays.

    Which approach you take depends entirely on your context and what makes the most sense to you.

  • edited April 2014

    An alternative version:

    // forum.processing.org/two/discussion/4491/
    // is-it-possible-to-nest-multiple-versions-of-
    // a-2d-array-in-another-array
    
    static final int GRAYS = 9;
    static final color[] grays = new color[GRAYS];
    
    static {
      for (int i = GRAYS; i-- != 0;
        grays[i] = min(0400 - 040*i, 0xFF));
    
      println(grays);
    }
    
    static final int DIM = 100, ROWS = 3, COLS = 5;
    final color[][] grid = new color[ROWS][COLS];
    
    {
      // column 0 
      grid[0][0] = grays[0];
      grid[1][0] = grays[3];
      grid[2][0] = grays[4];
      // column 1
      grid[0][1] = grays[5];
      grid[1][1] = grays[8];
      grid[2][1] = grays[1];
      // column 2
      grid[0][2] = grays[7];
      grid[1][2] = grays[1];
      grid[2][2] = grays[0];
      // column 3
      grid[0][3] = grays[3];
      grid[1][3] = grays[1];
      grid[2][3] = grays[2];
      // column 4
      grid[0][4] = grays[0];
      grid[1][4] = grays[6];
      grid[2][4] = grays[0];
    }
    
    void setup() {
      size(COLS*DIM, ROWS*DIM, JAVA2D);
      frameRate(60);
      noLoop();
      smooth(4);
    
      noStroke();
      rectMode(CORNER);
    
      background(grays[0]);
    }
    
    void draw() {
      for (int r = 0; r != ROWS; translate(0, DIM)) {
        final color[] cols = grid[r++];
    
        for (int c = 0; c != COLS; c++) {
          fill(cols[c]);
          rect(c*DIM, 0, DIM, DIM);
        }
      }
    }
    
  • edited April 2014 Answer ✓

    I guess I've found some way -> a 3D array! (*)

    /**
     * Grid Palette (v2.03)
     * by  des812 (2014/Apr)
     * mod GoToLoop
     *
     * forum.processing.org/two/discussion/4491/
     * is-it-possible-to-nest-multiple-versions-of-
     * a-2d-array-in-another-array
     */
    
    static final int GRAYS = 9;
    static final color[] grays = new color[GRAYS];
    
    static {
      for (int i = GRAYS; i-- != 0;
        grays[i] = min(0400 - 040*i, 0xFF));
    
      println(grays);
    }
    
    static final int DIM = 100, PALETTES = 3;
    static final int ROWS = 3, COLS = 5;
    final color[][][] grids = new color[PALETTES][ROWS][COLS];
    
    color[][] grid;
    int idx;
    
    {
      //Palette 0:
      grid = grids[0];
    
      // column 0 
      grid[0][0] = grays[0];
      grid[1][0] = grays[3];
      grid[2][0] = grays[4];
      // column 1
      grid[0][1] = grays[0];
      grid[1][1] = grays[8];
      grid[2][1] = grays[1];
      // column 2
      grid[0][2] = grays[7];
      grid[1][2] = grays[1];
      grid[2][2] = grays[0];
      // column 3
      grid[0][3] = grays[3];
      grid[1][3] = grays[1];
      grid[2][3] = grays[0];
      // column 4
      grid[0][4] = grays[0];
      grid[1][4] = grays[6];
      grid[2][4] = grays[0];
    }
    
    {
      //Palette 1:
      grid = grids[1];
    
      // column 0 
      grid[0][0] = grays[2];
      grid[1][0] = grays[2];
      grid[2][0] = grays[0];
      // column 1
      grid[0][1] = grays[2];
      grid[1][1] = grays[5];
      grid[2][1] = grays[5];
      // column 2
      grid[0][2] = grays[0];
      grid[1][2] = grays[2];
      grid[2][2] = grays[2];
      // column 3
      grid[0][3] = grays[3];
      grid[1][3] = grays[2];
      grid[2][3] = grays[0];
      // column 4
      grid[0][4] = grays[2];
      grid[1][4] = grays[2];
      grid[2][4] = grays[0];
    }
    
    {
      //Palette 2:
      grid = grids[2];
    
      // column 0 
      grid[0][0] = grays[0];
      grid[1][0] = grays[0];
      grid[2][0] = grays[3];
      // column 1
      grid[0][1] = grays[0];
      grid[1][1] = grays[3];
      grid[2][1] = grays[3];
      // column 2
      grid[0][2] = grays[0];
      grid[1][2] = grays[3];
      grid[2][2] = grays[3];
      // column 3
      grid[0][3] = grays[0];
      grid[1][3] = grays[3];
      grid[2][3] = grays[8];
      // column 4
      grid[0][4] = grays[0];
      grid[1][4] = grays[3];
      grid[2][4] = grays[4];
    }
    
    void setup() {
      size(COLS*DIM, ROWS*DIM, JAVA2D);
      frameRate(60);
      noLoop();
      smooth(4);
    
      noStroke();
      rectMode(CORNER);
    }
    
    void draw() {
      grid = grids[idx];
    
      for (color[] row: grid) {
        for (int c = COLS; c-- != 0;) {
          fill(row[c]);
          rect(c*DIM, 0, DIM, DIM);
        }
    
        translate(0, DIM);
      }
    }
    
    void keyPressed() {
      if (++idx == grids.length)  idx = 0;
      if (!online)  frame.setTitle("Palette Index # " + idx);
      redraw();
    }
    
    void mousePressed() {
      keyPressed();
    }
    
  • Brilliant! I had a hunch about a 3D array but for the life of me I couldn't figure out how to implement it. This is fantastic... I'm going to dissect it line by line... and hopefully bend it to my will. Thank you so much. If I get stumped trying to comprehend something or have trouble bending it to my will is it ok if I post more questions to this thread? Thanks again!

  • edited April 2014

    Of course you can keep posting more questions! ^:)^
    And btW, a slightly compacter version 3: ~:>

    /**
     * Grid Palette (v3.01)
     * by  des812 (2014/Apr)
     * mod GoToLoop
     *
     * forum.processing.org/two/discussion/4491/
     * is-it-possible-to-nest-multiple-versions-of-
     * a-2d-array-in-another-array
     */
    
    static final int GRAYS = 9;
    static final color[] grays = new color[GRAYS];
    
    static {
      for (int i = GRAYS; i-- != 0;
        grays[i] = min(0400 - 040*i, 0xFF));
    
      println(grays);
    }
    
    static final int DIM = 100, PALETTES = 3;
    static final int ROWS = 3, COLS = 5;
    final color[][][] grids = new color[PALETTES][ROWS][COLS];
    
    int idx;
    
    { // Palette 0:
      final int[] indices = {
        0, 3, 4, // column 0
        0, 8, 1, // column 1
        7, 1, 0, // column 2
        3, 1, 0, // column 3
        0, 6, 0  // column 4
      };
    
      fillPalette(grids, 0, indices);
    }
    
    { // Palette 1:
      final int[] indices = {
        2, 2, 0, // column 0
        2, 5, 5, // column 1
        0, 2, 2, // column 2
        3, 2, 0, // column 3
        2, 2, 0  // column 4
      };
    
      fillPalette(grids, 1, indices);
    }
    
    { // Palette 2:
      final int[] indices = {
        0, 0, 3, // column 0
        0, 3, 3, // column 1
        0, 3, 3, // column 2
        0, 3, 8, // column 3
        0, 3, 4  // column 4
      };
    
      fillPalette(grids, 2, indices);
    }
    
    static final void
    fillPalette(color[][][] palette, int num, int[] seq) {
      final color[][] grid = palette[num];
      final int rows = grid.length, len = seq.length;
    
      int i = 0, r = 0, c = 0;
    
      while (i != len) {
        grid[r][c] = grays[seq[i++]];
        if ((r = (r+1) % rows) == 0)  c++;
      }
    }
    
    void setup() {
      size(COLS*DIM, ROWS*DIM, JAVA2D);
      frameRate(60);
      noLoop();
      smooth(4);
    
      noStroke();
      rectMode(CORNER);
    }
    
    void draw() {
      final color[][] grid = grids[idx];
    
      for (color[] row: grid) {
        for (int c = COLS; c-- != 0;) {
          fill(row[c]);
          rect(c*DIM, 0, DIM, DIM);
        }
    
        translate(0, DIM);
      }
    }
    
    void keyPressed() {
      if (++idx == grids.length)  idx = 0;
      if (!online)  frame.setTitle("Palette Index # " + idx);
      redraw();
    }
    
    void mousePressed() {
      keyPressed();
    }
    
  • Excellent... thanks! I'm starting to more closely analyze your code now... wow.

    Question: Is it possible for the palette arrays to reference rows instead of columns? My intention is to many more palette arrays and I think the code would be more visually logical if the rows of code corresponded to rows as they will be drawn. Granted I'm coming at this from a visual-centric perspective... and attempting to explore writing code as idiot proof and scalable as possible... since at this point my visual ideas greatly outweigh my programming ability.

    Again, your help is greatly appreciated.

  • edited April 2014

    Is it possible for the palette arrays to reference rows instead of columns?

    According to how the array's dimension order is laid out:
    final color[][][] grids = new color[PALETTES][ROWS][COLS];

    Right after the outer dimension comes the row dimension. Thus it's already in the way most of us like! :-j

    What is dissonant is how you had laid out the gray scale in your original example!
    Instead of defining row by row, you chose to define column by column:

    // column 0
      grid[0][0] = white;  // 0
      grid[1][0] = gray3;  // 3
      grid[2][0] = gray4;  // 4
    

    So I've followed your lead, since I didn't know whether changing to row by row would confuse &/or displease you! /:)
    But now that you asked for it, I've modified fillPalette() to accept a sequence or rows in order to fill the grid up:

    http://studio.processingtogether.com/sp/pad/export/ro.9tBDwfhlJ2R9D/latest

    /**
     * Grid Palette (v4.11)
     * by  des812 (2014/Apr)
     * mod GoToLoop
     *
     * forum.processing.org/two/discussion/4491/
     * is-it-possible-to-nest-multiple-versions-of-
     * a-2d-array-in-another-array
     *
     * studio.processingtogether.com/sp/pad/export/
     * ro.9tBDwfhlJ2R9D/latest
     */
    
    static final int GRAYS = 9;
    static final color[] grays = new color[GRAYS];
    
    static // Java only
    {
      for (int i = GRAYS; i-- != 0;
        grays[i] = min(0400 - 040*i, 0xFF));
    
      println(grays);
    }
    
    static final int DIM = 100, PALETTES = 3;
    static final int ROWS = 3, COLS = 5;
    final color[][][] grids = new color[PALETTES][ROWS][COLS];
    
    int idx;
    
    { // Palette 0:
      fillPalette(grids[0], new int[] {
        0, 0, 7, 3, 0, // row 0
        3, 8, 1, 1, 6, // row 1
        4, 1, 0, 0, 0  // row 2
      }  
      );
    }
    
    { // Palette 1:
      fillPalette(grids[1], new int[] {
        2, 2, 0, 3, 2, // row 0
        2, 5, 2, 2, 2, // row 1
        0, 5, 2, 0, 0  // row 2
      }
      );
    }
    
    { // Palette 2:
      fillPalette(grids[2], new int[] {
        0, 0, 0, 0, 0, // row 0
        0, 3, 3, 3, 3, // row 1
        3, 3, 3, 8, 4  // row 2
      }
      );
    }
    
    static final void fillPalette(color[][] grid, int[] seq) {
      int i = 0;
      for (color[] row: grid)
        for (int c = 0; c != COLS;
          row[c++] = grays[seq[i++]]);
    }
    
    void setup() {
      size(COLS*DIM, ROWS*DIM, JAVA2D);
      frameRate(60);
      noLoop();
      smooth(4);
    
      noStroke();
      rectMode(CORNER);
    }
    
    void draw() {
      final color[][] grid = grids[idx];
    
      for (color[] row: grid) {
        for (int c = COLS; c-- != 0;) {
          fill(row[c]);
          rect(c*DIM, 0, DIM, DIM);
        }
    
        translate(0, DIM);
      }
    }
    
    void keyPressed() {
      if (++idx == grids.length)  idx = 0;
      if (!online)  frame.setTitle("Palette Index # " + idx);
      redraw();
    }
    
    void mousePressed() {
      keyPressed();
    }
    
  • What is dissonant is how you had laid out the gray scale in your original example! Instead of defining row by row, you chose to define column by column

    I think I understand how that would seem dissonant from a code perspective. Guilty as charged... thanks for humoring me and for following my initial structure to reduce the chance of confusing me. Do you teach?

    From a visual perspective I structured it that way as illustrated:

    processing_grab_1

    Having fillPalette() accept a sequence of rows in order to fill the grid up is likewise easier for me to visualize as compared to v3.01, if that makes any sense... so thank you!

  • edited April 2014

    From a programmer's perspective, row x col arrays are much easier than the opposite. Check my cropped image below:

    Grid

    Also, posted the code online:
    http://studio.processingtogether.com/sp/pad/export/ro.9tBDwfhlJ2R9D/latest

  • That makes sense. I was looking at the code you posted and noticed the version changed. I've been monkeying around with v4.10 for a few hours this morning. Were the changes you made to v4.11 only comments?

  • edited April 2014

    Just comments like line #17 to warn it doesn't work in JavaScript mode.
    Plus the header includes link for the online version!
    In short, nothing has changed! ;)

  • Is there an advantage to using noLoop() in setup() and redraw() in keyPressed() as opposed to letting functions loop? Doesn't noLoop() need to be the last line in setup()? Is smooth() beneficial even if only rectangles will be drawn?

    How would I go about making specific keys and/or mouse gestures move in different directions within the 3D array?

    Thanks!

  • Is there an advantage to using noLoop() in setup() and redraw() in keyPressed() as opposed to letting functions loop?

    noLoop() turns off draw()'s auto-call. And thus sets the program in an eternal w8-for-user-reaction state.
    Most obvious advantage is CPU & GPU saving! Another subtle 1 is that we control when canvas is updated w/ redraw()!

    Doesn't noLoop() need to be the last line in setup()?

    Nope! It merely sets looping variable to false. ;)
    Also, draw() is always called once after setup()! @-)

    Is smooth() beneficial even if only rectangles will be drawn?

    In this case, it doesn't seem so. Try out smooth(2); and smooth(0); and check whether render quality ever changes!

  • How would I go about making specific keys and/or mouse gestures move in different directions within the 3D array?

    I don't get what's exactly being moved? :-/

  • That all makes sense. Thank you.

    Imagine that there are 25 (5 x 5) palette arrays instead of 3 and the middle one (#12) is the array initially drawn. Pressing the UP key would cause #7 to be drawn. From there pressing the RIGHT key would draw #8, then #9. From there you could only go UP to #4, LEFT to #8 or DOWN to #12. So the number of palette arrays would define the boundaries that could be navigated and thus drawn. Perhaps the corresponding mouse movements would function likewise. Does this make any sense?

  • edited October 2015

    So those palettes of grids are also grids themselves!? So the whole thing is 4D! @-)
    Fortunately, there's a way to emulate a 2D behavior in a 1D array. So let's leave grids as 3D. B-)
    But now, instead of constant PALETTES, we're gonna split it as PROWS & PCOLS instead.
    final color[][][] grids = new color[PROWS*PCOLS][ROWS][COLS];

    As you probably had noticed by now, variable idx represents the palette's current index. The grids' outer dimension.
    Version 4.xx just circularly increased it every time the user hit a mouse or a key button.

    This time you wish to specify 4 directions in order to navigate through palette's grids.
    Horizontal movement is merely either decrease or increase idx. No much diff. on how it currently is.
    Now for vertical movement, a whole row gotta be leaped over.
    That translates as either decrease or increase idx by PCOLS value! *-:)

    For those 2 diff. tasks, I've defined functions moveHorizontal() & moveVertical().
    Check them out in new version 5.0 below. Online version's got updated as well: >:/

    /**
     * Grid Palette (v5.23)
     * by  des812 (2014/Apr)
     * mod GoToLoop
     *
     * forum.processing.org/two/discussion/4491/
     * is-it-possible-to-nest-multiple-versions-of-
     * a-2d-array-in-another-array
     *
     * studio.processingtogether.com/sp/pad/export/
     * ro.9tBDwfhlJ2R9D/latest
     */
    
    static final int GRAYS = 9;
    static final color[] grays = new color[GRAYS];
    
    static // Java only
    {
      for (int i = GRAYS; i-- != 0;
        grays[i] = min(0400 - 040*i, 0xFF));
    
      println(grays);
      println();
    }
    
    static final int DIM = 100, FPS = 12, QUALITY = 0;
    static final int PROWS = 1, PCOLS = 3;
    static final int ROWS = 3, COLS = 5;
    final color[][][] grids = new color[PROWS*PCOLS][ROWS][COLS];
    
    int idx;
    
    { // Palette 0x1:
      fillPalette(grids[0], new int[] {
        0, 0, 7, 3, 0, // row 0
        3, 8, 1, 1, 6, // row 1
        4, 1, 0, 0, 0  // row 2
      }  
      );
    }
    
    { // Palette 0x1:
      fillPalette(grids[1], new int[] {
        2, 2, 0, 3, 2, // row 0
        2, 5, 2, 2, 2, // row 1
        0, 5, 2, 0, 0  // row 2
      }
      );
    }
    
    { // Palette 0x2:
      fillPalette(grids[2], new int[] {
        0, 0, 0, 0, 0, // row 0
        0, 3, 3, 3, 3, // row 1
        3, 3, 3, 8, 4  // row 2
      }
      );
    }
    
    static final void fillPalette(color[][] grid, int[] seq) {
      int i = 0;
      for (color[] row: grid)
        for (int c = 0; c != COLS;
          row[c++] = grays[seq[i++]]);
    }
    
    void setup() {
      size(COLS*DIM, ROWS*DIM, JAVA2D);
      frameRate(FPS);
      noLoop();
      smooth(QUALITY);
    
      noStroke();
      rectMode(CORNER);
    
      online = 1/2 == 1/2.;
    }
    
    void draw() {
      final color[][] grid = grids[idx];
    
      for (color[] row: grid) {
        for (int c = COLS; c-- != 0;) {
          fill(row[c]);
          rect(c*DIM, 0, DIM, DIM);
        }
    
        translate(0, DIM);
      }
    
      displayInfo();
    }
    
    void displayInfo() {
      final String msg = "Palette Index: #" + idx
        + "\t[" + (idx/PCOLS | 0) + ", " + idx%PCOLS + "]";
    
      println(msg);
      if (!online)  frame.setTitle(msg);
    }
    
    void mousePressed() {
      jumpPalette(mouseButton == LEFT? -1 : 1);  
      redraw();
    }
    
    void mouseWheel(MouseEvent e) {
      jumpPalette(e.getCount()*PCOLS);
      redraw();
    }
    
    void keyPressed() {
      final int k = keyCode;
    
      if      (k == 'A' | k == LEFT)   jumpPalette(-1);
      else if (k == 'D' | k == RIGHT)  jumpPalette(1);
      else if (k == 'W' | k == UP)     jumpPalette(-PCOLS);
      else if (k == 'S' | k == DOWN)   jumpPalette(PCOLS);
    
      redraw();
    }
    
    void jumpPalette(int step) {
      idx = (idx + step + grids.length) % grids.length;
    }
    
  • edited April 2014

    Actually, I've just realized there's no really a need to have separate moveHorizontal() & moveVertical() functions! :(|)
    Well, unless you dislike allowing movements à la Pac-Man's maze, where it shows up at the opposite side! [-(
    Anyways, renamed moveHorizontal() as jumpPalette(). And deleted moveVertical()! :-B

  • This is fantastic... thank you! I've been chewing on it for a few hours already. I have more questions now, of course... but I'm going to keep working on a new sketch that will at least make the questions more tangible... and perhaps some answers will reveal themselves by doing so.

  • edited April 2014

    removed duplicate posting...not sure how that happened...sorry

  • I've identified some questions and tried to resolve them but am stuck again... so I've pasted the new sketch below (with comments in the areas I'm struggling with) in the hopes that you can again point me in the right direction.

    Here's what I'm trying to accomplish:

    1. make the centermost palette (#10 in this case) be the palette drawn by default... [(PROWS*PCOLS)]/2?
    2. prevent wrapping in all directions so that horizontal movements terminate on every row as vertical movements currently do with respect to columns.
    3. make mouse movements correspond to directional key presses.

    Continued thanks for your help.

    /**
     * Grid Palette (v5.01) edited by des812
     * by  des812 (2014/Apr)
     * mod GoToLoop
     *
     * forum.processing.org/two/discussion/4491/
     * is-it-possible-to-nest-multiple-versions-of-
     * a-2d-array-in-another-array
     *
     *
     * 
     */
    
    static final int GRAYS = 9;
    static final color[] grays = new color[GRAYS];
    
    //static // Java only
    {
      for (int i = GRAYS; i-- != 0;
        grays[i] = min(0400 - 040*i, 0xFF));
    
      println(grays);
    }
    
    static final int DIM = 100;
    static final int PROWS = 7, PCOLS = 3; // array of PALETTES
    static final int ROWS = 3, COLS = 5;
    final color[][][] grids = new color[PROWS*PCOLS][ROWS][COLS]; // [PROWS*PCOLS] = total PALETTES
    
    int idx;
    
    // PALETTES ROW 0
    
    { // Palette 0:
      fillPalette(grids[0], new int[] {
        8, 8, 8, 8, 8, // row 0
        8, 7, 7, 7, 7, // row 1
        8, 7, 6, 6, 6  // row 2
      }  
      );
    }
    
    { // Palette 1:
      fillPalette(grids[1], new int[] {
        8, 8, 8, 8, 8, // row 0
        7, 7, 7, 7, 7, // row 1
        6, 6, 6, 6, 6  // row 2
      }
      );
    }
    
    { // Palette 2:
      fillPalette(grids[2], new int[] {
        8, 8, 8, 8, 8, // row 0
        7, 7, 7, 7, 8, // row 1
        6, 6, 6, 7, 8  // row 2
      }
      );
    }
    
    // PALETTES ROW 1
    
    { // Palette 3:
      fillPalette(grids[3], new int[] {
        8, 7, 6, 5, 5, // row 0
        8, 7, 6, 5, 4, // row 1
        8, 7, 6, 5, 4  // row 2
      }  
      );
    }
    
    { // Palette 4:
      fillPalette(grids[4], new int[] {
        5, 5, 5, 5, 5, // row 0
        4, 4, 4, 4, 4, // row 1
        3, 3, 3, 3, 3  // row 2
      }
      );
    }
    
    { // Palette 5:
      fillPalette(grids[5], new int[] {
        5, 5, 6, 7, 8, // row 0
        4, 5, 6, 7, 8, // row 1
        4, 5, 6, 7, 8  // row 2
      }
      );
    }
    
    // PALETTES ROW 2
    
    { // Palette 6:
      fillPalette(grids[6], new int[] {
        8, 7, 6, 5, 4, // row 0
        8, 7, 6, 5, 4, // row 1
        7, 6, 5, 4, 3  // row 2
      }  
      );
    }
    
    { // Palette 7:
      fillPalette(grids[7], new int[] {
        3, 2, 2, 2, 3, // row 0
        3, 2, 1, 2, 3, // row 1
        2, 1, 0, 1, 2  // row 2
      }
      );
    }
    
    { // Palette 8:
      fillPalette(grids[8], new int[] {
        4, 5, 6, 7, 8, // row 0
        4, 5, 6, 7, 8, // row 1
        3, 4, 5, 6, 7  // row 2
      }
      );
    }
    
    // PALETTES ROW 3 - center row
    
    { // Palette 9:
      fillPalette(grids[9], new int[] {
        8, 7, 6, 5, 4, // row 0
        7, 6, 5, 4, 3, // row 1
        8, 7, 6, 5, 4  // row 2
      }  
      );
    }
    
    // PALETTES COLUMN 1 - center column  
    
    { // Palette 10:
      fillPalette(grids[10], new int[] {
        3, 2, 1, 2, 3, // row 0
        2, 1, 0, 1, 2, // row 1
        3, 2, 1, 2, 3  // row 2
      }
      );
    }
    
    { // Palette 11:
      fillPalette(grids[11], new int[] {
        4, 5, 6, 7, 8, // row 0
        3, 4, 5, 6, 7, // row 1
        4, 5, 6, 7, 8  // row 2
      }
      );
    }
    
    // PALETTES ROW 4
    
    { // Palette 12:
      fillPalette(grids[12], new int[] {
        7, 6, 5, 4, 3, // row 0
        8, 7, 6, 5, 4, // row 1
        8, 7, 6, 5, 4  // row 2
      }  
      );
    }
    
    { // Palette 13:
      fillPalette(grids[13], new int[] {
        2, 1, 0, 1, 2, // row 0
        3, 2, 1, 2, 3, // row 1
        3, 2, 2, 2, 3  // row 2
      }
      );
    }
    
    { // Palette 14:
      fillPalette(grids[14], new int[] {
        3, 4, 5, 6, 7, // row 0
        4, 5, 6, 7, 8, // row 1
        4, 5, 6, 7, 8  // row 2
      }
      );
    }
    
    // PALETTES ROW 5
    
    { // Palette 15:
      fillPalette(grids[15], new int[] {
        8, 7, 6, 5, 4, // row 0
        8, 7, 6, 5, 4, // row 1
        8, 7, 6, 5, 5  // row 2
      }  
      );
    }
    
    { // Palette 16:
      fillPalette(grids[16], new int[] {
        3, 3, 3, 3, 3, // row 0
        4, 4, 4, 4, 4, // row 1
        5, 5, 5, 5, 5  // row 2
      }
      );
    }
    
    { // Palette 17:
      fillPalette(grids[17], new int[] {
        4, 5, 6, 7, 8, // row 0
        4, 5, 6, 7, 8, // row 1
        5, 5, 6, 7, 8  // row 2
      }
      );
    }
    
    // PALETTES ROW 6
    
    { // Palette 18:
      fillPalette(grids[18], new int[] {
        8, 7, 6, 6, 6, // row 0
        8, 7, 7, 7, 7, // row 1
        8, 8, 8, 8, 8  // row 2
      }  
      );
    }
    
    { // Palette 19:
      fillPalette(grids[19], new int[] {
        6, 6, 6, 6, 6, // row 0
        7, 7, 7, 7, 7, // row 1
        8, 8, 8, 8, 8  // row 2
      }
      );
    }
    
    { // Palette 20:
      fillPalette(grids[20], new int[] {
        6, 6, 6, 7, 8, // row 0
        7, 7, 7, 7, 8, // row 1
        8, 8, 8, 8, 8  // row 2
      }
      );
    }
    
    static final void fillPalette(color[][] grid, int[] seq) {
      int i = 0;
      for (color[] row: grid)
        for (int c = 0; c != COLS;
          row[c++] = grays[seq[i++]]);
    }
    
    void setup() {
      size(COLS*DIM, ROWS*DIM, JAVA2D);
      frameRate(60);
      noLoop();
      smooth(4);
    
      noStroke();
      rectMode(CORNER);
    }
    
    void draw() {
      final color[][] grid = grids[idx];
    
      for (color[] row: grid) {
        for (int c = COLS; c-- != 0;) {
          fill(row[c]);
          rect(c*DIM, 0, DIM, DIM);
        }
    
        translate(0, DIM);
      }
    
      //  println("draw idx: " + idx);
    
      if (!online)  frame.setTitle("Palette Index: # " + idx
        + "\t[" + idx/PCOLS + ", " + idx%PCOLS + "]");
    }
    
    void mousePressed() {
      moveHorizontal(mouseButton == LEFT? -1 : 1);  
      redraw();
    }
    
    void keyPressed() {
      final int k = keyCode;
    
      if      (k == 'A' | k == LEFT)   moveHorizontal(-1);
      else if (k == 'D' | k == RIGHT)  moveHorizontal(1);
      else if (k == 'W' | k == UP)     moveVertical(-PCOLS);
      else if (k == 'S' | k == DOWN)   moveVertical(PCOLS);
    
      redraw();
    }
    
    void moveHorizontal(int step) {
      idx = (idx + step + grids.length) % grids.length; // original GoToLoop code
    
      //  if (idx+step >= 0 & idx+step < grids[idx].length)  idx += step; // prevent wrapping row 0 only
      //  needs to go row by row in for loop?
    
      //  println("moveHorizontal idx: " + idx);
      //  println("moveHorizontal step: " + step);
      //  println("moveHorizontal grids.length: " + grids.length);
      //  println("moveHorizontal grids.length/PROWS: " + grids.length/PROWS);  
      //  println("moveHorizontal grids[idx].length: " + grids[idx].length);
      //  println("moveHorizontal grids[idx].length/PCOLS: " + grids[idx].length/PCOLS);
      //  println("moveHorizontal (idx + step + grids.length) % grids.length: " + ((idx + step + grids.length) % grids.length));
    }
    
    void moveVertical(int step) {
      if (idx+step >= 0 & idx+step < grids.length)  idx += step;
    
      //  println("moveVertical idx: " + idx);
      //  println("moveVertical step: " + step);
      //  println("moveVertical idx+step: " + (idx+step));
      //  println("moveVertical grids.length: " + grids.length);
    }
    
Sign In or Register to comment.