123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- def otherwise=true:
- def dead=0, alive= not dead:
- def radius=1,
- diameter= (2*radius)+1,
- neighbours= (diameter*diameter)-1:
- proc calculate.next.state(chan link[], value in[], state, var next.state)=
- var count:
- seq
- var state.of.neighbour[neighbours]:
- seq
- par i=[0 for neighbours]
- link[in[i]] ? state.of.neighbour[i]
- count:=0
- seq i=[0 for neighbours]
- if
- state.of.neighbour[i]=alive
- count:=count+1
- state.of.neighbour[i]=dead
- skip
- if
- count<2
- next.state:=dead
- count=2
- next.state:=state
- count=3
- next.state:=alive
- count>3
- next.state:=dead
- :
- proc broadcast.present.state(chan link[], value out[], state)=
- par i=[0 for neighbours]
- link[out[i]] ! state
- :
- def set.state=1, ask.state=2, terminate=3:
- proc cell(chan link[], value in[], out[], chan control, sense)=
- var state, instruction:
- seq
- state:=dead
- control ? instruction
- while instruction <> terminate
- seq
- if
- instruction=set.state
- control ? state
- instruction=ask.state
- var next.state:
- seq
- par
- broadcast.present.state(link, out, state)
- seq
- calculate.next.state(link, in, state,
- next.state)
- sense ! (state<>next.state); next.state
- state:=next.state
- control ? instruction
- :
- def array.width=5, array.height=5:
- def number.of.cells=array.height*array.width,
- number.of.links=neighbours*number.of.cells:
- proc initialize(value x, y, var in[], out[])=
- seq delta.x=[-radius for diameter]
- seq delta.y=[-radius for diameter]
- var direction:
- seq
- direction:=delta.x+(diameter*delta.y)
- if
- direction<>0
- var index, process:
- seq
- process:=x+(array.width*y)
- index:=(neighbours+direction) \ (neighbours+1)
- out[index]:=index+(neighbours*process)
- process:=((x+delta.x+array.width) \ array.width) +
- (array.width*
- ((y+delta.y+array.height) \ array.height))
- index:=(neighbours-direction) \ (neighbours+1)
- in[index]:=index+(neighbours*process)
- direction=0
- skip
- :
- def control= not ((not 0)<<5), escape=control/\'[':
- proc move.cursor(chan screen, value x, y)=
- screen ! escape; '='; '*s'+y; '*s'+x
- :
- proc initialize.display(chan screen)=
- screen ! control /\ 'Z'
- :
- proc clean.up.display(chan screen)=
- move.cursor(screen, 0, array.height)
- :
- proc display.state(chan screen, value x, y, state)=
- seq
- move.cursor(screen, x, y)
- if
- state=alive
- screen ! '**'
- state=dead
- screen ! '*s'
- :
- proc generation(chan screen, control[], sense[], var active)=
- seq
- seq cell=[0 for number.of.cells]
- control[cell] ! ask.state
- active:=false
- seq cell=[0 for number.of.cells]
- var changed, next.state:
- seq
- sense[cell] ? changed; next.state
- if
- changed
- seq
- display.state(screen, cell\array.width,
- cell/array.width, next.state)
- active:=true
- not changed
- skip
- :
- proc edit(chan keyboard, screen, control[])=
- def ctrl= not ((not 0)<<5):
- def left.key= 'h', right.key= 'l', up.key= 'k', down.key= 'j',
- uproot.key= '*s', plant.key= '**', plant.key2= '8':
- var x, y, editing, ch:
- seq
- x:=array.width/2
- y:=array.height/2
- editing:=true
- while editing
- seq
- move.cursor(screen, x, y)
- keyboard ? ch
- if
- (ch=left.key) and (x>0)
- x:=x-1
- (ch=right.key) and (x<(array.width-1))
- x:=x+1
- (ch=up.key) and (y>0)
- y:=y-1
- (ch=down.key) and (y<(array.height-1))
- y:=y+1
- (ch=uproot.key) or (ch=plant.key) or (ch=plant.key2)
- var state:
- seq
- state:=(dead /\ (ch=uproot.key)) \/
- (alive /\ ((ch=plant.key) or (ch=plant.key2)))
- control[x+(array.width*y)] ! set.state; state
- display.state(screen, x, y, state)
- (ch='q') or (ch='Q')
- editing:=false
- otherwise
- skip
- :
- def idle=1, editing=2, single.stepping=3, free.running=4, terminated=5:
- proc display.activity(chan screen, value activity)=
- seq
- move.cursor(screen, array.width+1, array.height+2)
- proc write.string(value str[])=
- seq i=[1 for str[byte 0]]
- screen ! str[byte i]
- :
- if
- activity=idle
- write.string("Idle")
- activity=editing
- write.string("Edit")
- activity=single.stepping
- write.string("Step")
- activity=free.running
- write.string("Busy")
- activity=terminated
- write.string("Done")
- :
- proc controller(chan keyboard, screen, control[], sense[])=
- var activity:
- seq
- activity:=idle
- initialize.display(screen)
- while activity<>terminated
- seq
- display.activity(screen, activity)
- var ch:
- pri alt
- (activity <> editing) & keyboard ? ch
- if
- (ch='q') or (ch='Q')
- activity:=terminated
- (ch='i') or (ch='I')
- activity:=idle
- (ch='e') or (ch='E')
- activity:=editing
- (ch='r') or (ch='R')
- activity:=free.running
- (ch='s') or (ch='S')
- activity:=single.stepping
- (activity=editing) & skip
- seq
- edit(keyboard, screen, control)
- activity:=idle
- (activity=free.running) or (activity=single.stepping) & skip
- var changing:
- seq
- generation(screen, control, sense, changing)
- if
- (activity=single.stepping) or (not changing)
- activity:=idle
- (activity=free.running) and changing
- skip
- display.activity(screen, activity)
- seq cell=[0 for number.of.cells]
- control[cell] ! terminate
- clean.up.display(screen)
- :
- chan link[number.of.links], control[number.of.cells], sense[number.of.cells]:
- seq
- output ! RAW
- par
- controller(input, output, control, sense)
- par x=[0 for array.width]
- par y=[0 for array.height]
- var in[neighbours], out[neighbours]:
- seq
- initialize(x, y, in, out)
- cell(link, in, out, control[x+(array.width*y)],
- sense[x+(array.width*y)])
- output ! TEXT
|