Serie ficheros virtuales



VBA. Ficheros virtuales




VBA Ficheros virtuales. El Juego de la Vida de J.H.Conway


1 Introducción
2 Las reglas del Juego de la Vida de Jhon H.Conway
3 La estructura de soporte
4 La implementación núcleo de la evolución poblacional
5 Implementación de la hoja de muestra

                                                                                                          _______


1 Introducción

En el blog hermano C Ficheros virtuales se presentó un programa para generar evoluciones poblacionales de autómatas celulares según las reglas del "Juego de la Vida" establecidas por el matemático Jhon Horton Conway.

Este programa se encapsuló como una DLL a la que se le dotó de interfaces COM y Net. Ahora se desarrolla el mismo programa en VBA.


Aquí, los servicios centrales de las evoluciones de la población se implementan como complemento excell y la presentación visual se deja a una hoja como la siguiente



El fuente base de la hoja y del complemento se puede encontrar en el libro JuVida, los ficheros relacionados son

- El libro Excell "JuVida.xls" propiamente dicho que contiene la hoja JVida de presentación

- El complemento Excell "JVida.xla" que contiene la algorítmica para generar las evoluciones poblacionales del juego

- El complemento Excell "W.xla" soporte de los ficheros virtuales, común para todos los desarrollos presentados en el blog

 

 

 

Los fuentes completos del desarrollo se presentan en el enlace VBA. Fuentes, mientras que en Instalación de Componentes, se muestran los pasos a seguir en la instalación de complementos Excell.



                                                                                                          _______


2 Las reglas del Juego de la Vida de Jhon H.Conway


Estas reglas modelan la vida de una sociedad de autómatas celulares del plano.

 

 

Se parte del principio de que cada celda del plano puede contener un organismo y que cada celda tiene ocho vecinas que la rodean.

 

 

En cada generación los nacimientos y muertes siguen unas sencillas reglas:

 

·      Un organismo nace en cualquier celda vacía que tenga exactamente 3 vecinos

·      Un organismo muere por aislamiento si tiene menos de 2 vecinos

·      Un organismo muere por superpoblación si tiene más de 3 vecinos

·      El resto de celdas no se modifica

 

 

 

Veamos un ejemplo concreto de evolución de algunas figuras sencillas

 

 

           @          @       @

@@@       @ @        @ @      @

@ @       @ @

 

 

 

@         @@         @@       @@       @@      @@    @@      @@     @@     @@

@@        @@         @@       @@       @@      @@    @@      @@     @@     @@

 

 

 

                     @       @@@       @       @

  @       @@@      @@ @@     @@@      @ @      @

@@ @@    @@ @@              @@ @@

 @ @     @@ @@     @   @     @@@     @   @     @             @      @      

  @        @        @@@      @@@               @     @@@     @      @      @@@

                              @       @@@      @             @      @      

 

 


                                                                                                          _______


3 La estructura de soporte


 Para dar soporte a las evoluciones, se crea una base de datos compuesta por un fichero físico y uno lógico, según el siguiente esquema:

                                                 20          20
                                               10 + 10  |  10 + 10  | 10
                                                i    j  |   j    i  |  a

                                               K    Celdas        : i,j
                                               K01  Celda inversa : j,i
                                               D    Marca_Activo  : a = {0/1 Visualmente activo}


y que se crea con las instrucciones

                                               lNID = W_NEW("PVIDAC", 20, 50)
                                               lNID01 = W_CRTLF("PVIDAC01", "PVIDAC", 1 + 20, 20)


                                                                                                        _______


4 La implementación núcleo de la evolución poblacional

El núcleo de la implementación consiste en transcribir las reglas del Juego de la Vida utilizando un fichero de respaldo, con el mismo diseño que el principal, en donde se guarda la situación anterior y se aplica para generar la generación siguiente.


Precisamente ese es el objeto de la rutina principal J_Gen del complemento excell JVida que sigue a continuación

