Control de flujo, condiciones y bucles para artistas

Divide y vencerás

Lo que os propongo es dividir el problema en partes más sencillas que podamos afrontar gradualmente hasta dar con la solución completa. Ya sabéis lo que dicen de divide y vence.

Dibujando una celda

Empecemos de nuevo por lo más esencial, dibujar el primer cuadrado de la esquina superior. Éste no nos debería costar demasiado pues ya sabemos lo que tenemos que hacer:

function draw() {
  background(220);
  
  var ancho_celda = width/8;
  var alto_celda = height/8;
  
  // Dibujamos un cuadrado
  rect(0, 0, ancho_celda, alto_celda)
}

Muy bien, ya hemos dado el primer paso.

Dibujando una fila

Ahora que tenemos un cuadrado nuestro siguiente objetivo será dibujar toda la fila, por ahora sin preocuparnos de los colores.

Para conseguirlo podemos dibujar los 8 cuadrados uno al lado del otro en un bucle for:

function draw() {
  background(220);
  
  var ancho_celda = width/8;
  var alto_celda = height/8;
  
  // Dibujamos una fila
  for (var i=0; i<8; i++) {
    // Dibujamos un cuadrado
    rect(i*ancho_celda, 0, ancho_celda, alto_celda)
  }
}

¡Vamos progresando!

Dibujando el tablero

Tenemos una fila, salta a la vista qué debemos hacer, ¿verdad? Dibujar 8 filas una debajo de otra.

Aquí es mis estimados alumnos donde entra en juego el segundo bucle, un bucle dentro de otro, pues si tenemos un bucle para dibujar una fila, debemos utilizarlo dentro de otro para que se repita nuevamente.

function draw() {
  background(220);
  
  var ancho_celda = width/8;
  var alto_celda = height/8;
  
  // Recorremos 8 filas
  for (var j=0; j<8; j++) {
    // Dibujamos una fila
    for (var i=0; i<8; i++) {
       // Dibujamos un cuadrado
       rect(i*ancho_celda, 0, ancho_celda, alto_celda)
    }
  }
}

Con esto tenemos la fila dibujándose 8 veces en el mismo sitio, tenemos que ajustar la altura para dibujar las celdas dependiendo de la fila:

function draw() {
  background(220);
  
  var ancho_celda = width/8;
  var alto_celda = height/8;
  
  // Recorremos 8 filas
  for (var j=0; j<8; j++) {
    // Dibujamos una fila
    for (var i=0; i<8; i++) {
       // Dibujamos un cuadrado
       rect(i*ancho_celda, j*alto_celda, ancho_celda, alto_celda)
    }
  }
} 

¡Por fin! Ahora sí tenemos lo necesario para poder pintar el tablero, pues estamos dibujando cuadrados que podemos rellenar de colores.

La cuestión es determinar de qué color pintar los cuadrados... ¿Se os ocurre alguna forma?

Pintando una fila

Como no sabemos exactamente por dónde empezar hagamos lo mismo que antes, pintemos el diseño de la primera fila con el primer cuadrado en blanco, el segundo en negro y así sucesivamente.

Una forma de pintar los cuadrados sería comprobando el contador del for anidado. Podemos hacer diferentes if y si la i vale 0 pintarlo blanco, si vale 1 pintarlo negro, si vale 2 blanco, etc.

Sin embargo como podéis suponer esta forma no es óptima y lo malo es que no sabemos como determinar automáticamente este caso. ¿Cómo podemos hacerlo entonces? Bueno, la clave está en un operador aritmético que todavía no conocemos y váis a aprender ahora mismo, el módulo.

¿Sabéis lo que es una división entera? Cuando por ejemplo dividimos 5 entre 2, el resultado es 2 y nos sobra 1. Ese 1 se llama resto o residuo de la división entera. Pues bien, el operador de módulo % es un operador como la suma o la división, pero lo que hace es devolvernos el residuo de una división.

¿Por qué es tan importante? Porque si calculamos el módulo de un número entre otro y el resultado es diferente de cero podemos determinar si ese número es múltiplo del primero o no. En otras palabras, podemos saber si una casilla es par o impar y eso amigos es todo lo que necesitamos para pintar las celdas:

function draw() {
  background(220);
  
  var ancho_celda = width/8;
  var alto_celda = height/8;
  
  // Recorremos 8 filas
  for (var j=0; j<8; j++) {
    // Dibujamos una fila
    for (var i=0; i<8; i++) {
      // Determinamos si el módulo del contador de la fila es par
      if (i%2 == 0) {
        // Si el residuo es 0 es par, pintamos blanco
        fill(255)
      } else {
        // Si el residuo es diferente de 0 es impar, pintamos negro 
        fill(0)
      }
      // Dibujamos un cuadrado
      rect(i*ancho_celda, j*alto_celda, ancho_celda, alto_celda)
    }
  }
}

Bien, hemos pintado la estructura de las líneas impares perfectamente.

Pintando el tablero

Ahora nos falta identificar las líneas pares y ya lo tendremos. ¿Cómo podemos hacerlo? Pues de la misma forma que hemos determinado si las celdas eran pares podemos comprobar las filas, haciendo uso de condiciones anidadas:

function draw() {
  background(220);
  
  var ancho_celda = width/8;
  var alto_celda = height/8;
  
  // Recorremos 8 filas
  for (var j=0; j<8; j++) {

    // Determinamos los colores de la fila
    var color_celda_par;
    var color_celda_impar;
    if (j%2 == 0) {
      // Si la fila es par 
      color_celda_par = 255;
      color_celda_impar = 0;
    } else {
      // Si la fila es impar 
      color_celda_par = 0;
      color_celda_impar = 255;
    }

    // Dibujamos una fila
    for (var i=0; i<8; i++) {
      // Determinamos si el módulo del contador de la fila es par
      if (i%2 == 0) {
        // Si el residuo es 0 es par
        fill(color_celda_par)
      } else {
        // Si el residuo es diferente de 0 es impar
        fill(color_celda_impar)
      }
      // Dibujamos un cuadrado
      rect(i*ancho_celda, j*alto_celda, ancho_celda, alto_celda)
    }

  }

}

Sin palabras, perfectamente geométrico, perfectamente equilibrado. Dibujado programáticamente usando variables, condiciones y bucles.

En esto amigos consiste el arte de dibujar gráficos, en ingeniárselas para dibujar lo que queramos sobre el lienzo y lo mejor es que no hay una sola forma de hacer las cosas. Por eso es una tarea tan creativa a la par que lógica.

Por cierto, si queréis almacenar colores RGB en una variable se puede hacer usando la función color de p5, que por cierto acepta tanto valores en formato RGB como en hexadecimal:

if (j%2 == 0) {
  // Si la fila es par 
  color_celda_par = color('#DAB692');
  color_celda_impar = color(133, 44, 25);
} else {
  color_celda_par = color(133, 44, 25);
  color_celda_impar = color('#DAB692');
}