# 정적 체스(Static Chess) 게임

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

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=14813](https://news.hada.io/topic?id=14813)
- GeekNews Markdown: [https://news.hada.io/topic/14813.md](https://news.hada.io/topic/14813.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-05-14T10:11:58+09:00
- Updated: 2024-05-14T10:11:58+09:00
- Original source: [val.town](https://www.val.town/v/maxm/staticChess)
- Points: 1
- Comments: 1

## Topic Body

### Static Chess 구현
- 평범하고, 필수적인 기능만 있는 체스 구현
- 모든 페이지는 오직 HTML과 CSS로만 구성됨
- 모든 체스 이동은 링크를 클릭해서 이뤄짐
- 친구에게 링크를 보내면 상대방이 이동하고 다시 링크를 보내주는 방식으로 진행
- 불필요한 애니메이션이나 화려한 인터랙티브 요소가 게임플레이를 방해하지 않음
- 구글이 이 사이트를 인덱싱할 때 모든 가능한 체스 이동을 계산할 수 있을지 궁금함

### 기능 제한 및 버그
- 기능이 매우 제한적이고 동작하지 않을 수 있음 
- 버그를 발견하면 제보 부탁

### 영감을 준 아이디어
- 틱택토 게임의 모든 가능한 상태를 보여주는 사이트에 대한 Hacker News 토론에서 영감을 얻음

### 향후 계획
- 실제 게임플레이를 지원하도록 확장할 계획
- 친구들과 장기전을 할 수 있는 심플한 인터페이스가 될 수 있을 것 같음
- 정적 AI와 대결하는 기능을 추가하는 것도 재미있을 것 같음
- 추가되었으면 하는 기능이 있다면 PR 환영

### 주요 코드
```typescript
class StaticChess { 
  // 생략...
  async fetch(req: Request): Promise&lt;Response&gt; {
    const gameInfo = parseURL(req.url); 
    if (gameInfo === undefined) {
      return new Response("Not Found", { status: 404, headers: { "cache-control": "max-age=86400, public" } }); 
    }
    const game = new Game(gameInfo.game, gameInfo.selected);
    return new Response(
      renderToString(
        &lt;html&gt;
          {/* 생략... */}
          &lt;div className="board"&gt;
            {this.rows.map(row => (
              &lt;div key={row} className="row"&gt;{this.squares.map(square => game.squareContent(row, square))}&lt;/div&gt;
            ))}
          &lt;/div&gt;
          {/* 생략... */}
        &lt;/html&gt;
      ),
      { headers: { "content-type": "text/html", "cache-control": "max-age=86400, public" } },
    );
  }
}

class Game {
  // 생략... 
  squareContent(row: number, square: number) {
    // 생략...
    const squareContent = (() => {
      if (this.selectable.includes(pos)) { 
        return &lt;a href={`/${this.fen}/${pos}`}&gt;{pieces[this.board[row][square]?.type]}&lt;/a&gt;;
      }
      const nextMove = this.nextMoves[pos];
      if (nextMove !== undefined) {
        return (
          &lt;a href={`/${nextMove.after.replaceAll(" ", "_")}/`}&gt;
            {pieces[this.board[row][square]?.type]} 
          &lt;/a&gt;
        );
      }
      return &lt;span&gt;{pieces[this.board[row][square]?.type]}&lt;/span&gt;;
    })();
    // 생략...
  }
}
```

### GN⁺의 의견
- 웹 체스 게임을 HTML/CSS만으로 구현하는 것은 흥미로운 시도임. 하지만 모든 상태를 정적 페이지로 만드는 것은 실용성 면에서는 의문임. 
- 현실적인 사용성을 고려하면 결국 백엔드에서 상태를 관리하고 프론트엔드에서 API를 호출하는 형태가 되어야할 것 같음.
- 정적 페이지로 모든 상태를 미리 계산해두는 것은 아이디어로서는 재미있지만, 실제 사용자에게는 큰 의미가 없어보임.
- React로 SSR하는 것은 괜찮은 접근이지만, 캐싱이나 프리페칭 등 성능을 개선할 여지가 많아보임.
- 비슷한 오픈소스 프로젝트로는 lichess가 있음. 풍부한 기능과 멋진 UI를 제공하므로 참고해볼만함.
- 체스 엔진과 연동해서 AI 모드를 지원하려면 WASM을 활용하는 것도 고려해볼 수 있겠음.

## Comments



### Comment 25219

- Author: neo
- Created: 2024-05-14T10:11:58+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=40342803) 
- URL에 FEN을 추가하여 체스960(피셔 랜덤 체스) 또는 다른 "사용자 지정 시작 위치" 변형을 플레이할 수 있음. 공백은 밑줄로 대체해야 함.
- 유효한 움직임은 감지하지만 체크메이트는 인식하지 못함.
  - 예시 URL에서는 체크메이트라고 표시되어야 함.
- 또 다른 URL 예시에서 체크메이트까지 성공적으로 진행됨.
- CDN(예: Cloudflare)을 사용하여 캐시 적중률을 확인해보는 것을 제안함.
- 기물을 전혀 움직일 수 없는 체스 변형을 기대했다는 농담.
- 정적 웹 페이지이고 체스의 최소한의 구현임에도 놀랍게도 지연이 있음.
- 2006년에 파이썬을 배우기 위해 리버시 보드게임과 거의 동일한 것을 구현했음. 상대는 간단한 미니맥스 검색 기반 AI였음. 당시에는 자바스크립트 없이 모든 상태를 URL에 넣는 것이 더 명확한 접근 방식이었음.
- FEN 외에도 조각으로 이동 기록을 포함하는 것이 좋겠음. 예시 URL 제공.
- 사이트맵이 없어서 가능한 모든 체스 상태 목록을 찾을 수 없었음.
- 이 프로젝트를 통해 `https://fav.farm`과 `https://val.town`이라는 유용한 리소스를 알게 됨.
