Passing (boolean) values from cell to cell in a grid

Hello,

I’m having trouble solving a problem which I don’t think should be very difficult, yet I haven’t been able to come close to how to figure it out.

The simplified version of my idea starts with a grid of objects, let’s say cells in a 5x5 grid, with all of them having a boolean state set to false except for one - for example the cell in the middle. I would like this one cell to be the starting point of a path travelling (randomly) through the grid meeting certain conditions:

  • Some input (a random number, noise, etc.) would determine the way of the path, moving left, up, right or down to the next cell, and from there on continue further until some parameter has been met (like a total amount of moves, a certain location has been reached, etc.).

  • I would like it’s current location to be a different color from colours where it has already been.

  • I want it to not be able to leave the grid structure and not re-enter cells which it has already passed unto.

For now though I’m having difficulties figuring out what a good structure for this would be, considering I’m trying to do this as neatly as possible and am therefor attempting to do it in a OOP-manner. I have tried different setups but I feel like every time I come short in the way that I approach them. The latest version I have tried is below here.

Grid g;
int scl, cols, rows, total, margin;
int wi, wj;

void setup() {
  size(500, 500);

  scl = 100;
  cols = width/scl;
  rows = height/scl;
  total = cols*rows;
  margin = scl/2;

  g = new Grid();
}

void draw() {
  background(0);
  g.show();
}

void mousePressed() {
  walk();
}

void walk() {
  int a = int(random(4));
  if (a == 0 && wi > 0) {
    wi -= 1;
  } else if (a == 1 && wj > 0) {
    wj -= 1;
  } else if (a == 2 && wi < cols-1) {
    wi += 1;
  } else if (a == 3 && wj < rows-1) {
    wj += 1;
  }

  println(wi, wj);
}


class Grid {
  Cell[] c;

  Grid() {
    c = new Cell[total];

    wi = floor(cols/2);
    wj = floor(rows/2);

    int k = 0;
    for (int i = 0; i < cols; i++) {
      for (int j = 0; j < rows; j++) {
        float x = i*scl;
        float y = j*scl;
        c[k] = new Cell(x, y, scl, scl, k, i, j);
        k++;
      }
    }
  }

  void show() {
    int k = 0;
    for (int i = 0; i < cols; i++) {
      for (int j = 0; j < rows; j++) {
        c[k].show();
        k++;
      }
    }
  }
}


class Cell {
  float x, y, w, h;
  int count;
  boolean state = false;
  boolean prevState = false;

  int i, j;

  Cell(float x, float y, float w, float h, int k, int i, int j) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.i = i;
    this.j = j;
    count = k;

    if (wi == i && wj == j) {
      state = true;
      prevState = true;
    }
  }

  void show() {
    checkState();
    if (prevState) {
      fill(0);
      noStroke();
    }
    if (state && prevState) {
      fill(255, 0, 0);
      noStroke();
    } else {
      fill(-1);
      stroke(0);
    }
    rect(x, y, w, h);
  }

  void checkState() {
    if (wi == i && wj == j) {
      state = true;
      prevState = state;
    } else{
      state = true;
      
    }
  }
}

I hope any of you could help me with tackling these problems I’m facing here, or point me to sketches by others that make use of the same idea. Really any help is much obliged. Thanks a lot in advance. :innocent:

This is a simplified diagram illustrating the idea I have. Black is it’s current location, grey is the available locations to travel to, and red is the locations where it has already been.

Use a 2D array as a grid

I think you make your life easier when you use c as 2D array/grid (and not 1D array).

See tutorials: two-dimensional arrays on the website

Then you can use the pos of the walker wi,wj and check the field next to it like

c[i+wi][j+wj]

etc.


Remark

also, most of the variables you declare before setup belong into the Grid class


Remark

When he goes into a corner and there are only fields around the walker he has already visited (are not allowed anymore), the game ends, he cannot leave the corner

Warm regards,

Chrisir

Example

// Black is it’s current location, grey is the available locations to travel to, 
// and red is the locations where it has already been.

Grid g;

void setup() {
  size(500, 500);
  g = new Grid();
}

void draw() {
  background(0);
  g.show();
}

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

void mousePressed() {
  g.walk();
}

//=================================================================

class Grid {

  int  cols, rows;
  int wi, wj;

  Cell[][] myGrid;

  // constr 
  Grid() {
    int scl = 100;
    cols = width/scl;
    rows = height/scl;
    myGrid = new Cell[5] [5];

    wi = floor(cols/2);
    wj = floor(rows/2);

    for (int i = 0; i < cols; i++) {
      for (int j = 0; j < rows; j++) {
        float x = i*scl;
        float y = j*scl;
        myGrid[i][j] = new Cell(x, y, scl, scl, 0, i, j);
      }
    }
  }

  void show() {
    for (int i = 0; i < cols; i++) {
      for (int j = 0; j < rows; j++) {
        myGrid[i][j].show(wi, wj);
      }
    }

    // show the fields he can move to 
    for (int i = -1; i <= 1; i+=1) {
      for (int j = -1; j <= 1; j+=1) {
        // 
        if (! ( i==0 && j==0 ))
          if (i!=0 || j!=0) 
            if (! ( i==j)) 
              if (! ( i==-1 && j==1)) 
                if (! ( i==1 && j==-1)) 
                  if (i+wi>=0  && j+wj>=0)
                    if (i+wi<5  && j+wj<5)
                      if (! myGrid[i+wi][j+wj].occupied) // must be empty 
                        myGrid[i+wi][j+wj].show2(); // show gray
      }
    }
  }

  void walk() {
    int a = int(random(4));

    int wiPrev=wi;
    int wjPrev=wj;

    if (a == 0 && wi > 0) {
      wi -= 1;
    } else if (a == 1 && wj > 0) {
      wj -= 1;
    } else if (a == 2 && wi < cols-1) {
      wi += 1;
    } else if (a == 3 && wj < rows-1) {
      wj += 1;
    }

    // must be empty / otherwise take back move
    if (!allowed(wi, wj)) {
      wi=wiPrev; 
      wj=wjPrev;
    }//if 
    println(wi, wj);
  }//func 

  boolean allowed( int x, int y  ) {
    //  not re-enter cells which it has already passed unto.
    if (!myGrid[x][y].occupied)
      return true;  // field is empty 
    else
      return false; // field has already been visited
  }
}

//=================================================================

class Cell {
  float x, y, w, h;
  int count;
  boolean state = false;
  boolean prevState = false;
  boolean occupied=false;

  int i, j;

  Cell(float x, float y, 
    float w, float h, 
    int k, int i, int j) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.i = i;
    this.j = j;
    count = k;

    /* if (wi == i && wj == j) {
     state = true;
     prevState = true;
     }*/
  }

  void show(int wi, int wj) {
    checkState(wi, wj);

    if (prevState) {
      fill(0);
      noStroke();
    }
    if (state && prevState) {
      fill(255, 0, 0);
      noStroke();
    } else {
      fill(-1);
      stroke(0);
    }

    if (wi == i && wj == j) {
      fill(0);
    }

    stroke(0);
    rect(x, y, w, h);
  }

  void show2() {
    fill(111); 
    stroke(0);
    rect(x, y, w, h);
  }

  void checkState(int wi, int wj) {
    if (wi == i && wj == j) {
      occupied=true; 
      state = true;
      prevState = state;
    } else {
      state = true;
    }
  }
}
//