elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Entrar al Canal Oficial Telegram de elhacker.net


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Consulta Pascal
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Consulta Pascal  (Leído 2,741 veces)
Pascaloro

Desconectado Desconectado

Mensajes: 1


Ver Perfil
Consulta Pascal
« en: 22 Noviembre 2018, 16:11 pm »

Buenos días!! disculpen que lo publique acá pero no se donde publicarlo no encontré ninguna sección de pascal... Estoy haciendo un batalla naval para la facultad (estoy en primer año) y tengo que hacer que los barcos se carguen random en la matriz, sin que colapsen entre si y sin que sean contiguos(No importa si son contiguos en diagonal) logre hacer prácticamente todo pero tengo un problema y es que aveces me carga perfectamente la matriz con los barcos sin que se choquen entre si, pero aveces también me tira un runtime 201 como si se saliera de rango en algún momento pero no logro ver/entender cuando pasa eso y como debería corregirlo... Muchas gracias!! y perdón por publicarlo acá necesito ayuda urgente.
Código:
program BatallaNaval;
const
        MinF=1;
        MaxF=15;
        MinC=1;
        MaxC=15;
        CantBarcos=5;
        MaxJugadas=10;
type
        Matriz=Array[MinF..MaxF,MinC..MaxC] of char;
Function BarcoValidoHorizontal(Tablero:matriz;c,f,t:integer):boolean;
var
b:integer;
begin
    b:=1;
    BarcoValidoHorizontal:=False;
    If c+t<MaxC then begin
        If ((Tablero[f,c]<>'B') and (Tablero[f,c-1]<>'B')) then begin
            If Tablero[f,c+1]<>'B' then begin
                While b<>t do begin
                    if (((Tablero[f,c+1]<>'B') and (Tablero[f-1,c]<>'B')) and (Tablero[f+1,c]<>'B')) then begin
                        c:=c+1;
                        b:=b+1;
                    end
                    else
                        BarcoValidoHorizontal:=False;
                end;
                If b=t then
                    BarcoValidoHorizontal:=True;
            end;
        end
        else
            BarcoValidoHorizontal:=False;
    end
    else
        BarcoValidoHorizontal:=false;
end;
Function BarcoValidoVertical(Tablero:matriz;c,f,t:integer):boolean;
var
b:integer;
begin
    b:=1;
    BarcoValidoVertical:=False;
    If f+t<Maxf then begin
        If ((Tablero[f,c]<>'B') and (Tablero[f-1,c]<>'B')) then begin
            If Tablero[f+1,c]<>'B' then begin
                While b<>t do begin
                    if (((Tablero[f+1,c]<>'B') and (Tablero[f,c-1]<>'B')) and (Tablero[f,c+1]<>'B')) then begin
                        f:=f+1;
                        b:=b+1;
                    end
                    else
                        BarcoValidoVertical:=False;
                end;
                If b=t then
                    BarcoValidoVertical:=True;
            end;
        end
        else
            BarcoValidoVertical:=False;
    end
    else
        BarcoValidoVertical:=false;
end;
procedure GenerarTablero(var Tablero:Matriz);
var
       c,f,i,j,b,t,p,k:integer;
begin
        For i:=1 to MaxC do
                For j:=1 to MaxF do
                        Tablero[i,j]:='*';
        k:=0;
        While k<CantBarcos do begin
                b:=0;
                randomize;
                c:=Random(14)+1;
                f:=Random(14)+1;
                t:=Random(4)+2;
                p:=Random(2);
                If p=1 then begin
                    If BarcoValidoHorizontal(Tablero,c,f,t)=True then begin
                        While (b<=t) do begin
                               Tablero[f,c]:='B';
                                c:=c+1;
                                b:=b+1;
                        end;
                    end
                    else
                        k:=k-1;
                end
                else
                    If BarcoValidoVertical(Tablero,c,f,t)=true then begin
                        While (b<=t) do begin
                                Tablero[f,c]:='B';
                                f:=f+1;
                                b:=b+1;
                        end;
                    end
                    else
                        k:=k-1;
                k:=k+1;
        end;
