pygameでRPG（まほう）

テスト中

[新RPGの目次](https://qiita.com/hijpa/items/31900e327315fa8e4eea)

# まほう

<details><summary>ここにコードがあります</summary>

```python:

import pygame
from pygame import *
import sys
import time
import random

# 部分一致で値を取得する関数
def get_value_by_partial_key(dictionary, partial_key):
    for key in dictionary:
        if key in partial_key:
            return dictionary[key]
    return None

# 改行してテキストを描画する関数（バトルメッセージ）
def draw_text(surface, message, pos, font, color=(255, 255, 255)):
    lines = message.split('\n')
    x, y = pos
    for line in lines:
        text_surface = font.render(line, True, color)
        surface.blit(text_surface, (x, y))
        y += text_surface.get_height() * 2

# 2列×3行のテキストを描画する関数（ステータスウィンドウ・コマンドウィンドゥ）
def draw_text_grid(screen, text_list, start_x, start_y, spacing_x, spacing_y):
    for col_index, col in enumerate(text_list):  # 列ごとに処理
        for row_index, text in enumerate(col):  # 各行のテキストを描画
            text_surface = font.render(text, True, white)
            x = start_x + col_index * spacing_x  # 列ごとにX座標を調整
            y = start_y + row_index * spacing_y  # 行ごとにY座標を調整
            screen.blit(text_surface, (x, y))

# ここのpathはそのままにしておく(パスを貼り付けるところではない)
def bgm(path):
    pygame.mixer.music.load(path)
    pygame.mixer.music.play(-1)

pygame.init()
width, height = 640, 480
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('まほう')

# ここにフォントのパスを貼り付ける
font = pygame.font.Font(, 18)
# ここにカーソル画像のパスを貼り付ける
cursor = pygame.image.load()
# ここにモンスター画像のパスを貼り付ける
monsterA_image = pygame.image.load()
# ここにモンスター画像のパスを貼り付ける
monsterB_image = pygame.image.load()
# ここにモンスター画像のパスを貼り付ける
monsterC_image = pygame.image.load()

# SE
# ここにボタン音のパスを貼り付ける
sound = pygame.mixer.Sound()
# ここにダメージ音のパスを貼り付ける
sound2 = pygame.mixer.Sound()

# BGM
# ここに戦闘のBGMのパスを貼り付ける
battle_bgm = 
# ここに勝ったときのBGMのパスを貼り付ける
win_bgm = 
# ここに負けたときのBGMのパスを貼り付ける
lose_bgm = 

bgm(battle_bgm)    

# モンスター
nameA = ""
nameB = ""
nameC = ""
# モンスターのグループ
# 全角スペースで区切ります
# ex) "スライム　ウルフ"
# ひとグループ５体までです
groupA = ""
groupB = ""
groupC = ""
monster_list = [groupA,groupB,groupC]

# 色
white = (255, 255, 255)

# カーソル
alpha = 220
delta = 5

message = "モンスターが あらわれた！"

battle_message = True
command = False
select = False
masic_select = False
defeat = False

actor_index = 0
select_index = 0
masic_index = 0
chara_index = 0
cmd_index = 0
cmd_num1 = 0
cmd_num2 = 0

phase = 0
masic_phase = 0

# 枠点滅
status_flash = 0
status_visible = 0
mon_flash = 0
mon_visible = 0
player_damage = 0
mon_damage = 0

# まほうエフェクト
masic_effect = 0
# まほうフレーム
masic_frame = 0
# まほうサーフェイス
damera_surface = pygame.Surface((width,height),SRCALPHA)
damera_surface.fill((255,201,14,128))
hoimun_surface = pygame.Surface((width,height),SRCALPHA)
hoimun_surface.fill((255,255,255,128))
# まほうリスト
damera = {"masic_name":"ダメラ","MP":2,"数値":10,"masic_effect":1,"masic_type":"攻撃まほう","surface":damera_surface}
hoimun = {"masic_name":"ホイムン","MP":3,"数値":30,"masic_effect":2,"masic_type":"補助まほう","surface":hoimun_surface}
masic_list = [damera,hoimun]
cmd_cursor = False
# キャラリスト
chara_list = ["ゆうしゃ","せんし"]

# レクト
select_rect = pygame.Rect(width * 0.4,height * 0.67,220,140)
select_rectx,select_recty = select_rect.topleft
cmd_rect = pygame.Rect(20, height * 0.67, 220, 140)
cmd_rectx,cmd_recty = cmd_rect.topleft
message_rect = pygame.Rect(20, height * 0.67, 600, 140)
message_rectx,message_recty = message_rect.topleft


# 2列×3行のテキストデータ
text_list = [
    ["攻撃", "魔法", "ガード"],  # 1列目
    ["アイテム", "装備", "逃げる"]  # 2列目
]

status_data = []

# 勇者の初期ステータス
player_name = "ゆうしゃ"
player_Max_HP = 53
player_HP = 53
player_Max_MP = 5
player_MP = 5
player_power = 23
player_quick = 6
player_deffence = 0
player_level = 1

# 2列×3行のテキストデータ
text_list2 = [
    ["H", "M", "ゆ"],  # 1列目
    [f"{player_HP}", f"{player_MP}", f"{player_level}"]  # 2列目
]

# モンスターの初期ステータス
mon_images_dict = {nameA: monsterA_image,
                   nameB: monsterB_image,
                   nameC: monsterC_image}
mon_HP_dict = {nameA: 4,nameB: 6,nameC: 8}
mon_power_dict = {nameA: 3,nameB: 25,nameC: 6}
mon_deffence_dict = {nameA: 4,nameB: 4,nameC: 8}
mon_quickness_dict = {nameA:3,nameB:4,nameC:8}
mon = random.choice(monster_list)
mon_group_list = mon.split()

for i in range(len(mon_group_list)):  
    status_data.append({
        "name": f"{mon_group_list[i]}",
        "HP": get_value_by_partial_key(mon_HP_dict,mon_group_list[i]),
        "power": get_value_by_partial_key(mon_power_dict,mon_group_list[i]),
        "deffence": get_value_by_partial_key(mon_deffence_dict,mon_group_list[i]),
        "quickness": get_value_by_partial_key(mon_quickness_dict,mon_group_list[i]),
        "image": get_value_by_partial_key(mon_images_dict,mon_group_list[i]),
        "attack_on": 0
    })

status_data.append({"name": f"{player_name}","HP":player_HP,"MP":player_MP,"power":player_power,"deffence":player_deffence,"quickness": player_quick,})


# モンスターの位置を定義（奇数・偶数で異なる）
monster_positions = {
    1: [0.5],  # 1体
    2: [0.4, 0.6],  # 2体
    3: [0.3, 0.5, 0.7],  # 3体
    4: [0.2, 0.4, 0.6, 0.8],  # 4体
    5: [0.1, 0.3, 0.5, 0.7, 0.9]  # 5体
}

# モンスターの位置を設定
monster_rects = [
    get_value_by_partial_key(mon_images_dict,mon_group_list[i]).get_rect(center=(width * monster_positions[len(mon_group_list)][i], height * 0.5))
    for i in range(len(mon_group_list))
]


running = True
clock = pygame.time.Clock()

while running:
    clock.tick(60)
    # 画面を黒色に塗りつぶし
    screen.fill((0, 0, 0))
    # ステータスウィンドゥ
    if status_visible == 0:
        pygame.draw.line(screen, white, (20, 58),(118, 58))
        pygame.draw.rect(screen, white, (20, 20, 102, 134), 3)
        text = font.render("ゆうしゃ", True, white)
        screen.blit(text,(35, 35))
        draw_text_grid(screen, text_list2, start_x=32, start_y=65, spacing_x=40, spacing_y=30)  # テキスト描画
        text_list2 = [["H", "M", "ゆ"],[f"{player_HP}", f"{player_MP}", f"{player_level}"]]
    # モンスターの画像表示
    if mon_group_list:
        for i in range(len(mon_group_list)):
            if select_index == i and mon_visible == 0:
                screen.blit(get_value_by_partial_key(mon_images_dict,mon_group_list[i]), (monster_rects[i].topleft))
            if select_index != i:
                screen.blit(get_value_by_partial_key(mon_images_dict,mon_group_list[i]), (monster_rects[i].topleft))
    # コマンドウィンドゥ
    if command:
        cursor.set_alpha(alpha)
        alpha += delta
        if alpha <= 120 or alpha >= 255:
            delta = -delta
        pygame.draw.line(screen, white, (20, 358),(236, 358))
        pygame.draw.rect(screen, white, cmd_rect, 3,5)
        text = font.render("ゆうしゃ", True, white)
        screen.blit(text,((cmd_rectx + 14) + 60,(cmd_recty + 14)))
        draw_text_grid(screen, text_list, start_x=51, start_y=365, spacing_x=98, spacing_y=34)  # テキスト描画
        if cmd_cursor:
            screen.blit(cursor, ((cmd_rectx + 5) + 100 * cmd_num2, (cmd_recty + 40) + 34 * cmd_num1))  # カーソル描画
            cmd_index = cmd_num1 + (cmd_num2 * 3)
        # 魔物選択ウィンドゥ
        if select or masic_phase == 2 and masic_list[masic_index]["masic_type"] == "攻撃まほう":
            pygame.draw.rect(screen,white,select_rect,3,5)
            # モンスター名の描画
            if mon_group_list:
                for i, mon in enumerate(mon_group_list):
                    text = font.render(mon, True, white)
                    screen.blit(text, ((select_rectx + 14) + 30, (select_recty + 14) + 24 * i))
                screen.blit(cursor, ((select_rectx + 14), (select_recty + 11) + 24 * select_index))  # カーソル描画
        if masic_phase == 2 and masic_list[masic_index]["masic_type"] == "補助まほう":
            pygame.draw.rect(screen,white,select_rect,3,5)
            # キャラ選択
            # カーソル
            for i, chara in enumerate(chara_list):
                text = font.render(chara, True, white)
                screen.blit(text, ((select_rectx + 14) + 30, (select_recty + 14) + 24 * i))
            screen.blit(cursor, ((select_rectx + 14), (select_recty + 11) + 24 * chara_index))  # カーソル描画
        if masic_select and masic_phase == 1:
            # まほうがある場合のみ描画
            pygame.draw.rect(screen,white,select_rect,3,5)
            if masic_list:
                for i, masic in enumerate([masic_list[i]["masic_name"] for i in range(len(masic_list))]):
                    text = font.render(masic, True, white)
                    screen.blit(text, ((select_rectx + 14) + 30, (select_recty + 14) + 24 * i))
                screen.blit(cursor, ((select_rectx + 14), (select_recty + 11) + 24 * masic_index))  # カーソル描画
    # メッセージウィンドゥ
    if battle_message:
        pygame.draw.rect(screen, white, message_rect, 3,5)
        # バトルメッセージ
        draw_text(screen,message,((message_rectx + 24),(message_recty + 24)),font)

    # プレイヤーのダメージエフェクト
    if status_flash > 0:
        status_visible = pygame.time.get_ticks() // 90 % 2
        status_flash -= 1
        if status_flash == 19:
            sound2.play()
    if status_flash == 1:
        status_flash = 0
        status_visible = 0
        if player_HP <= 0:
            bgm(lose_bgm)
            message = "そのあと\nゆうしゃのすがたをみたものはいない"
            phase = 4
        else:
            phase = 2
    # モンスターのダメージエフェクト
    if mon_flash > 0:
        mon_visible = pygame.time.get_ticks() // 90 % 2
        mon_flash -= 1
        if mon_flash == 19:
            sound2.play()
    if mon_flash == 1:
        mon_flash = 0
        mon_visible = 0
        if status_data[select_index]["HP"] <= 0: 
            defeat = True
        else:
            phase = 2
                
    # まほう（色付き半透明レクト）
    if player_MP >= masic_list[masic_index]["MP"]:
        if masic_frame > 0:
            screen.blit(masic_list[masic_index]["surface"],(0,0))
            masic_frame -= 1

    pygame.display.update()
    
    # キーハンドラー
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_z and mon_flash == 0 and status_flash == 0:
                # あらわれた！を消してコマンドウィンドゥをひらく
                if phase == 0:
                    sound.play()                        
                    battle_message = False # あらわれた！を消す
                    command = True
                    cmd_cursor = True
                    phase = 1
                # コマンドウィンドゥを開いたまま、魔物選択ウィンドゥをひらく
                # 「たたかう」
                elif phase == 1 and cmd_index == 0:
                    sound.play()                        
                    select = True
                    cmd_cursor = False
                    phase = 2
                # 「まほう」
                elif phase == 1 and cmd_index == 1:
                    sound.play()                        
                    masic_select = True
                    cmd_cursor = False
                    masic_phase += 1
                    if masic_phase == 2:
                        phase = 2
                # 魔物選択ウィンドゥを消して、メッセージの表示
                elif phase == 2:
                    command = False
                    select = False
                    masic_phase = 3
                    battle_message = True
                    status_data2 = sorted(status_data, key=lambda dictionary: dictionary["quickness"], reverse=True)
                    if actor_index < len(status_data2):
                        current_actor = status_data2[actor_index]
                        sound.play()
                        if cmd_index == 0:
                            message = f'{current_actor["name"]}の　こうげき！'
                        if cmd_index == 1:
                            if current_actor["name"] == "ゆうしゃ":
                                message = f'{player_name}は　{masic_list[masic_index]["masic_name"]}を　となえた！'
                                masic_effect = masic_list[masic_index]["masic_effect"]
                                masic_frame = 10
                            else:
                                message = f'{current_actor["name"]}の　こうげき！'

                        phase = 3
                    # ターン終了したら、コマンドウィンドゥをひらく
                    elif actor_index == len(status_data):
                        actor_index = 0
                        select_index = 0
                        masic_index = 0
                        masic_phase = 0
                        cmd_index, cmd_num1,cmd_num2 = 0, 0, 0
                        sound.play()
                        battle_message, command, masic_select, cmd_cursor = False, True, False, True
                        phase = 1
                        for i in range(len(mon_group_list)):
                            status_data[i]["attack_on"] = 0
                # プレイヤーの攻撃(モンスターに与えるダメージ)
                elif phase == 3 and current_actor["name"] == "ゆうしゃ" and not defeat:
                    if cmd_index == 1 and player_MP < masic_list[masic_index]["MP"]:
                        message = "ＭＰが足りない…"
                        phase = 2
                    elif cmd_index == 0 or masic_list[masic_index]["masic_type"] == "攻撃まほう":
                        if cmd_index == 0:
                            mon_damage = player_power // 2 - status_data[select_index]["deffence"] // 4
                        elif cmd_index == 1:
                            mon_damage = masic_list[masic_index]["数値"]
                            player_MP -= masic_list[masic_index]["MP"]
                        mon_damage = random.randint(mon_damage,int(mon_damage * 1.5))
                        if mon_damage <= 0:
                            mon_damage = 1
                        status_data[select_index]["HP"] -= mon_damage
                        message = f'{player_name}の　こうげき！\n{status_data[select_index]["name"]}に　{mon_damage}の ダメージ！' 
                        mon_flash = 20
                        if status_data[select_index]["attack_on"] == 1:
                            actor_index -= 1
                    elif masic_list[masic_index]["masic_type"] == "補助まほう":
                        # まほう（回復）
                        if masic_effect == 2:
                            if player_MP >= masic_list[masic_index]["MP"]:
                                recovery  = random.randint(masic_list[masic_index]["数値"],int(masic_list[masic_index]["数値"] * 1.5))
                                player_HP = min(player_Max_HP,player_HP + recovery)
                                message = f'{player_name}は　{masic_list[masic_index]["masic_name"]}を　となえた！\n{chara_list[chara_index]}の　きずが　かいふくした！' 
                        player_MP -= masic_list[masic_index]["MP"]
                        phase = 2
                    actor_index += 1
                elif defeat:
                    message = f'{player_name}の　こうげき！\n{status_data[select_index]["name"]}に　{mon_damage}の ダメージ！\n{status_data[select_index]["name"]}をたおした！'
                    del mon_group_list[select_index]
                    del monster_rects[select_index]
                    del status_data[select_index]
                    defeat = False
                    phase = 2
                    # モンスターをすべてたおした時の処理
                    if len(mon_group_list) == 0:
                        bgm(win_bgm)
                        message = "モンスターたちをやっつけた！"
                        phase = 4
                # モンスターの攻撃(プレイヤーに与えるダメージ)
                elif phase == 3:
                    sound.play()
                    for i in range(len(mon_group_list)):
                        if current_actor["name"] == status_data[i]["name"]:
                            player_damage = status_data[i]["power"] // 2 - player_deffence // 4
                            player_damage = random.randint(player_damage,int(player_damage * 1.5))
                            if player_damage <= 0:
                                player_damage = 1
                            player_HP -= player_damage
                            message = f'{current_actor["name"]}の　こうげき！\n{player_name}に　{player_damage}のダメージ！'
                            status_flash = 20
                            if player_HP <= 0:
                                player_HP = 0
                    current_actor["attack_on"] = 1
                    actor_index += 1
                # ワンテンポ置く
                elif phase == 4:
                    sound.play()
                    phase = 5
                elif phase == 5:
                    sound.play()
                    pygame.quit()
                    sys.exit()
                        
            #方向キー
            if event.type == KEYDOWN:
                if command and not select and not masic_select:
                    if event.key == K_DOWN:
                        cmd_num1 = (cmd_num1 + 1) % 3  # 下へ移動
                    if event.key == K_UP:
                        cmd_num1 = (cmd_num1 - 1) % 3  # 上へ移動
                    if event.key == K_RIGHT:
                        cmd_num2 = (cmd_num2 + 1) % 2  # 下へ移動
                    if event.key == K_LEFT:
                        cmd_num2 = (cmd_num2 - 1) % 2  # 下へ移動
                if select or masic_phase == 2 and masic_list[masic_index]["masic_type"] == "攻撃まほう":
                    if event.key == K_DOWN:
                        select_index = (select_index + 1) % len(mon_group_list)  # 下へ移動
                    if event.key == K_UP:
                        select_index = (select_index - 1) % len(mon_group_list)  # 上へ移動
                if masic_phase == 2 and masic_list[masic_index]["masic_type"] == "補助まほう":
                    if event.key == K_DOWN:
                        chara_index = (chara_index + 1) % len(chara_list)  # 下へ移動
                    if event.key == K_UP:
                        chara_index = (chara_index - 1) % len(chara_list)  # 上へ移動
                if masic_select and masic_phase <= 1:
                    if event.key == K_DOWN:
                        masic_index = (masic_index + 1) % len(masic_list)  # 下へ移動
                    if event.key == K_UP:
                        masic_index = (masic_index - 1) % len(masic_list)  # 上へ移動
                                       

```
</details>


<details><summary>ここにコードの概要があります</summary>

# コードの概要

### 1.インポート:star:
　import pygame
　from pygame import *
　import sys
　import time
　import random
　
### 2.関数:hammer_pick:
　部分一致で値を取得する関数　改行してテキストを描画する関数
　2列×3行のテキストを描画する関数
　BGMの関数

### 3.セットアップ:gear:
　パス　各種変数(`まほう`)　レクト　コマンドテキスト　勇者のステータス
　ステータステキスト　モンスター関連

### 4.描画:art:
　ステータスウィンドウ　モンスター画像　コマンドウィンドゥ
　魔物選択ウィンドゥ　`キャラの選択ウィンドゥ`　`まほうの選択ウィンドゥ`　
　バトルメッセージウィンドゥ

　プレイヤーのダメージエフェクト ＋ 敗北判定
　モンスターのダメージエフェクト ＋ 倒したかどうかの判定

　`まほう(色付き半透明レクト)`

### 5.キーハンドラー:keyboard:
　**Zキー：**
 (あらわれた！　たたかうコマンド　`まほうコマンド`　こうげきメッセージ
 `まほうメッセージ`　ターン終了　 `MP判定`
 モンスターへ与えるこうげきダメージ計算　`モンスターへ与えるまほうダメージ計算`　`まほう回復`　倒した時の処理　プレイヤーに与えるダメージ計算
 ワンテンポ置く　画面を閉じる)　
　**方向キー：**
 (コマンドの方向キー、魔物選択の方向キー　
　`キャラ選択の方向キー`　`まほう選択の方向キー`)

-----------------------------------------------------------------------------
</details>

<details><summary>ここに変数の説明があります</summary>


**変数の説明**



---

### **🔢 インデックス**
```python
masic_index = 0
chara_index = 0
```
🧙‍♂️ **説明**: まほう（魔法）とキャラの選択に使用するインデックス変数。カーソルの位置にも利用している。  
🎯 **データ取得**:  
- 🌀 **まほう** → `masic_list` から値を取得  
- 🧑‍🎤 **キャラ** → `chara_list` から要素を取得  

---

### **🔄 まほう選択の段階**
```python
masic_phase = 0
```
⚡ **説明**: まほうの選択を **2段階** に分ける。  
- 🔥 **攻撃まほう** → `masic_phase = 1` で **まほう選択**、`masic_phase = 2` で **モンスター選択**。  
- ❤️ **回復まほう** → `masic_phase = 1` で **まほう選択**、`masic_phase = 2` で **キャラ選択**。  

---

### **💥 まほうエフェクト**
```python
masic_effect = 0
```
🌟 **説明**: まほうの効果を管理するフラグ。  
- 🔥 **攻撃まほう** → `1`  
- ❤️ **回復まほう** → `2`  

---

### **⏳ まほうフレーム**
```python
masic_frame = 0
```
⌛ **説明**: まほうのエフェクトの持続時間を管理する変数。  
🕰️ まほうメッセージの表示時に設定され、`10` から `1` ずつ減少。（正確な秒数は不明）  

---

### **🎨 まほうサーフェイス（半透明）**
```python
damera_surface = pygame.Surface((width, height), SRCALPHA)
damera_surface.fill((255, 201, 14, 128))

hoimun_surface = pygame.Surface((width, height), SRCALPHA)
hoimun_surface.fill((255, 255, 255, 128))
```
🖌️ **説明**: まほうの視覚的なエフェクトを表す半透明のサーフェイス。  
- 🔥 **攻撃まほう** → **オレンジ** (`damera_surface`)  
- ❤️ **回復まほう** → **白** (`hoimun_surface`)  

---

### **📖 まほう辞書**
```python
damera = {
    "masic_name": "ダメラ",
    "MP": 2,
    "数値": 10,
    "masic_effect": 1,
    "masic_type": "攻撃まほう",
    "surface": damera_surface
}

hoimun = {
    "masic_name": "ホイムン",
    "MP": 3,
    "数値": 30,
    "masic_effect": 2,
    "masic_type": "補助まほう",
    "surface": hoimun_surface
}
```
📜 **説明**: まほうのデータを辞書として管理。  
📌 **各まほうの特性**:
- 🌀 **MP** → 消費MP  
- 🔥 **masic_effect** → `1`（攻撃まほう） / `2`（回復まほう）  
- 📊 **数値** → 攻撃まほうは **ダメージ**、回復まほうは **回復量**  
- 🎭 **masic_type**:
  - `"攻撃まほう"` → **魔物選択ウィンドウ** を開く  
  - `"補助まほう"` → **キャラ選択ウィンドウ** を開く  

---

### **📋 まほうのリスト**
```python
masic_list = [damera, hoimun]
```
🗂️ **説明**: まほうのデータをまとめたリスト。  

---

### **🖱️ コマンドカーソル**
```python
cmd_cursor = False
```
👀 **説明**: コマンド選択中にコマンドカーソルを **表示** するフラグ。  

---

### **👥 キャラリスト**
```python
chara_list = ["ゆうしゃ", "せんし"]
```
🧑‍🎤 **説明**: 回復まほう使用時に選択する **キャラリスト**。  
⚠️ `"せんし"` はカーソルのテスト用。（**実際には使用しない**）  

---


</details>


<details><summary>ここにコードの説明があります</summary>


```python
# まほう（回復）
if masic_effect == 2:
    if player_MP >= masic_list[masic_index]["MP"]:
        recovery  = random.randint(masic_list[masic_index]["数値"],int(masic_list[masic_index]["数値"] * 1.5))
        player_HP = min(player_Max_HP,player_HP + recovery)
        message = f'{player_name}は　{masic_list[masic_index]["masic_name"]}を　となえた！\n{chara_list[chara_index]}の　きずが　かいふくした！' 
```

min(player_Max_HP,player_HP + recovery)
player_Max_HPを超えないようにする。

例:
**player_Max_HPを超える場合**
player_Max_HP 53
player_HP `50`
recovery `30`
min(53,80)
最小値が選ばれ、53

**player_Max_HPを超えない場合**
player_HP `13`
recovery `30`
min(53,43)
最小値が選ばれ、43


</details>


**`まほうフローチャート`:point_down:**
```mermaid

graph TB

%%{
  init: {
    'look': 'handDrawn'
  }
}%%

subgraph コマンド
a
end

subgraph masic_phase1
subgraph まほう選択
b
c
end
end

subgraph masic_phase2
subgraph モンスター選択
d
e
f
end

subgraph キャラ選択
g
h
end
end

コマンド-->まほう選択
a[まほう
cmd_index1]
b[ダメラ
masic_index0]-->モンスター選択
c[ホイムン
masic_index1]-->キャラ選択
d[モンスター名
select_index0]
e[モンスター名
select_index1]
f[モンスター名
select_index2]
g[ゆうしゃ
chara_index0]
h[せんし
chara_index1]

```