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


 


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)


  Mostrar Mensajes
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... 65
11  Programación / Desarrollo Web / Re: ¿Como puedo mejorar esta colisión? JS "canvas" en: 19 Agosto 2017, 06:12
No hay mucho de donde mejorarla. Técnicamente es correcta. Aunque es cierto que algo si se puede.

Te comento. Tu estás considerando siempre dos áreas, pero vamos a hacernos una imagen mental, para que sea más fácil entender donde quiero ir a parar.

imagina que tienes una espda y luchas contra otro que también tiene una espada. El área de cada uno, entonces es uno mismo y las dimensiones de la propia espada. es fácil de entender, verdad?

Bien, entonces la cuestión es... a quién le importa, tu espalda o 'su' espalda?. quiero decir, que la intercepción se basará en un punto, y no es preciso un área.

Supongamos que 'el jugador' es This (tu, yo, el que lo lea que se ponga en primera persona) y que el 'enemigo' es el área (rect).... con esto y lo dicho previamente pasemos al pseudocódigo...

Código:
Clase cThis
      entero X, Y, Width, Height
      entero Right, Bottom

      // Asignación de todos los datos del área (se reposiciona y redimensiona)
      Funcion MoverYDimensionar(rect Area) // puedes pasar valores individuales, (x,y,Width,Height) o incluso solo dos puntos de la diagonal principal '\' y calcular como proceda, o bien sobrecargar la función si se usan más que solo una.
          This.x = Area.X
          This.y = Area.Y
          This.Width = Area.Width
          This.Height = Area.Height

          This.Right = (This.X + This.Width)
          This.Bottom = (This.Y + This.Height)
      Fin Funcion

      // Cuando se desplaza (pero mantiene el tamaño):
      //       ('Inc'remento indica si los valores son relativos o absolutos)
      Funcion Mover(entero X, entero Y, buleano Inc)
          Si (Inc = FALSE)
              This.X = X
              This.Y = Y
          Sino
              This.X += X
              This.Y += Y
          Fin si

          This.Right = (This.X + This.Width)
          This.Bottom = (This.Y + This.Height)
      Fin funcion
    
      // Cuando se cambia de tamaño (pero mantiene su posición):
      //       ('Inc'remento indica si los valores son relativos o absolutos)
      Funcion Dimensionar(entero Witdth, entero Height, buleano Inc)
          Si (Inc = FALSE)
              This.Width = Width
              This.Height = Height
          Sino
              This.Width += Width
              This.Height += Height
          Fin si

          This.Right = (This.X + This.Width)
          This.Bottom = (This.Y + This.Height)
      Fin Funcion

// y por fin la detección de la colisión.
      // El detector de colisión, ahora exige menos matemáticas.
      Buleano = Funcion ColisionaCon(cThis cT)
           // si de entrada se aleja horizontalmente, no perdemos tiempo en comprobaciones verticales
          Si ( cT.Rigth > This.X) y (cT.X < This.Right) luego              
              Devolver ( cT.Bottom > This.Y) y (cT.Y < This.Bottom)
          Sino
              Devolver FALSE
          Fin si
      Fin Funcion
Fin clase


Tanto 'nosotros' (player) como el 'enemigo' seríamos instancias de cThis, y se llamaría así:
Código:
Si Player.ColisionaCon(Enemigo) luego
     ...

Funciona y es más rápido, porque:
A - Se calcula una única vez, el valor 'Right y Botton', y se guardan, en lo sucesivo ya no se calculan. Por tanto cada vez que haya que hacer la detección de colisión, nos ahorramos 4 sumas.
B - También contribuye a la velocidad que la comparación la dividimos en dos pasos, primero horizontal y luego vertical, (no importa si fuera al revés, de hecho si fuere más frecuente los movimientos verticales, sería mejor poner delante la comprobación vertical). al dividirlo en dos pasos no forzamos una posterior comprobación si la previa ya falló, pero incluso si es necesario la segunda comprobación también es ligera (no realiza sumas).

En Resumen, la detección ahora solo requiere:
    2 ó 4 comparaciones y 0 sumas
Antes requería:
    4 comparaciones y 4 sumas


Las sumas se hacen una sola vez cuando se establece/modifica el tamaño o se reposiciona, pero no con cada verificación de colisión.
Aunque al final viene a ser lo mismo, sin embargo el momento es diferente, al mover o redimensionar, no suele haber tanta carga de trabajo, luego... deja más tiempo para actualizar valores, en cambio cuando se exige detectar suele haber más trabajo 'pesado' en curso, entonces aligerar de ahí es adecuado.
En resumen, desplazamos la carga de trabajao a momentos menos activos, aligerando los momentos más activos. Aunque siempre va a depender de cada caso concreto...

...pero bueno, lo que pedías es posible...


---------------------
p.d.: Al publicar ya había más respuestas... te comento: asegúrate tras rehacer tu código que funciona en todos los casos... he aquí una imagen de los casos posibles (considera el cuadro rosado como el jugador y los azules como el enemigo), falta el caso de que el jugador esté completamente dentro del área del enemigo (el cuadro rosa dentro de uno azul), en las imágenes quedaba sobrecargado y se prestaba a confusión así que la he evitado.
12  Programación / Programación C/C++ / Re: crear matriz con numeros aleatorios en c en: 19 Agosto 2017, 04:37
Por eso es mejor responder con pseudocódigo. No pueden copiar y pegar sin más, tienen que leerlo sí o sí, y entenderlo... obligas a que se esfuercen...
13  Programación / Java / Re: Comparar Imagenes y encontrar similitudes. en: 17 Agosto 2017, 16:49
Exacto...

Una vez con los 4 puntos y uno considerado como el 'centro geométrico', desde los 4 hay que buscar los puntos salientes que tocando a la figura logran encerrar por completo la figura.

La parte que puede parecer un poco confusa (espero que no), es la de considerar el ángulo convexo o cóncavo, ya que eso depende del cuadrante (en realidad ángulo de ambos puntos alrededor del eje).

Por último, aunque no se ha mencionado explicítamente si no que se ha dejado un poco al aire, es que consideramos similitud... porque puede tener diferentes interpretaciones según lo que busquemos:
Similitud en la forma, similitud en tamaño (área), etc...
Se ha asumido de forma genérica, pero los detalles dados permiten avanzar en la dirección que uno pretenda.

p.d.: No he mirado tu código aún... cuando avances algo más le hecho un vistazo.
Ten en cuenta que es fácil perderse, o desalientarse porque hay muchos pequeños detalles que mimar y ponder en orden. Pero bueno, cada función en pseudocódidigo está en grandes pasos (y escrito al vuelo), se puede pulir y detallar más llegado el caso.
14  Programación / Java / Re: Comparar Imagenes y encontrar similitudes. en: 16 Agosto 2017, 18:19
Olvidaba decirte, que hay otra más sencilla y rápida, pero es aplicable solo cuando tengas la seguridad de que las imágenes tienenn todas la misma orientación y si no es así, deben antes ser rotadas, considerando los 4 puntos más sobresalientes de uno consderado centro.

Esto es, si hay que rotarlas, primero trazas un punto que inscriba por completo la figura, pero tocando en al menos 3 puntos el exterior del perímetro de la figura.
Luego buscas 3-4 puntos más alejados del centro.

Esos puntos te sirven para saber cuanto puede estar rotada una figura respecto d ela otra y si es preciso se rotan. También para saber si una está desplazada respecto de otra.

Recuerda que debemos tener imágenes donde el fondo es blanco y la figura (no solo el trazo que la encierra) es negro (o viceversa), pero si es transparente hay que considerar la transparencia del color opuesto a la tinta d ela figura (blanco o negro).

Finalmente solo cuando estés seguro que 'encajan' en el mismo centro.

Entonces se hace una operación xor entre los píxeles de ambas imágenes. El resultado será el siguiente:
255 xor 255 = 0
0 xor 0 = 0
255 xor 0 = 255
0 xor 255 = 255
Es decir, donde una imagen coincida (dentro y fuera de la figura) con la otra, dará un píxel negro en la imagen resultado, y blanco cuando sean distintas. Contando el número de blancos sabremos cuanto difiere (o contando los blancos sabremos cuanto es igual). Usa la tolerancia con diferentes valores, para ver qué resultados te da.

Esta solución, es la adecuada cuando no hay que ser muy extrictos y las formas son más o menos claras, del mismo tamaño, pequeñas y la velocidad es muy importante.

P.d.: Aquí no se ha considerado si la imagen están espejadas (que veo que tienes dos iguales pero espejadas entre sí). cuando cabe la posibilidad de que estén espejadas, hay que hacer 4 comparaciones (4 bucles idénticos), el primero tal cual (como si las dos estuvieren corrctas, en otra donde la segunda imagen esté invertida horizontalemente, la 3ª donde se considere invertida a la segunda figura verticalemtne y la 4º donde se consdiere invertida a la segunda figura tanto vertical como horizontalmente.
Con los reconocimientos en el mensaje anterior es fácil detectar si están invertidas, porque las  áreas, perímetros vendrán a coincidir y medidas y ángulos  conncidirán en orden inverso...
15  Programación / Java / Re: Comparar Imagenes y encontrar similitudes. en: 16 Agosto 2017, 06:45
...primero debes detectar los bordes salientes...

Esto es:
- Recorre la imagen horizontalmente bajando hasta tocar el primer píxel, luego ídem pero desde abajo hacia arriba.
- Recorre la imagen verticalmente avanzando a la derecha hasta que toques el primer píxel, luego ídem pero desde la derecha y avanzando hacia la izquierda...

La forma más exacta, es resaltar los vértices salientes... Imagina que con un lápiz trazas líneas para encerrar cada figura en un polígono, pero siempre con ángulos convexos ('reentrantes', nunca cóncavos hacia afuera) y siempre tocando la figura, por supuesto.

Mediante la comparación luego de:
A - La superficie interna del polígono. buen candidato para determinar rápidamente los similares (pero no óptimo si varían en tamaño)
B - La cantidad de lados del polígono resultante. Buen candidato para a primera vista determinar similitud incluso entre diferentes tamaños.
C - Los ángulos que forman cada par de lados del polígono. Es la tarea final, las previas son aproximaciones rápidas.

Y con esto  es relativamente asequible determinar su similitud con un porcentaje.
Éste algoritmo sería el adecuado, si además las formas tienen diferente tamaño (dos figuras iguales o muy parecidas pero de diferente tamaño), ya que los ángulos se mantienen así como el número de lados del polígono.




Basicamente  en pseudocódigo son estos pasos:
Esta sería la función principal (tras los pasos que llevas)
Código:
Buleano = Funcion Buscarsimilitudes(Lista de Imagenes Figuras )
    Lista Poligonos  // lista de poligono
    Lista Poligono // lista de líneas

    Por cada figura en Figuras
         Poligono = CrearPoligono(figura)
         Poligonos.Add (Poligono)
    Siguiente

    Bucle para j desde 0 Poligonos.Length -2  //el último se debe comparar
        Poligono = Poligonos.Item(j)
        Bucle para k desde j a Poligonos.Length -1
            Si EsSimilar(Poligono, Poligonos.Item(k))  luego
                // Mostrar coincidencia en la forma que tengas previsto.  
                Similares = TRUE
            Fin si
        Siguiente
    Siguiente
  
    Devolver Similares //si al menos hubo 2 similares entre sí, devolverá TRUE.
Fin Funcion

Aquí el pseudocódigo para crear un polígono de cada imagen (a grandes rasgos).
Tu primer paso será entonces un "localizador de puntos salientes" de la figura...
El segundo, será un "trazador de líneas"... primero empezamos con los 4 puntos (uno de cada orientación, se trata de intentar lanzar una línea de uno de ellos al del lado contiguo, si corta en algún punto la figura, se debe buscar otro punto saliente entre medias y repetir).
Es mejor usar una lista que un array porque no se sabe cuanto se va a almacenar.
Código:
Lista = Funcion CrearPoligono(imagen Figura)
    Lista Puntos  //donde señaden los puntos.
    Lista Poligono //donde se añaden las líneas
    entero j, k
    punto centro

    centro = PuntoCentral(Figura) // se trata de hallar aprox, el punto central de la imagen, un eje de cordenadas en el centro.
    Puntos = BuscarLos4PuntosMásSalientes // (de las 4 orientaciones), da igual si prefieres buscarlos en diagonal, pero es más complejo recorrer así la imagen.    
    j=0
    k=(j+1)
    Hacer
        Linea = TrazarLinea(puntos.Item(j), Puntos.Item(k) )
        Si Linea CortaFigura(Linea, Figura) luego //Si la línea corta la figura...
            Punto = Buscar nuevo punto saliente entre ambos, y añadir delante del destino
            Puntos.Add(punto, k)            
        Sino
            //OJO: No trato el caso de que k sea el último y el 3º punto debiera ser el primero el 0º
            // queda a tu esfuerzo modificarlo como convenga...
            Si AnguloEsConcavo(puntos.Item(j), Puntos.Item(k),  Puntos.Item(k+1), centro ) = FALSE luego
              
                Poligono.Add(Linea)
                j = k
                Si (k < Puntos.Count) luego                  
                    k +=1
                Sino
                    Si (k=0) luego
                       Conectado = TRUE
                    Sino
                        k = 0
                    Fin si
                Fin si
            Sino
                El punto intermedio entre los dos se elimina // hace concavidad, la búsqueda (la programación) del más saliente no fue 'adecuada', pero bueno esto nos permite avanzar aunque sea más lentamente.
                // j y k no cambian, así al retorno se traza la línea entre esos dos (que antes tenían uno en medio).
            Fin si
        Fin si
    Repetir Mientras (Conectado= FALSE)
    Devolver Poligono
Fin funcion

También puedes buscar similitud por perímetro cuando el número de lados es desigual. Si la superficie y el perímetro son similares hay probabilidades.
Código:
Buleano = EsSimilar(Lista p1, Lista p2)  // p1 y p2 son sendos polígonos
    Area1 = HallarArea(p1)
    Area2 = HallarArea(p2)
  
    Si SimilitudPorTolerancia(Area1, Area2, ToleranciaArea) = TRUE luego  //tolerancia debe expresarse en forma de porcentaje aceptable, p.e.: '90' por ciento.
         // son de tamaño similar, no hay zoom, o es escaso.
        Si SimilitudAngulos(p1, p2, ToleranciaAngulos) = TRUE luego
            Devolver TRUE
        Fin si
    Sino  // son distintos, puede que uno esté con zoom... comprobamos lados y angulos
        // comprobamos la similitud en el número de lados.
        Si SimilitudPorTolerancia(p1.Length, p2.Length, ToleranciaLados) = TRUE luego
            Si SimilitudAngulos(p1, p2, ToleranciaAngulos) = TRUE luego
                Devolver TRUE
            Fin si
        Si no
            // El número de lados si no cincide ver si hay o falta un lado de tamaño muy corto, pero no se expone aquí...
            // Si cambia el númeor de lados, vamos a exigir más exactitud, con los ángulos
            Si SimilitudAngulos(p1, p2, ToleranciaAngulos+ToleranciaExigente) = TRUE luego
                Devolver TRUE
            Fin si
        Fin si
    Fin si
Fin Funcion

Tolerancia debe ser un valor en el rango 1-100, pero si se pone 100 exige exactitud total, y si se pone 1, una casa será igual que un coche, un valor adecuado podría ser 90% es decir uno es similar a otro si es un 90% del área (esto es solo varía un 10%, no confundir ambos valores, pués puede hacerse  al derecho o al revés).
Código:
Buleano = Funcion SimilitudPorTolerancia(entero v1, entero v2, byte Tolerancia)
    Si (v1 >= v2) luego  //
        Si (((v1/100) * Tolerancia) >= v2) luego Devolver TRUE
    Sino
        Si (((v2/100) * Tolerancia) >= v1) luego Devolver TRUE
    Fin si
Fin Funcion

Se traza una línea ente los puntos extremos, y considerando el centro, se ve si p2, a que lado queda
respecto de la línea, según el centro debe quedar en un sitio u otro para saber si es cóncavo o convexo.
Código:
Buleano = Funcion  AnguloEsConcavo(Punto p1, Punto p2, Punto p3, Punto centro)
   Linea  
    
    Linea = TrazarLínea(p1,p3) //Trazar una línea desde p1 a p3

    //Ver donde queda p2 respecto de la linea y según p1 y p3 estén orientados respecto del centro
    Si p1.X < centro.x
        // Sin terminar... queda a tu esfuerzo
    Sino
        // Sin terminar... queda a tu esfuerzo
    Fin si
Fin Funcion

Código:
Buleano = Funcion SimilitudAngulos(Poligono pol1, Poligono pol2)
    Lista Angs1, Angs2
    Decimal ang1, ang2  //valor en  coma flotante
    Buleano Similares

    Angs1 = AngulosPoligono(pol1)
    Angs2 = AngulosPoligono(pol2)

    // Quizás una figura esté rotada respecto de otra, luego exige encontrar ekl punto de coincidencia.
    // pero puede pasar que haya más de un ángulo en una figura que tenga el mismo que otro en la otra figura...
    Bucle para i desde 0 a Angs1.Length
        ang1 = Angs1.Item(i)
        Bucle para cada j desde 0 a Angs2.length
            ang2 = Angs1.Item(j)
            // se convierten a enteros, tal como exige la función...
            Si SimilitudPorTolerancia(ConvertirAEntero(ang1), ConvertirAEntero(ang2), ToleranciaAngulo) = TRUE luego
                Similares = TRUE
                Bucle para k desde j+1 a Angs1.Length
                    ang2 = Angs1.Item(k)
                    Si SimilitudPorTolerancia(ConvertirAEntero(ang1), ConvertirAEntero(ang2), ToleranciaAngulo) = False luego
                        Similares = FALSE
                        Salir del bucle
                    Fin si
                Fin Bucle
                Si (Similares = TRUE) luego Devolver TRUE
            Fin si
        Fin bucle    
    Fin Bucle
Fin Funcion
Crea una lista con los ángulos del polígono.
Código:
Lista = Funcion AngulosPoligono(Poligono Pol)
    Lista Angulos
    Punto p1, p2, p3
    
    p1 = pol1.Item(0)
    p2 = pol1.Item(1)
    p3 = pol1.Item(2)
    Angulo = AnguloFormado3Pt(p1, p2, p3)
    Angulos.Add(angulo)
    Bucle para j desde 3 a p1.Length - 1 // si es un triángulo, no entrará en el bucle        
        p1=p2
        p2=p3
        p3= pol1.Item(j)
        Angulo = AnguloFormado3Pt(p1, p2, p3)
        Angulos.Add(angulo)
    Fin bucle
    // Faltan 2 ángulos, los formados por el final y el comienzo
    p1=p2
    p2=p3
    p3= pol1.Item(0)    
    Angulo = AnguloFormado3Pt(p1, p2, p3)
    Angulos.Add(angulo)

    p1=p2
    p2=p3
    p3= pol1.Item(1)    
    Angulo = AnguloFormado3Pt(p1, p2, p3)
    Angulos.Add(angulo)
    
    Devolver Angulos
Fin Funcion

Código:
Decimal = AnguloFormado3Pt(Punto p1, Punto p2, Punto p3)
   // queda a tu esfuerzo, son simples matemáticas...
Fin funcion

Aumento una de las figuras y realizo un pequeño dibujo a mano alzada. Nota el número de lados del polígono que encierra la figura, sus ángulos, etc... así te formas una idea y con esto debiera valerte... aunque tienes trabajo por delante...

16  Foros Generales / Foro Libre / Re: timo con alquiler en: 15 Agosto 2017, 22:41
Si ha spagado con tarjeta de crédito y no han pasado aún 15 días (no sé con exactitud cuántos son), basta que le digasa tu banco que regrese atrás la operación, porque resultó ser un timo. Y listo...

Y eso no quita que puedas interponer denuncia en la policía (siempre que puedas demostrar el pago por un servicio incumplido ), los emails y un extracto bancario firmado por el director del banco (donde aparece la salida del dinero desde tu cuenta a la que sea), deberían ser suficientes pruebas.
17  Programación / Java / Re: Codigo para crear SUDOKUS en: 15 Agosto 2017, 17:36
Tengo una mala noticia...

A pesar de que dicen que si hay más de x pistas, un sudoku solo tiene una solución, puedo demostrar que es falso... sin la necesidad de sesudas matemáticas, basta uno donde se demuestre que efectivamente tiene dos soluciones y x pistas.

En la siguiente imagen, se ve un sudoku correctamente resuelto:
Cada fila hay, bloque y columna cumple la condición. Sin embargo, no me lo da por bueno, si comparo el Sudoku que crea el usuario (en este caso yo), con la solución interna.

Marcado en rojo (y rodeado en azul a mano), las discrepancias que existen con la solución que se generó para el sudoku (en amarillo las pistas, que como se ve son 30ytantas.

En la solución 'real', donde pone 8 es 6 y donde pone 6 es 8 (en ambos casos). Sin embargo este mapa es legítimamente correcto, luego:
queda demostrado como falso
que exista una única solución posible,
cuando el número de pistas es superior a 17.



En consecuencia, es razonable que la solución se verifique no por comparación de la solución almacenada, si no por comprobación de todas las filas, columnas y bloques.

En algún punto hay que poner alguna función que permita al usuario pasar los valores que va marcando y podría ser algo como esto (yo he preferido una propiedad)

Código:
Byte = Propiedad Leer Valor(X, Y)
   n = ((Y * c_Nueve) + X)
   Devolver User(n)
Fin Propiedad

Propiedad Escribir Valor(X, Y, V)
        byte n
        TiposDeValor  t  //una enumeración para indicar al dibujar que tipo de tinta usar
        
        n = ((Y * c_Nueve) + X)
        Si (Pistas(n) = 0) luego  //Si la casilla es una pista, no se toca
            Si (User(n) = 0) luego  //la casilla está ocupada ya?
                Si (v > 0) luego ' que se llena
                    Faltas = (Faltas - 1)  //Descontamos una falta cuando se ingresa un valor, si antes estaba vacía.
                    t = VALOR_TIPO_USER  //la casilla tendrá un valor (1-9)
                Sino
                    t = VALOR_TIPO_VACIO // la casilla se dejará libre.
                Fin si
            Sino  // la casilla ya está ocupada, aquí se cambiará valor o se borrará.
                Si (v = 0) luego
                    Faltas += 1 // antes había un valor, ahora se borra, aumentan las faltas uno más...
                    t = VALOR_TIPO_VACIO // la casilla se dejará libre.
                Sino
                    t = VALOR_TIPO_USER  // se remplaza el valor actual por otro.
                Fin si
            Fin si
            
            User(n) = v  //Asignamos el valor recibido
            
            //valor, casilla(x,y), tipo de tinta a usar
            Disparar Evento DibujarValor(v, X, Y, t)  
            
            Si (Faltas = 0) luego  // Solo se verifica el sudoku, cuando se hayan entrado todos los valores.
                Si (VerificarSudoku = True) luego                    
                    Disparar Evento FinDePartida(True) //True, porqueel mismo evento con False, puede usarse si el usuario decide Resetear la partida.
                Fin si
            Fin si
        Fin si
    Fin Propiedad



Ésta (la siguiente) es una función intermedia, que llama a una u otra para verificar si la solución es corecta, visto lo visto (verificado que NO SIEMPRE existe una UNICA solución), es preferible descartarla e  invocar siempre a  ValidarSolucionMultiple. Y en consecuencia no e spreciso mantener en memoria el array de la solución una vez generado y obtenido las pistas (dicho de otro modo, dicho array podría ser reutilizado para las pistas, eso al gusto)
Código:
Buleano = Funcion VerificarSudoku
    Si  (SolucionUnica = True) luego
        VerificarSudoku = ValidarSolucionSimple
    Sino
        VerificarSudoku = ValidarSolucionMultiple
    Fin si
Fin Funcion

Como decía más arriba:
En consecuencia, es razonable que la solución se verifique no por comparación de la solución almacenada, si no por comprobación de todas las filas, columnas y bloques.
18  Programación / .NET / Re: Una ayuda simple (visual basic, 2017) en: 15 Agosto 2017, 06:31
es lo mismo... un bucle do...


Código:
Cazado = FALSE
Hacer
   Intentar
       EnRango = FALSE
       Hacer
          ... dia ' Hacemos la idea de que esta línea representa el ´codigo para el día
        Repetir mientras EnRango = FALSE       
 
       Cazado = TRUE
   Cazar error
       Mensaje "Escriba solo números 'porfaplis'..."
   Final intento
Repetir mientras Cazado = FALSE

Esto solo para el día, haz lo mismo para mes y lo mismo para año, si quieres generar un solo bucle para todos, crea una función para devolver el valor correcto en el rango:



Código:
Entero = Funcion PedirValorEnRango(Maximo, minimo, MensajeRango, MensajeError)
    Intentar
          EnRango=FALSE
          Hacer
              Pedir valor
              si (Valor >=Minimo) y (valor <=Maximo) luego
                   EnRango=TRUE
              Sino
                   Mostrar MensajeRango
              Fin si
          Repetir mientras EnRango=False
          Devolver Valor
    Cazar Error
         Mostrar MensajeError
         Devolver -1
   Final intento
Fin Funcion

Y esta función se llamaríamás simple desde un código similar a:
Código:
    Hacer
        Dia = PedirValorEnRango(1,31, "Números delmes entre 1 y 31", "Por favor solo números, no letras ni palabras.")
    Repetir mientras Dia = -1

    Hacer
        Mes = PedirValorEnRango(1,12, "Mes debe ser un número entre 1 y 12", "Por favor solo números, no letras ni palabras.")
    Repetir mientras Mes = -1

    Hacer
        Año = PedirValorEnRango(1800,2020, "Año debe ser entre 2800 y 2020", "Por favor solo números, no letras ni palabras.")
    Repetir mientras Año = -1

    Mostrar día, mes y año
       
 
19  Programación / Java / Re: Codigo para crear SUDOKUS en: 15 Agosto 2017, 05:49
Te respondo por aquí el mensaje privado (útil para todos).

Bien, las pistas pueden ir en efecto entre 17 y las que quieras.
Probablemente alguien que no sea muy entusiasta de las matemáticas y todo lo que sea pensar, necesite la mitad de las casilla como pistas, incluso alguna más...

Yo propondría un límite de 45 pistas como máximo y un mínimo de 17 (para que en efecto tenga una única solución).
Esto implica de alguna manera establecer niveles de dificultad. El nivel de dificultad, va a depender de 3 factores básicos:
A - Número de pistas (cuantas menos, más difícil).
B - Distribución en el 'mapa'.
C - Destribución de valores.

Lo básico es centrarse en el número de pistas, pero de soslayo miramos las otras dos posibilidades.

B - Supongamos que aportamos 27 pistas y que estas se colocan usando exactamente 3 bloques (el 1º, el 5º y el 9º)... esta distribución es algo distinta a si las colocamos de forma aleatoria.
C - Supongamos ahora que las pistas, nos centramos en que valores vamos a colocar (no importa dónde para este caso). Supongamos que sigue siendo 27 pistas, no es lo mismo proporcionar los nueves valores 2,3 y 4 que proporcionar 3 pistas de cada valor (111,222,333,444,555,666,777,888,999), y es disitnto de si los valores son elegidos al azar, puede que haya tres 9, y cuatro 1, pero solo un 5.

Estos dos casos (B y C) es para estudiarlos más a fondo. Su estudio exhaustivo escapa de la ayuda a proporcionar en el foro. A falta de ello es mejor dividirlo en 2 grupos, si son elegidos al azar les concedemos un valor de 'no difícil' y si los elegimos pensando en 'putear' al usuario, le concederíamos un valor de 'difícil'.

Queda por tratar el caso A (el número de pistas). hay que repartirlos en tantos grupos como niveles de dificultad. El reparto no debería ser 'fijo', es decir que aumente la misma cantidad de pistas a medida que baja la dificultad. Ya que esto sería una serie aritmética y es más razonable y ajustado a la realidad una serie serie geométrica.

En matemáticas, una serie se deifne por: un rango de valores llamados términos o medios interpolados, los valores extremos del rango, y la proporción entre cada elemento en el rango, llamada razón.
Si tienes oxidada tus matemáticas, repásalas... busca progresiones aritméticas y progresiones geométricas...

Entonces decidamos cuantos niveles de dificultad queremos tener?. ¿3, 4, 5, 6, 7?. Supongamos 5. Entonces lo primero es crear la serie. Luego esto se fija en un array. el array lo que va a contener será el número de pistas donde comienza ese nivel de dificultad...
Por ejemplo si la serie fuera aritmetica y la razón 5, el array NivDificultad podría tener estos valores.
NivDificultad(0) = 17
NivDificultad(1) = 23
NivDificultad(2) = 29
NivDificultad(3) = 35
NivDificultad(4) = 41
NivDificultad(5) = 47 // este no entra en nivel, es el punto límite.

Entonces si está en el nivel 0 (el más difícil, aunque puede invertirse el número y el más alto expresar más dificultad), se elige una cantidad entre:
NivDificultad(0) y NivDificultad(1)-1
...es decir si elige al azar un número entre 17 y 22
Si nivel 1 entre 23 y 28, etc...

pero... pero hemos elegido una progresión geométrica... Así que cada grupo no tendrá la misma cantidad de valores, pero el enfoque del array y su uso, es el mismo.

Código:
Array Byte = Funcion InterpolacionGeom(Niveles, Minimo, Maximo)
    Decimal Razon, n, p //números con decimales.
    Array Byte Im(0 a Niveles) //Uno más, para guardar el valor final

    razon = RazonGeometrica(Maximo, Minimo, Niveles-1)

    Im(k) = Minimo
    p = im(0)
    Bucle para k desde 1 hasta Niveles-1
       n = p   // Im(k-1) //ídem d elo que se comenta abajo, se pierde precisión y no se alcanza el valor máximo ni lo reparte bien.
       p = (n * razon)
       Im(k) = valor entero de p
       // im(k) = entero de (im(k - 1) * Razon)  
       //podría valer esto, que es una sola línea, pero perdemos precisión en cada iteración. El problema sería tanto mayor cuannto más ciclos tuviere el bucle.
    Fin bucle
    Im(Niveles) = Maximo  //si el código del bucle fue bien esta línea sería inenecesaria,
     //pero si los decimales varían uno arriba o abajo, esto lo fija al punto exacto.
    
    Devolver array Im
Fin Funcion

Generalmente, todos los lenguajes de programación disponen de raíz cuadrada, pero no de raíz cúbica, raíz cuarta ni raíz 125, etc...
Sin embargo, si poseen potenciación y la radicación se define como el inverso de las potencias, al igual que la división es el inverso de las multiplicaciones y la resta el inverso de la suma.
Esto es lo que hacemos aquí:
Código:
Decimal = Funcion RazonGeometrica(Maximo, minimo, Terminos) // terminos intermedios entre ambos extremos
   Devolver ((Maximo/Minimo) elevado a la (1/ (Terminos+1))
Fin Funcion

Una vez que imprimas el resultado del array devuelto, no te vas a sorprender mucho, porque son pocos niveles, también puedes fijar los valores del array 'manualmente', te evitas ambas funciones... pero dejas de aprender cosas.

Tu ya sabiendo que el usuario ha elegido x nivel, seleccionas al azar el número de pistas en cada partida:
NumPistas = Seleccional azar un valor entre( NivDificultad(Dificultad) y NivDificultad(Dificultad+1) -1 )

Y por hoy vale...

p.d.: Espón donde tengas dudas, para no dar vueltas a cosas que no pudierna interesarte e ir al grano.
20  Programación / .NET / Re: Una ayuda simple (visual basic, 2017) en: 15 Agosto 2017, 04:17
Bien. Ves com te has respondido tú mismo?.

Efectivamente si lo piensas... al yo darte respuesta, tu deber es comprobarla, y si yo te doy una fecha errada, tu deber es indicarme que un mensaje 'no es correcto, proporciones un valor en el rango x-y y volverme a pedir de nuevo el dato... y repetir hasta que 'aborte' o dé un valor correcto. (el problema de las consolas, cuando se dispone de interfaz de usuario, se pone un control y los valores mínimo y maximo ajustan el rango, entonces no hay posibilidad de salirse del rango).

Entonces del pensamiento, de la idea, pasamos al pseudocódigo:

Código:
Hacer
    Pedir entrada 'x' con el mensaje 'm'
    Comprobar si 'x' está en el rango
Repetir mientras x fuera de rango

Ese pseudocódigo, representa la idea, y es breve porque es 'genérico', pero se puede expandir, desde el momento en que conocemos ciertos detalles, y podemos hacerlo más 'específico':

Código:
buleano EnRango = FALSE //declaración de una variable...
Hacer
    Pedir 'año' al usuario con el mensaje "Ingrese un año entre los límites: 1800 y 2020 (ambos incluído)"
    Si ((año mayor o igual que 1800) y (año es igual o menor que 2020)) luego
        EnRango = TRUE
    Fin si
Repetir mientras (EnRango=FALSE)

...y esto debieras tu ya poder traducirlo a algo más específco como es el lenguaje que quieras usar...
No hay nada complejo, un bucle do...while, entrada de datos, condicional y comparación matemática...

p.d.: dejemos de lado la posibilidad de que el usuario aborte, se trata de un simple ejercicio..
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... 65
Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines