シェルスクリプトで作る：ドライデルゲーム - ユダヤの伝統をターミナルで体験

ハヌカーというユダヤ教の祭りをご存知でしょうか？この祭りで伝統的に遊ばれる「ドライデル」というゲームがあります。Googleは「Google ドライデル」という特別なインタラクティブバージョンを提供していますが、今回は一味違う、シェルスクリプトでの実装に挑戦してみました。ターミナル上で動作する、シンプルながらも楽しいインタラクティブゲームを一緒に作ってみましょう。

## ドライデルとは？

Google ドライデルはウェブブラウザで遊べるオンラインバージョンとして知られていますが、元々のドライデルは実際の4面体の独楽（こま）です。

ドライデルは4面体の独楽（こま）で、各面にヘブライ文字が刻まれています：

- `נ`（ヌン/Nun）- 何もしない
- `ג`（ギメル/Gimel）- すべてを獲得
- `ה`（ヘイ/Hey）- 半分を獲得
- `ש`（シン/Shin）- 1つ入れる

これらの文字は「ネス・ガドル・ハヤ・シャム」（そこで大きな奇跡が起こった）というヘブライ語の頭文字です。この「奇跡」とは、古代エルサレムの神殿で1日分の油が8日間燃え続けたという「油の奇跡」を指しています。

ゲームの詳しいルールは[Google ドライデルについての詳細な解説](https://note.com/yonaka15/n/n85294c39bf32) をご覧ください。

## シェルスクリプトでの実装

今回は、このドライデルゲームをzshで実装してみました。特徴は以下の通りです：

- アニメーションつきの回転表現
- カラー出力でビジュアル的な楽しさを追加
- キーボード入力によるインタラクティブな操作

以下が完全なソースコードです：

```zsh
#!/bin/zsh
# ドライデルの文字と意味を定義
declare -A dreidel_faces=(
    [1]="נ (ヌン/Nun) - 取らない"
    [2]="ג (ギメル/Gimel) - 全部取る"
    [3]="ה (ヘイ/Hey) - 半分取る"
    [4]="ש (シン/Shin) - 1つ入れる"
)

# アニメーション用の回転シンボル
spin_chars=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')

# 色の定義
BLUE='\033[0;34m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color

# スピン中のアニメーション表示
function spin_animation() {
    local i=0
    local frames=10
    echo -n "ドライデルを回しています "
    for ((j=0; j<frames; j++)); do
        echo -ne "\r${BLUE}${spin_chars[$((i % 10))]}${NC} ドライデルを回しています..."
        i=$((i + 1))
        sleep 0.1
    done
    echo
}

# メイン関数
function play_dreidel() {
    echo "${GREEN}=== ドライデル ====${NC}"
    echo "スペースキーを押して回す (終了するには q を押してください)"
    
    while true; do
        read -sk1 key
        
        case $key in
            " ")
                spin_animation
                # ランダムに面を選択
                result=$((RANDOM % 4 + 1))
                echo "${GREEN}結果:${NC} ${dreidel_faces[$result]}"
                echo
                ;;
            "q")
                echo "\nゲームを終了します"
                exit 0
                ;;
        esac
    done
}

# ゲーム開始
play_dreidel
```

## 実装の解説

### 1. データ構造の定義

まず、ドライデルの各面の情報を連想配列で定義します：

```zsh
declare -A dreidel_faces=(
    [1]="נ (ヌン/Nun) - 取らない"
    [2]="ג (ギメル/Gimel) - 全部取る"
    [3]="ה (ヘイ/Hey) - 半分取る"
    [4]="ש (シン/Shin) - 1つ入れる"
)
```

### 2. アニメーションの実装

回転のアニメーションは、Braille文字（点字）のパターンを利用して表現します：

```zsh
spin_chars=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
```

`spin_animation`関数では、これらの文字を順番に表示することで回転の動きを表現します。`echo -ne`の`-n`オプションで改行を抑制し、`-e`オプションでエスケープシーケンスを有効にしています。

### 3. インタラクティブな操作

`read -sk1`コマンドを使用して、1文字ずつのキー入力を受け付けています。スペースキーで回転、qキーで終了です。

```zsh
while true; do
    read -sk1 key
    case $key in
        " ")
            # スペースキーの処理
            ;;
        "q")
            # 終了処理
            ;;
    esac
done
```

## 使い方

1. スクリプトを保存（例：`dreidel.sh`）
2. 実行権限を付与：`chmod +x dreidel.sh`
3. 実行：`./dreidel.sh`
4. スペースキーで回転、qキーで終了

## 技術的なポイント

1. **Unicode文字の使用**
   - ヘブライ文字とBraille文字を直接使用
   - ターミナルのフォントによっては表示が異なる可能性があります

2. **ANSIエスケープシーケンス**
   - カラー出力を実現するために使用
   - `\033[0;34m`のような形式で色を指定

3. **zshの機能活用**
   - 連想配列（`declare -A`）の使用
   - キー入力の処理（`read -sk1`）

## 発展の可能性

このスクリプトは基本的な機能のみを実装していますが、以下のような拡張が考えられます：

1. マルチプレイヤー対応
   - プレイヤーの得点管理
   - ターン制の実装

2. 視覚的な強化
   - ASCIIアートでの独楽の表示
   - より複雑なアニメーション

3. ゲームロジックの完全実装
   - ポットの管理
   - 実際のゲームルールに基づく勝敗判定

## まとめ

シンプルなシェルスクリプトで、伝統的なゲームを現代的に再解釈してみました。基本的なシェルスクリプトの機能を組み合わせることで、意外と楽しいインタラクティブなゲームが作れることがわかります。

この実装を通じて、以下のような技術的要素について学ぶことができます：

- シェルスクリプトでのユーザーインタラクション
- Unicodeを含む文字列の扱い
- ターミナルでのアニメーション表現
- ANSIエスケープシーケンスによる装飾

## 参考資料

- [ZshでのKey Bindingについて](https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html)
- [Unicode文字一覧（Braille Patterns）](https://www.unicode.org/charts/PDF/U2800.pdf)