Object subclass: #LifeCell instanceVariableNames: '' classVariableNames: 'Alive Dead ' poolDictionaries: '' category: 'Life'! !LifeCell methodsFor: 'accessing' stamp: 'tak 3/16/2003 21:44'! isSet self shouldNotImplement! ! !LifeCell methodsFor: 'accessing' stamp: 'tak 3/16/2003 21:54'! nextWhen: aNumber self shouldNotImplement! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! LifeCell class instanceVariableNames: ''! !LifeCell class methodsFor: 'instance creation' stamp: 'tak 3/16/2003 21:51'! alive ^Alive ! ! !LifeCell class methodsFor: 'instance creation' stamp: 'tak 3/16/2003 21:51'! dead ^Dead ! ! !LifeCell class methodsFor: 'class initialization' stamp: 'tak 3/16/2003 21:49'! initialize " self initialize " Alive _ LifeCellAlive new. Dead _ LifeCellDead new.! ! LifeCell subclass: #LifeCellAlive instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Life'! !LifeCellAlive methodsFor: 'accessing' stamp: 'tak 3/16/2003 21:44'! isSet ^ true.! ! !LifeCellAlive methodsFor: 'accessing' stamp: 'tak 3/16/2003 21:57'! nextWhen: aNumber aNumber = 2 ifTrue: [^LifeCell alive]. aNumber = 3 ifTrue: [^LifeCell alive]. ^LifeCell dead. ! ! LifeCell subclass: #LifeCellDead instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Life'! !LifeCellDead methodsFor: 'accessing' stamp: 'tak 3/16/2003 21:45'! isSet ^ false.! ! !LifeCellDead methodsFor: 'accessing' stamp: 'tak 3/16/2003 21:57'! nextWhen: aNumber aNumber = 2 ifTrue: [^LifeCell dead]. aNumber = 3 ifTrue: [^LifeCell alive]. ^LifeCell dead. ! ! Object subclass: #LifeMap instanceVariableNames: 'map ' classVariableNames: '' poolDictionaries: '' category: 'Life'! !LifeMap methodsFor: 'initialize' stamp: 'tak 3/16/2003 22:12'! new: aPoint map _ Array2D width: aPoint x + 2 height: aPoint y + 2. self clear.! ! !LifeMap methodsFor: 'accessing' stamp: 'tak 3/16/2003 22:07'! at: aPoint ^(map at: aPoint x + 1 at: aPoint y + 1)! ! !LifeMap methodsFor: 'accessing' stamp: 'tak 3/16/2003 22:09'! at: aPoint put: anObject map at: aPoint x + 1 at: aPoint y + 1 put: anObject! ! !LifeMap methodsFor: 'accessing' stamp: 'tak 3/16/2003 22:13'! setAt: aPoint self at: aPoint put: LifeCell alive! ! !LifeMap methodsFor: 'accessing' stamp: 'tak 3/16/2003 22:13'! unsetAt: aPoint self at: aPoint put: LifeCell dead! ! !LifeMap methodsFor: 'public' stamp: 'tak 3/16/2003 22:12'! clear map atAllPut: LifeCell dead.! ! !LifeMap methodsFor: 'public' stamp: 'tak 3/16/2003 22:03'! height ^map height - 2! ! !LifeMap methodsFor: 'public' stamp: 'tak 3/16/2003 22:07'! isSetAt: aPoint ^ (self at: aPoint) isSet.! ! !LifeMap methodsFor: 'public' stamp: 'tak 3/16/2003 23:19'! random 1 to: self width do: [:x | 1 to: self height do: [:y | 2 atRandom = 1 ifTrue: [self setAt: x @ y] ifFalse: [self unsetAt: x @ y]]]! ! !LifeMap methodsFor: 'public' stamp: 'tak 3/16/2003 22:44'! step | prev | prev _ self copy. 1 to: self width do: [:x | 1 to: self height do: [:y | self at: x @ y put: ((self at: x @ y) nextWhen: (prev numAt: x @ y))]]! ! !LifeMap methodsFor: 'public' stamp: 'tak 3/16/2003 22:03'! width ^map width - 2! ! !LifeMap methodsFor: 'private' stamp: 'tak 3/16/2003 22:44'! copy | another newMap | another _ super copy. newMap _ Array2D width: map width height: map height. map rowsAndColumnsDo: [ :x :y | newMap at: x at: y put: (map at: x at: y)]. another map: newMap. ^another! ! !LifeMap methodsFor: 'private' stamp: 'tak 3/16/2003 22:31'! map: anArray2D map _ anArray2D! ! !LifeMap methodsFor: 'private' stamp: 'tak 3/16/2003 21:29'! numAt: aPoint | num | num _ 0. (self isSetAt: aPoint - (-1@-1)) ifTrue: [ num _ num + 1 ]. (self isSetAt: aPoint - ( 0@-1)) ifTrue: [ num _ num + 1 ]. (self isSetAt: aPoint - ( 1@-1)) ifTrue: [ num _ num + 1 ]. (self isSetAt: aPoint - (-1@ 0)) ifTrue: [ num _ num + 1 ]. (self isSetAt: aPoint - ( 1@ 0)) ifTrue: [ num _ num + 1 ]. (self isSetAt: aPoint - (-1@ 1)) ifTrue: [ num _ num + 1 ]. (self isSetAt: aPoint - ( 0@ 1)) ifTrue: [ num _ num + 1 ]. (self isSetAt: aPoint - ( 1@ 1)) ifTrue: [ num _ num + 1 ]. ^num ! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! LifeMap class instanceVariableNames: ''! !LifeMap class methodsFor: 'class initialization' stamp: 'tak 3/16/2003 20:45'! new: aPoint | lifeMap | lifeMap _ self new. lifeMap new: aPoint. ^lifeMap.! ! Morph subclass: #LifeMorph instanceVariableNames: 'map cellSize life ' classVariableNames: '' poolDictionaries: '' category: 'Life'! !LifeMorph commentStamp: 'tak 3/16/2003 23:58' prior: 0! LifeMorph new openInHand! !LifeMorph methodsFor: 'initialization' stamp: 'tak 6/23/2003 17:44'! initialize super initialize. map _ LifeMap new: 20 @ 20. life _ 0. cellSize _ 10 @ 10. self extent: (map width @ map height) * cellSize! ! !LifeMorph methodsFor: 'drawing' stamp: 'tak 3/16/2003 23:30'! drawOn: aCanvas 1 to: map width do: [:x | 1 to: map height do: [:y | | r | r _ ((x - 1) @ (y - 1)) * cellSize + self topLeft extent: 10 @ 10. (map isSetAt: x @ y) ifTrue: [aCanvas fillRectangle: r color: Color black] ifFalse: [aCanvas fillRectangle: r color: Color white]]]! ! !LifeMorph methodsFor: 'stepping and presenter' stamp: 'tak 6/23/2003 16:30'! step life < 0 ifTrue: [map random. life _ 50] ifFalse: [map step. life _ life - 1]. self changed! ! !LifeMorph methodsFor: 'stepping and presenter' stamp: 'tak 6/23/2003 16:30'! stepTime ^ 200! ! TestCase subclass: #LifeTest instanceVariableNames: 'lifeMap ' classVariableNames: '' poolDictionaries: '' category: 'Life'! !LifeTest commentStamp: 'tak 3/16/2003 20:50' prior: 0! TestRunner open ! !LifeTest methodsFor: 'Testing' stamp: 'tak 3/16/2003 21:58'! testDeadOrAlive | cell | self assert: LifeCell alive isSet. self assert: LifeCell dead isSet not. cell _ LifeCell alive. self assert: (cell nextWhen: 2) isSet. self assert: (cell nextWhen: 3) isSet. self assert: (cell nextWhen: 4) isSet not. cell _ LifeCell dead. self assert: (cell nextWhen: 2) isSet not. self assert: (cell nextWhen: 3) isSet. self assert: (cell nextWhen: 4) isSet not. ! ! !LifeTest methodsFor: 'Testing' stamp: 'tak 3/16/2003 21:20'! testNumber " Get environment " lifeMap setAt: 1@1. lifeMap setAt: 1@3. lifeMap setAt: 3@1. lifeMap setAt: 3@3. self assert: (lifeMap numAt: 2@2) = 4. ! ! !LifeTest methodsFor: 'Testing' stamp: 'tak 3/16/2003 22:04'! testSet self assert: (lifeMap width = 10). self assert: (lifeMap height = 10). lifeMap setAt: 5@5. self assert: (lifeMap isSetAt: 5@5). lifeMap unsetAt: 5@5. self assert: (lifeMap isSetAt: 5@5) not. ! ! !LifeTest methodsFor: 'Testing' stamp: 'tak 3/16/2003 22:42'! testStepFrom2 " If 2 cells alive around, the cell do not change " lifeMap setAt: 1@1. lifeMap setAt: 2@2. lifeMap setAt: 3@3. lifeMap step. self assert: (lifeMap isSetAt: 2@2). lifeMap clear. lifeMap setAt: 1@1. lifeMap unsetAt: 2@2. lifeMap setAt: 3@4. lifeMap step. self assert: (lifeMap isSetAt: 2@2) not. ! ! !LifeTest methodsFor: 'Testing' stamp: 'tak 3/16/2003 21:30'! testStepFrom3 " If 3 cells alive around, new cell will birth. " lifeMap setAt: 1@1. lifeMap setAt: 1@3. lifeMap setAt: 3@3. lifeMap step. self assert: (lifeMap isSetAt: 2@2). ! ! !LifeTest methodsFor: 'Testing' stamp: 'tak 3/16/2003 21:30'! testStepFrom4 " If 4 cells alive around, new cell will birth. " lifeMap setAt: 1@1. lifeMap setAt: 1@3. lifeMap setAt: 2@2. lifeMap setAt: 3@1. lifeMap setAt: 3@3. lifeMap step. self assert: (lifeMap isSetAt: 2@2) not. ! ! !LifeTest methodsFor: 'Running' stamp: 'tak 3/16/2003 20:52'! setUp lifeMap _ LifeMap new: 10@10. ! ! LifeCell initialize!