GIGAスクール端末(Chromebook)やタブレットで、休み時間などに手軽に遊べるリバーシです。 公立小学校での利用を想定し、低スペック端末での動作・ふりがな・オフライン利用を重視しています。
公開先: https://reversi.giga-school.com/
先生向けの使い方は MANUAL.md、 実測値と「測っていないもの」は AUDIT.md にあります。
1台の端末を2人で使い、黒と白を交代で置いていくリバーシです。
- コンピュータ対戦(AI)はありません。 通信対戦・オンライン対戦もありません
- アカウント登録もログインも不要。URL を開いた瞬間から遊べます
- 対戦の記録も設定も端末に保存しません(
localStorageを一切使っていません)。 再読み込みすると 8x8 の初期盤面に戻ります - 外部へ出て行く通信は Web フォントの取得だけで、それが塞がれても全機能が動きます
開くと 8x8 の盤面が出て、黒の手番から始まります。
| できること | 中身 |
|---|---|
| 石を置く | 置ける場所が白い半透明の丸で光る。タップ/クリック、または Tab で移動して Enter・スペース |
| ひっくり返す | はさんだ石が、置いた場所から近い順に 0.1 秒ずつずれてめくれる |
| 状況を見る | 手番の色・⚫️⚪️ それぞれの石の数・どちらが優勢かを表すメーター |
| パス | 置ける場所が無い側は自動でパス。約1.5秒の案内を挟んで手番が移る |
| 待った | 「↩️ 待った!」で1手ずつ戻す。回数の制限なし(パスも1手として戻せる) |
| 終局 | 盤面が全部うまるか、両者が続けてパスすると終了。紙吹雪と勝敗(石の数つき)を出し、「もう一度」で同じ盤面サイズのまま再開 |
| 盤面サイズを変える | 4・6・8・10・12。数字を変えて「開始/リセット」を押す。奇数や範囲外は赤字で案内し、盤面は変えない |
| あそびかたを読む | 「?」ボタンで児童向けの説明(3ステップ)。Esc か「わかった!」で閉じ、焦点は「?」に戻る |
| 音を消す | 「🔊 ON」/「🔇 OFF」。効果音は Web Audio API でその場で合成しており、音声ファイルは1つも持たない |
| アプリとして入れる | 「⬇️ アプリにする」。ブラウザから合図(beforeinstallprompt)を受け取れたときだけ表示する |
| 更新を受け取る | 新版が用意できると「あたらしい ばんが あります」の帯が出る。「さいしんに する」を押すまで切り替わらない |
| 圏外で開く | 一度も開いたことがない端末で圏外の場合だけ、offline.html の案内画面が出る |
- 盤面サイズを 4〜12(偶数)で変えられる。低学年は 4x4 や 6x6 から始められる
- ふりがな(ルビ)付き。色のついたボタンの上でも読めるよう、親の文字色を継がせている
- キーボードだけで遊べる。石を置ける場所だけが Tab の対象になる
- オフラインで動く(PWA)。一度開けば、圏外でも起動する
- インストールできる。ホーム画面のアイコンから、ブラウザの枠なしで開ける
- 音は消せる。感覚過敏の児童に配慮して、効果音のON/OFFを画面から切り替えられる
- 児童の個人情報を一切あつかわない。入力欄が無く、端末の外へ何も送らない
- 拡大を禁止していない。ブラウザの拡大・ピンチ操作がそのまま使える
npm ci
npm run dev # 開発サーバー(http://localhost:5173/Reversi/ で開く)
npm run build # 本番ビルド(dist/ ができる)
npm run preview # ビルドしたものを確認するbase をリポジトリ名の絶対パスに固定しているため、開発サーバーでも
/Reversi/ を付けた URL で開きます(理由は「設計上の注意」1)。
npm run check # lint → test → build → 品質ゲート
npm run verify-gate # 品質ゲート自体を「わざと壊して」確かめる(check-project.mjs --self-test)CI(.github/workflows/ci.yml)は、この2つをそのまま順に走らせます。
npm run check の中身は lint → テスト(14件)→ ビルド → 品質ゲート です。
push する前に必ず両方通してください。
テストの実行を
node --test "tests/**/*.test.js"に戻さないでください。 あの書き方は Node 自身にグロブを展開させるもので、Node 22 以降でしか動きません。 当時は手元が 22・CI が 20 だったため、手元では 14件通るのに CI だけが落ちました。scripts/run-tests.mjsがファイルを自分で数え上げて渡すので、版にもシェルにも依存しません。 Node 20 と 22 の両方で通ることを確認しています(package.jsonのenginesは>=20、 CI と公開のランナーは現在いずれも Node 22 です)。
npm run verify-gate は、検査そのものが動いているかを確かめます。
「指摘 0件でした」だけでは、検査が動いているのか何も見ていないのか区別が付きません。
リポジトリを一時ディレクトリへ写して1か所だけ壊し、その指摘が実際に出るかを 27件分見ます。
検査に手を入れたら、必ずこれも走らせてください。
アプリ本体:
| ファイル | 役割 |
|---|---|
index.html |
入れ物。CSP・PWA の <head> 一式 |
privacy.html terms.html |
プライバシーポリシーと利用規約。1枚で完結する静的な頁(JS も外部 CSS も読まない)。vite.config.js の rollupOptions.input に並べたものだけが dist に入るので、頁を足したらそこにも足すこと。抜けると本番で 404 になる |
src/main.jsx |
起動と Service Worker の登録 |
src/App.jsx |
画面(盤面・スコア・操作・2つのモーダル・効果音) |
src/lib/reversi.js |
ゲームの中核ロジック(純粋関数のみ) |
src/pwa.js |
Service Worker の登録と更新の案内 |
src/index.css |
スタイルの正本 |
public/sw.js |
Service Worker |
public/offline.html |
圏外のときに出る画面 |
public/install-hook.js |
インストールの合図を捕まえる |
public/manifest.webmanifest |
PWA の manifest(id / scope / start_url) |
public/icon*.png public/icon.svg |
アイコン一式(通常・maskable・apple-touch) |
検査と CI:
| ファイル | 役割 |
|---|---|
tests/reversi.test.js |
中核ロジックのテスト(14件) |
scripts/run-tests.mjs |
テストの実行(対象ファイルを自分で数え上げる) |
scripts/check-project.mjs |
品質ゲートの入口。正本があれば合成する |
scripts/lib/giga-v5-checks.mjs |
品質ゲートの検査本体 |
scripts/lib/png.mjs |
PNG を画素まで読む(アイコンの透明・セーフゾーン検査用) |
scripts/lib/giga-v5-checks.mjs |
共通の検査の【正本のコピー】。直すときは正本(GIGAyama.github.io/standards/lib/)を直して配る |
scripts/lib/local-checks.mjs |
このリポジトリだけの検査(正本に行き先が無かった5件) |
quality.config.json |
品質ゲートの設定(repoName・各種の上限値) |
.github/workflows/ci.yml |
push / PR で check と verify-gate を走らせる |
.github/workflows/deploy.yml |
main への push で品質ゲートを通してから GitHub Pages へ公開 |
| ファイル | 編集してよいか |
|---|---|
src/** public/** index.html privacy.html terms.html |
ここを直す |
dist/** |
手で編集しない(npm run build の生成物) |
dist/sw.js の先読み一覧は、vite.config.js のプラグインがビルド時に
実ファイル名で埋めます。public/sw.js が原本です。
旧配信元の gigayama.github.io は同一オリジンを数十個のアプリで共有していました。同居する配置に戻したときのため、
そのため、普通なら問題にならない書き方が事故になります。
"id": "/Reversi/",
"start_url": "/Reversi/",
"scope": "/Reversi/"リポジトリ名の絶対パスで固定しています。
id を省略すると start_url が代わりの識別子になり、
似た構成の別アプリと取り違えられて「開いたら違うアプリが立ち上がる」事故が起きます。
このリポジトリをコピーして新しいアプリを作るときは、この3つと
vite.config.js の base、quality.config.json の repoName を最初に書き換えてください。
caches.keys() の結果を全部消すと、同じ端末に入っている他の GIGA アプリが
オフラインで起動しなくなります。 CACHE_PREFIX で始まるものだけを掃除しています。
対戦の最中に新版へ入れ替わると、並べたばかりの盤面が消えます。 画面に出る「さいしんに する」を押してもらってから切り替えます。
script-src 'self' なので、インラインの <script> と onclick= は動きません。
'unsafe-inline' を足して解決しないでください。CSP を入れた意味がほとんど無くなります。
JavaScript は必ず外部ファイルに置いてください。
ビルド設定で modulePreload のポリフィルを外しているのも同じ理由です
(インラインの <script> として差し込まれるため)。
上げ忘れると更新が反映されません。
色のついたボタンの上に固定色のふりがなを置くと読めなくなります。
src/index.css で、色のついた面では親の色を継がせています。
1か所ずつ直さないでください。
ビルドが吐く JS / CSS のファイル名にはハッシュが付くため、手では書けません。
vite.config.js のプラグインが埋めています。
ここが空だとオフラインで白い画面になります。
初回訪問では HTML も JS も Service Worker が有効になる前に読み込まれるため、
fetch ハンドラを通らず runtime キャッシュにも入らないからです。
Chromebook(GIGA標準機)/ iPad / Windows PC / 電子黒板 / スマートフォン。 横 320px・縦 568px を下限として、横スクロールが出ないことを実測で確認しています。
盤面は、ヘッダー・スコア・操作パネルを除いた残りの領域いっぱいまで自動で広がり、 正方形を保ちます。画面の高さが足りないときはフッターを隠し、 横向きで高さが足りないときは「スコア/盤面/操作」を横並びに組み替えます。
学校のネットワークが fonts.googleapis.com を塞いでいても動きます。
Web フォントが届かない場合は端末側の日本語フォントに落ちるだけで、
実行に必要なコードは CDN から一切読んでいません。
Copyright © 2026 GIGAyama