Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Serapis

#2491
Es una 'noticia' de RT, qué se puede esperar...?

Me hace gracia eso de "un búnker con un servidor desconectado"...
#2492
Solo añadir que el bucle no precisa llegar a 0, cuando solo queda un elemento por ordenar resulta absurdo pedir que elija otro (si solo queda 1), al azar para que ocupe su puesto...

Recuerda que cada lenguaje tiene una forma de activar el generador aleatorio, mediante una semilla, si no, suelen repetirse las secuencias, lo  cual es más notorio, cuando se piden exactamente de cada vez las mismas cantidades de números aleatorios.
Generalmente elegir una semilla adecuada es algo complicado, pero salvo que haya un botón de 'destruir el mundo', basta con usar el timer (los segundos que han pasado desde la medianoche), incluso usar ese valor para elegir un primo de una lista. y con es eprimo 'moduar' ese valor del timer para usarlo como semilla... 
#2493
La baraja de cartas, debe mantenerla 'la banca'. El jugador a lo sumo debe mantener las suyas propias... aunque si (el juego) no es muy complejo, no resulta difícil hacer que la banca mantenga o sepa a quien pertenece cada carta que ha salido (esto libera en parte a cada jugador de dicha tarea (es más sencillo aquí), pero solo si resulta conveniendte según la dinámica del juego):


estructura Cartas
    byte Numero  // por ejemplo de 1 a 40... esto se asigna una sola vez cuando se crea el juego.
    byte Jugador   // valor 0, carta aún en poder de la banca, otro valor pertenece al jugador cuyo indice se indica
fin estructura

byte NumCartas
constante MaxCartas = 40
Array de Cartas Baraja (0 a maxcartas -1)



Cuando una carta es retirada por un jugador, no es preciso moverla a otro array, se intercambia por la última 'accesible' en el array... veámoslo (parcialmente) en un método de la banca...
Nota que dependeindo del tipo de juego, el jugador toma la 'siguiente carta' que le reparten o a veces puede elegir él mismo, se asume el primer caso... están barajadas y sedescnoce cuales son.



evento PartidaTerminada

// Esta función solo podría ser llamada si como resultado del código de arriba al jugador se le permite jugar su turno...
// entrega la siguiente carta al jugador
byte Funcion Apuesta(byte Jugador)
    byte tmp
    cartas crt  //tipo cartas, la estructura...

    Si (NumCartas > 0)  //' si quedan cartas que repartir
        // Haciendo esta resta ahora en vez de al final, nos evita el -1, en las 3 ocasiones que aquí se usa...
        numCartas -= 1   // restamos una carta disponible... al principio eran 40, cuando llegue a 0, la partida acaba.
       tmp = Random(entre 0 y numCartas)                 
       // intercambiar la carta índice tmp por la carta índice numcartas
       crt =  Baraja(tmp)       
       Baraja(tmp) = Baraja(numCartas)
       Baraja(numCartas) = crt        
       

       crt.Jugador = jugador   //esta carta se marca pertenececiente (apostada, elegida, designada) a éste jugador
       devolver crt.Numero   //devolve rla carta... el número puede ser referencia del valor
        // Así el 1 al 10 pueden ser oros, del 11 al 20, copas, del 21 al 30 espadas y del 31 al 40 bastos... o cualquier otra disposición... según tu preferencia, o que uses cartas de pokér y requieras 52 cartas, etc...
    sino
         Disparar evento PartidaTerminada  //ofrece la posibilidad de escrutar qien ganó la partida, mostrar resultados etc...

         // No estaría demás aquí solicitar si se desea jugar otra partida, en vez de asumir que es así...
         //Si jugadoresquierenOtraPartida
         NumCartas = MaxCartas
         BarajarCartas   // pone a 0 el apartado .jugador de cada carta y luego desordena las cartas...
         BorrarDatosPartida  // los que pueda tener la banca y los jugadores, pero no un computo global del juego, si lo hay...
         //sino
             //juego terminado, mostrar el ganador absoluto de todas las partidas (mejor mostrar la lista de ordenada de jugadores con nº de partidas ganadas, puntuación etc...
         //fin si
    fin si
