Skip to content

Examples

HactarCE edited this page May 1, 2020 · 2 revisions

Examples (concept)

Conway's Game of Life

@ndca 0

@name "Conway's Game of Life"
@author "HactarCE"
@designer "John Conway"
@year "1970"
@url "https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life"

@pattern r"bo$2bo$3o!"

@transition
  set total = napkin.outer.count(#live)
  if total == 3 then
    become #live
  elseif total == 2 then
    remain
  else
    become #dead
  end
end

Wireworld

@ndca 0

@name "Wireworld"
@author "HactarCE"
@designer "Brian Silverman"
@year "1987"
@url "https://en.wikipedia.org/wiki/Wireworld"

@pattern r".BA$C2.4C$.2C!"

@states { _, #head, #tail, #wire }

@transition
  if this is #head then
    become #tail
  end
  if this is #tail then
    become #wire
  end
  if this is #wire and napkin.outer.count(#head) is 1..2 then
    become #head
  end
end

HPP

@ndca 0

@name "HPP"
@author "HactarCE"
@designer "Hardy, Pomeau, and de Pazzis"
@year "1973"
@url "https://en.wikipedia.org/wiki/HPP_model"

// States are defined to remain compatible with Golly's HPP implementation.
@states {
  {#space, #wall} #w:{false, true} #n:{false, true} #e:{false, true} #s:{false, true},
  #sink,
  #source #w #n #e #s,
}

@transition
  set westbound = napkin[E] is #w
  set northbound = napkin[S] is #n
  set eastbound = napkin[W] is #e
  set southbound = napkin[N] is #s
  if this is #space then
    set total = westbound + northbound + eastbound + southbound
    if total == 2 then
      if northbound then
        become #e & #w
      else
        become #n & #s
      end
    else
      become #w:(westbound) & #n:(northbound) & #e:(eastbound) & #s:(southbound)
    end
  end
  if this is #wall then
    become #w:(eastbound) & #n:(southbound) & #e:(westbound) & #s:(northbound)
  end
end

Langton's Ant

@ndca 0

@name "Langton's Ant"
@author "HactarCE"
@designer "Chris Langton"
@year "1986"
@url "https://en.wikipedia.org/wiki/Langton%27s_ant"

// States are defined to remain compatible with Golly's Langton's Ant implementation.
@states {
  #value:{0, 1},
  #value:{0, 1} #ant {#n, #e, #s, #w},
}

@transition
  set new_value = this#value
  if this#ant then
    set new_value = not(new_value)
  end
  set result = #value:(new_value)
  if napkin[W] is #n & #value:0 | #s & value:1 then
    set result &= #e
  end
  if napkin[N] is #e & #value:0 | #w & value:1 then
    set result &= #s
  end
  if napkin[E] is #s & #value:0 | #n & value:1 then
    set result &= #w
  end
  if napkin[S] is #w & #value:0 | #e & value:1 then
    set result &= #n
  end
  // If multiple ants collide, error because there is no such state.
  // In Golly, this just kills both ants to avoid any assymetry.
  // Alternatively, with 16 states one could allow overlapping ants (like HPP).
  become result
end

Busy Boxes

// TODO: generalize to any number of dimensions (need some kind of iteration over all combinations of axes; i.e. all planes)

@ndca 0

@name "Busy Boxes"
@author "HactarCE"
@designer "Ed Fredkin and Daniel B. Miller"
@year "2005"
@url "http://busyboxes.org/faq.html"

@dim 3

@radius 3

@states {
  #blank,
  #border,
  #box {#parity:0..1} {#t:0..5},
}

@transition
  // Optimization: exit early if immediate neighbors are empty
  if (napkin & box(1)).count() then
    remain
  end

  test this#t / 2
    case 0
      set plane = napkin.XY_
    case 1
      set plane = napkin.YZ_
    case 2
      set plane = napkin.ZX_
  end

  test plane
    case a"
      . . . . . . .
      . . n . n . .
      . n . . . x .
      . . . a . . n
      . n . . b . .
      . . . . . . n
      . . . n . n .
    " where {
      'n' is ~#box,
      'x' is #box & #parity:(not(this#t % 2)),
      'a' is ~#border,
      'b' is ~#border set b,
      sym is r4r,
    }
      become b
  end
end

Busy Boxes (experimental spacial and temporal periodicity syntax)

@ndca 0

@name "Busy Boxes"
@author "HactarCE"
@designer "Ed Fredkin and Daniel B. Miller"
@year "2005"
@url "http://busyboxes.org/faq.html"

@dim from 2..6

@radius 3

@period {
  x + y % 2 set parity,
  t % (dim * (dim - 1)) set time,
}

@states { #blank, #box, #border }

@transition
  if time % 2 != parity then
    remain
  end

  // Optimization: exit early if immediate neighbors are empty
  if (napkin & box(1)).count() then
    remain
  end

  test time / 2
    case 0
      set plane = napkin.XY_
    case 1
      set plane = napkin.YZ_
    case 2
      set plane = napkin.ZX_
  end

  test plane
    case a"
      . . . . . . .
      . . n . n . .
      . n . . . x .
      . . . a . . n
      . n . . b . .
      . . . . . . n
      . . . n . n .
    " where {
      'n' is ~#box,
      'x' is #box,
      'a' is ~#border,
      'b' is ~#border set b,
      sym is r4r,
    }
      become b
  end
end

Brew

@ndca 0

@name "Brew"
@author "HactarCE"
@designer "Dui Mauris Football (?)"
@year "2018"

@states {
  #dead,
  #live:1..250,
}

@transition
  if this is #live then
    if napkin.count(this#live) is 2..3 then
      remain
    else
      become #live:(this#live - 1)
    end
  else
    set next = this
    // Allow higher states to override.
    for nb in napkin.filter(#live).states do
      if nb#live > next#live and napkin.count(nb) == 3 then
        set next = nb
      end
    end
    // Die into the next lower state.
    if next == this and napkin.count(this) isnt 2..3 then
      set next = #live:(this#live - 1)
    end
    become next
  end
end
Clone this wiki locally