Silverback9

#야생으로

Creative Coding 독학 제203일 2024년10월16일(수)

오늘은 <우리의 알갱이>가 자연스럽게 내려오도록 프로그램을 개선해 보겠습니다~~^^* YEAH~~!!

<우리의 알갱이>는

(1) 자신의 바로 아래가 비어 있으면 거기에 안착한다~

(2) 자신의 바로 아래에 다른 알갱이가 있으면

(3) 그 알갱이 오른쪽을 살펴 그곳이 비어 있으면 거기에 안착한다~

(4) 그 알갱이 오른쪽에 다른 알갱이가 있으면 

(5) 그 알갱이 왼쪽을 살펴 그 곳이 비어 있으면 거기에 안착한다~

의 순서로 안착할 장소를 찾게 되지요?^^*

그러다 보니, <우리의 알갱이>가 오른쪽에 먼저 안착하는 패턴을 보이게 되는 것 같아요.

<자연스러움>은? <반복>에 <임의성>이 함께 할 때 발생하는 것 같은데요~~^^*

자리찾기 절차 (1)->(2)->(3)->(4)->(5)는 충실하게 반복하면서도!!!

<오른쪽 먼저 살피고 왼쪽 살피기>
->
<둘 중의 하나를 먼저 살피고 다른 하나를 살피기>

로 우선순위 규칙을 살짝 바꾸어 임의성을 더해 보면 어떨까요^^*?

근데…살펴 볼 두 자리를 오른쪽 왼쪽으로 정의하는 것을 계속하면,

자리찾기 절차 (1)->(2)->(3)->(4)->(5)가 좀더 복잡한 절차로 바뀌어야 할 것 같아요..

음….

자리찾기 절차 (1)->(2)->(3)->(4)->(5)를 유지하면서도, <오른쪽 – 왼쪽>을 <하나 – 다른 하나>로 바꿀 수 있는 방법이 있을까요?

음…

네…?

오….?

아……!

아 네….!

오…신선해요!

신선한 발상의 전환이예요!

< 아래오른쪽 grid[ i + 1 ][ j + 1 ] 아래왼쪽 grid[ i – 1 ][ j + 1 ] >을

< 아래A grid[ i + dir ][ j + 1 ] 아래B grid[ i – dir ][ j + 1 ] >의 형태로 바꾸고,

dir에 -1 또는 1의 값을 임의적으로 부여하면 되겠네요!!!

dir가 1이면,

아래A grid[i + dir][j+1] 은 grid[i + 1][j+1] : 오른쪽

아래B grid[i - dir][j+1]은 grid[i - 1][j+1] : 왼쪽

dir가 -1이면,

아래A grid[i + dir][j+1] 은 grid[i -1][j+1] : 왼쪽

아래B grid[i - dir][j+1]은 grid[i + 1][j+1] : 오른쪽

이 되네요.

아래A를 먼저 살피고 아래B를 살핀다는 것이

<오른쪽 먼저 왼쪽 다음>을 의미할 수도 있고

<왼쪽 먼저 오른쪽 다음>을 의미할 수도 있는

임의성을 가지게 되는 것 같아요!!!

그러면, 자리찾기 절차는

(1) 자신의 바로 아래가 비어 있으면 거기에 안착한다~

(2) 자신의 바로 아래에 다른 알갱이가 있으면

(3) 아래A를 살펴 그곳이 비어 있으면 거기에 안착한다~

(4) 아래A에 다른 알갱이가 있으면

(5) 아래B를 살펴 그 곳이 비어 있으면 거기에 안착한다~

의 순서로 안착할 장소를 찾게 되는 것이지요?^^*

그래서!!!

자리찾기 절차의 <반복>은 유지가 되면서~

오른쪽 왼쪽 우선순위에 <임의성>이 생겨나서~

자연스러움이 발생할 것 같아요!!!

그럼 이 아이디어를 코드로 표현해 볼까요~~^^*

아참!! 아래A와 아래B가 화면 안에 있을 때에만 grid[][]의 구성요소를 저장하도록 하는 안전장치도 잊지 말기로 해요~~, 우리~~^^*