fin funcion

#2494
Criptografía / Re: RC4
12 Mayo 2018, 04:04 AM
Si manejas bytes y sumas los valores de 2 bytes, como resultado obtienes o un valor de un byte o un valor superior al límite de un byte, luego si haces un modulo 256 (o and 255), sigues teniendo un valor en el rango de byte.

El array de semila posee 256 bits, luego a un nivel distinto, necesita hacer lo mismo... cada vez que se alcanza el bit 256º operando sobre la semilla, debe regresar al bit 1º...
#2495
Ya veremos... De momento yo apuesto a que no.
#2496
Sí... definitivamente yo prefiero el P.I.L.I. del anuncio de tv...


[youtube=640,360]https://www.youtube.com/watch?v=LkbQLSwrLm8[/youtube]
#2497
Pués, yo tampoco lo veo tan extraño...

Lo razonable cuando a un chico le gusta algo de forma muy relevante es que le dedique su tiempo en cuerpo y alma, lo mismo que el resto se lo dedica a jugar al fútbol o luego más tarde a perseguir chicas o a tomar cervezas...

Además, lo suyo ha sido una idea... hoy día tener una idea es mucho más fácil de verla implementada que hace 3 décadas atrás. Hay muchas herramientas, no ya solo ordenadores, incluso impresoras 3D...

En los 80, tenías que conformarte con revistas y poco más, los libros, en español, en general no eran muy técnicos, uno tras otro solo daban vueltas y vueltas a cuestiones de principantes, sin prácticamente ninguna profundidad, así que o recurrías a libros en inglés o no avanzabas...

Lo que le hace falta al chaval es que al subir de edad, no lo 'malogren' en los estudios... a menudo, se encuentra uno profesores (durante su crecimiento), que lejos de inspirarte son todo lo contrario... Además, ser prematuro en algo, tampoco es ningún indicador de éxito, ni de genialidad, solo de interés (que ya es bastante).
#2498
Cita de: engel lex en 12 Mayo 2018, 00:32 AM
sobre lo de linux cambiar de idea, me parece que está de más poner 2 caracteres para salto de linea D: especialmente porque si fuera como dices, el LF solo en windows, dejara el cursor en la misma posición horizontal de la linea anterior... y eso no sucede D:

sin embargo CRLF está muy ampliamente implementado, por lo menos en HTTP como protocolo, si no se usa el 0D 0A (CRLF) muchos aplicativos no son capaces de intepretar el paquete
Claro Engel, un S.O. o lenguaje, debe ser consecuente con sus decisiones... si LF basta, es porque así se ha implementado, lo mismo que si hubieran querido usar GS (separador de grupo), o tabvertical o espacio duro (byte 160)... un diseño pese a lo idiota del diseño, tendrá que ser consecuente al menos consigo mismo...

Yo refiero, que que hay ocasiones donde uno debe improvisar soluciones (y ahí uno debe tomar decisiones que a futuro pueden verse acertadas o no) y otras donde solamente BASTA mirar la solución existente y constatar si es eficaz o no, especialmente cuando algo ya existe desde varias décadas atrás... como es el caso de la máquina de escribir... el diseño del teclado y del comportamiento, obedece precisamente a eso, al diseño de la máquina de escribir que se ha ido mejorando desde su invención... puede despreciarse, pero solo por soberbia, no por razonamiento lógico que lo justifique... Añadir teclas, o cambiar la distribución es algo que se ha hecho y puede justificarse, cambiar el comportamiento, es otra cosa.
#2499
Sin más explicaciones... asumo que no mantienes referencias de turnos.

Lo primero es que debes mantener la ronda, tanda.
Una ronda es una fase donde cada jugador hace 'su apuesta', jugada, etc... cuando todos la han hecho, se pasa a la siguiente ronda, etc...

En una ronda, según el juego, cada jugador puede o bien jugar siempre en un orden concreto o no. Sea como sea, a cada jugador se le otorga su 'turno', indistintamente de que jueguen en un orden específico o no.