end;
procedure Mostrar(Tablero:matriz);
var
        c,f:integer;
begin
        For c:=1 to maxC do begin
                For f:=1 to MaxF do
                        write(Tablero[c,f]);
                        writeln;
        end;
end;
var
Tablero:matriz;
begin
GenerarTablero(Tablero);
Mostrar(Tablero);
end.


En línea

Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.391


Ver Perfil
Re: Consulta Pascal
« Respuesta #1 en: 25 Noviembre 2018, 02:43 am »

No lo he revisado a fondo...
Aseguraría que tu fallo consiste en tus bucles While... ya que los condicionas para acabar cuando alcancen el valor de 't', pero anterior al bucle no verificas si el 'barco' cabe a partir de ahí. Tu sumas filas o columnas hasta que posiblemente desborde el array...
Citar
   While b<>t do begin
        if (((Tablero[f+1,c]<>'B') and (Tablero[f,c-1]<>'B')) and (Tablero[f,c+1]<>'B')) then begin
            f:=f+1;

Tendrías que revisar varios bucles.

La lógica es que crees algunas funciones de revisión...
Te aclaro un poco por encima, bueno las 3 funciones principales del tema que te trae...

- Primero creamos el mapa, además cuando se inicie una nueva partida, también se invoca.
- Básicamente borramos el mapa, marcando cada casilla con 'agua', vacía, un valor 0 si usas bytes,o un char "0"...
Código:
funcion GenerarBorrarMapa(integer Filas, integer Columnas)
    integer j, k
    MAXCOLUMNA = (columnas-1)   //Maxcolumna y maxfila se DEBEN declarar a nivel de modulo... lo mismo que los arrays de Mapa (tableros).
    MAXFILA = (filas-1)
 
    // Hay 2 mapas el propioy el del enemigo...
    Dimensionar array MapaA(0 a MAXFILA , 0 a MAXCOLUMNA ) //es el array de las casillas, el tablero...
    Dimensionar array MapaB(0 a MAXFILA , 0 a MAXCOLUMNA )

    Bucle para j desde 0 a MAXFILA
        bucle para k desde 0 hasta MAXCOLUMNA
            MapaA(j,k) = 0 // marcamos la casilla como vacía
            MapaB(j,k) = 0 // marcamos la casilla como vacía
        siguiente
    siguiente
fin funcion

- Ahora se posicionan todos los barcos en un mapa  (MapaA o MapaB)
- Es decir se debe invocar dos veces cada vez con un mapa distinto.
- Hemos supuesto que la flota se compone de (por ejemplo); Un barco de 5 casillas, 2 de 4, 3 de 3 y 1 de 2 casillas... total la flota tiene 7 barcos... (24 casillas)
Código:
funcion PosicionarFlota(array Mapa)
     PosicionarBarco(5, Mapa)  // es preferible posicionar primero los barcos más grandes,
       //los pequeños luego caben mejor en medias que si se hace al revés...
      // por eso los vamos colocando en este orden de mayor a menor...

     PosicionarBarco(4, Mapa)
     PosicionarBarco(4, Mapa)
     PosicionarBarco(3, Mapa)
     PosicionarBarco(3, Mapa)
     PosicionarBarco(3, Mapa)
     PosicionarBarco(2, Mapa)
fin funcion

