はじめに
ブラウザで遊べる「あみだくじ」を作ってみました。
オンライン あみだくじ
登録不要で、PC・スマートフォンから利用できます。
「あみだくじなんて縦線と横線を描いて、上から下へたどるだけ」
最初はそんな感じで考えていました。
ところが実際にWebアプリとして作ってみると、
- あみだの生成
- 横線の管理
- 経路判定
- アニメーション
- スマートフォンでの操作
- 結果のシャッフル
- 状態の保存・共有
など、意外と考えることがありました。
今回は具体的なソースコードやアルゴリズムには触れず、どんな考え方で作ったのかを簡単に紹介します。
全体の構成
大まかな構成はこんな感じです。
Browser
│
├─ 名前・結果の入力
├─ あみだの編集
├─ 各種設定
│
▼
Application Logic
│
├─ あみだ生成
├─ 横線管理
├─ 経路判定
├─ 結果管理
└─ アニメーション制御
│
▼
Backend
│
├─ データ保存
└─ 共有URL管理
│
▼
Database
規模としては小さなWebアプリなので、できるだけシンプルな構成を意識しています。
ただし、画面上では単純に見える「あみだ」の部分には、それなりに状態管理が必要になりました。
あみだくじをデータとして考える
画面だけを見ると、
A B C D
│ │ │ │
│─────│ │ │
│ │ │─────│
│ │─────│ │
│ │ │ │
という単純なものです。
しかしプログラム側では、「線がある」という見た目だけではなく、
どの位置に横線があるか
どの縦線と接続しているか
現在どの経路を進んでいるか
次にどちらへ移動するか
といった情報として扱う必要があります。
つまり、
「絵としてのあみだくじ」と「データとしてのあみだくじ」をどう対応させるか
が最初のポイントでした。
横線をどう扱うか
ユーザー自身が横線を追加できるようにしています。
さらに、自分で作るのが面倒な場合はCPUに横線を追加してもらうこともできます。
単純にランダムな位置へ線を追加するだけなら簡単ですが、あみだくじとして成立させるためには一定のルールが必要になります。
概念的には、
横線を追加したい
↓
追加可能な位置か判定
↓
既存の横線との関係を確認
↓
内部データを更新
↓
画面へ反映
という流れです。
CPUによる生成も基本的には同じデータ構造を使っています。
ただし、具体的にどのような条件で横線を生成しているかについては、アプリ内部のロジックなので今回は割愛します。
経路判定
当然ですが、あみだくじなのでスタート地点から正しいゴールへ到達しなければいけません。
考え方としては、
START
↓
縦方向へ進む
↓
横線がある?
↓ YES
隣の縦線へ移動
↓
再び縦方向へ
↓
・・・
↓
GOAL
となります。
文章にすると非常に単純です。
ただ、実際には画面上の座標をそのまま頼りに処理してしまうと、表示サイズやスマートフォン対応などで扱いづらくなります。
そのため、
表示と経路判定をできるだけ分離する
ことを意識しました。
ここも具体的なデータ構造や探索方法については非公開にしておきます。
「計算」と「見せ方」を分ける
今回少し意識したのがここです。
あみだくじの場合、
A → 3
B → 1
C → 4
D → 2
という結果だけなら、内部的にはすぐに求めることができます。
でも、それを即座に表示してしまったら面白くありません。
あみだくじは、
スタート
↓
線をたどる
↓
横へ移動
↓
また下へ
↓
どこに行く?
↓
結果発表!
という過程も含めて楽しむものです。
そこで、
経路を求める処理
と
経路を見せる処理
を別のものとして考えました。
アニメーション
経路が決まったら、その情報を使って画面上で線をたどらせます。
イメージとしては、
経路データ
↓
移動区間へ分解
↓
現在位置を更新
↓
画面を描画
↓
次の区間へ
↓
GOAL
という感じです。
さらに、
- 1人だけスタート
- 全員同時スタート
- アニメーション速度変更
にも対応させています。
特に全員を同時に動かす場合は、単純な「1本の線を動かす」だけとは少し違った状態管理が必要になりました。
スマートフォン対応
PCだけならマウス操作を前提にできますが、今回はスマートフォンでも使えるようにしました。
あみだくじの場合、
「線と線の間を押して横線を追加する」
という操作があります。
そのため、
PC
└─ マウス
Smartphone
└─ タッチ
の両方で違和感なく操作できる必要があります。
さらに画面幅が変われば、縦線同士の間隔も変わります。
このあたりも、表示座標と内部データを密結合させないようにした理由の一つです。
結果を隠す
あみだくじなので、最初から結果が見えていると楽しさが半減します。
そこで結果を隠した状態でも実行できるようにしました。
さらにゴール側をシャッフルする機能も入れています。
ここでも、
画面に何を表示するか
と
内部で持っている状態
を分けて考える必要があります。
URLで共有する
作ったあみだくじはURLで共有できるようにしています。
さらに、
編集できるURL
閲覧専用URL
を分けています。
単純に画面を共有するだけではなく、
「誰が変更できるのか」
も考慮した構成にしました。
作ってみて感じたこと
「あみだくじ」という題材自体はかなり単純です。
でもWebアプリにしてみると、
入力
↓
データ化
↓
横線生成
↓
経路判定
↓
描画
↓
アニメーション
↓
結果表示
↓
保存・共有
と、意外といろいろな処理が必要でした。
特に面白かったのは、
「結果を正しく求めること」と「ユーザーに楽しく見せること」は別問題
だったことです。
経路を計算するだけなら比較的シンプルでも、そこにアニメーションやスマートフォン操作が加わると設計することが増えてきます。
小さなWebアプリですが、状態管理・描画・経路判定・UIを考える題材としてはなかなか面白かったです。
まとめ
今回作ったものはこちらです。
オンライン あみだくじ
PC・スマートフォンの両方から利用できます。
今回は全体的な設計の考え方だけ紹介しました。
横線生成や経路判定などの具体的なアルゴリズム・データ構造・ソースコードについては公開していません。
一見すると単純な「あみだくじ」ですが、
「実際にWebアプリとして作ると、意外と考えることが多い」
というのが今回作ってみて一番面白かったところでした。