domingo, 8 de septiembre de 2013

¿Como colocar los barcos en la grilla?

Un gran problema se nos presentó al momento de colocar los barcos dentro de la grilla, ya que como conocemos los barcos pueden ocupar 1, 2, 3, 4 y 5 grillas tanto sea horizontalmente como verticalmente. Por lo que esto conllevó a controlar todas las posibilidades y circunstancias que podían ocurrir. Una de ellas fue controlar que el barco no se ubique fuera del "Picture Box" para lo cual utilizamos la propiedad location del Picture Box y así poder controlar este evento.

Dentro de esto también se encontraba que como los barcos deben ser ubicados verticalmente y horizontalmente, se debía controlar que los barcos no se salgan del Picture Box que los contiene y controlar el movimiento randómico de los barcos hasta que el jugador le parezca la mejor opción.

Otra gran dificultad fue como ubicar y colocar los barcos que ocupan más de una grilla, para esta operación se procedió a la imagen de los barcos dividirlas en puntos, para así con estos puntos poder extender, ensanchar o achicar al barco, con esto conseguimos la colocación y ubicación de los barcos que ocupan más de una grilla.

A continuación se les presenta el código y las 3 funciones que fueron creadas para estos propósitos antes mencionados que son:
  • Función Ubicación
  • Función PonerBarco
  • Función Verificar