- Aquí la función que reposiciona un solo barco... nota que se elige si colocarlo vertical u horizontal
- Luego se elige al azar la fila donde ponerlo, después se verifica si cabe en dicha fila, si no cabe se busca otra... Se supone que el mapa es lo suficientemente grande para que quepan todos los barcos holgadamente... si no es así... fallará.
- Al comprobar que un barco cabe en una fila, devuelve la posición donde cabe... pero intentamos colocarlo al azar, solo si tras 5 intentos al azar no fue osible ubicarlo, usamos la posición devuelta.
- Notar que la misma función para verificar si cabe el barco se usa dos veces, perimero recorriendo toda la fila, luego solo desde la posición elegida al azar.
- Solo se pone el pseudocódigo para el caso horizontal, el vertical es solo cambiar donde proceda...
Código:
funcion PosicionarBarco( integer piezas , array Mapa)
    buleano b = random(entre 0 y 1)
    integer cabe, pos, n, k
  
    Si b=1 // elegimos ponerlo en horizontal
        Hacer
            fila = random(entre 0 y MAXFILA)
            cabe = BarcoCabeEnFila(piezas, fila, 0, TRUE)
        Repetir mientras (cabe= -1)

        hacer   // haremos 5 reintentos de ubicalro al azar, si fallan, se posicionará en 'cabe'.
            pos = Random(entre 0 y MAXCOLUMNA)
            pos = BarcoCabeEnFila(Piezas, Fila, pos, FALSO)
            n = (n+1)    
        Repetir mientras ((pos=-1) y (n < 5))

        // si se intentó 5 veces al azar y no encajó, lo posicionamos donde se encontró en la fila
        Si (pos= -1) luego pos = cabe
        
        // Finalmente marcamos las casillas donde se colca el barco, con el valor del barco.
        bucle para k desde pos hasta (pos + piezas-1)    
            Mapa(fila, k) = piezas  // una casilla ocupada la marcamos con el número de piezas que tiene ese barco... un barco de 2, con el valor-char 2, uno de 4 con valor o char 4, etc... la vacía tiene valor 0.
        fin si
    Sino // b=0 , se coloca en vertical
         // similar a lo de horizontal, cambiando donde proceda.
    fin si
fin funcion


- Esta función trata de ver si un barco de x piezas de tamaño, cabe en la fila dada... a partir de la posición que se pide. Para ello basta saber si tiene el números de casillas consecutivas libres que tiene 'piezas' de barco.
- La fila ya puede tener casillas ocupadas... cuando se vaya a colocar el barco, primero lo intentará al azar, tras x intentos fallidos, se tomaría el hueco encontrado y devuelto por esta funcion.
- La función se usa con dos usos bien diferenciados al inicio, se recorre la fila entera si es necesario... buscando que quepa. En la otra funcionalidad solo se recorre hasta encontrarlo o se sale... es decir no comprueba más alla de la posición de inicio recibida si se haya alguna ocupada. El parámetro 'Reubicable' se encarga de esto... fíjate en la llamada quien lo llama con TRUE y quien con FALSE
- La función Gemela- BarcoCabeEnColumna, es casi idéntica, cambia solo la comprobación del mapa: If Mapa(k, Columna)  ... MAXCOLUMNA
Código:
integer = funcion BarcoCabeEnFila(integer Piezas, integer Fila, Integer Pos, buleano Reubicable)
    integer k, n

    Bucle para k desde Pos hasta MAXFILA
        If Mapa(fila, k) = 0  // " " "Agua" , casilla no ocupada actualmente.
             n = (n+1)
             Si n=Piezas devolver (k-piezas)  // devuelve el punto donde comienza a estar libre
        sino
            si Reubicable=FALSO salir del bucle // o devolver -1 saliendo de la funcion.
            n = 0
        fin si        
    fin bucle

    devolver -1  // no cabe un barco de ese tamaño.
fin funcion

Listo... ya tienes por donde seguir...


« Última modificación: 25 Noviembre 2018, 02:56 am por NEBIRE » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Pascal o C « 1 2 3 »
Programación General
SpuTniK. 29 17,267 Último mensaje 25 Julio 2010, 20:50 pm
por IDarknightI
Consulta; Necesito armar una consulta para saber si una fecha ha caido dentro...
Bases de Datos
astinx 6 6,434 Último mensaje 23 Diciembre 2011, 20:34 pm
por astinx
Pascal vs C++: Pascal mejor que c++?
Programación General
Bomb-P 4 10,413 Último mensaje 11 Mayo 2013, 20:42 pm
por BlackM4ster
utilizar valor de consulta en otra consulta
PHP
demonstrator 0 2,060 Último mensaje 12 Septiembre 2014, 02:59 am
por demonstrator
Pascal-- ayuda con matrizes no compila pascal ide
Programación General
Augusto 0 2,152 Último mensaje 6 Noviembre 2017, 22:50 pm
por Augusto
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines