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

#921
jajaja... que graciosos son estos chinos a veces, con sus 'ocurrencias'.

Si hubiera sido España el país de origen, en la primavera del 2019, pués es fijo, que los primeros infectados se hubieran detectado en España... y de España a países de los alrededores, pero no, ...las infecciones comenzaron en China en 2019 (según sus propios datos, vete a saber si ya estaba allí un año antes), de allí se pasó a los países vecinos, y luego poco a poco al resto del mundo, porque todos los gobiernos (como buenos G1L1P0Y@5 que son, se negaron a cerrar fronteras ...por miedo a  parecer racistas, lo que les convierte en culpables de la expansión y la gran mayoría   de las muerte, son achacables a su ineptitud e inoperancia).
Antes de las infecciones chinas, no había infectados en ninguna parte.

Yo, ya dije que tarde o temprano, se acabaría desmontando parte de sus mentiras, como las fechas y las cifras de muertes, que ya nadie se cree. Y la historieta del pangolín, el murciélafo y demás mandanga, también se acabará descubriendo que es mentira...

#922
Java / Re: Ayuda con mazo de cartas!!
3 Julio 2020, 00:29 AM
Cita de: Ruusa en  2 Julio 2020, 18:59 PM

Código (java) [Seleccionar]

public void mezclar() {
Random r = new Random();
for(int i = 0; i < cartas.length; i ++) {
int pos = r.nextInt(40);
Cartas aux = cartas[i];
cartas[i] = cartas[pos];
cartas[pos] = aux;
}
cartaActual = 0;
}

Esta función está mal.
No garantiza un reparto aleatorio.
El bucle debe empezar desde atrás hasta el comienzo... (por sencillez), pero sobre todo porque el rango aleatorio debe reducirse en cada iteración.


MAX_CARTAS = 40
...
Funcion Barajar
   Bucle para i desde MAX_CARTAS-1 hasta 1 retrocediendo
       pos = random(0 a i)
       aux = cartas(i)
       cartas(i) = cartas(pos)
       cartas(pos) = aux
   Siguiente

   cartaActual =MAX_CARTAS
Fin funcion


Así en la primera iteración se elige un valar entre 0 y 39, en la segunda entre 0 y 38, en la 3ª entre 0 y 37... pero la posición 39, ya fue depositado en la 1ª iteración, la 38º en la 2ª y el 37 en la 3ª, etc...
y cuando solo queda 1 elemento (en la posición 0), no es preciso barajarlo consigo mismo, se deja el valor que resta, por eso basta llegar hasta 1...

Si lo miras bien, de esta manera absolutamente todas las posiciones son cambiadas, salgan o no en el generador aleatorio...
del modo que tu lo haces, si la posición 20 (por ejemplo), sale elegido 3 veces, se puede afirmar que habrá 3 cartas que no cambiarán su posición de antes de barajar.

Una vez que las cartas están barajadas, se pueden tomar en orden correlativo  (no importa tanto si de arriba abajo o de abajo hacia arriba), pero igual que en la realidad e spreferible tomar la de más arriba e ir descendiendo hasta llegar a 0, favorece posteriores barajados...  luego necesitas cambiar tu función 'GetCarta'


carta = funcion GetSiguienteCarta
   si (cartaActual = 0)
        mensaje "no quedan cartas"
        // más abajo comento de cambiar este caso...
  Si no
       cartaActual  -=1
       devolver cartas(CartaActual)
  fin si
fin funcion

La función no es muy distinta a la que tienes, pero es preferible hacerlo de forma regresiva, pués empezamos, descontando cartaactual y luego devolvemos la carta en dicha posición... paramos cuando el valor llega a 0 y se reclama otra.

Según de que típo de juego se trate, pueden repartirse todas la comienzo, algo que solo será posible si el número de jugadores es congruente con el número de cartas. Opuedne repartirse una cantidad fija.
También dependeindo del juego pued ehaber descartes de cartas a medida que se juega... con ese descarte, se van amontonando juntas, y cuando el mazo está vacío se trasladan estas al mazo (sean la cantidad que sean (pero debe llevarse la cuenta)  y se barajan, ahora cartaActual  valdrá esa cantidad y por tanto en vez de decir 'no quedan cartas' , se invoca esa función que recoje el mazo de cartas descartadas, y se barajan como el mazo, al término devuelve la última. ...pero como digo, depende del tipo de juego y las reglas que tenga...
Sería más  o menos:

carta = funcion GetSiguienteCarta
   si (cartaActual = 0) // no quedan cartas"
        PasarDescarteAMazo
  fin si

  cartaActual  -=1
  devolver cartas(CartaActual)
fin funcion

// tomar mazo de descarte , pasarlo al mazo de cartas y barajarlo
funcion PasarDescarteAMazo
   entero k
   
   bucle para k desde 0 hasta DescarteActual -1      
       Cartas(k) = Descarte(k)     // Descarte es otra instancia de 'Cartas'.
   siguiente

   Barajar(DescarteActual )   // exige modificar la función barajar para que reciba el parámetro de cuantas tiene en tal momento.
fin funcion

// Una función para que un jugador pueda descartarse de alguna carta...
// se amontona en otro mazo de cartas, del que s elleva la cuenta.
funcion Descartar(carta)
   Descarte(DescarteActual ) = carta
   DescarteActual +=1
fin funcion

// una constande de la clase 'Cartas'
MAX_CARTAS = 40
...
funcion NuevaPartida
  Barajar(MAX_CARTAS)
  ...
fin funcion

Funcion Barajar(cantidad)  // ahora se recibe un parámetro que es la cantidad a barajar hasta 1.
   Bucle para i desde cantidad-1 hasta 1 retrocediendo
       pos = random(0 a i)
       aux = cartas(i)
       cartas(i) = cartas(pos)
       cartas(pos) = aux
   Siguiente

   cartaActual = cantidad
    descarteActual = 0    // el mazo de descarte ahora está vací...
Fin funcion


Luego en el bucle ese de asignar las cartas... el siguiente bucle:
Código (java) [Seleccionar]
for(int valor = 1; valor <= 12; valor ++)
sería más sencillo, claro y eficiente, separarlo en dos bucles:

bucle desde 1 hasta 7
...
bucle desde 10 hasta 12
...


Finalmente, al repartir en la función 'repartirJugadores', repartes cada vez 4 cartas a cada jugador... dependerá de cuantos jugadores sean, no podrá servir 4 cartas a cada jugador todas las veces que se llame. Mira si el juego permite descartarse... y si en el juego siempre hay cartas de descarte o si el juego puede completarse sin necsidad de tomar más cartas... las reglas del juego definirán ciertos aspectos.
#923
El chip será todo lo descomunal que quiera indicar el redactor del artículo, pero las tarjetas de memoria actuales son un MAMOTRETO, y su consumo asusta...

Por otro lado, un chip de ese tamaño, tendrá un disipador mucho más efectivo y que puede ser mas reducido en tamaño (aunque me temo que acabará teniendo un volumen incrementado a los actuales en el mismo factor que el chip).

Es fin, es preferible un chip grande a una tarjeta 20 veces más voluminosa.
#924
Crear un lenguaje de programación no es asequible a todo el mundo.  Se requiere tener un cierto nivel de conocimientos bastante elevado.

Primero te preguntaría por tu nivel de programación... si no es el adecuado, la recomendación obvia es 'déjalo'.

Lo primero de todo es crear la especificacion del lenguaje, definir al completo el lenguaje (algunas detalles pueden quedarse en el tintero hasta tener claro otras), ya que todos los pasos entre éste y la interpretación o compilación dependen de éste paso, deben cumplir todos los requisitos.

La especificación puedes crearla en BNF (en la práctica EBNF). Últimamente está de moda ANTLR.

BNF, se aprende poco más tiempo que lo que se tarda en leer este mensaje media docena de veces:
https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form

Crea la especificación de tu lenguaje, cuando la tengas (lleva tiempo, y depende mucho de lo que se pretenda hacer) vuelve y preséntala y hablamos de los siguientes pasos. Si no culminas este punto, no merece perder más tiempo en ello (ni tú ni yo).
#925
La página oficial de Kotlin (guárdala entre tus favoritos)
https://kotlinlang.org/

Android:
https://kotlinlang.org/docs/reference/android-overview.html

Foro:
https://discuss.kotlinlang.org/?_ga=2.35976739.223400761.1593293234-1004860491.1593293232

...y ya navegas por aquellos mares a tu antojo.
#926
Cita de: Machacador en 21 Junio 2020, 22:52 PM
A mi me han confundido bastante con árabe y yo no soy español ni nada de eso... mi apellido Figueroa proviene de California en USA, y eso lo se porque en la serie de "El Zorro" salía un cabo de este apellido, y como todos sabemos, aquello sucedía en California...
USA compró California a España, "Por un puñado de dólares." :silbar: :silbar: :silbar:
#927
Creo que hay dos cosas distintas entremezcladas...

- Una cosa es que te confundan con otra procedencia... lo cual no tiene ninguna importancia. Quién puede acertar a ojo sin confusión, si un tipo es chino, coreano, japonés, o noruego, finlandés, sueco... o gambiano, etíope, nigeriano... o... es razonable confundirse a menudo.
- Y otra cosa distinta es el desprecio con que te traten (producto o no, de dicha confusión).

Supongo que es esto último  y no la 'mera confusión', lo que molesta a cualquiera.
Por lo demás como dice #!drvy, generalizar en cosas como 'por qué los españoles se enojan...' es absurdo...
#928
Programación General / Re: Manejo de Strings
21 Junio 2020, 22:26 PM
No es tan complicado...

En primer lugar puesto que se quiere devolver en un array hay que precalcular el tamaño que él mismo tendrá.

Dado que cada carácter tiene 2 variaciones (mayúscula minúscula), que no hay permutaciones de lugar y el tamaño del string...
cantidad = 2^size(delString)
Siendo la cadena: 'string' size=6; 2^6=64. Luego el array tendrá 64 ítems.

La segunda parte, se resuelve en un bucle recursivo... usando grafos. Básicamente es un árbol binario. Nota que no es preciso usar ni construir ninguna estructura especial, más allá del array. Aunque tirando por un árbol binario, te sería más sencillo.

La palabra tendrá un nodo raíz (pongamos '*'), que accede a la primera letra, es decir 's' y 'S' son sus dos nodos hijo.
A su vez cada una de ellas tiene como nodos hijos a la siguiente letra en las dos versiones (mayúscula y minúscula).
Te pongo la jerarquía, de nodos, el de la izquierda es un nodo ya añadido al árbol, los de la derecha son los hijos que se le añaden como hijos:

*= s|S    <--- hijo izquierdo y derecho del nodo raíz.
s= t|T    <--- hijo izquierdo y derecho del nodo izquierdo de raíz
S= t|T    <--- hijo izquierdo y derecho del nodo derecho de raíz
t= r|R     // etc...
T= r|R
r= i|I
R= i|I
i= n|N
I= n|N
n= g|G
N= g|G
g=
G=


Nota que los dos últimos nodos no tienen hijos...

Ahora si se recorre todas las posibilidades del árbol obtendrás las 64 combinaciones distintas (desprecia el nodo raíz para formar la combinación a la hora de pasarlo al array de destino).
El problema de usar una estructura de árbol, es que empleará más espacio del strictamente necesario, ya que por ejemplo, al llegar al último nodo, n y N, cada uno de ellos tendrán por nodos finales 'g' y 'G', es decir se habrá añadido 32 nodos 'g' y 32 nodos 'G'.
Estrictamente basta un array de una estructura simple con cada uno de esos nodos:

Estructura Nodo
   char Nombre
   byte NumHijos
   arrayde Nodo Hijos()   // 2
   boleano Terminal
   entero Indice
Fin estructura

Array de nodo Nodos()


Luego se puede pasar como una cadena de texto, o un array de texto, el contenido de más arriba '*= s|S, s= t|T, S= t|T ..." , el caso es una función recibe y parsea dicho contenido al array Nodos() que se compone de la estructura nodo.
Rellenando dicho array quedaría así:

nodos(0).Nombre = "*"
nodos(0).NumHijos = 2
nodos(0).Hijos(0) =  nodos(1) // 's'
nodos(0).Hijos(1) =  nodos(2) // 'S'
nodos(0).Indice = 0
nodos(0).Terminal = FALSE

nodos(1).Nombre = "s"
nodos(1).NumHijos = 2
nodos(1).Hijos(0) =  nodos(3)  // 't'
nodos(1).Hijos(1) =  nodos(4)  // 'T'
nodos(1).Indice = 1
nodos(1).Terminal = FALSE

nodos(2).Nombre = "S"
nodos(2).NumHijos = 2
nodos(2).Hijos(0) =  nodos(3)  // 't'
nodos(2).Hijos(1) =  nodos(4)  // 'T'
nodos(2).Indice = 2
nodos(2).Terminal = FALSE
...
...
...

nodos(10).Nombre = "N"
nodos(10).NumHijos = 2
nodos(10).Hijos(0) =  nodos(11)  // 'g'
nodos(10).Hijos(1) =  nodos(12)  // 'G'
nodos(10).Indice = 10
nodos(10).Terminal = FALSE

nodos(11).Nombre = "g"
nodos(11).NumHijos = 0
nodos(11).Hijos // no dimensionado.
nodos(11).Indice = 11
nodos(11).Terminal = TRUE

nodos(12).Nombre = "G"
nodos(12).NumHijos = 0
nodos(12).Hijos // no dimensionado.
nodos(12).Indice = 12
nodos(12).Terminal = TRUE


Ahora con dciho array una función recorre recursivamente, tomando en cada ciclo el 'nombre' del nodo visitado, que se usa para ir concatenando la variación adecuada. La recursión finaliza cuando el nodo es terminal...
Como cada nodo tiene 2 hijos (podrían tener 1 o más), se precisa tambén un bucle interno para dicho recorrido de hijos.

La función de recorrido se invoca desde la que parsea la entrada,  sería más o menos así:


Funcion Recorrer(nodo n, entero i, entero xWord, string parcial, array string Salida() )
   entero j, k

   bucle para k desde 0 hasta n.NumHijos-1
       j = n.Hijos(k).Indice
       
       parcial.Add( nodos(j).Nombre, i)         //añade el char de 'nodos(j).Nombre' en la posición 'i' del string 'parcial'
       i +=1
       
       Si (nodos(j).Terminal = TRUE)
           Salida(xWord) = parcial
           xWord +=1
       Sino
           Recorrer(nodos(j), i, xWord, parcial, Salida)
       fin si

       i -=1
       // estrictament esto no es necesario, ya que 'i' permitirá sobrescribir sin borrar el previo.
       parcial.Remove( i)     // elimina de parcial el char en la posición 'i'
   Siguiente
Fin funcion

Esta función (así de simple), recorre todas las combinaciones posibles.

La función que parsea el texto de entrada, lo dejo a tu esfuezo, pués se trata de 'desguazar' dicha cadena en sus nodos, y cada nodos en sus elementos, para generar el array de nodos. Se requieren dos bucles, en el primero se crea el array con los 13 nodos (0 a 12, el 0 es el raíz), aplicando nombre, indice (el mismo del contador del bucle), número de hijos y si es o no terminal. Es terminal si no tiene hijos (caso de 'g' y 'G'). En el segundo bucle, se rellenan los datos que no se conocían , esto es, los hijos, requiere una búsqueda. Por ejemplo: Sabiendo que 't' tiene como hijos a 'r' y a 'R', precisa buscar que posicón ocupan esos nodos 'r' y 'R', para terminar de rellenar los datos (es decir busca rel índice de ?????:

nodos(3).Hijos(0) =  nodos(?????)  // 'r'
nodos(3).Hijos(1) =  nodos(?????)  // 'R'


La funcion principal, invoca a dos, una para generar los nodos y luego para realizar el recorrido.

Array de String() = funcion CombinatoriaMayusMinus(string Palabra)
   entero sizeArray = (2 ^ palabra.size)
   array de String Salida(0 a sizeArray -1)
   string s = Palabra
   entero indexChar =0, indexWord =0


   Llamada a ParseEntrada(Palabra)
   Llamada a Recorrer(nodos(0), indexChar, indexWord , s, Salida)
   Devolver  Salida
fin funcion



La función que construye el array de la estructura 'nodo'...
Nota que aquí tomamos la palabra entrada, sin generar las producciones comentadas al principio (dada la simplicidad de dichas producciones, es todo muy deducible).

Funcion ParseEntrada(string Palabra)
   entero k, j, i, n

   dimensionar nodos(0 a palabra.size * 2)    // esta declarado a nivel raiz (ver más arriba)
   
   nodo(0).Nombre = "*"    // <--- nodo raíz
   nodo(0).Indice = 0
   nodo(0).NumHijos = 2
   nodo(0).Terminal = False

   j = 0
   bucle para k desde 0 hasta palabra.Size -2  // la última letra es terminal y no tiene 'siguiente letra'
       j +=1
       nodo(j).Nombre = palabra.charAt(k).ToLower   //// <---- la minuscula
       nodo(j).Indice = j
       nodo(j).NumHijos = 2   ' porque es mayus y minus
       nodo(j).Terminal = False
       
       j +=1
       nodo(j).Nombre = palabra.charAt(k).ToUpper    // <---- la mayuscula
       nodo(j).Indice = j
       nodo(j).NumHijos = 2   ' porque es mayus y minus
       nodo(j).Terminal = False
   Siguiente

   j +=1
   nodo(j).Nombre = palabra.charAt(k).ToLower   //// <---- la minuscula
   nodo(j).Indice = j
   nodo(j).NumHijos = 0  
   nodo(j).Terminal = TRUE
       
   j +=1
   nodo(j).Nombre = palabra.charAt(k).ToUpper    // <---- la mayuscula
   nodo(j).Indice = j
   nodo(j).NumHijos = 0
   nodo(j).Terminal = TRUE

// -------------------- fin primera fase ----------------
 
   // Ahora falta asociar los hijos a cada nodo.
   //    Siendo siempre solo 2 hijos es muy simple y no hace falta esta busqueda, es deducible
   //    pero en casos con diferente número de hijos, tocará buscar...
   n = (j-2)
   bucle para k desde 0 hasta n
       bucle para i desde 0 hasta nodos(k).NumHijos -1
           j = BuscarNodo(... )  // <--- esta función y los parámetros que deba recibir, los dejo a tu esfuerzo
           // pero para la palabra 'string', para '*' buscamos nodo(?).nombre, donde nombre son  's' y 'S' (en cada ciclo)
           //    para 'R' buscamos 'i' e 'I', etc...
           nodos(k).Hijos(i) = nodos(j)
       Siguiente
   Siguiente

// -------------------- fin segunda fase ----------------
fin funcion


Una captura:
(nota que yo he dejado el 'nombre' de la raíz  '*', con cada uno)




La salida completa sería:
Citar
*= s|S; s= t|T; S= t|T; t= r|R; T= r|R; r= i|I; R= i|I; i= n|N; I= n|N; n= g|G; N= g|G; g=; G=
Nodo Inicial: *
Nodos Finales: g, G


1 ---> *string   0
1 ---> *strinG   0
1 ---> *striNg   0
1 ---> *striNG   0
1 ---> *strIng   0
1 ---> *strInG   0
1 ---> *strINg   0
1 ---> *strING   0
1 ---> *stRing   0
1 ---> *stRinG   0
1 ---> *stRiNg   0
1 ---> *stRiNG   0
1 ---> *stRIng   0
1 ---> *stRInG   0
1 ---> *stRINg   0
1 ---> *stRING   0
1 ---> *sTring   0
1 ---> *sTrinG   0
1 ---> *sTriNg   0
1 ---> *sTriNG   0
1 ---> *sTrIng   0
1 ---> *sTrInG   0
1 ---> *sTrINg   0
1 ---> *sTrING   0
1 ---> *sTRing   0
1 ---> *sTRinG   0
1 ---> *sTRiNg   0
1 ---> *sTRiNG   0
1 ---> *sTRIng   0
1 ---> *sTRInG   0
1 ---> *sTRINg   0
1 ---> *sTRING   0
1 ---> *String   0
1 ---> *StrinG   0
1 ---> *StriNg   0
1 ---> *StriNG   0
1 ---> *StrIng   0
1 ---> *StrInG   0
1 ---> *StrINg   0
1 ---> *StrING   0
1 ---> *StRing   0
1 ---> *StRinG   0
1 ---> *StRiNg   0
1 ---> *StRiNG   0
1 ---> *StRIng   0
1 ---> *StRInG   0
1 ---> *StRINg   0
1 ---> *StRING   0
1 ---> *STring   0
1 ---> *STrinG   0
1 ---> *STriNg   0
1 ---> *STriNG   0
1 ---> *STrIng   0
1 ---> *STrInG   0
1 ---> *STrINg   0
1 ---> *STrING   0
1 ---> *STRing   0
1 ---> *STRinG   0
1 ---> *STRiNg   0
1 ---> *STRiNG   0
1 ---> *STRIng   0
1 ---> *STRInG   0
1 ---> *STRINg   0
1 ---> *STRING   0

Número de nodos: 13
Total de caminos: 126
Total de Salidas: 64

La opción de resolverlo con un árbol, es también adecuada, como te describí más arriba... pero elige el modelo que mejor veas factible de entender e implementar...
#929
Cita de: corlo en 18 Junio 2020, 23:20 PM

Código (vb) [Seleccionar]

Private Sub Command3_Click()
    Open App.Path & "\Base1.txt" For Input As #1
    Do While Not EOF(1)
        Input #1, identificacion, azar, azar1, azar2, azar3, azar4
        If Text1 = identificacion Then
            Text2 = azar
            Text3 = azar1
            Text4 = azar2
            Text5 = azar3
            Text6 = azar4
        End If
    Loop
    Close #1
End Sub

Esto es muy ineficiente...
Estás leyendo secuencialmente un fichero para localizar un valor...
Cuando es posible, es más óptimo el acceso aleatorio a la posición deseada del fichero.

Si el valor está ordenado, y por tanto 'identificación' es el enésimo registro, puedes calcular la posición y saltar directamente a ella.
Viendo que 'identificador' aumenta 1 a 1, es deducible que el contenido en el fichero está ordenado...

Si no está ordenado, todavía puedes ir saltando... y leer en cada ciclo, solo 'identificación' hasta que lo encuentras, y acto seguido lees lo que se precisa.



Cita de: corlo en 18 Junio 2020, 23:20 PM

Código (vb) [Seleccionar]

Private Sub Form_Load()
    ' 1
    If identificacion = 0 Then
        Open App.Path & "\Base1.txt" For Append As #1
        Close #1
    End If

    ' 2
    If identificacion = 0 Then identificacion = 0

    Open App.Path & "\Base1.txt" For Input As #1
    Do While Not EOF(1)
        Input #1, identificacion, azar, azar1, azar2, azar3, azar4
    Loop

    ' 3
    Text1 = identificacion + 1
    Close #1
End Sub


1 - Abrir, para luego cerrar, qué sentido tiene????.
2 - Esa línea es redundante... sobra.
3 - Nuevamente es muy ineficiente... estás accediendo al último registro.... calcula: del tamaño del fichero, resta el tamaño de 1 regsto, posicionas el cursor ahí.. Basta leer solo el último registro.
En ficheros pequeños la ineficiencia no se aprecia, cuando operes con ficheros de muchos Mb... (pongamos 1Gb.... se hará intolerable la espera).



Y por favor, ya llevas tiempo en el foro, acostumbra a usar la etiquetas del 'código GESHI', ...las encuentras cuando editas el mensaje entre las opciones de edición de dicha ventana...
#930
En primer lugar el código, siempre que sea posible y haya en el listado de etiquetas Geshi, el lenguaje para el mismo, procede colocarlo dentro de tales etiquetas... para que resulte cómodo leer y mantenga al menos el formato de la indentación.
O manualmente... (quitando los espacios se convierte en las etiquetas BBcode)
[ code = vb ] tu código aquí [ / code ]

Line input, lee una linea entera es decir hasta que encuentre un salto d elínea, sea la cantidad de bytes que sea. Por lo que solo resulta indicado en ciertas situaciones:
- Se pretende leer texto, por tanto leer cada vez una línes es adecuado, porque a priori, nos e conoce el tamaño de cada línea.
- Los datos están fuertemente formateados. En tal caso, el usuario se supone conocer correctamente la estructura y la forma de 'desguazar' (parse), dicha línea en las variables que proceda.
- Cualquier otra situación, pero solo cuando hay un único dato en cada línea (que no requiere un parsingm ás allá de la asignación).

Luego, Line input, lee 'string', cadenas de texto... de ahí el error que te arroja, puesto que tu (seguramente) intentas volcarlo en un tipo integer.


Antes de eso, con input es más procedente cuando se conoce muy bien el formato que compone el fichero y éste tiene (o puede tener) distintos tipos...
Así algo como:
Código (vb) [Seleccionar]

Dim numVertices as byte
Dim Vertices() as single
dim canal as integer
dim Ruta as string

   ' Abrir el fichero...
   ruta = "tu ruta al fichero deseado..."
   canal = Freefile
   open ruta for input as #canal

   ' leer datos
   input #canal,,numVertices
   if (numVertices >0)
       redim vertices(0 to numVertices-1)
        input #canal,, vertices
   else
       '... algún mensaje de error si procede...
   end if

  close #canal

   
Que viene a decir... primero se lee la cantidad de vertices que es un byte (es decir un valor entre 1 y 255) y la siguiente lectura leerá, tantos valores de tipo single como indique...
Esto es porque hay un formato reconocido para el fichero que se conoce, y por tanto se aplicó al escribir y eél mismo es adecuado para leer.

No puedes escribir 10 bytes y luego pretender leer 12.
Las variables Azar, Azar1... y 'contador' están declarados como 'integer', luego por cada uno se leen 2 bytes.
EOF, detectará correctamente el final del fichero, siempre que una lectura cumpla una de estas dos condiciones:
A - se lee 1 único byte cada vez en el bucle.
B - Se leen los bytes que sean, pero congruentes al tamaño. Esto es, si se guardaron 60 bytes, puedo leer en cada ciclo, 2, o en cada ciclo 3, o en cada ciclo, 4 o en cada ciclo, 5, 10, 12, 15, 20, 30, 60... porque todos ellos son submúltiplos de 60
Si el fichero tiene 60 bytes y en cada ciclo se leen 7 bytes, al llegar al 8º ciclo, he leído 56 bytes (7*8), luego en el siguiente ciclo, al intentar leer 7 bytes, puésto que solo restan 60-56 = 4, saltará el error...

En el caso 'A', solo interesa cuando se sepa que es precisamente así como se quiere leer byte a byte, porque el tipo de datos de destino son bytes, o bien cuando es uno mismo quien procederá a componer el tipo que proceda. Ahora leer byte a byte es lento.
En el caso 'B', interesa cuando uno tiene que leer datos de forma más o menos compleja, aunque si hay un 'patrón' sería mejor crear una estrcutura (type), y leer con una sola variable todo el contenido d ela estructura, es decir 'record a record'...

Cierto problema con 'input' es que es 'exigente, es decir requiere que la lista de variables leída estén en el mismo orden y sean del mismo tipo que se escribieron, es decir si fueras a leer un entero donde se escribió una cadena, el entero devolvería 0.

Es más conveniente, para evitar ciertas complejidades para quienes no se leen nada de documentación leer y escribir en 'binary' mode... ya que lee y escribe bytes al tipo que lee, no guarda ninguna info del tipo que se guarda, luego es perfectamente sencillo guardar un tipo long (4 bytes) y luego leerlo como bytes, como integer como byte e integer, como long, incluso como cadena.

Código (vb) [Seleccionar]

'....
   dim k as long, j as integer, i as byte, b as boolean, s as string, ib() as byte  

   ' Escribimos un valor de tipo long = 4 bytes.
   Open ruta for binary as #canal
   k = 1145323841
   put #canal,,k
   debug.print "Escrito el tipo long con valor: " & cstr(k)
   close #canal

   ' Leemos un tipo long = 4 bytes.
   k= 0
   canal = freefile
   open ruta for binary as #canal
   get #canal,, k
   debug.print "Leido el tipo long con valor: " & cstr(k)
   close #canal
   debug.print

   ' Leemos un tipo integer 2 veces (2+2)=4 bytes.
   canal = freefile
   open ruta for binary as #canal
   get #canal,, j
   debug.print "Leido el tipo integer con valor: " & cstr(j)
   get #canal,, j
   debug.print "Leido otrol tipo integer con valor: " & cstr(j)
   close #canal
   debug.print

   ' Leemos un tipo integer y byte 2 veces (2+1+1)=4 bytes.
   canal = freefile
   open ruta for binary as #canal
   get #canal,, j
   debug.print "Leido el tipo integer con valor: " & cstr(j)
   get #canal,, i
   debug.print "Leido el tipo byte con valor: " & cstr(i)
   get #canal,, i
   debug.print "Leido otro tipo byte con valor: " & cstr(i)
   close #canal
   debug.print

   ' Leemos un tipo integer y byte 2 veces (2+1+1)=4 bytes.
   canal = freefile
   open ruta for binary as #canal
   get #canal,, j
   debug.print "Leido el tipo integer con valor: " & cstr(j)
   get #canal,, i
   debug.print "Leido el tipo byte con valor: " & cstr(i)
   get #canal,, i
   debug.print "Leido otro tipo byte con valor: " & cstr(i)
   close #canal  
   debug.print

   ' Leemos un tipo integer y boolean (2+2)=4 bytes.
   canal = freefile
   open ruta for binary as #canal
   get #canal,, j
   debug.print "Leido el tipo integer con valor: " & cstr(j)
   get #canal,, b
   debug.print "Leido el tipo boolean con valor: " & cstr(b)
   close #canal
   debug.print

   ' Leemos los mismos, al revés tipo boolean e integer (2+2)=4 bytes.
   canal = freefile
   open ruta for binary as #canal
   get #canal,, b
   debug.print "Leido el tipo boolean con valor: " & cstr(b)
   get #canal,, j
   debug.print "Leido el tipo integer con valor: " & cstr(j)
   close #canal
   debug.print

   ' Leemos un tipo byte a byte, 4 veces (1+1+1+1)=4 bytes.
   canal = freefile
   open ruta for binary as #canal
   get #canal,, i
   debug.print "Leido el tipo byte con valor: " & cstr(i)
   get #canal,, i
   debug.print "Leido otro byte con valor: " & cstr(i)
   get #canal,, i
   debug.print "Leido otro byte con valor: " & cstr(i)
   get #canal,, i
   debug.print "Leido otro byte con valor: " & cstr(i)
   close #canal
   debug.print

   ' Leemos un tipo byte y 3 más en un array (1+1+1+1)=4 bytes.
   canal = freefile
   open ruta for binary as #canal
   get #canal,, i
   debug.print "Leido el tipo byte con valor: " & cstr(i)
   redim ib(0 to 2) ' dimensionar el array a un tamaño igual o menor a lo que reste en el fichero.
   get #canal,, ib
   debug.print "Leido un array de 3 bytes con valores: ",  cstr(ib(0)),  cstr(ib(1)),  cstr(ib(2))
   close #canal
   debug.print

   ' Leemos un tipo string de 3 caracteres (1+1+1+1)=4 bytes.
   canal = freefile
   open ruta for binary as #canal
   s= space$(4)  ' dimensionar el string... si no es un string nulo ""
   get #canal,, i
   debug.print "Leido el tipo byte con valor: " & cstr(i)
   redim ib(0 to 2)
   get #canal,, ib
   debug.print "Leido un array de 3 bytes con valores: ",  cstr(ib(0)),  cstr(ib(1)),  cstr(ib(2))
   close #canal
   debug.print

Nota que cada vez hemos abierto y cerrado el fichero... no es estrictamente necesario, bastaría con reposicionar el curso de lectura al comienzo:

el acceso aleatorio a un fichero en modo binario, es reposicionando el cursor donde convenga
Código (vb) [Seleccionar]

   Seek(canal), 1  ' reposiciona el curso al comienzo del fichero.

   Seek(canal),( lof(canal) -20) ' reposiciona el curso al final del fichero, -20 bytes, dará error si esa posición sale negativa (el fichero tiene menos de 20 bytes)



También se puede preguntar por la posición actual... por ejemplo para guardarla, leer datos y volver a ese mismo punto por segunda vez.
Código (vb) [Seleccionar]

   k = Seek(canal)


Es posible tener más de un cursor apuntando al mismo fichero... uno podría estar leyendo de una cabecera de datos, mientras el otro canal apunta a los datos que el registor leído en la cebecera indicare (probablemente previo cálculo)
Código (vb) [Seleccionar]

   canal1 = freefile
   open ruta for binary as #canal1
   canal2 = freefile
   open ruta for binary as #canal2


Nota también que es preferible usar la sentencia 'freefile' para obtener un canal libre, que usar una constante directamente... cuando peres con proyectos de cierta complejidad, no puedes tener control de 'números', Freefile devuelve siempre un canal no usado que se asigna a una variable, que identifica únivocamente al fichero concreto... si además la variable tiene un nombre más específico, mejor: canalPrecios (por ejemplo, para un fichero cuyo contenido son precios), canalClientes (por ejemplo para un fichero cuyo contenido son registros con los datos de clientes)

Nota que en modo binario, se lee un solo dato (variable) cada vez... input, permite leer una lista, es parte de lo que determina si usar un modo u otro, pero es muy dependiente del modo en que se escribió.

... en cualquier caso, acude a la documentación de VB6, que es muy completa, lleva el cursor al keyword del lenguaje de tu interés y pulsa 'F1', la ayuda aparece siempre pulsando la tecla de función: 'F1', pero si está encima de un keyword, busca el mismo... y la propia documentación suele contener ejemplos.

Hay que practicar, pero lo correcto es aprender documentándose. Practicar sin documentación, supone emplear 20 veces más de tiempo para aprender, algo que leyendo unos párrafos, se aprende en 15 minutos y se practca en 1 hora... con solo práctica puedes dedicarle días, y todavía surgirán errores y dudas que uno no termina de comprender y es seguro, que quedarán lagunas...(detalles que jamás se llega a conocer).