Una ronda entonces se compone de un simple array del tamaño del número de jugadores. Si juegan 6, ronda tiene 6 elementos, si juegan 8 jugadores ronda tiene 8 elementos.
Cada elemento de la ronda mantiene una referencia a cada jugador... dicha referencia puede ser a un objeto jugador, o como mínimo a un índice que relaciona  únivocamente a un jugador con (por ejemplo), un array de jugadores...

Entonces cuando quieras conocer el estado de cada uno, basta consultar el objeto ronda, recorrerlo, para tener acceso a cada jugador.

Ronda puede se rmás o menos sencillo o complejo, según lo que necesites y quiera shacer desde ese objeto... lo mínimo sería.


Ronda()  array de bytes //string, objetos jugador, etc..
Turno, Numjugadores byte

evento NuevaRonda
evento SuTurno(byte jugador)  // string, objeto jugador, etc...

byte = Propiedad lectura TurnoJugador
    devolver Turno
fin propiedad

byte = Propiedad lectura CantidadJugadores
    devolver NumJugadores
fin propiedad

buleano = Funcion FinRonda
    devolver (turno = (NumJugadores-1))
fin funcion


// Creando una nueva instancia del objeto.
funcion Nuevo(byte jugadores)
   NumJugadores = jugadores
   Redimencionar array Ronda(0 a NumJugadores -1)
   Turno = 0
fin funcion

// Se reclama que se permita jugar al siguiente jugador
funcion SiguienteTurno
    Si (turno < (NumJugadores-1))
        Turno + =1
    Sino
        Turno = 0
        disparar evento NuevaRonda
    Fin si
    disparar evento SuTurno(Turno)
Fin funcion


Como ves en el ejemplo, no hacemos uso del array... si solo se guía el objeto por un valor que señala un índice, y ese es siempre incremental, esto es sucede siempre en orden, no se precisa.
En tal caso este objeto lo instancia la 'base del juego' (podría ser o llamarse objeto 'banca'). Así  cuando se dispara el evento turno, la base del juego recibe el evento y como mantiene referencia a cada jugador sabrá derivar el turno al jugador que corresponda. 

Esto es sencillo, si se la forma de interacción fuera más complejo, porque os jugadores no precisan jugar por turnos, es cuando se precisa hacer uso del array... También en este caso quizás sea preferible que no sea el objeto banca quien utilice este objeto directamente, simplemente lo crea y luego pasa una referencia del mismo a cada jugador que se 'inscribe' en el juego, y es luego el jugador quien directamente haga su juego y lo anuncia a este objeto...
No haré algo exhausitvo ni muy grande, solo lo suficiente para reflejar esta última idea...


Ronda()  array de bytes //string, objetos jugador, etc..
Turno, Numjugadores byte

evento NuevaRonda
//evento SuTurno(byte jugador)  // string, objeto jugador, etc...

byte = Propiedad lectura TurnosJugados // en la Ronda actual
    devolver Turno
fin propiedad

byte = Propiedad lectura CantidadJugadores
    devolver NumJugadores
fin propiedad

buleano = Funcion FinRonda
    devolver (Turno = (NumJugadores-1))
fin funcion


// Creando una nueva instancia del objeto.
funcion Nuevo(byte jugadores)
   NumJugadores = jugadores
   Redimencionar array Ronda(0 a NumJugadores -1)
   Turno = 0
fin funcion

// Un jugador reclama su turno de jugada...
// solo será posible si no ha jugado ya su turno en esta ronda...
buleano = funcion TurnoJugador(byte Jugador)
    Si  (Turno = (NumJugadores-1))  // se acabó la ronda actual?, si sí, siguiente ronda
        Turno = 0
        bucle para k desde a NumJugadores -1
            Ronda(k) = 0
        siguiente
        disparar evento NuevaRonda
    Fin si

    Si (Ronda(jugador)= 0)  // si no ha jugado en esta ronda, se le permite
        Ronda(Jugador) = 1  // ma
        Turno + =1
        //     disparar evento SuTurno(Turno)
        Devolver True  // el evento queda remplazado por la devolución de la llamada.
    Sino   // este jugador ya jugó en esta ronda.
        devolver FALSE
    Fin si
Fin funcion


Como ves, el código es casi el mismo, estos son las diferencias:
- Se ha cambiado el nombre de la propiedad: TurnoJugador por TurnosJugados
- el evento SuTurno, no se requiere.
- La funcion TurnoJugador:
-----  Ahora devuelve un bulenao en vez de dispara el evento 'suTurno'
-----  Recibe como parámetro el índice del jugador que pretende jugar.
-----  El array Rondas, mantiene quien ha jugado en esta ronda y quien no, sea cual sea el orden en que jueguen.

Finalmente puedes usar un sencillo negociado con este objeto, en vez de usarlo solamente para obtener turno y recordar que  jugadores jugaron ya en la ronda, también puedes añadir un método que recuerde 'la apuesta' del jugador... así la consulta como debe hacerse sí sí aquí, ya se tiene la respuesta sin una consulta posterior al jugador...

En el siguiente pseudocodigo, solo pongo las ideas, los cambios que fueren precisos al resto queda a tu esfuerzo...
verás (por ejemplo) que ahora el array en vez de ser de tipo byte es del tipo de una estructura de 'datos'...

    enumeracion EstadoDeTurno
        TURNO_NO_JUGADO = 0
        TURNO_JUGANDO = 1 
        TURNO_YA_JUGADO =2
    Fin enumeracion

    estructura Datos
        EstadoDeTurno Estado   // del tipo de la enumeración justo recién declarada.
        byte Carta
    fin estructura

    Ronda()  array de Datos  // de la estructura recién declarada.


// ofrecer el turno de juego a un jugador...
buleano = funcion TurnoJugador(byte Jugador)
   

    Si (Ronda(jugador).Estado = TURNO_NO_JUGADO)  // si no ha jugado en esta ronda, se le permite
        Ronda(Jugador).Estado = TURNO_JUGANDO 
        //Turno + =1
        //     disparar evento SuTurno(Turno)
        Devolver True  // el evento queda remplazado por la devolución de la llamada.
    Sino   // este jugador ya jugó en esta ronda.
        devolver FALSE
    Fin si
Fin funcion

// jugador comunica su apuesta en esta ronda...
funcion ApuestaJugador(byte Jugador, byte Carta)
    Si (Ronda(jugador).Estado = TURNO_JUGANDO)
        Ronda(Jugador).Estado = TURNO_YA_JUGADO
        Ronda(Jugador).Carta = Carta
        Turno + =1

        Si  (Turno = (NumJugadores-1))  // se acabó la ronda actual?, si sí, siguiente ronda
            disparar evento RondaTerminada // Último momento para consultar, luego se borrarán los datos...
            Turno = 0
            bucle para k desde a NumJugadores -1
                Ronda(k).Estado = TURNO_NO_JUGADO
                Ronda(k).Carta = 0  //equivale a ninguna
            siguiente
        fin si
    Fin si
Fin funcion

// Devuelve la apuesta dle jugador, (0 si todavía no apostó/jugó su turno...
// la consulta se puede hacer en cualquier momento, pero mejor cuando se lanza el evento RondaTerminada
byte = funcion ConsultarApuesta(byte Jugador)
    devolver Ronda(Jugador).Carta
fin funcion


Ahora el evento cambio de nombre, porque sucede justo al término de la ronda... pero antes de borrar los datos de la ronda, para dar ocasión a consultar la jugada de cada jugador...
Si carta = 0 es para señalar que no ha jugado, los valores de cartas deberán comenzar de 1 en adelante, si es forzado que deba empezar en 0, usar el valor 255 para indicar que el jugador no ha apostado aún...
Nota que ahora ase ha añadido además un método de consulta, y que el array Ronda ahora tiene pleno sentido... frente  al primer pseudocódigo, quersultaba inútil, o en el segundo, que permitía ya liberar el orden de juego de los turnos, ahora... es más útil mantiendo info de la ronda actual... si eres inquieto, sabrás darle más utilidad.
Un objeto ronda, pués puede ser muy útil para mantener los datos de la ronda actual...

