# 병 속의 도시 – 256 바이트 레이캐스팅 시스템

> Clean Markdown view of GeekNews topic #14928. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=14928](https://news.hada.io/topic?id=14928)
- GeekNews Markdown: [https://news.hada.io/topic/14928.md](https://news.hada.io/topic/14928.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-05-21T23:35:16+09:00
- Updated: 2024-05-21T23:35:16+09:00
- Original source: [frankforce.com](https://frankforce.com/city-in-a-bottle-a-256-byte-raycasting-system/)
- Points: 3
- Comments: 1

## Topic Body

### City In A Bottle – 256 바이트 레이캐스팅 시스템

- **소개**
  - 오늘은 256 바이트의 HTML 파일에 담긴 작은 레이캐스팅 엔진과 도시 생성기를 소개함.
  - 이 프로그램은 여러 개념을 작은 공간에 담아 퍼즐을 푸는 것처럼 이해할 수 있음.
  - 주요 구성 요소는 HTML 코드, 프레임 업데이트 루프, 렌더링 시스템, 레이캐스팅 엔진, 그리고 도시 자체임.

- **전체 코드**
  - 이 코드는 단순한 JavaScript 스니펫이 아니라 전체 HTML 프로그램임.
  - ```html
    &lt;canvas style=width:99% id=c onclick=setInterval('for(c.width=w=99,++t,i=6e3;i--;c.getContext`2d`.fillRect(i%w,i/w|0,1-d*Z/w+s,1))for(a=i%w/50-1,s=b=1-i/4e3,X=t,Y=Z=d=1;++Z&lt;w&amp;(Y&lt;6-(32&lt;Z&amp;27&lt;X%w&amp;&amp;X/9^Z/8)*8%46||d|(s=(X&amp;Y&amp;Z)%3/Z,a=b=1,d=Z/w));Y-=b)X+=a',t=9)&gt;
    ```

# HTML 코드

- **HTML 코드**
  - HTML 부분은 간단한 캔버스 요소와 onclick 이벤트로 구성됨.
  - ```html
    &lt;canvas style=width:99% id=c onclick=setInterval('',t=9)&gt;
    ```
  - 캔버스 요소의 id는 'c'로 설정되어 JavaScript에서 접근 가능함.
  - onclick 이벤트는 프로그램을 시작하며, setInterval 호출로 업데이트 루프를 생성함.

### JavaScript 코드

- **JavaScript 코드**
  - 캔버스가 클릭될 때 실행되는 199 바이트의 JavaScript 코드.
  - ```javascript
    for(c.width=w=99,++t,i=6e3;i--;c.getContext`2d`.fillRect(i%w,i/w|0,1-d*Z/w+s,1))for(a=i%w/50-1,s=b=1-i/4e3,X=t,Y=Z=d=1;++Z<w&(Y<6-(32<Z&27<X%w&&X/9^Z/8)*8%46||d|(s=(X&Y&Z)%3/Z,a=b=1,d=Z/w));Y-=b)X+=a
    ```

- **코드 분석**
  - 코드를 읽기 쉽게 분해함.
  - ```javascript
    c.width = w = 99
    ++t
    for (i = 6e3; i--;){
      a = i%w/50 - 1
      s = b = 1 - i/4e3
      X = t
      Y = Z = d = 1
      for(; ++Z<w &  (Y < 6 - (32<Z & 27<X%w && X/9^Z/8)*8%46 ||  d | (s = (X&Y&Z)%3/Z, a = b = 1, d = Z/w));) {
        X += a
        Y -= b
      }
      c.getContext`2d`.fillRect(i%w, i/w|0, 1 - d*Z/w + s, 1)
    }
    ```

- **코드 단계별 설명**
  - `c.width = w = 99`: 캔버스를 초기화하고 너비를 99 픽셀로 설정함.
  - `++t`: 시간 변수를 증가시켜 애니메이션을 만듦.
  - `for (i = 6e3; i--;){}`: 루프를 통해 각 픽셀의 밝기를 결정함.
  - `a = i % w / 50 - 1`: 카메라 벡터의 수평 성분을 계산함.
  - `b = s = 1 - i / 4e3`: 카메라 벡터의 수직 성분을 계산함.
  - `X = t`: 시간 값을 시작 X 위치로 사용함.
  - `Y = Z = d = 1`: Y, Z, d 값을 초기화함.
  - `for(; ++Z<w & ...;)`: 레이캐스팅 시스템이 충돌을 감지할 때까지 루프를 돌림.
  - `c.getContext`2d`.fillRect(i%w, i/w|0, 1 - d*Z/w + s, 1)`: 각 픽셀을 그려 최종 이미지를 만듦.

### 추가 학습

- **추가 학습**
  - 이 데모는 Revision 2022 데모 파티에 출품되었으며, Pouet에서 확인 가능함.
  - Shadertoy에서 256 바이트 셰이더로 확장된 버전을 확인할 수 있음.
  - Daniel Darabos가 만든 인터랙티브 도구를 통해 프로그램의 다양한 측면을 실시간으로 조작 가능함.

### GN⁺의 의견

- **흥미로운 점**
  - 이 프로그램은 매우 작은 코드로 복잡한 그래픽을 생성하는 방법을 보여줌.
  - 초급 소프트웨어 엔지니어에게도 이해하기 쉬운 기본 수학만 사용함.
  - 코드 최적화와 미니멀리즘의 좋은 예시로, 코드 골프와 같은 대회에서 유용할 수 있음.

- **비판적 시각**
  - 코드가 매우 압축되어 있어 가독성이 떨어질 수 있음.
  - 실용적인 응용보다는 예술적, 실험적 목적에 더 적합함.

- **관련 기술**
  - 비슷한 프로젝트로는 Shadertoy에서 다양한 셰이더 예제를 확인할 수 있음.
  - Dwitter와 같은 플랫폼에서 다른 작은 코드 예제를 탐색할 수 있음.

- **기술 도입 고려사항**
  - 이 기술을 도입할 때는 코드의 가독성과 유지보수성을 고려해야 함.
  - 작은 코드로 복잡한 기능을 구현하는 데 따른 성능 최적화와 디버깅의 어려움을 인지해야 함.

## Comments



### Comment 25446

- Author: neo
- Created: 2024-05-21T23:35:17+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=40416109) 
##### 해커뉴스 댓글 모음 요약

- **1K Pinball Game in JavaScript**: 
  - "이 정도의 코드로 이렇게 많은 정보를 담아낼 수 있다는 것이 놀라움."
  - "이게 정말 멋지지만, 기사를 읽는 동안 루프가 계속 돌아서 노트북이 과열됨."
  - "관련 자료: [Atari 2600] Pitfall의 월드 빌드 방식, 절차적 생성, 게으른 평가 등."

- **절차적 생성 및 게으른 평가**:
  - "절차적 생성에 대한 다양한 자료 링크 제공."
  - "게으른 평가와 레이트레이싱 알고리즘의 유사성에 대한 관찰."

- **기타 의견**:
  - "정말 멋지다! 잘했음."
  - "작업과 기사 모두 놀라움."
  - "256바이트 MS-DOS 데모와 유사한 Remnants by Alcatraz - 유튜브 링크 포함."
  - "자바스크립트로 작성된 것이 더 인상적임."
  - "정말 놀라움."
  - "읽는 재미가 있음."
  - "이걸 좋아한다면 트위터의 #tweetcart도 좋아할 것. Pico-8 가상 콘솔을 위한 트윗 크기의 프로그램들."
