lifegame.ocm 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. def otherwise=true:
  2. def dead=0, alive= not dead:
  3. def radius=1,
  4. diameter= (2*radius)+1,
  5. neighbours= (diameter*diameter)-1:
  6. proc calculate.next.state(chan link[], value in[], state, var next.state)=
  7. var count:
  8. seq
  9. var state.of.neighbour[neighbours]:
  10. seq
  11. par i=[0 for neighbours]
  12. link[in[i]] ? state.of.neighbour[i]
  13. count:=0
  14. seq i=[0 for neighbours]
  15. if
  16. state.of.neighbour[i]=alive
  17. count:=count+1
  18. state.of.neighbour[i]=dead
  19. skip
  20. if
  21. count<2
  22. next.state:=dead
  23. count=2
  24. next.state:=state
  25. count=3
  26. next.state:=alive
  27. count>3
  28. next.state:=dead
  29. :
  30. proc broadcast.present.state(chan link[], value out[], state)=
  31. par i=[0 for neighbours]
  32. link[out[i]] ! state
  33. :
  34. def set.state=1, ask.state=2, terminate=3:
  35. proc cell(chan link[], value in[], out[], chan control, sense)=
  36. var state, instruction:
  37. seq
  38. state:=dead
  39. control ? instruction
  40. while instruction <> terminate
  41. seq
  42. if
  43. instruction=set.state
  44. control ? state
  45. instruction=ask.state
  46. var next.state:
  47. seq
  48. par
  49. broadcast.present.state(link, out, state)
  50. seq
  51. calculate.next.state(link, in, state,
  52. next.state)
  53. sense ! (state<>next.state); next.state
  54. state:=next.state
  55. control ? instruction
  56. :
  57. def array.width=5, array.height=5:
  58. def number.of.cells=array.height*array.width,
  59. number.of.links=neighbours*number.of.cells:
  60. proc initialize(value x, y, var in[], out[])=
  61. seq delta.x=[-radius for diameter]
  62. seq delta.y=[-radius for diameter]
  63. var direction:
  64. seq
  65. direction:=delta.x+(diameter*delta.y)
  66. if
  67. direction<>0
  68. var index, process:
  69. seq
  70. process:=x+(array.width*y)
  71. index:=(neighbours+direction) \ (neighbours+1)
  72. out[index]:=index+(neighbours*process)
  73. process:=((x+delta.x+array.width) \ array.width) +
  74. (array.width*
  75. ((y+delta.y+array.height) \ array.height))
  76. index:=(neighbours-direction) \ (neighbours+1)
  77. in[index]:=index+(neighbours*process)
  78. direction=0
  79. skip
  80. :
  81. def control= not ((not 0)<<5), escape=control/\'[':
  82. proc move.cursor(chan screen, value x, y)=
  83. screen ! escape; '='; '*s'+y; '*s'+x
  84. :
  85. proc initialize.display(chan screen)=
  86. screen ! control /\ 'Z'
  87. :
  88. proc clean.up.display(chan screen)=
  89. move.cursor(screen, 0, array.height)
  90. :
  91. proc display.state(chan screen, value x, y, state)=
  92. seq
  93. move.cursor(screen, x, y)
  94. if
  95. state=alive
  96. screen ! '**'
  97. state=dead
  98. screen ! '*s'
  99. :
  100. proc generation(chan screen, control[], sense[], var active)=
  101. seq
  102. seq cell=[0 for number.of.cells]
  103. control[cell] ! ask.state
  104. active:=false
  105. seq cell=[0 for number.of.cells]
  106. var changed, next.state:
  107. seq
  108. sense[cell] ? changed; next.state
  109. if
  110. changed
  111. seq
  112. display.state(screen, cell\array.width,
  113. cell/array.width, next.state)
  114. active:=true
  115. not changed
  116. skip
  117. :
  118. proc edit(chan keyboard, screen, control[])=
  119. def ctrl= not ((not 0)<<5):
  120. def left.key= 'h', right.key= 'l', up.key= 'k', down.key= 'j',
  121. uproot.key= '*s', plant.key= '**', plant.key2= '8':
  122. var x, y, editing, ch:
  123. seq
  124. x:=array.width/2
  125. y:=array.height/2
  126. editing:=true
  127. while editing
  128. seq
  129. move.cursor(screen, x, y)
  130. keyboard ? ch
  131. if
  132. (ch=left.key) and (x>0)
  133. x:=x-1
  134. (ch=right.key) and (x<(array.width-1))
  135. x:=x+1
  136. (ch=up.key) and (y>0)
  137. y:=y-1
  138. (ch=down.key) and (y<(array.height-1))
  139. y:=y+1
  140. (ch=uproot.key) or (ch=plant.key) or (ch=plant.key2)
  141. var state:
  142. seq
  143. state:=(dead /\ (ch=uproot.key)) \/
  144. (alive /\ ((ch=plant.key) or (ch=plant.key2)))
  145. control[x+(array.width*y)] ! set.state; state
  146. display.state(screen, x, y, state)
  147. (ch='q') or (ch='Q')
  148. editing:=false
  149. otherwise
  150. skip
  151. :
  152. def idle=1, editing=2, single.stepping=3, free.running=4, terminated=5:
  153. proc display.activity(chan screen, value activity)=
  154. seq
  155. move.cursor(screen, array.width+1, array.height+2)
  156. proc write.string(value str[])=
  157. seq i=[1 for str[byte 0]]
  158. screen ! str[byte i]
  159. :
  160. if
  161. activity=idle
  162. write.string("Idle")
  163. activity=editing
  164. write.string("Edit")
  165. activity=single.stepping
  166. write.string("Step")
  167. activity=free.running
  168. write.string("Busy")
  169. activity=terminated
  170. write.string("Done")
  171. :
  172. proc controller(chan keyboard, screen, control[], sense[])=
  173. var activity:
  174. seq
  175. activity:=idle
  176. initialize.display(screen)
  177. while activity<>terminated
  178. seq
  179. display.activity(screen, activity)
  180. var ch:
  181. pri alt
  182. (activity <> editing) & keyboard ? ch
  183. if
  184. (ch='q') or (ch='Q')
  185. activity:=terminated
  186. (ch='i') or (ch='I')
  187. activity:=idle
  188. (ch='e') or (ch='E')
  189. activity:=editing
  190. (ch='r') or (ch='R')
  191. activity:=free.running
  192. (ch='s') or (ch='S')
  193. activity:=single.stepping
  194. (activity=editing) & skip
  195. seq
  196. edit(keyboard, screen, control)
  197. activity:=idle
  198. (activity=free.running) or (activity=single.stepping) & skip
  199. var changing:
  200. seq
  201. generation(screen, control, sense, changing)
  202. if
  203. (activity=single.stepping) or (not changing)
  204. activity:=idle
  205. (activity=free.running) and changing
  206. skip
  207. display.activity(screen, activity)
  208. seq cell=[0 for number.of.cells]
  209. control[cell] ! terminate
  210. clean.up.display(screen)
  211. :
  212. chan link[number.of.links], control[number.of.cells], sense[number.of.cells]:
  213. seq
  214. output ! RAW
  215. par
  216. controller(input, output, control, sense)
  217. par x=[0 for array.width]
  218. par y=[0 for array.height]
  219. var in[neighbours], out[neighbours]:
  220. seq
  221. initialize(x, y, in, out)
  222. cell(link, in, out, control[x+(array.width*y)],
  223. sense[x+(array.width*y)])
  224. output ! TEXT