Control de flujo, condiciones y bucles para artistas

Relaciones múltiples

A parte de crear condiciones múltiples con la estructura if, else if y else también tenemos la posibilidad de definir más de una relación en la misma expresión lógica.

Siguiendo con el ejemplo de antes, en él tenemos un lienzo dividido en cuatro partes y en cada una establecemos un color diferente. Pero supongamos por un momento que en lugar de cuatro colores queremos manejar dos, el verde para la primera y tercera parte y el azul para la segunda y la cuarta.

Podríamos cambiar el código para conseguir este funcionamiento sin mucha complicación:

if (circulo.y > 300) { 
  circulo.r = 0
  circulo.g = 0
  circulo.b = 220
  print("Cuarta parte")
}  else if (circulo.y > 200) { 
  circulo.r = 0
  circulo.g = 220
  circulo.b = 0
  print("Tercera parte")
} else if (circulo.y > 100) { 
  circulo.r = 0
  circulo.g = 0
  circulo.b = 220
  print("Segunda parte")
} else if (circulo.y > 0) { 
  circulo.r = 0
  circulo.g = 220
  circulo.b = 0
  print("Primera parte")
}

Es una forma correcta de solucionarlo pero una vez más no es la óptima.

Veréis, hay una regla no escrita en programación que dice que si estás repitiendo código es que lo estás haciendo mal y así es, tenemos los mismos códigos repetidos. ¿Ya que tenemos sólo dos colores no sería más lógico implementar dos condiciones? Pues eso se puede lograr usando múltiples relaciones.

Para unir dos relaciones contamos con dos operadores lógicos conocidos como and y or. Dependiendo de lo que necesitamos hacer utilizaremos uno u otro:

  • and: Conocido como Y lógica ejecutará un bloque cuando se cumplan las dos relaciones.
  • or: Conocido como O lógica ejecutará un bloque si por lo menos se cumple una de las dos relaciones.

Sabiendo esto os planteo la siguiente cuestión. ¿Cómo podemos asegurarnos en una única condición de que la figura se encuentra en la primera parte del lienzo? No podemos simplemente decir que su posición y es mayor que 0 porque esa condición también sirve para las otras tres partes.

Lo que limita la primera parte es el valor máximo de y, que en este caso es 100, por tanto la condición que garantiza que el círculo se encuentra en la primera parte es la unión de ambas a la vez, cuando y > 0 y también y <= 100.

Aplicando esta lógica para cada parte tendremos las siguientes condiciones:

  • Parte 1: y > 0 a la vez que y <= 100.
  • Parte 2: y > 100 a la vez que y <= 200.
  • Parte 3: y > 200 a la vez que y <= 300.
  • Parte 4: y > 300 a la vez que y <= 400.

Utilizar estas relaciones múltiples sería una alternativa a los else if, ya que cada opción excluye a las otras. Sabiendo que el operador lógico para el and es && podríamos hacer lo siguiente para unificar estas relaciones:

if (circulo.y > 300 && circulo.y <= 400) { 
  circulo.r = 0
  circulo.g = 0
  circulo.b = 220
  print("Cuarta parte")
}

if (circulo.y > 200 && circulo.y <= 300) { 
  circulo.r = 0
  circulo.g = 220
  circulo.b = 0
  print("Tercera parte")
} 

if (circulo.y > 100 && circulo.y <= 200) { 
  circulo.r = 0
  circulo.g = 0
  circulo.b = 220
  print("Segunda parte")
} 

if (circulo.y > 0 && circulo.y <= 100) { 
  circulo.r = 0
  circulo.g = 220
  circulo.b = 0
  print("Primera parte")
}

Son condiciones tan exclusivas que no importa el orden como las definamos.

¿Pero en qué afecta esto a lo que os decía al principio? Pues es la clave de todo porque si sabemos que cada uno de estos conjuntos de relaciones implica una de las partes, si pudiéramos unir los conjuntos de la primera parte y la tercera y de la segunda con la cuarta, ¡ya podríamos ahorrarnos repetir código! Y ahí es cuando entra en acción el operador or que se escribe con ||:

if ( (circulo.y > 200 && circulo.y <= 300) || (circulo.y > 0 && circulo.y <= 100)) { 
  circulo.r = 0
  circulo.g = 220
  circulo.b = 0
  print("Primera parte o tercera")
} 
  
if ((circulo.y > 300 && circulo.y <= 400) || (circulo.y > 100 && circulo.y <= 200)) { 
  circulo.r = 0
  circulo.g = 0
  circulo.b = 220
  print("Segunda parte o cuarta")
}

Entiendo que tanto código pueda ser abrumador, tranquilos, vamos a simplificarlo para que se entienda mucho mejor, mirad:

var primera = circulo.y > 200 && circulo.y <= 300;
var segunda = circulo.y > 100 && circulo.y <= 200
var tercera = circulo.y > 0 && circulo.y <= 100;
var cuarta  = circulo.y > 300 && circulo.y <= 400;

if (primera || tercera) { 
  circulo.r = 0
  circulo.g = 220
  circulo.b = 0
} 
  
if (segunda || cuarta) { 
  circulo.r = 0
  circulo.g = 0
  circulo.b = 220
}

¿Muchísimo mejor verdad?

Con esto ya sabéis qué es condicionar el código, cómo utilizar relaciones múltiples y estáis más que preparados para aprender a utilizar los bucles.