1 ポイント 投稿者 GN⁺ 2024-05-14 | 1件のコメント | WhatsAppで共有

Static Chess の実装

  • 平凡で、必要最低限の機能だけを備えたチェスの実装
  • すべてのページは HTML と CSS のみで構成
  • すべてのチェスの手はリンクをクリックして行う
  • 友だちにリンクを送ると相手が指し、再びリンクを送り返す方式で進行
  • 不要なアニメーションや派手なインタラクティブ要素がゲームプレイを妨げない
  • Google がこのサイトをインデックスするとき、あり得るすべてのチェスの手を計算できるのか気になる

機能制限とバグ

  • 機能は非常に限定的で、動作しない場合がある
  • バグを見つけたら報告歓迎

着想のもとになったアイデア

  • 三目並べゲームのあらゆる可能な状態を表示するサイトについての Hacker News の議論から着想を得た

今後の計画

  • 実際のゲームプレイをサポートするよう拡張する予定
  • 友人たちと長期戦を楽しめるシンプルなインターフェースになりそう
  • 静的な AI と対戦する機能を追加するのも面白そう
  • 追加してほしい機能があれば PR 歓迎

主なコード

class StaticChess { 
  // 생략...
  async fetch(req: Request): Promise<Response> {
    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(
        <html>
          {/* 생략... */}
          <div className="board">
            {this.rows.map(row => (
              <div key={row} className="row">{this.squares.map(square => game.squareContent(row, square))}</div>
            ))}
          </div>
          {/* 생략... */}
        </html>
      ),
      { 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 <a href={`/${this.fen}/${pos}`}>{pieces[this.board[row][square]?.type]}</a>;
      }
      const nextMove = this.nextMoves[pos];
      if (nextMove !== undefined) {
        return (
          <a href={`/${nextMove.after.replaceAll(" ", "_")}/`}>
            {pieces[this.board[row][square]?.type]} 
          </a>
        );
      }
      return <span>{pieces[this.board[row][square]?.type]}</span>;
    })();
    // 생략...
  }
}

GN⁺ の意見

  • Web チェスゲームを HTML/CSS だけで実装するのは興味深い試み。ただし、すべての状態を静的ページにするのは実用性の面では疑問が残る。
  • 現実的な使い勝手を考えると、結局はバックエンドで状態を管理し、フロントエンドから API を呼び出す形になるように思える。
  • 静的ページとしてすべての状態を事前計算しておくのはアイデアとしては面白いが、実際のユーザーにとってはあまり大きな意味はなさそう。
  • React で SSR するのは悪くないアプローチだが、キャッシュやプリフェッチなどパフォーマンス改善の余地が大きそう。
  • 類似のオープンソースプロジェクトとしては lichess がある。豊富な機能と優れた UI を備えており、参考になる。
  • チェスエンジンと連携して AI モードをサポートするなら、WASM の活用も検討できそう。

1件のコメント

 
GN⁺ 2024-05-14
Hacker Newsのコメント
  • URLにFENを追加して、チェス960(フィッシャーランダムチェス)やその他の「カスタム開始配置」バリアントをプレイできる。空白はアンダースコアに置き換える必要がある。
  • 合法手は検出するが、チェックメイトは認識しない。
    • 例のURLではチェックメイトと表示されるべき。
  • 別のURLの例では、チェックメイトまで正しく進行する。
  • CDN(例: Cloudflare)を使ってキャッシュヒット率を確認してみることを提案する。
  • 駒をまったく動かせないチェスのバリアントを期待していた、という冗談。
  • 静的なウェブページで、しかもチェスの最小限の実装であるにもかかわらず、驚くほど遅延がある。
  • 2006年にPythonを学ぶため、リバーシのボードゲームとほぼ同じものを実装した。対戦相手は単純なミニマックス探索ベースのAIだった。当時はJavaScriptなしで全状態をURLに入れる方が、より明快なアプローチだった。
  • FENに加えて、棋譜の移動履歴を含めるのもよさそう。URLの例あり。
  • サイトマップがないため、可能なすべてのチェスの状態一覧を見つけられなかった。
  • このプロジェクトを通じて、https://fav.farmhttps://val.town という便利なリソースを知った。