'//-----------------------------------------------------------------------------
'// Algoritmo de nueva generación poblacional
'//-----------------------------------------------------------------------------
Function J_Gen() As Long

 Dim Er As Integer    ' Control de errores intermedios
 Dim Nvec As Integer  ' Contador de vecinos ocupados en población anterior
 Dim a As Long        ' 0/1 Celda activa
 Dim i As Long        ' Contador de for en i
 Dim j As Long        ' Contador de for en j
 Dim k As Long        ' Contador de READ's
 Dim lResul As Long   ' Control de resultados intermedios
 Dim sDatos As String ' Paso de datos
 Dim dRand As Double  ' Rand


 ' NºGeneración

 NGEN = NGEN + 1



 ' Paso 1. Vuelca situación actual como anterior y limpia situación actual

 lResul = W_CPY("PVIDAC", "PVIDAA", 1)



 ' Paso 2. Genera envoltura de exploración en población anterior

 lResul = 0

 Do While True
  
  k = k + 1
 
  Er = W_READ("PVIDAC", k, sDatos)
  If Er > 0 Then Exit Do

  i = CLng(Mid(sDatos, 1, 10)) - ISUM
  j = CLng(Mid(sDatos, 11, 10)) - JSUM
 
  lResul = lResul + PrEvolAnt(i, j)
 
 Loop



 ' Paso 3. Limpia destino

 Er = W_CLRF("PVIDAC")



 ' Paso 4. Núcleo algorítmico. Reglas del "juego de la vida de John H.Conway"

 k = 0

 Do While True
 
  k = k + 1
  
  Er = W_READ("PVIDAA", k, sDatos)
  If Er > 0 Then Exit Do
  
  i = CLng(Mid(sDatos, 1, 10)) - ISUM
  j = CLng(Mid(sDatos, 11, 10)) - JSUM
  a = CLng(Mid(sDatos, 41, 10))


  ' Nº vecinos ocupados
 
  Nvec = PrNvec(i, j)


  ' Si una celda vacia tiene 3 vecinos exactamente, se ocupa

  If a = 0 And Nvec = 3 Then
 
   lResul = J_Write(i, j, 1)
   GoTo EtFinBucle
  
  End If
 

  ' Si una celda ocupada tiene menos de 2 vecinos muere por aislamiento

  If a > 0 And Nvec < 2 Then GoTo EtFinBucle


  ' Si una celda ocupada tiene + 3 vecinos muere por superpoblación

  If a > 0 And Nvec > 3 Then GoTo EtFinBucle


  ' El resto de celdas se mantiene como estaba

  If a = 0 Then GoTo EtFinBucle

  lResul = J_Write(i, j, 1)
 

EtFinBucle:
 
 Loop

 
 ' Devuelve el nº de generación alcanzado

 J_Gen = NGEN


End Function


                                                                                                        _______


5 Implementación de la hoja de muestra


En esta versión el código es más sencillo que en las implementaciones de los blogs hermanos porque una hoja excell proporciona un tapiz de soporte natural.

Así, prescindiremos de los botones de desplazamiento horizontal y vertical puesto que podemos crear una hoja de tamaño suficiente como para contener todo el conjunto poblacional.


La esencia de la implementación consiste en la rutina de generación, bajo autoinvocación temporal, y en la rutina de presentación que veremos ahora extractadas:


'-------------------------------------------------------------------------------------------
' Rutina de autorelleno
'-------------------------------------------------------------------------------------------
Sub AutoRelleno()

 Dim t               ' Time actual
 Dim t1              ' Time actual + n
 
 
 ' Filtro

 If iAuto = 0 Then Exit Sub
 
 
 ' Ejecuta tareas de autorelleno en curso


   ' Nueva generación
  
   lNGen = J_Gen()
   lNPob = J_Npob()


   ' Regenera/Presenta

   If lNPob = 0 Or lNGen > 1000 Then
      Call Generar_click
   Else
      Call Presentar
   End If

 
 
 ' Ejecuta tareas de auto-invocación
 
 t = Time                       ' Time actual
 
 t1 = t + TimeValue("00:00:01") ' Time + 1 segundos
 
 Application.OnTime t1, "Hoja1.AutoRelleno"

End Sub

                                                                                                        _______


'-------------------------------------------------------------------------------------------
' Rutina de presentación visual de resultados
'-------------------------------------------------------------------------------------------
Sub Presentar()

Dim Er As Integer  ' Control de errores intermedios
Dim l As Long      ' Contador de for
Dim i As Long      ' Fila
Dim j As Long      ' Columna
Dim a As Long      ' 0/1 activo
Dim lResul As Long ' Control de resultados intermedios

Dim M2 As Long     ' Pivote presentación (Deviene de la variable global M=100 filas*columnas vistas)



' Suspende visulización

Application.ScreenUpdating = False


' Limpia anterior
 
Range(Cells(1, 1), Cells(M, M)).Select
Selection.ClearContents
Selection.Interior.ColorIndex = xlNone


' Marco de Referencia

M2 = M / 9


' Presenta resultados

Do While True

 l = l + 1
 Er = J_Read(l, i, j, a)
 If Er > 0 Then Exit Do
 If a > 0 Then
 
 
  ' Filtros de salida de marcomarco
 
  If i + M2 < 1 Then
 
   lResul = J_Write(i, j, 0)
   GoTo EtFinBucle
  
  End If

 
   ...

 
 
If j + M2 > M Then
 
   lResul = J_Write(i, j, 0)
   GoTo EtFinBucle
  
  End If
 
 
  ' Marca
 
  Cells(i + M2, j + M2).Select
 
  With Selection.Interior
        .ColorIndex = 1
        .Pattern = xlSolid
  End With
 
 End If
 
EtFinBucle:
 
Loop


' Estadísticas

Range("CY102") = lNMuestra
Range("CZ102") = lNGen
Range("DA102") = lNPob


' Restaura visualización

Application.ScreenUpdating = True

End Sub


                                                                                                       
_______



Puede compararse la presentación en VBA con la presentación en otros lenguajes que se muestra en la página base de la serie; por ejemplo con el desarrollo paralelo en javascript, que se materializa en la página juvida.ficherosvirtuales.com




                                                                                                        _______