How to resolve the algorithm Abelian sandpile model step by step in the FutureBasic programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Abelian sandpile model step by step in the FutureBasic programming language

Table of Contents

Problem Statement

Implement the Abelian sandpile model also known as Bak–Tang–Wiesenfeld model. Its history, mathematical definition and properties can be found under its wikipedia article. The task requires the creation of a 2D grid of arbitrary size on which "piles of sand" can be placed. Any "pile" that has 4 or more sand particles on it collapses, resulting in four particles being subtracted from the pile and distributed among its neighbors. It is recommended to display the output in some kind of image format, as terminal emulators are usually too small to display images larger than a few dozen characters tall. As an example of how to accomplish this, see the Bitmap/Write a PPM file task. Examples up to 2^30, wow! javascript running on web Examples:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Abelian sandpile model step by step in the FutureBasic programming language

Source code in the futurebasic programming language

_mFile = 1
begin enum
  _iClose
end enum

_window = 1
begin enum 1
  _gridView
  _gridSizeLabel
  _gridSizeFld
  _centerNumLabel
  _centerNumFld
  _colorRadio
  _monoRadio
  _avalancheBtn
end enum


void local fn BuildMenu
  menu _mFile,,, @"File"
  menu _mFile, _iClose,, @"Close", @"w"
  MenuItemSetAction( _mFile, _iClose, @"performClose:" )
end fn


void local fn BuildWindow
  window _window, @"Abelian Sandpile Model", (0,0,513,360), NSWindowStyleMaskTitled + NSWindowStyleMaskClosable + NSWindowStyleMaskMiniaturizable
  
  subclass view _gridView, (20,20,320,320)
  
  textlabel _gridSizeLabel, @"Grid size:", (385,322,61,16)
  textfield _gridSizeFld,, @"5", (452,319,41,21)
  ControlSetFormat( _gridSizeFld, @"0123456789", YES, 4, 0 )
  
  textlabel _centerNumLabel, @"Center number:", (347,285,99,16)
  textfield _centerNumFld,, @"32", (452,282,41,21)
  ControlSetFormat( _centerNumFld, @"0123456789", YES, 4, 0 )
  
  radiobutton _colorRadio,, NSControlStateValueOn, @"Color", (367,249,59,18)
  radiobutton _monoRadio,, NSControlStateValueOff, @"Mono", (432,249,61,18)
  
  button _avalancheBtn,,, @"Avalanche", (375,13,96,32)
  
  WindowMakeFirstResponder( _window, _gridSizeFld )
end fn


void local fn ViewDrawRect
  long gridSize = fn ControlIntegerValue(_gridSizeFld)
  CGRect bounds = fn ViewBounds( _gridView )
  CGFloat cellSize = bounds.size.width/gridSize
  ColorRef col0 = fn ColorWhite, col1, col2, col3
  long r, c, value
  CGFloat x = 0, y = 0
  ColorRef color
  
  if ( fn ButtonState( _colorRadio ) == NSControlStateValueOn )
    col1 = fn ColorRed
    col2 = fn ColorGreen
    col3 = fn ColorBlue
  else
    col1 = fn ColorWithRGB( 0.25, 0.25, 0.25, 1.0 )
    col2 = fn ColorWithRGB( 0.5, 0.5, 0.5, 1.0 )
    col3 = fn ColorWithRGB( 0.75, 0.75, 0.75, 1.0 )
  end if
  
  for r = 0 to gridSize-1
    for c = 0 to gridSize-1
      value = mda_integer(r,c)
      select ( value )
        case 1    : color = col1
        case 2    : color = col2
        case 3    : color = col3
        case else : color = col0
      end select
      
      BezierPathFillRect( fn CGRectMake( x, y, cellSize, cellSize ), color )
      x += cellSize
    next
    x = 0
    y += cellSize
  next
end fn


void local fn AvalancheAction
  long r, c, gridSize = fn ControlIntegerValue(_gridSizeFld)
  long centerNum = fn ControlIntegerValue(_centerNumFld)
  long midNum = gridSize/2
  long limit = gridSize-1
  BOOL stable = NO
  long value
  
  // initialize array
  mda_kill
  for r = 0 to gridSize-1
    for c = 0 to gridSize-1
      mda(r,c) = 0
    next
  next
  mda(midNum,midNum) = centerNum
  
  // collapse
  while ( stable == NO )
    stable = YES
    for r = 0 to gridSize-1
      for c = 0 to gridSize-1
        value = mda_integer(r,c)
        if ( value > 3 )
          mda(r,c) = @(mda_integer(r,c)-4)
          if ( r > 0 ) then mda(r-1,c) = @(mda_integer(r-1,c) + 1)
          if ( r < limit ) then mda(r+1,c) = @(mda_integer(r+1,c) + 1)
          if ( c > 0 ) then mda(r,c-1) = @(mda_integer(r,c-1) + 1)
          if ( c < limit ) then mda(r,c+1) = @(mda_integer(r,c+1) + 1)
          stable = NO : break
        end if
      next
      if ( stable == NO ) then break
    next
  wend
  
  ViewSetNeedsDisplay( _gridView )
end fn


void local fn DoAppEvent( ev as long )
  select ( ev )
    case _appWillFinishLaunching
      fn BuildMenu
      fn BuildWindow
      fn AvalancheAction
    case _appShouldTerminateAfterLastWindowClosed : AppEventSetBool(YES)
  end select
end fn

void local fn DoDialog( ev as long, tag as long, wnd as long, obj as CFTypeRef )
  select ( ev )
    case _btnClick
      select ( tag )
        case _avalancheBtn : fn AvalancheAction
        case _gridSizeFld, _centerNumFld  : fn AvalancheAction
        case _colorRadio, _monoRadio : ViewSetNeedsDisplay( _gridView )
      end select
    case _viewDrawRect : fn ViewDrawRect
  end select
end fn

on appevent fn DoAppEvent
on dialog fn DoDialog

HandleEvents

  

You may also check:How to resolve the algorithm Bitcoin/address validation step by step in the Wren programming language
You may also check:How to resolve the algorithm Parallel calculations step by step in the SequenceL programming language
You may also check:How to resolve the algorithm Concurrent computing step by step in the VBA programming language
You may also check:How to resolve the algorithm Least common multiple step by step in the J programming language
You may also check:How to resolve the algorithm Anti-primes step by step in the Java programming language