2026年6月22日月曜日

Godotでフリーセルを作った

GodotというOSSゲームエンジンを使ってフリーセルを作りました


ゲーム本体:フリーセル | マグロにアグロ

GitHub:asurato/godot-freecell · GitHub


作ってみた理由は、

  • Godotとかgdscriptとかを触ってみたかったから
  • GodotはCLIから操作しやすく、AIコーディングに向いてそうだから

の2つ。CLAUDE.mdや仕様書を整備して、AI様の往く末を見守った。


実装は3段階で作成した。1つ目は盤面やカードなどの値オブジェクトで、gdscriptにおけるResource。2つ目はUIを伴わない純粋ロジック層。3つ目はUIが絡むGodot層。

Resourceを最初に定めたのは、セーブやロード、あとはフリーセル特有のUndoやRedoに対応しやすくするため。「データからシステムを考えるのは悪」だとWeb系の方々には言われそうだが、ことゲーム開発においては先に決めといた方が良さそう。GodotではResourcesをJsonやバイナリで出力できるのが大変便利でおススメ。

2つ目の純粋ロジック(非UI)層ではGutを使って単体テストを書かせまくった。それと、データと振る舞いを明確に分離させたくて全メソッドをstaticで書かせたりもした(staticおじさんだと煽るのはやめてください!まだお兄さんなので!)。で、これはオチなんですが、全staticメソッド化は特に効果なかったので真似しなくていいです。単にファイル分ければええねん。

3つ目はGodot層で、UI関係を全部ぶち込んだ。多少だがUI検証用の結合テストも追加した。


色々書いてしまったが、開発に特に効いたのは以下の3点だったと思う

  • 最初にドキュメントを整備した
  • Resourcesを通してセーブ&ロードの仕組みを早めに導入した
  • テストを書かせまくった


というわけで、暇な人は遊んでみてください!

2026年6月12日金曜日

PixiJSでマインスイーパーを作った

PixiJSという描画エンジンを使ってマインスイーパーを作りました

ゲームのリンク: マインスイーパー | マグロにアグロ

コード: GitHub - asurato/mine-sweeper


AI Coding+PixiJSを試したくて作りました。AIはTypeScriptの出力が得意らしいとはどこかで聞いていたので、「じゃあゲーム開発もTypeScriptでやればええやん」という興味より。

結構驚いたのが旗や爆弾を画像を使わずに表現できたことで、PixiJSのポリゴン的なやつを使ってAI様がそれっぽく仕上げてくれました。視覚情報はないはずなのにようやっとる。

AIが出力した旗のコードはこんな感じ。ようやっとる。

function drawFlag(g: PixiGraphics, x: number, y: number, size: number) {
  const poleX = x + size * 0.35;
  const poleTop = y + size * 0.15;
  const poleBottom = y + size * 0.75;
  const poleWidth = size * 0.06;

  // ポール(旗竿)
  g.rect(poleX, poleTop, poleWidth, poleBottom - poleTop);
  g.fill(COLORS.flagPole);

  // 旗の布(三角形)
  const flagLeft = poleX + poleWidth;
  const flagTop = poleTop;
  const flagRight = x + size * 0.8;
  const flagBottom = y + size * 0.45;
  g.poly([flagLeft, flagTop, flagRight, (flagTop + flagBottom) / 2, flagLeft, flagBottom]);
  g.fill(COLORS.flag);

  // 土台
  const baseWidth = size * 0.3;
  const baseHeight = size * 0.12;
  const baseX = poleX + poleWidth / 2 - baseWidth / 2;
  const baseY = poleBottom;
  g.rect(baseX, baseY, baseWidth, baseHeight);
  g.fill(COLORS.flagBase);
}