let dir = 1;
if(random(1) < 0.5) {
dir *= -1;
}

let belowA;
let belowB;

if ( i + dir >= 0 && i + dir <= cols - 1) {
   belowA = grid[ i + dir ][ j + 1 ];
}
if ( i - dir >= 0 && i - dir <= cols - 1) {
   belowB = grid[ i - dir ][ j + 1 ];
}
 if (below === 0) { 
          nextGrid[i][j + 1] = 1; 
        }
        else if (belowA === 0) {       
          nextGrid[i + dir][j+1] = 1; 
        }
        else if (belowB === 0) {
         nextGrid[i - dir][j+1] = 1;   
        } 
        else {       
         nextGrid[i][j] = 1; 
        }
      }
    }
  }
grid = nextGrid;

음…이제 전체 코드를 살펴 보실 마음의 준비가 되셨나요~~^^* 두둥~~^^* 콩닥콩닥~~^^*

function make2DArray(cols, rows) {
  let arr = new Array(cols);
  for (let i = 0; i < arr.length; i++) {
    arr[i] = new Array(rows);
    for (let j = 0; j < arr[i].length; j++) {
      arr[i][j] = 0;
    }
  }
  return arr;
  //새까맣게 채워진 모눈 종이를 return합니다. 
}

function mouseDragged() {
  let col = floor(mouseX / resolution);
  let row = floor(mouseY / resolution);
  
  if(col >= 0 && col <= cols-1 && row >= 0 && row <= rows-1) {
  grid[col][row] = 1; 
  }
  
  
  //마우스가 클릭되면 자동적으로 작동되는 함수입니다~~^^*
  //메인 함수에서 따로 호출할 필요가 없어요~~^^*
  //mouseX, mouseY가 위치하는 화면 위치 좌표를 resoultion으로 나눈 후 그 몫의 정수 부분만 취하면, 해당 위치에 자리한 grid배열의 구성요소를 알 수 있을 것 같아요~^^*
  //마우스의 위치가 화면 안에 있을 때만 grid배열의 구성요소를 찾아 값을 1 저장하겠습니다. 
  //메인 함수의 색칠하는 for 구문 안에서 흰 색으로 표현되겠지요~^^* 
} 


let grid;
let cols;
let rows;
let resolution = 10;

function setup() {
  createCanvas(400, 400);
  cols = width / resolution;
  rows = height / resolution;

  grid = make2DArray(cols, rows);
  //지금 단계 까만 모눈 종이 준비~~^^*
  
}

