Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
67 lines
1.7 KiB
Smalltalk
67 lines
1.7 KiB
Smalltalk
"Conway's Game of Life — 2D grid stepped by the standard rules:
|
|
live with 2 or 3 neighbours stays alive; dead with exactly 3 becomes alive.
|
|
Classic-corpus program for the Smalltalk-on-SX runtime. The canonical
|
|
'glider gun' demo (~36 cells, period-30 emission) is correct but too slow
|
|
to verify on the spec interpreter without JIT — block, blinker, glider
|
|
cover the rule arithmetic and edge handling."
|
|
|
|
Object subclass: #Life
|
|
instanceVariableNames: 'rows cols cells'!
|
|
|
|
!Life methodsFor: 'init'!
|
|
rows: r cols: c
|
|
rows := r. cols := c.
|
|
cells := Array new: r * c.
|
|
1 to: r * c do: [:i | cells at: i put: 0].
|
|
^ self! !
|
|
|
|
!Life methodsFor: 'access'!
|
|
rows ^ rows!
|
|
cols ^ cols!
|
|
|
|
at: r at: c
|
|
((r < 1) or: [r > rows]) ifTrue: [^ 0].
|
|
((c < 1) or: [c > cols]) ifTrue: [^ 0].
|
|
^ cells at: (r - 1) * cols + c!
|
|
|
|
at: r at: c put: v
|
|
cells at: (r - 1) * cols + c put: v.
|
|
^ v! !
|
|
|
|
!Life methodsFor: 'step'!
|
|
neighbors: r at: c
|
|
| sum |
|
|
sum := 0.
|
|
-1 to: 1 do: [:dr |
|
|
-1 to: 1 do: [:dc |
|
|
((dr = 0) and: [dc = 0]) ifFalse: [
|
|
sum := sum + (self at: r + dr at: c + dc)]]].
|
|
^ sum!
|
|
|
|
step
|
|
| next |
|
|
next := Array new: rows * cols.
|
|
1 to: rows * cols do: [:i | next at: i put: 0].
|
|
1 to: rows do: [:r |
|
|
1 to: cols do: [:c |
|
|
| n alive lives |
|
|
n := self neighbors: r at: c.
|
|
alive := (self at: r at: c) = 1.
|
|
lives := alive
|
|
ifTrue: [(n = 2) or: [n = 3]]
|
|
ifFalse: [n = 3].
|
|
lives ifTrue: [next at: (r - 1) * cols + c put: 1]]].
|
|
cells := next.
|
|
^ self!
|
|
|
|
stepN: n
|
|
n timesRepeat: [self step].
|
|
^ self! !
|
|
|
|
!Life methodsFor: 'measure'!
|
|
livingCount
|
|
| sum |
|
|
sum := 0.
|
|
1 to: rows * cols do: [:i | (cells at: i) = 1 ifTrue: [sum := sum + 1]].
|
|
^ sum! !
|