cellular automaton vonNeumann; const dimension = 2; const distance = 1; const north = [0, 1]; const east = [1, 0]; const west = [-1, 0]; const south = [0, -1]; const cell = [0, 0]; type cstates = (zz, zo, oz, oo); type sstates = (si, sz, so, szz, szo, soz, soo, szzz); type attype = union cstate : cstates; sstate : sstates; end; type celltype = record typ : (unex, normt, spect, conf, sens); excited : boolean; dir : celladdress; attribut : attype; end; group news = {north, east, west, south}; group inv_news = {south, west, east, north}; color "arrvn.gif" ((*cell.excited?1:0) + (value(*cell.typ) - 1) * 2:7, 0:4) ~ *cell.typ in {normt, spect} and *cell.dir = east; color "arrvn.gif" ((*cell.excited?1:0) + (value(*cell.typ) - 1) * 2:7, 1:4) ~ *cell.typ in {normt, spect} and *cell.dir = west; color "arrvn.gif" ((*cell.excited?1:0) + (value(*cell.typ) - 1) * 2:7, 2:4) ~ *cell.typ in {normt, spect} and *cell.dir = north; color "arrvn.gif" ((*cell.excited?1:0) + (value(*cell.typ) - 1) * 2:7, 3:4) ~ *cell.typ in {normt, spect} and *cell.dir = south; color "arrvn.gif" (4:7, value(*cell.attribut.cstate):4) ~ *cell.typ = conf; color "arrvn.gif" (5 + (value(*cell.attribut.sstate) div 4):7, (value(*cell.attribut.sstate) mod 4):4) ~ *cell.typ = sens; initial /* [normt, false, 1, 0, zz, szz ] ~ x >= lx/2 and y = ly-1 and option = 1 ; [normt, true, 0, 1, zz, szz ] ~ x = lx/2 and y = ly/2 and option = 1 ; [normt, false, 0, 1, zz, szz ] ~ x = lx/2 and y > ly/2 and option = 1 ; [spect, prob(0.2), 1, 0, zz, szz ] ~ option = 0 and prob(0.2); */ [unex, false, 0, 0, zz, szz] ~ true; var n, i : celladdress; var all_norm, one_norm, one_spec : boolean; var nextsens : sstates; rule begin one_norm := one(n in news & i in inv_news : *n.typ = normt and *n.dir = i and *n.excited); all_norm := all(n in news & i in inv_news : *n.typ != normt or *n.dir != i or *n.excited) and one_norm; one_spec := one(n in news & i in inv_news : *n.typ = spect and *n.dir = i and *n.excited); case *cell.typ of unex : if one_spec or one_norm then begin *cell.typ := sens; *cell.excited := false; *cell.attribut.sstate := si; end; sens : begin nextsens := si; case *cell.attribut.sstate of si : if one_spec or one_norm then nextsens := so else nextsens := sz; so : if one_spec or one_norm then nextsens := soo else nextsens := soz; sz : if one_spec or one_norm then nextsens := szo else nextsens := szz; szz : if one_spec or one_norm then begin *cell.typ := normt; *cell.dir := west; end else nextsens := szzz; szo : if one_spec or one_norm then begin *cell.typ := spect; *cell.dir := east; end else begin *cell.typ := normt; *cell.dir := south; end; soz : if one_spec or one_norm then begin *cell.typ := spect; *cell.dir := west; end else begin *cell.typ := spect; *cell.dir := north; end; soo : if one_spec or one_norm then begin *cell.typ := conf; *cell.attribut.cstate := zz; end else begin *cell.typ := spect; *cell.dir := south; end; szzz : if one_spec or one_norm then begin *cell.typ := normt; *cell.dir := north; end else begin *cell.typ := normt; *cell.dir := east; end; end; *cell.attribut.sstate := nextsens; end; normt : if one_spec then *cell.typ := unex else *cell.excited := one_norm or one(n in news : *n.typ = conf and *cell.dir != n and *n.attribut.cstate in {oz, oo}); spect : if one_norm then *cell.typ := unex else *cell.excited := one_spec or one(n in news : *n.typ = conf and *n.attribut.cstate in {oz, oo}); conf : if one_spec then *cell.typ := unex else if all_norm then case *cell.attribut.cstate of zz : *cell.attribut.cstate := zo; zo : *cell.attribut.cstate := oo; oz : *cell.attribut.cstate := zo; oo : *cell.attribut.cstate := oo; end else case *cell.attribut.cstate of zz : *cell.attribut.cstate := zz; zo : *cell.attribut.cstate := oz; oz : *cell.attribut.cstate := zz; oo : *cell.attribut.cstate := oz; end; end; end;