...y bueno, para tú no haber puesto ni una línea de código, creo que yo ya he puesto suficiente pseudocódigo para aclarar alguna de tus dudas...
#2500
Programación Visual Basic / Re: Código QR
11 Mayo 2018, 01:11 AM
Perdona... no me di cuenta de tu mensaje hasta hoy que respondía a otro usuario...

El caso, es que falla por varias cuestiones, la primera es que en Delphi, no tienen NPI de lo que es un variant, en segundo lugar, porque la firma de la API es incorrecta...

Te pongo todo el código al caso (incluído el previo)... no te he puesto el tratamiento del png recibido, toda vez que tu señalas que quieres operarlo después con GDI+

El proyecto, asumiendo el código previo anterior aún válido, exige un control image y dos controles de botón. El botón 1 para obtener un fichero bmp que luego cargamos en el control image. El botón 2 para obtener el stream del png (los bytes en memoria, tal cual si hubiéramos pedido un fichero png, y luego leído de disco (obtener el stream es más rápido desde luego, lectura y escritura a y desde disco siempre es más lento que copiar a y desde memoria)).
Código (vb) [Seleccionar]

' Declaraciones

' Nivel de corrección para reconocer posibles fallos. A más calidad, más capacidad de recuperación, pero exige más carga de trabajo, etc...
Private Enum ErrorCorrectionLevel
    LowQuality = 0
    MediumQuality = 1
    StandardQuality = 2
    HighQuality = 3
End Enum

' para copiar datos de memoria de un sitio a otro..
Private Declare Sub CMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

' API, para obtener el codigo-QR en un fichero bmp.
Private Declare Sub GuardarImagen Lib "quricol32.dll" Alias "GenerateBMPW" (ByVal file As String, ByVal text As String, ByVal Margen As Long, ByVal PixelSize As Long, ByVal nivel As ErrorCorrectionLevel)
' API, para obtener el stream en formato png.
Private Declare Sub GetPngStream Lib "quricol32.dll" Alias "GetPNGW" (ByVal text As String, ByVal Margen As Integer, ByVal PixelSize As Integer, ByVal nivel As ErrorCorrectionLevel, ByRef bufSize As Long, ByRef ptrBits As Long)


Código (vb) [Seleccionar]

' Código del botón, para obtener una imagen en formato BMP (luego la cargamos).
Private Sub Command1_Click()
    Dim ruta As String, ruta2w As String, msg As String
    Dim res As Long
   
    msg = StrConv("Hola que tal estas", vbUnicode)
    ruta = App.Path & "\Qr.bmp"
    ruta2w = StrConv(ruta, vbUnicode)
    Call GuardarImagen(ruta2w, msg, 2, 3, HighQuality)

    If (Dir(ruta) <> "") Then
        Set Image1.Picture = LoadPicture(ruta)
    End If
End Sub

' carga del formulario...
Private Sub Form_Load()
    Me.BackColor = vbBlack ' contraste para que destaque...
    Image1.Stretch = True
End Sub


Código (vb) [Seleccionar]

Private Sub Command2_Click()
    Dim msg As String
    Dim res As Long, k As Long, ptr As Long
    Dim stm() As Byte
   
    msg = StrConv("Hola que tal estas", vbUnicode)
   
    Call GetPngStream(msg, 2, 3, HighQuality, k, ptr)
   
    If (k < 1) Then
        MsgBox "No parece haberse recibido ninguna imagen..."
    Else
        ReDim stm(0 To k - 1)
        Call CMem(ByVal VarPtr(stm(0)), ByVal ptr, k)
       
        ' tu código restante iría aquí:
        ' yo sólo imprimo el valor de los bytes... para verificar que es correcto.
        For j = 0 To k - 1
            Debug.Print stm(j)
        Next
       
        ' ...
    End If
End Sub


Y en efecto, el volcado me arroja:
137
80
78
71
13
10
26
10
0
0
0
13
73
72
68
82
...
que son los bytes correspondientes a la cabecera de un png: "%PNG        IHDR"...

..y por último sólo recordarte que al final estamos usando la librería de Delphi Quricol32.dll, no el wrapper de C# Quricol.Barcode.dll.