Skip to content

Commit dde2939

Browse files
authored
Merge pull request #36 from HossamSaberr/feature-wrap-neighbors
Feat: Add wrap and neighbor access methods for grid logic
2 parents ce2e0aa + b97ed14 commit dde2939

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed

src/Containers-Array2D-Tests/CTArray2DTest.class.st

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,34 @@ CTArray2DTest >> testAtColumnPut [
8787
1 to: foo height do: [ :y | self assert: (foo atColumn: 2 atRow: y) equals: 1 ]
8888
]
8989

90+
{ #category : 'tests-accessing' }
91+
CTArray2DTest >> testAtColumnWrapAtRowWrap [
92+
93+
| array |
94+
array := self arrayClass width2Height3.
95+
96+
self assert: (array atColumnWrap: 1 atRowWrap: 1) equals: 1.
97+
98+
self assert: (array atColumnWrap: 3 atRowWrap: 1) equals: 1.
99+
100+
self assert: (array atColumnWrap: 2 atRowWrap: 4) equals: 2.
101+
102+
self assert: (array atColumnWrap: 0 atRowWrap: 0) equals: 6.
103+
]
104+
105+
{ #category : 'tests-accessing' }
106+
CTArray2DTest >> testAtColumnWrapAtRowWrapPut [
107+
108+
| array |
109+
array := self arrayClass width2Height3.
110+
111+
array atColumnWrap: 3 atRowWrap: 2 put: 99.
112+
self assert: (array atColumn: 1 atRow: 2) equals: 99.
113+
114+
array atColumnWrap: 0 atRowWrap: 0 put: 88.
115+
self assert: (array atColumn: 2 atRow: 3) equals: 88.
116+
]
117+
90118
{ #category : 'tests-accessing' }
91119
CTArray2DTest >> testAtPut [
92120

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

347+
{ #category : 'tests-accessing' }
348+
CTArray2DTest >> testNeighborsAtColumnAtRow [
349+
350+
| array neighbors topCornerNeighbors |
351+
array := self arrayClass width2Height3.
352+
353+
neighbors := array neighborsAtColumn: 1 atRow: 2.
354+
self assert: neighbors size equals: 5.
355+
self assert: (neighbors includesAll: #(1 2 4 5 6)).
356+
357+
topCornerNeighbors := array neighborsAtColumn: 1 atRow: 1.
358+
self assert: topCornerNeighbors size equals: 3.
359+
self assert: (topCornerNeighbors includesAll: #(2 3 4)).
360+
]
361+
362+
{ #category : 'tests' }
363+
CTArray2DTest >> testNeighborsAtColumnAtRowOutOfBounds [
364+
365+
| array |
366+
367+
array := self arrayClass width2Height3.
368+
369+
self should: [ array neighborsAtColumn: 99 atRow: 99 ] raise: Error.
370+
]
371+
372+
{ #category : 'tests' }
373+
CTArray2DTest >> testNeighborsAtColumnWrapAtRowWrap [
374+
375+
| array neighbors |
376+
377+
array := self arrayClass fromArray: #(1 2 3 4 5 6 7 8 9) width: 3.
378+
379+
neighbors := array neighborsAtColumnWrap: 1 atRowWrap: 1.
380+
381+
self assert: neighbors size equals: 8.
382+
self assert: (neighbors includesAll: #(2 3 4 5 6 7 8 9)).
383+
]
384+
385+
{ #category : 'tests' }
386+
CTArray2DTest >> testNeighborsAtColumnWrapAtRowWrapOutOfBounds [
387+
| array |
388+
389+
array := self arrayClass width2Height3.
390+
391+
self should: [ array neighborsAtColumnWrap: 99 atRowWrap: 99 ] raise: Error.
392+
]
393+
394+
{ #category : 'tests-accessing' }
395+
CTArray2DTest >> testNeighborsEight [
396+
397+
| array neighbors |
398+
array := self arrayClass fromArray: #(1 2 3 4 5 6 7 8 9) width: 3.
399+
400+
neighbors := array neighborsAtColumn: 2 atRow: 2.
401+
402+
self assert: neighbors size equals: 8.
403+
self assert: (neighbors includesAll: #(1 2 3 4 6 7 8 9)).
404+
]
405+
319406
{ #category : 'tests-printing' }
320407
CTArray2DTest >> testPrinting [
321408

src/Containers-Array2D/CTArray2D.class.st

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,28 @@ CTArray2D >> atColumn: x put: aCollection [
193193
^ aCollection
194194
]
195195

196+
{ #category : 'accessing' }
197+
CTArray2D >> atColumnWrap: col atRowWrap: row [
198+
"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."
199+
200+
| wrappedCol wrappedRow |
201+
wrappedCol := ((col - 1) \\ self width) + 1.
202+
wrappedRow := ((row - 1) \\ self height) + 1.
203+
204+
^ self atColumn: wrappedCol atRow: wrappedRow
205+
]
206+
207+
{ #category : 'accessing' }
208+
CTArray2D >> atColumnWrap: col atRowWrap: row put: aValue [
209+
"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)."
210+
211+
| wrappedCol wrappedRow |
212+
wrappedCol := ((col - 1) \\ self width) + 1.
213+
wrappedRow := ((row - 1) \\ self height) + 1.
214+
215+
^ self atColumn: wrappedCol atRow: wrappedRow put: aValue
216+
]
217+
196218
{ #category : 'accessing rows/columns' }
197219
CTArray2D >> atRow: y [
198220
"Answer the content of the whole column at y"
@@ -353,6 +375,46 @@ CTArray2D >> isSelfEvaluating [
353375
^ self class == CTArray2D and: [ contents isSelfEvaluating ]
354376
]
355377

378+
{ #category : 'enumerating' }
379+
CTArray2D >> neighborsAtColumn: col atRow: row [
380+
"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."
381+
382+
| neighbors |
383+
384+
(col between: 1 and: self width) ifFalse: [ self error: 'Column out of bounds' ].
385+
(row between: 1 and: self height) ifFalse: [ self error: 'Row out of bounds' ].
386+
387+
neighbors := OrderedCollection new.
388+
389+
row - 1 to: row + 1 do: [ :r |
390+
col - 1 to: col + 1 do: [ :c |
391+
(r = row and: [ c = col ]) ifFalse: [
392+
(r between: 1 and: self height) ifTrue: [
393+
(c between: 1 and: self width) ifTrue: [
394+
neighbors add: (self atColumn: c atRow: r) ] ] ] ] ].
395+
396+
^ neighbors
397+
]
398+
399+
{ #category : 'enumerating' }
400+
CTArray2D >> neighborsAtColumnWrap: col atRowWrap: row [
401+
"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."
402+
403+
| neighbors |
404+
405+
(col between: 1 and: self width) ifFalse: [ self error: 'Column out of bounds' ].
406+
(row between: 1 and: self height) ifFalse: [ self error: 'Row out of bounds' ].
407+
408+
neighbors := OrderedCollection new.
409+
410+
row - 1 to: row + 1 do: [ :r |
411+
col - 1 to: col + 1 do: [ :c |
412+
(r = row and: [ c = col ]) ifFalse: [
413+
neighbors add: (self atColumnWrap: c atRowWrap: r) ] ] ].
414+
415+
^ neighbors
416+
]
417+
356418
{ #category : 'accessing - compatibility' }
357419
CTArray2D >> numberOfColumns [
358420
"Answer the receiver's width, i.e., its number of x"

0 commit comments

Comments
 (0)