Saturday, July 18, 2009

Una respuesta (Parte B)

Ayer, vimos como podemos transformar 5 grandes secciones de código entre solo una sección. Deberían asegurar que entienden como el nuevo código funciona. No es tan difícil, sola una parte es complicado.. lo de verificar que los barcos no cruzan.

Hoy día vamos a ver como podemos utilizar los poderes de las clases (en Java, o cualquier otra lenguaje) a limpiar el código más.

Vamos a empezar con la sección del código mencionada arriba - la verificación del los barcos.

//verifcamos que el barco no cruza los barcos anteriores
for (int i=0; i<lista_barcos[barco_acutal].tamano; i++)
for (int j=barca_actual; j==0; j--)
{
//este es poquito sucio .. necesitamos verificar que ninguna de los coordenados en el barco actual son iguales a todos los coordenados de los barcos anteriores.

// asumimos que no cruzamos, si revisamos todos y todavia cruza es falso, bien.
boolean cruza=false;
for (int k=0; j<lista_barcos[j].posiciones.length; k++)
if (lista_barcos[j].posiciones[k].equals(lista_barcos[barco_acutal].posiciones[i]))
cruza=true;
}


¿Que hace este código? En pseudocódigo:

Para cada barco B antes el barco actual
Revisamos todos los posiciones en B y verifica que ninguna es la misma que nuestra barca actual.


Ayer, definimos una clase para representar un barco. Dijimos que esta clase es como un struct en C. Es verdad, pero no es todo. Clases son mucho mas poderosos que esta.. podemos definir métodos que operan a los datos al dentro la clase. Es como una paquete -- datos y métodos.

Entonces vamos a redefinir la clase a ser:

public class Barco
{
//los datos
public String nombre; // guardar el nombre del barco
public Point[] posiciones; // una lista de puntos donde el barco es ubicado
public int tamano; // El tamano del barco, i.e., el numero de espacios que tiene

//los metodos
public boolean esCruzado(Barco b1) //comparar el barco en este clase con otro barco b1.
{
boolean cruza=false;
for (int i=0; i<this.posiciones.length; ++i)
for (int k=0; j<b1.posiciones.length; ++k)
if(b1.posiciones[k].equals(this.posiciones[i]))
cruza=true;
return cruza;
}
}


Ahora cada barco que creamos tiene un método esCruzado que podemos utilizar para ver si otro barco se cruza.

Con este método definido, podemos mejorar el código poquito más. En vez del código complejo arriba, podemos escribir:


boolean cruza=false;
//verifcamos que el barco no cruza los barcos anteriores
for (int j=barca_actual; j==0; j--)
{
if (lista_barcos[barco_acutal].esCruzado(lista_barcos[j]))
cruza=true;
}


¿Mucho más entendible, si? El arte de programación es este proceso que acaba de hacer. Tomamos algoritmos complejos y intentamos a reducirlos a una forma simple y entendible.

Ahora.. preguntas para ustedes:

1) ¿Es un ciclo for la mejor manera para hacer esta? ¿Exista una forma más eficiente?

2) ¿Pueden identificar otra métodos que podemos agregar al código nuevo para limpiarlo más?

3) ¿Pueden identificar el error de lógica en el código que acabamos de escribir? ¿Exista en el código anterior? ¿Es más fácil para identificar ahora?

No comments:

Post a Comment