// Función ubicación que me servirá para la ubicación de los picturebox de los barcos
        private void Ubicacion(Random valor)
        {
            // Creo un entero posición y lo inicializo en  para definir la posición del barco dentro del 
            // arreglo anteriormente creado
            int posicion = 0;
            // Lazo for each para los barocs
            foreach (Barco obj in barcos)
            {
                // Lazo infinito para verificar que no se sobrelapen los barcos
                while (true)
                {
                    // Generamos un randómico en X que va de 0 a 10
                    int x = valor.Next(0, 10);
                    // Generamos un randómico en Y que va de 0 a 10
                    int y = valor.Next(0, 10);
                    
                    // Con esta condición definimo que no se salga el tamaño en ancho del picturebox
                    if ((x + obj.PuntosVida) < 10)
                    {
                        // Condición para que no se sobrelapen los picturebox de los barcos
                        if (Verificar(posicion, x, y, obj.PuntosVida, 1))
                        {
                            // Creo un punto para la posición del picturebox dentro del formularios para 
                            // que se ubique correctaente el barco
                            Point punto = new Point((x * 30) + picPosicion.Location.X, (y * 30) + 
                                picPosicion.Location.Y);
                            // Agrego en el barco la posición
                            obj.Posicion = punto;
                            // Definimos el ancho del barco y lo asociamos con los puntos de vida
                            obj.Ancho = obj.PuntosVida * 30;
                            // Definimos el largo del barco
                            obj.Largo = 30;
                            // LLamamos a la función actualizar de la clase Barco
                            obj.Actualizar();
                            // Llamamos a la función poner barco 
                            PonerBarco(x, y, obj.PuntosVida, 1, obj.PuntosVida);
                            // Rompo el lazo infinito con cualquier condición que cumpla
                            break;
                        }
                    }
                    // Caso contrario si no es en lo horizontal ahora condición para la colocación 
                    // vertical
                    else if ((y + obj.PuntosVida) < 10)
                    {
                        // // Condición para que no se sobrelapen los picturebox de los barcos
                        if (Verificar(posicion, x, y, 1, obj.PuntosVida))
                        {
                            // Creo un punto para la posición del picturebox dentro del formularios para 
                            // que se ubique correctaente el barco
                            Point punto = new Point((x * 30) + picPosicion.Location.X, (y * 30) + picPosicion.Location.Y);
                            // Agrego en el barco la posición
                            obj.Posicion = punto;
                            // Defino el ancho del barco
                            obj.Ancho = 30;
                            // Definimos el largo del barco con los puntos de vida
                            obj.Largo = obj.PuntosVida * 30;
                            // LLamamos a la función actualizar de la clase Barco
                            obj.Actualizar();
                            // Llamamos a la función poner barco 
                            PonerBarco(x, y, 1, obj.PuntosVida, obj.PuntosVida);
                            // Rompo el lazo infinito con cualquier condición que cumpla
                            break;
                        }
                    }
                }
                // Aumentamos la posición en 1 para verificar que no se sobrelapen los barcos
                posicion++;
            }
        }

        // Función PonerBarco para colocar el barco dentro del picturebox
        private void PonerBarco(int x, int y, int ancho, int largo, int tipo)
        {
            // Creamos el punto de posición del barco
            Point punto = new Point(picPosicion.Location.X + (x * 30), picPosicion.Location.Y + (y * 30));
            
            // Con el swtich definimos que tipo de barco vamos a colocar en el picturebox
            switch (tipo)
            {
                    // Caso 1 Definen los datos (propiedades) del picture box esto es para todos los casos
                case 1:
                    picBarco1.Location = punto;
                    picBarco1.Width = ancho * 30;
                    picBarco1.Height = largo * 30;
                    picBarco1.BorderStyle = BorderStyle.FixedSingle;
                    picBarco1.Visible = true;
                    picBarco1.BackColor = Color.Blue;
                    break;
                case 2:
                    picBarco2.Location = punto;
                    picBarco2.Width = ancho * 30;
                    picBarco2.Height = largo * 30;
                    picBarco2.BorderStyle = BorderStyle.FixedSingle;
                    picBarco2.Visible = true;
                    picBarco2.BackColor = Color.Purple;
                    break;
                case 3:
                    picBarco3.Location = punto;
                    picBarco3.Width = ancho * 30;
                    picBarco3.Height = largo * 30;
                    picBarco3.BorderStyle = BorderStyle.FixedSingle;
                    picBarco3.Visible = true;
                    picBarco3.BackColor = Color.Green;
                    break;
                case 4:
                    picBarco4.Location = punto;
                    picBarco4.Width = ancho * 30;
                    picBarco4.Height = largo * 30;
                    picBarco4.BorderStyle = BorderStyle.FixedSingle;
                    picBarco4.Visible = true;
                    picBarco4.BackColor = Color.Yellow;
                    break;
                case 5:
                    picBarco5.Location = punto;
                    picBarco5.Width = ancho * 30;
                    picBarco5.Height = largo * 30;
                    picBarco5.BorderStyle = BorderStyle.FixedSingle;
                    picBarco5.Visible = true;
                    picBarco5.BackColor = Color.Brown;
                    break;
            }
        }

        // Función que nos permitirá veriicar que no se sobrelapen los barcos
        private bool Verificar(int posicion, int x, int y, int ancho, int largo)
        {
            // Si la posición del barco dentro del arreglo es 0 se colocará en el picturebox
            if (posicion == 0)
                return true;
            // Caso contrario 
            else
            {
                // Creo un lazo for para ir obteniendo la propiedad puntos de los barcos ya posicionados
                for (int i = 0; i < posicion; i++)
                {
                    // Creo un arreglo de puntos con la propiedad Puntos de los barcos
                    Point[] valor = barcos[i].Puntos;
                    // Verificamos si el ancho es diferente de 1 (el barco estará horizontalmente)
                    if (ancho != 1)
                    {
                        // Hacemos un for each del arreglo de puntos obtenido
                        foreach (Point punto in valor)
                        {
                            // Otro lazo for para hacer la comparación del ancho del barco y los puntos
                            // del barco anteriormente posicionado
                            for (int j = 0; j < ancho; j++)
                            {
                                // Hacemos la verificación si encontramos una coincidencia del punto retornará
                                // la función un false ya que se sobrelapan
                                if (punto == new Point(picPosicion.Location.X + (j * 30) + (x * 30), 
                                    picPosicion.Location.Y + (y * 30)))
                                    return false;
                            }
                        }
                    }
                    // Verificamos si el largo es diferente de 1 (el barco estará verticalmente)
                    else if (largo != 1)
                    {
                        // Hacemos un for each del arreglo de puntos obtenido
                        foreach (Point punto in valor)
                        {
                            // Otro lazo for para hacer la comparación del largo del barco y los puntos
                            // del barco anteriormente posicionado
                            for (int j = 0; j < largo; j++)
                            {
                                // Hacemos la verificación si encontramos una coincidencia del punto retornará
                                // la función un false ya que se sobrelapan
                                if (punto == new Point(picPosicion.Location.X + (x * 30), picPosicion.Location.Y + (y * 30) + (j * 30)))
                                    return false;
                            }
                        }
                    }
                }
                // Retorna verdadero si no hay ninguna coincidencia
                return true;
            }                     
        }



No hay comentarios:

Publicar un comentario