오늘은! 가장자리에 있는 <우리의 세포>에게 이웃 세포를 찾아 주는 날이예요~~!!!
YEAH~~!!!
<우리의 세포> grid[ i ][ j ]의
왼쪽 이웃은 [ i – 1 ][ j ]이고 오른쪽 이웃은 [ i + 1 ][ j ]인데요…
위쪽 이웃은 [ i ][ j – 1 ]이고 아래쪽 이웃은 [ i ][ j + 1 ]인데요…
- cols: 세로기둥 총 갯수 (x축 배열 구성원 총 갯수)
- rows: 칸 총 갯수 rows (y축 배열 구성원 총 갯수)
<우리의 세포>가
왼쪽 가장자리 grid[0][j]에 있으면,
왼쪽에 아무도 없으니까...
가로줄 제일 끝에 있는 세포 grid[cols-1][j]를
오른쪽 가장자리 grid[cols -1][j]에 있으면,
오른쪽에 아무도 없으니까...
가로줄 제일 앞에 있는 세포 grid[0][j]를
위쪽 가장자리 grid[i][0]에 있으면,
위쪽에 아무도 없으니까...
세로줄 제일 끝에 있는 세포 grid[i][rows-1]을
아래쪽 가장자리 grid[i][rows-1]에 있으면,
아래쪽에 아무도 없으니까...
세로줄 제일 앞에 있는 세포 grid[i][0]을
이웃세포로 연결해 줄게요~^^*
지난 번 일차원 배열의 가장자리 구성요소의 이웃을 찾아 주던 작업이 혹시 기억나시나요?
그때 우리는 나머지 연산자의 유용성에 깜짝! 놀랐었는데요~~^^*
A라는 수에 B라는 수를 더한 후 B로 나눈 나머지 값은 항상 A가 된다!
(1 + 5) % 5 = 1 (6 / 5 의 몫은 1이고 나머지는 1이다)
(2 + 7) % 7 = 2 (9 / 7 의 몫은 1이고 나머지는 2이다)
이 원리를 이용해서, 왼쪽 이웃 -오른쪽 이웃 – 위쪽 이웃 – 아래쪽 이웃을 구할 수 있을 것 같아요.
- cols: 세로기둥 총 갯수 (x축 배열 구성원 총 갯수)
- rows: 칸 총 갯수 rows (y축 배열 구성원 총 갯수)
(1) 왼쪽 이웃은 grid[ ( ( i – 1 ) + cols ) % cols ][ j ]
x축 배열 구성원이 10개인 경우
x축 배열 맨 앞 구성원인 grid[ 0 ][ j ]의
왼쪽 이웃
= grid[(0 - 1 + 10) % 10][j]
= grid[9 % 10][j]
= grid[9][j]
= x축 배열 맨 마지막 구성원
(2) 오른쪽 이웃은 grid[ ( ( i + 1 ) + cols ) % cols ][ j ]
x축 배열 구성원이 10개인 경우
x축 배열 맨 뒤 구성원인 grid[ 9 ][ j ]의
오른쪽 이웃
= grid[( 9 + 1 + 10 ) % 10][j]
= grid[20 % 10][j]
= grid[0][j]
= x축 배열 맨 앞 구성원
(3) 위쪽 이웃은 grid[ i ][( ( j – 1 ) + rows ) % rows ]
y축 배열 구성원이 10개인 경우
y축 배열 맨 앞 구성원인 grid[ i ][ 0 ]의
위쪽 이웃
= grid[i][(0 - 1 + 10) % 10]
= grid[i][9 % 10]
= grid[i][9]
= y축 배열 맨 아래 구성원
(4) 아래쪽 이웃은 grid[ i ][ ( ( j + 1 ) + rows ) % rows ]
y축 배열 구성원이 10개인 경우
y축 배열 맨 뒤 구성원인 grid[ i ][ 9 ]의
아래쪽 이웃
= grid[i][( 9 + 1 + 10) % 10]
= grid[i][20 % 10]
= grid[i][0]
= y축 배열 맨 위 구성원
이 과정을 살펴 보니, grid[i][j]의 이웃세포는 나눗셈 연산을 하여 구할 수 있고, 맨 앞 구성원과 맨 뒤 구성원이 서로 연결되어 진다는 것을 다시금 확인할 수 있는 것 같아요!
그러면 우리, 살아있는 이웃세포의 총 합을 구하는 함수 countNeighbor( )를 개선해 볼까요?
function countNeighbors(grid, x, y) {
let sum = 0;
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
let col = (x + i + cols) % cols;
let row = (y + j + rows) % rows;
sum += grid[col][row];
}
}
sum -= grid[x][y];
return sum;
}
와우!! 드디어 전체 코드를 완성해서 프로그램을 실행해 볼 수 있을 것 같아요~~^^*
function make2DArray(cols, rows) {
let arr = new Array(cols);
for (let i = 0; i < arr.length; i++) {
arr[i] = new Array(rows);
}
return arr;
}
let grid;
let cols;
let rows;
let resolution = 10;
function setup() {
createCanvas(600, 400);
cols = width / resolution;
rows = height / resolution;
grid = make2DArray(cols, rows);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
grid[i][j] = floor(random(2));
}
}
}
function draw() {
background(0);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
let x = i * resolution;
let y = j * resolution;
if (grid[i][j] == 1) {
fill(255);
stroke(0);
rect(x, y, resolution - 1, resolution - 1);
}
}
}
let next = make2DArray(cols, rows);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
let state = grid[i][j];
// Count live neighbors!
let sum = 0;
let neighbors = countNeighbors(grid, i, j);
if (state == 0 && neighbors == 3) {
next[i][j] = 1;
} else if (state == 1 && (neighbors < 2 || neighbors > 3)) {
next[i][j] = 0;
} else {
next[i][j] = state;
}
}
}
grid = next;
}
function countNeighbors(grid, x, y) {
let sum = 0;
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
let col = (x + i + cols) % cols;
let row = (y + j + rows) % rows;
sum += grid[col][row];
}
}
sum -= grid[x][y];
return sum;
}
이제 가장자리 이웃들이 서로를 만나서 아름다운 모눈종이 풍경을 완성하는 Game of Life를 감상하러 저와 함께 가실까요~^^*
가장자리의 이웃들이 서로의 이웃이 되어주는 아름다운 관계! 나머지 연산자가 완성시킨 이 아름다운 관계가 Game of Life 전체 풍경을 참 자연스럽게 보이도록 만들어 주네요.
관심사가 같다면, 세상 가장자리에 있어도 반대편 가장자리에 있는 이웃을 만나, 아름다운 대화를 나눌 수 있다는 것. 그것이 나머지 연산자의 힘이고, 언어의 힘이고, 통신의 힘이고, 교통의 힘인 것 같아요~^^*
우리들의 나머지 연산자 %도 감사하고,
어떤 것에 관심을 가지게 된 계기들도 감사하고,
이 관심을 키워나갈 수 있도록 도와주시는 가족과 이웃과 친구와 선생님도 감사하고,
이 관심을 표현할 수 있도록 도와주는 모국어도 외국어들도 감사하고,
지구 반대편 친구와 토론을 즐겁게 나눌 수 있도록 도와주는 인터넷 통신도 감사하고,
지구 곳곳 친구들을 직접 만날 수 있도록 도와주는 세계 교통 체계도 새삼 감사하네요~^^*
네~^^* 그렇죠~~^^*
맞아요~^^*
자신의 관심사를 나눌 땐, 마음이 즐겁고 편안하고 활발해져서, 말도 술술 나오죠~^^*
네~~^^* 저도 그래요~~^^*
우리는
관심사에 대한 자신의 기량을 키워서,
지구 친구들과의 대화와 토론의 즐거움을 넘어,
세상의 문제를 해결하는 데 실질적인 기여를 할 수 있는 순간들을
항상 꿈꾸게 되는데요~^^*
오늘 Game of Life 프로그램을 완성하고 나니,
우리 각자의 그리고/또는 공통된 관심사의
거대한 지구 생태계 속에서,
지구 친구들과 생명력을 함께 나누는 모습도
컴퓨터 화면 위에 펼쳐지고 있는 것 같아서 참 기분이 좋은데요~^^*
세상과 관심사를 나누고 또 관심사를 통해서 세상에 기여할 수 있다는 믿음과 감사함이 한 층 더 쌓이는 것 같아요^^*
오늘 저와 함께 Game of Life를 완성해 주셔서 감사합니다!
내일 우리 또 만나서, 코딩 공부 함께 할까요~~^^*
그 무엇도 우리의 코딩 공부를 멈출 수는 없으니까요! YEAH!!!
오늘도 맛있는 점심 드시고요!! 멋진 하루 보내시고요!!
내일 우리 또 다시 만나요!!
네!! 꿈은 이루어 집니다!!
댓글 남기기