Nested loops, ending "early"

Now I have this question about nested loops.
With the buildTiles() method, I would like to have the option to create fewer Tile objects than grid cells, but still number them in the “id” field, and assign the grid cell coordinates sequentially to each Tile.
For instance, if “tiles[]” only has 5 elements, only create 5 Tiles.
I understand why this code doesn’t do what I am hoping for, I just don’t know how to write it in a way that it could.
Can anyone please suggest a good way to accomplish this?

int nCols, nRows, colW, rowH, cellSize;
PVector[][] centers;
Tile[] tiles;
void setup() {
  size(301, 301);
  nCols = 3;
  nRows = 3;
  colW = 100;
  rowH = 100;
  cellSize = 100;
  centers = new PVector[nCols][nRows];
  tiles = new Tile[nCols * nRows];
}
void draw() {
  background(255);
  buildGrid();
  buildTiles();
  displayGrid();
  displayTiles();
}
void buildGrid() {
  for (int c = 0; c < nCols; c++) {
    for (int r = 0; r < nRows; r++) {
      centers[c][r] = new PVector(c * colW + colW / 2, 
        r * rowH + rowH / 2);
    }
  }
}
void buildTiles() {
  for (int n = 0; n < tiles.length; n = n) {
    for (int r = 0; r < nCols; r++) {
      for (int c = 0; c < nRows; c++) {
        tiles[n] = new Tile(str(n+1), c, r);
        n++;
      }
    }
  }
}
void displayGrid() {
  for (int c = 0; c < nCols; c++) {
    for (int r = 0; r < nRows; r++) {
      stroke(127);
      fill(92, 0, 0, 255);
      rectMode(CENTER);
      rect(centers[c][r].x, centers[c][r].y, colW, rowH);
    }
  }
}
void displayTiles() {
  for (int i = 0; i < tiles.length; i++) {
    tiles[i].drawTile();
  }
}
class Tile {
  String id;
  PVector loc;
  Tile(String id, float x, float y) {
    this.loc = new PVector(x, y);
    this.id = id;
  }
  void drawTile() {
    noStroke();
    fill(255);
    textSize(36);
    textAlign(CENTER, CENTER);
    text(id, loc.x * cellSize + cellSize/2, 
      loc.y * cellSize + cellSize/2);
  }
}
1 Like
void buildTiles() {
  int n = 0;
    for (int r = 0; n < tiles.length && r < nCols; r++) {
      for (int c = 0; n < tiles.length && c < nRows; c++) {
        tiles[n] = new Tile(str(n+1), c, r);
        n++;
    }
  }
}

This is what I would do. Notice that the loops work as before, but a second condition has been added, one that, when n reaches the value desired, causes both loops to be done.

Untested code, YMMV, there might be better ways too.

2 Likes

Here’s how I would do it:

void buildTiles() {
  int row = 0; // Which row is it in?
  int column = 0; // Which column is it in?
  for (int i = 0; i < tiles.length; i++) {
    tiles[i] = new Tile(str(i+1), column, row);
    if (column < nCols-1) {
      column++; // If column isn't more than how many columns are there, continue.
    } else {
      row++; // If column is more, than go down a row
      column = 0; // And set the column to 0
    }
  }
}

2 Likes

Thank you both! Much appreciated