function draw() {
  background(0);
   
  let nextGrid = make2DArray(cols, rows);
  //다음 단계 까만 모눈 종이 준비~~^^*

  for (let i = 0; i < cols; i++){
    for (let j = 0; j < rows; j++) {
      let state = grid[i][j]; //지금 단계 상태 저장~
      if (state === 1) { //이 칸이 하얗다면~~^^*
        let below = grid[i][j+1]; //바로 아래 칸을 찾아서~
        
        let dir = 1;
        if(random(1) < 0.5) {
          dir *= -1;
        }
        
        let belowA;
        let belowB;
        if ( i + dir >= 0 && i + dir <= cols - 1) {
          belowA = grid[ i + dir ][ j + 1 ];
        }
        if ( i - dir >= 0 && i - dir <= cols - 1) {
          belowB = grid[ i - dir ][ j + 1 ];
        }
        //오른쪽 왼쪽 임의적으로, 위치좌표가 화면 안쪽에 있을 때만, 아래A와 아래B가 grid[][] 구성요소를 저장해요~^^*
        
        
        
        if (below === 0) { //바로 아래 칸이 까맣다면~~^^*
          nextGrid[i][j + 1] = 1; //바로 아래 칸을 하얗게~^^*
        }
        else if (belowA === 0) {
        //바로 아래 칸은 희지만 아래A 칸이 까맣다면~~^^*
          nextGrid[i + dir][j+1] = 1; //알갱이의 바로 아래A 칸을 하얗게~^^*
        }
        else if (belowB === 0) {
        //바로 아래 칸도 희고, 아래A 칸도 희지만, 아래B 칸은 까맣다면~~^^*
         nextGrid[i - dir][j+1] = 1; //알갱이의 아래B 칸을 하얗게~^^*   
        } 
        else {
        //그렇지 않을 때, 즉, 
        //바로 아래 칸도 아래A 칸도 그 아래B 칸도 희거나 
        //바래 아래 칸이 존재하지 않을 때 
         nextGrid[i][j] = 1; //알갱이의 현재 자리를 하얗게~^^*
        }
      }
    }
  }

grid = nextGrid; //다음 단계 모눈 종이 상태를 지금 단계 모눈 종이에 저장~

  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      
      let x = i * resolution;
      let y = j * resolution;
      
      fill(grid[i][j] * 255); 
      //grid[i][j]값이 1이면 1*255 = 255 즉, 흰색으로 채웁니다.
      //grid[i][j]값이 0이면 0*255 = 0 즉, 검은색으로 채웁니다.
      stroke(255);
      square(x, y, resolution); 
       
    }
  }
  //마우스 클릭 한 곳의 알갱이가 하얗게 변하나요? ^^*
  //그리고 그 아래칸들이 차례로 하얗게 까맣게 변화되나요?^^*
  //하얀 알갱이가 까만 하늘에서 내려오는 것처럼 보이나요?^^*
  //하얀 알갱이가 바닥에 가만히 머무르나요?^^*
  //하얀 알갱이가 마른 모래 언덕처럼 부드럽게 쌓이나요? 
  //마우스가 왼쪽 가장자리 오른쪽 가장자리 가더라도 프로그램이 계속 되나요?
  //마우스로 한 곳을 천천히 오래 드래그해도 프로그램이 계속 되나요? 
  //알갱이가 왼쪽 오른쪽 임의적으로 자연스럽게 쌓이나요?^^*
}

자연스럽게 쌓이는 마른 모래 언덕을 보러 갈까요~~^^*

사계절 반복되는 기후와 임의적으로 변화되는 날씨, 예상가능한 하루의 일상과 예상치 못한 사건의 등장. 반복과 임의성은 우리의 삶을 자연스럽게 만드는 것 같아요~^^*

똑같은 크기의 휴대폰 통화음도, 조용한 곳에서는 엄청 크게 들리고, 지하철이 달려 들어오는 곳에서는 엄청 작게 들리는 것처럼, 사물의 일정한 반복성과 그때그때 다른 환경요소의 변화는 우리의 삶의 순간을 다양하게 느끼고 기억하게 만드는 것 같아요.

어느 한 순간을 박제하여, 그 순간 속의 대상에 대한 경험과 느낌을 그 대상에 대한 영원한 경험과 느낌으로 확정하는 것은, 그 대상에 대한 자연스러운 이해를 잃어버리는 결과가 되는 것 같기도 하네요.

우리 환경의 수많은 요소들, 우리가 만나거나 스쳐 지나가는 수많은 사물과 사람들 모두 각자의 <반복>와 <임의성>을 발휘하며 또는 체험하며 <존재의 자연스러움>을 충실하게 실천하고 있을 것 같아요.

순간을 영원으로 생각하지 않고 자연스러운 변화 속의 아름답고 소중한 순간으로 감사하고 싶어지는 날이예요~~^^*

삶의 축제를 오늘도 이 세상에 선사하며 자연스러움 한 스푼을 기여해 보고 싶어요~~^^*

오늘 저와 함께 자연스러워서 행복해 지는 마른 모래 언덕을 쌓아 주셔서 감사합니다~~^^*

오늘도

자연스럽고 행복한 아침!

자연스럽고 행복한 하루!

보내시고요!

아참! 근데요~^^* 모래를 한 알갱이 한 알갱이 뿌리려니 좀 답답하시지 않으셔요?

그럼 우리 내일은 한 스쿱 한 스쿱 시원하게 뿌려볼까요~~^^*

네~~^^* 내일 우리 또 만나서 도전! 계속 이어가면 좋겠어요~~!!!

네~~!!! 꿈은 이루어 집니다~~!!

댓글 남기기