Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions src/Containers-Array2D-Tests/CTArray2DTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -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 [

Expand Down Expand Up @@ -316,6 +344,65 @@ CTArray2DTest >> testIndexXY [
self assert: (foo indexX: 2 y: 3) equals: (3-1)*(foo width)+2
]

{ #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' }
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 [

| 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 [

Expand Down
62 changes: 62 additions & 0 deletions src/Containers-Array2D/CTArray2D.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,28 @@ CTArray2D >> atColumn: x put: aCollection [
^ aCollection
]

{ #category : 'accessing' }
CTArray2D >> atColumnWrap: col atRowWrap: row [
"Answer the element at the given coordinates. If the coordinates are outside the grid bounds, they wrap around using 1-based indexing logic to ensure seamless boundary traversal."

| 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 [
"Store the given value at the specified coordinates. If the coordinates are outside the grid bounds, they wrap around using 1-based indexing logic (e.g., in a grid of width 3, column 4 wraps to 1, and column 0 wraps to 3)."

| 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"
Expand Down Expand Up @@ -353,6 +375,46 @@ CTArray2D >> isSelfEvaluating [
^ self class == CTArray2D and: [ contents isSelfEvaluating ]
]

{ #category : 'enumerating' }
CTArray2D >> neighborsAtColumn: col atRow: row [
"Answer a collection of up to 8 valid elements surrounding the given origin. This method does not wrap; neighbors that would fall outside the grid are ignored. Throws an error if the starting origin coordinates are out of bounds."

| 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 [
"Answer a collection of exactly 8 elements surrounding the given origin, wrapping across grid boundaries where necessary. Throws an error if the starting origin coordinates are out of bounds."

| 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
]

{ #category : 'accessing - compatibility' }
CTArray2D >> numberOfColumns [
"Answer the receiver's width, i.e., its number of x"
Expand Down
Loading