[SOLVED] P5js check if tiles are the same color

I’m creating a short program that can randomize tiles to alternate white, then a random color from a set of 8 specific colors. However what i want to add to this is a way to check if the tiles around it are the same color, to then change one of the colors into something different. For instance, if you had a 3x3 tile arrangement:

**Red** - White - Blue
White - **Red** - White  
Black - White - Pink

This would change to:

**Red** - White - Blue
White - **Yellow** - White
Black - White - Pink

Im hung up, I believe the start of my issue comes with the fact that the color selection is chosen in setup. Im new to p5.js, thanks for any help.

Link to code: [Deleted]

1 Like

hi ZachMcMkay
first i have a question, how you made the account at
https://editor.p5js.org
possibly you forget to put in a user name? can change?

i think it is not so good for you, that your email is public.


you have to create your array of class ( Tile[] tiles ) at setup.
just run it with random colors.

but you can do ( at setup ) a second run over the ( already created ) array and check on the color ( and compare to the color of neighbors )
but need to do the grid math to find them.
( is that what you try with the offset? )

1 Like

If what you want is to choose 5 different colors from a set of 8, what you can do is store the 8 colors in an array, shuffle them, and then pick the first 5. Would that work?

oops… @kll’s response was not there when I wrote. I guess we did it in parallel :slight_smile:

Thanks for the speedy reply! I will make that change so that my email stays private. Didn’t notice that it was shown in the link!

The offset was simply to get every other square and make it white. I’ll try to do a second pass and see what happens! Thanks for the help!

Hi @ZachMcMkay,

For that second pass I think you need to convolute around your 3x3 tile to check the surrounding colors.
I’m sorry I don’t know P5.js so I made a quick example sketch with Processing Python that I annotated for clarity:

import random

colors = ((0, 0, 0), (255,0,0), (255,128,0), (255,255,0), (0,255,0), (0,0,255), (127,0,255), (255,102,178))

def setup():
    size(800, 800, P2D)
    smooth(8)

    cols = rows =  16
    step = int(width / cols)
    grid = [[[] for y in range(rows)] for x in range(cols)]
    xy = ((-1, -1), (1, -1), (1, 1), (-1, 1))
    
    for x in xrange(cols):
        for y in xrange(rows):
            i = x + y * cols
            switch = 0 if y%2 else 1
            grid[x][y] = random.choice(colors) if i%2 == switch else None #If tile is "not white" -> stores a color randomly selected from the list into a 2D array list
    
    
    #Second Pass
    for x in xrange(cols):
        for y in xrange(rows):
            
            #Only focusing on non-white tiles
            if grid[x][y] != None:
                
                nColors = []
                
                #Convolution 
                for loc in xy:

                    #Constraining the checking process to the edges of the grid
                    x_ = constrain(x + loc[0], 0, cols - 1) 
                    y_ = constrain(y + loc[1], 0, rows - 1)
                    nColors.append(grid[x_][y_]) #Stores neighboring colors
                    
                    #If neighbor (only diagonals) has same color values -> pick another color
                    if grid[x][y] == grid[x_][y_]:
                        
                        #Make sure to pick a new color that is not in the neighboring colors
                        colors_ = [c for c in colors if c not in nColors and c != grid[x_][y_]]
                        grid[x][y] = random.choice(colors_)
                        
                a, b, c = grid[x][y] #Values of the new color
                  
            fill(a, b, c) if grid[x][y] != None else fill(255)
            rect(x * step, y * step, step, step)
2 Likes

what i like with @solub 's version,
NO CLASS, only tile array remember pointer to color array.
( if you want play and learn class is ok… it is just not needed )
so also for the second step ( you compare of the color of neighbors )
no need to compare real colors, just the pointer 0 … 8

i not started about that color check function,
but want show what i have to make yours more easy.

// rect grid with offset
// as array of color pointer only, and delete the class thing

