Register to post in forums, or Log in to your existing account
 

Life Demo [[LifeDemo]] 
This is the classic Conway's Game of Life cellular automata simulation. It demonstrates the use of the advanced Grid component and how it can be tied to a two-dimensional array in the scripting language, and easily changed between multiple arrays. While the performance of the scripting language for large grids is limited, the program is fast enough to be an effective demonstration.

[Click here to see the XML source code]






Here is the zApp XML source code for this application:
Code:
<?xml version='1.0' encoding='ISO-8859-1' ?>
<!DOCTYPE zapp [
  <!ENTITY AppTitle "Zeus Demo: Life Simulation">
  <!ENTITY AppAuthor "Zugg Software">
  <!ENTITY AppVersion "1.0">
  <!ENTITY AppURL "http://www.zuggsoft.com/">
  <!ENTITY AppImage "ZAPP">
  <!ENTITY AboutBox SYSTEM "aboutbox.xml">
  ]>
<zapp>
  <splash color='#C4D2ED'>
    <image image='zapp' deltaleft='8' deltatop='8'/>
    <label align='Client' bevelouter='Lowered' autoleft='true' deltaleft='8' width='-8' height='-8' gradienttype='FullVertical' color='#C4D2ED' colorto='#7E98CB'><![CDATA[<b>&AppTitle;</b><br><br>
Version &AppVersion;<br><br>
by &AppAuthor;]]></label>
  </splash>
  <action name='StartSim' caption='Run/Stop' hint='Run simulation' image='play'>
    if StartSim.Checked then
      StartSim.Checked = false
      StartSim.Hint = "Run simulation"
      PauseSim.Hint = "Step simulation"
    else
      StartSim.Checked = true
      StartSim.Hint = "Pause simulation"
      PauseSim.Hint = "Pause simulation"
    end if
    LifeTimer.Enabled = StartSim.Checked
  </action>
  <action name='PauseSim' caption='Pause/Step' hint='Step simulation' image='pause'>
    if StartSim.Checked then
      StartSim.Checked = false
      StartSim.Hint = "Run simulation"
      PauseSim.Hint = "Step simulation"
      LifeTimer.Enabled = StartSim.Checked
    else
      LifeTimer.Execute
    end if
  </action>
  <toolbar name='mainmenu'>
    <menu caption='&amp;File'>
      <item action='_FileExit'/>
    </menu>
    <menu caption='&amp;View'>
      <item caption='Normal' script='core.themeindex = -1'/>
      <item caption='Aqua' script='core.theme = "aqua"'/>
      <item action='_ThemeSelect'/>
    </menu>
    <menu caption='&amp;Actions'>
      <item action='StartSim'/>
      <item action='PauseSim'/>
      <itemsep/>
      <item caption='Randomize'>
        for i = 0 to UBound(a,1)
          for j = 0 to UBound(a,2)
            if (math.randomint(0,100) > 70) then
              a(i,j) = CellColor.value
              b(i,j) = CellColor.value
            end if
          next
        next
        grid.datachanged
        gen = 0
        Status.Text = "Generation: 0"
      </item>
      <item caption='Clear'>
        for i = 0 to UBound(a,1)
          for j = 0 to UBound(a,2)
            a(i,j) = 0
            b(i,j) = 0
          next
        next
        grid.datachanged
        gen = 0
        Status.Text = "Generation: 0"
      </item>
    </menu>
    <menu caption='&amp;Help'>
      <item caption='&amp;About' script='core.execwindow( "About")'/>
    </menu>
    <itemsep/>
    <item action='StartSim'/>
    <item action='PauseSim'/>
    <itemsep/>
    <combo.colors name='CellColor' colors='x11ordered' text='gold' hint='Cell color'/>
    <spinedit name='Interval' value='500' minvalue='100' increment='100' width='80' hint='Update interval'/>
  </toolbar>
  <window name='main' caption='&AppTitle;' left="50" top="80" height="596" width="524">
    <toolbar name='mainmenu'/>
    <timer name='LifeTimer' interval='=Interval.value' immediate='true'>
      sub Generate( oldA, newA)
        maxi = UBound(newA,1)
        maxj = UBound(newA,2)
        for j = 0 to maxj
          for x = 0 to 2
            if (j+x < 1) or (j+x-1 > maxj) then
              z = 0
            elseif (oldA(0,j+x-1) > 0) then
              z = 1
            else
              z = 0
            end if
            prev(x) = 0
            prev2(x) = 0
            prev3(x) = z
            sum(x) = z
          next
          for i = 0 to maxi
            count = 0
            for x = 0 to 2
              if (i < -1) or (i >= maxi) or (j+x < 1) or (j+x-1 > maxj) then
                z = 0
              elseif (oldA(i+1,j+x-1) > 0) then
                z = 1
              else
                z = 0
              end if
              y = sum(x) - prev(x) + z
              count = count + y
              sum(x) = y
              prev(x) = prev2(x)
              prev2(x) = prev3(x)
              prev3(x) = z
            next
            z = prev2(1)
            count = count - z
            if (count < 2) then
              y = 0
            elseif (count = 2) then
              if (z = 0) then y = 0 else y = col
            elseif (count = 3) then
              y = col
            else
              y = 0
            end if
            newA(i,j) = y
          next
        next
      end sub
      col = CellColor.Value
      if (igen = 0) then
        Generate a, b
        grid.data = b
        igen = 1
      else
        Generate b, a
        grid.data = a
        igen = 0
      end if
      grid.update
      gen = gen + 1
      Status.Text = "Generation: " &amp; gen
    </timer>
    <grid name='Grid' Align='client'>
      <script event='oncellclick'>
        if (zEvent.Button = "Left") then
          grid.cell( zEvent.Row, zEvent.Col) = CellColor.Value
        elseif (zEvent.Button = "Right") then
          grid.cell( zEvent.Row, zEvent.Col) = 0
        end if
        zEvent.Handled = true
        grid.datachanged
      </script>
    </grid>
    <statusbar name='Status' showhelp='false'/>
    <script>
      dim a(), b()
      dim sum(2), prev(2), prev2(2), prev3(2)
      redim a(63,63), b(63,63)
      for i = 0 to UBound(a,1)
        for j = 0 to UBound(a,2)
          a(i,j) = 0
          b(i,j) = 0
        next
      next
      igen = 0
      grid.defkind="color"
      grid.rowheight=8
      grid.colwidth=8
      grid.data=a
      grid.gridlines="both"
      grid.gridlinecolor="black"
      grid.invertselect=false
      grid.editing=false
      gen = 0
    </script>
  </window>
  &AboutBox;
</zapp>

Most of the code consists of the script for generating the next generation of the life pattern. The algorithm is hard to read because it was optimized for as much performance as possible. It basically keeps track of running sums across a row rather than computing the neighbors individually.
Viewer Comments [0 - Post your comments]

Jump to:  

© 2009 Zugg Software. Hosted by Wolfpaw.net