From 87df204791f0a52463551bcc633c0ddfb1bc7ac3 Mon Sep 17 00:00:00 2001 From: HossamSaberr Date: Tue, 10 Mar 2026 09:11:03 +0200 Subject: [PATCH 1/2] Add wrap and neighbor access methods for grid logic --- .../CTArray2DTest.class.st | 55 +++++++++++++++++++ src/Containers-Array2D/CTArray2D.class.st | 36 ++++++++++++ 2 files changed, 91 insertions(+) diff --git a/src/Containers-Array2D-Tests/CTArray2DTest.class.st b/src/Containers-Array2D-Tests/CTArray2DTest.class.st index b7752ee..0e4c59f 100644 --- a/src/Containers-Array2D-Tests/CTArray2DTest.class.st +++ b/src/Containers-Array2D-Tests/CTArray2DTest.class.st @@ -87,6 +87,34 @@ CTArray2DTest >> testAtColumnPut [ 1 to: foo height do: [ :y | self assert: (foo atColumn: 2 atRow: y) equals: 1 ] ] +{ #category : 'tests-accessing' } +CTArray2DTest >> testAtColumnWrapAtRowWrap [ + + | array | + array := self arrayClass width2Height3. + + self assert: (array atColumnWrap: 1 atRowWrap: 1) equals: 1. + + self assert: (array atColumnWrap: 3 atRowWrap: 1) equals: 1. + + self assert: (array atColumnWrap: 2 atRowWrap: 4) equals: 2. + + self assert: (array atColumnWrap: 0 atRowWrap: 0) equals: 6. +] + +{ #category : 'tests-accessing' } +CTArray2DTest >> testAtColumnWrapAtRowWrapPut [ + + | array | + array := self arrayClass width2Height3. + + array atColumnWrap: 3 atRowWrap: 2 put: 99. + self assert: (array atColumn: 1 atRow: 2) equals: 99. + + array atColumnWrap: 0 atRowWrap: 0 put: 88. + self assert: (array atColumn: 2 atRow: 3) equals: 88. +] + { #category : 'tests-accessing' } CTArray2DTest >> testAtPut [ @@ -236,6 +264,33 @@ CTArray2DTest >> testLeftToRightFromBottomToTopDo [ ] +{ #category : 'tests-accessing' } +CTArray2DTest >> testNeighborsAtColumnAtRow [ + + | array neighbors topCornerNeighbors | + array := self arrayClass width2Height3. + + neighbors := array neighborsAtColumn: 1 atRow: 2. + self assert: neighbors size equals: 5. + self assert: (neighbors includesAll: #(1 2 4 5 6)). + + topCornerNeighbors := array neighborsAtColumn: 1 atRow: 1. + self assert: topCornerNeighbors size equals: 3. + self assert: (topCornerNeighbors includesAll: #(2 3 4)). +] + +{ #category : 'tests-accessing' } +CTArray2DTest >> testNeighborsEight [ + + | array neighbors | + array := self arrayClass fromArray: #(1 2 3 4 5 6 7 8 9) width: 3. + + neighbors := array neighborsAtColumn: 2 atRow: 2. + + self assert: neighbors size equals: 8. + self assert: (neighbors includesAll: #(1 2 3 4 6 7 8 9)). +] + { #category : 'tests-printing' } CTArray2DTest >> testPrinting [ diff --git a/src/Containers-Array2D/CTArray2D.class.st b/src/Containers-Array2D/CTArray2D.class.st index f81d77c..44212fb 100644 --- a/src/Containers-Array2D/CTArray2D.class.st +++ b/src/Containers-Array2D/CTArray2D.class.st @@ -193,6 +193,26 @@ CTArray2D >> atColumn: x put: aCollection [ ^ aCollection ] +{ #category : 'accessing' } +CTArray2D >> atColumnWrap: col atRowWrap: row [ + + | wrappedCol wrappedRow | + wrappedCol := ((col - 1) \\ self width) + 1. + wrappedRow := ((row - 1) \\ self height) + 1. + + ^ self atColumn: wrappedCol atRow: wrappedRow +] + +{ #category : 'accessing' } +CTArray2D >> atColumnWrap: col atRowWrap: row put: aValue [ + + | wrappedCol wrappedRow | + wrappedCol := ((col - 1) \\ self width) + 1. + wrappedRow := ((row - 1) \\ self height) + 1. + + ^ self atColumn: wrappedCol atRow: wrappedRow put: aValue +] + { #category : 'accessing rows/columns' } CTArray2D >> atRow: y [ "Answer the content of the whole column at y" @@ -301,6 +321,22 @@ CTArray2D >> leftToRightFromBottomToTopDo: aBlock [ aBlock value: (self atColumn: col atRow: row)]] ] +{ #category : 'enumerating' } +CTArray2D >> neighborsAtColumn: col atRow: row [ + + | neighbors | + neighbors := OrderedCollection new. + + row - 1 to: row + 1 do: [ :r | + col - 1 to: col + 1 do: [ :c | + (r = row and: [ c = col ]) ifFalse: [ + (r between: 1 and: self height) ifTrue: [ + (c between: 1 and: self width) ifTrue: [ + neighbors add: (self atColumn: c atRow: r) ] ] ] ] ]. + + ^ neighbors +] + { #category : 'accessing - compatibility' } CTArray2D >> numberOfColumns [ "Answer the receiver's width, i.e., its number of x" From 115bf2cdab0fc3930580e741c3ae1139238e3399 Mon Sep 17 00:00:00 2001 From: HossamSaberr Date: Thu, 26 Mar 2026 10:23:37 +0200 Subject: [PATCH 2/2] Add wrapped neighbors and enforce bounds checking for neighbor --- .../CTArray2DTest.class.st | 32 +++++++++++++++++++ src/Containers-Array2D/CTArray2D.class.st | 28 ++++++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/Containers-Array2D-Tests/CTArray2DTest.class.st b/src/Containers-Array2D-Tests/CTArray2DTest.class.st index 0e4c59f..52c26b2 100644 --- a/src/Containers-Array2D-Tests/CTArray2DTest.class.st +++ b/src/Containers-Array2D-Tests/CTArray2DTest.class.st @@ -279,6 +279,38 @@ CTArray2DTest >> testNeighborsAtColumnAtRow [ self assert: (topCornerNeighbors includesAll: #(2 3 4)). ] +{ #category : 'tests' } +CTArray2DTest >> testNeighborsAtColumnAtRowOutOfBounds [ + + | array | + + array := self arrayClass width2Height3. + + self should: [ array neighborsAtColumn: 99 atRow: 99 ] raise: Error. +] + +{ #category : 'tests' } +CTArray2DTest >> testNeighborsAtColumnWrapAtRowWrap [ + + | array neighbors | + + array := self arrayClass fromArray: #(1 2 3 4 5 6 7 8 9) width: 3. + + neighbors := array neighborsAtColumnWrap: 1 atRowWrap: 1. + + self assert: neighbors size equals: 8. + self assert: (neighbors includesAll: #(2 3 4 5 6 7 8 9)). +] + +{ #category : 'tests' } +CTArray2DTest >> testNeighborsAtColumnWrapAtRowWrapOutOfBounds [ + | array | + + array := self arrayClass width2Height3. + + self should: [ array neighborsAtColumnWrap: 99 atRowWrap: 99 ] raise: Error. +] + { #category : 'tests-accessing' } CTArray2DTest >> testNeighborsEight [ diff --git a/src/Containers-Array2D/CTArray2D.class.st b/src/Containers-Array2D/CTArray2D.class.st index 44212fb..0528e98 100644 --- a/src/Containers-Array2D/CTArray2D.class.st +++ b/src/Containers-Array2D/CTArray2D.class.st @@ -323,17 +323,39 @@ CTArray2D >> leftToRightFromBottomToTopDo: aBlock [ { #category : 'enumerating' } CTArray2D >> neighborsAtColumn: col atRow: row [ - + | neighbors | + + (col between: 1 and: self width) ifFalse: [ self error: 'Column out of bounds' ]. + (row between: 1 and: self height) ifFalse: [ self error: 'Row out of bounds' ]. + neighbors := OrderedCollection new. - + row - 1 to: row + 1 do: [ :r | col - 1 to: col + 1 do: [ :c | (r = row and: [ c = col ]) ifFalse: [ (r between: 1 and: self height) ifTrue: [ (c between: 1 and: self width) ifTrue: [ neighbors add: (self atColumn: c atRow: r) ] ] ] ] ]. - + + ^ neighbors +] + +{ #category : 'enumerating' } +CTArray2D >> neighborsAtColumnWrap: col atRowWrap: row [ + + | neighbors | + + (col between: 1 and: self width) ifFalse: [ self error: 'Column out of bounds' ]. + (row between: 1 and: self height) ifFalse: [ self error: 'Row out of bounds' ]. + + neighbors := OrderedCollection new. + + row - 1 to: row + 1 do: [ :r | + col - 1 to: col + 1 do: [ :c | + (r = row and: [ c = col ]) ifFalse: [ + neighbors add: (self atColumnWrap: c atRowWrap: r) ] ] ]. + ^ neighbors ]