let x = 12, y = x, w = 30, h = w, offset = 2, grid = 15, many = grid * grid;
let mytiles = [];      // array long "many" remember random color pointer only
var mycolors= [[255,0,0],[255,128,0],[255,255,0],[0,255,0],[0,0,255],[127,0,255],[255,102,178],[80,80,80]];      // array of 8 colors

function setup() {
  createCanvas(500, 500);
  noStroke();
  for (let i = 0; i < many; i++) mytiles[i]=int(random(8));     // make random tiles color array
//}
//function draw() {     // no need for draw loop now
  background(0);
  draw_myRects();
}

function draw_myRects() {
  for (let i = 0; i < many; i++) {
    let posx = x + (i % grid) * (w + offset);
    let posy = y + (floor(i / grid)) * (h + offset);
    fill(mycolors[mytiles[i]][0],mycolors[mytiles[i]][1],mycolors[mytiles[i]][2]);
    rect(posx, posy, w, h);
  }
}

1 Like

You’re right, comparing indices is more elegant and should be faster as well. Thanks for the suggestion.

OH wow! that is much easier. Thank you so much for the reply!

Thanks for your suggestion! I think you’re right and i like the idea

I have been able to detect when the corners are matching… Im still working on how to then change the element to something different

I have it set up perfectly now, it detects using a for loop if any of the corners match and if they do it console logs that there is a match. I did it smaller scale to visually count and found out its working perfectly. Should i just mytiles.splice(i,1)? or could i mytiles.[i]= int(random(8))

Sorry I’m just discovering P5.js today and don’t understand what you are referring to.

Here below a naive implementation of the example sketch I posted earlier, hope it helps.

https://editor.p5js.org/solub/sketches/cKYLiqrCa

let cols = 16, rows = 16, size = 400, step = size / cols, grid = [];
var colors= [[255,0,0],[255,128,0],[255,255,0],[0,255,0],[0,0,255],[127,0,255],[255,102,178],[80,80,80]];  
let xy = [[-1, -1], [1, -1], [1, 1], [-1, 1]];

function setup() {
  createCanvas(size, size);
  noStroke();
		
  for (let x = 0; x < cols; x++) {
    grid[x] = []
    for (let y = 0; y < rows; y++) {
      idx = x + y * cols;
      s = (y%2) ? 0 : 1;
      rdm = Math.floor(Math.random() * colors.length);
      grid[x][y] = (idx%2 == s) ? colors[rdm] : null;
    }
  }
	
  //Second Pass
  for (let x = 0; x < cols; x++) {
    for (let y = 0; y < rows; y++) {
						
      //Only focusing on non-white tiles
      if (grid[x][y] != null) {
        let nColors = [];
				
	//Convolution 
        for (let i = 0; i < xy.length; i++) {
	  x1 = constrain(x + xy[i][0], 0, cols - 1);
	  y1 = constrain(y + xy[i][1], 0, rows - 1);
	  nColors.push(JSON.stringify(grid[x1][y1])); //Stores neighboring colors
					
	 //If neighbor (only on diagonals) has same color values -> pick another color
         if (JSON.stringify(grid[x][y]) == JSON.stringify(grid[x1][y1])) {
	
           //Make sure to pick a new color that is not in the neighboring colors
	   let colrs = [];
	   for (let n = 0; n < colors.length; n++) {
	     if (!nColors.includes(JSON.stringify(colors[n])) && JSON.stringify(colors[n]) != JSON.stringify(grid[x1][y1])) {
	       colrs.push(colors[n])
             }
	    }
							
            grid[x][y] = colrs[Math.floor(Math.random(colrs.length))];
	  }
	}
      }
          
    if (grid[x][y] != null) {
      fill(grid[x][y][0], grid[x][y][1], grid[x][y][2])
      }
    else {
      fill(255)
    }
    rect(x * step, y * step, step, step)
  }
 }
}
2 Likes

Thanks so much!!! seeing the xy array made it click for me. I actually got my own code working now! You’re the man

Thanks for the help! got it working exactly how i want it to!

good, and can you share the code here?

https://editor.p5js.org/ZachMcMkay/sketches/3go0cEyvi Link to the working code!

2 Likes