Skip to main content

状態遷移ふたたび

ゲームAI課題

センサー・視界・状態遷移表・状態遷移図を書いてみよう


1. 今日の課題

今回の課題では、モンスターAIの行動を

センサー
視界
状態遷移表
状態遷移図

として整理します。

プログラムは書きません。

しかし、最後に C++ の switch case や State パターンへ変換できるように、条件や状態をきちんと整理します。


2. 今日のゴール

この課題のゴールは、次の4つです。

1. モンスターが何を調べているのかを考える
2. センサーの結果をフラグとして整理する
3. 状態遷移表を書ける
4. 状態遷移図を書ける

3. AIは何を見ているのか

ゲームAIは、人間のように画面を見ているわけではありません。

AIは、ゲーム内の情報を数値や条件として調べています。

例えば、

プレイヤーが見えているか
プレイヤーが攻撃範囲にいるか
探索時間が終わったか

などです。

このような情報を調べる仕組みを、ここでは センサー と呼びます。


4. センサーとは何か

センサーとは、

AIが状況を判断するために使う情報を調べる処理

です。

例えば、モンスターAIでは次のようなセンサーが考えられます。

センサー 調べること
視界センサー プレイヤーが見えているか
距離センサー プレイヤーが近いか
攻撃範囲センサー 攻撃できる距離にいるか
探索時間センサー 探索時間が終わったか
壁センサー プレイヤーとの間に壁があるか

5. 視界センサーの考え方

視界センサーは、

プレイヤーが見えているか?

を調べるセンサーです。

ただし、ゲームAIは本当に映像を見ているわけではありません。

多くの場合、次のような条件で「見えている」と判断します。

1. プレイヤーが一定距離以内にいる
2. プレイヤーがモンスターの前方にいる
3. プレイヤーとの間に壁がない

6. 視界センサーの例

距離が近い
かつ
前方にいる
かつ
壁で隠れていない
↓
プレイヤーを見つけた

C++で使うなら、次のような関数にできます。

bool CheckCanSeePlayer();

この関数が true なら、

isFindPlayer = true;

と考えます。


7. センサーからフラグを作る

AIの判断では、センサーの結果をフラグとして使うと分かりやすくなります。

bool isFindPlayer;      // プレイヤーを見つけた
bool isAttackRange;     // 攻撃範囲に入った
bool isLostPlayer;      // プレイヤーを見失った
bool isSearchTimeOver;  // 探索時間が終わった

つまり、

センサーで調べる
↓
フラグにする
↓
状態遷移の条件に使う

という流れです。


8. 状態とは何か

状態とは、

今、そのキャラクターが何をしているか

を表すものです。

例えば、モンスターには次のような状態があります。

状態 意味
Patrol 巡回している
Chase プレイヤーを追いかけている
Attack 攻撃している
Search プレイヤーを探している

9. 状態遷移とは何か

状態遷移とは、

ある状態から、別の状態に切り替わること

です。

例えば、

Patrol
↓ プレイヤーを見つけた
Chase

これは、

巡回中に視界センサーがプレイヤーを発見したので、
追跡状態に変わった

という意味です。


10. 今回作るモンスターAI

今回のモンスターは、次のように動きます。

普段は決められた道を巡回している。
視界センサーでプレイヤーを見つけたら追いかける。
距離センサーで攻撃範囲に入ったと分かったら攻撃する。
攻撃中に視界センサーでプレイヤーを見失ったら、周囲を探す。
探索時間センサーで時間切れになったら、巡回に戻る。

11. 使用する状態

今回使う状態は、次の4つです。

状態名 内容
Patrol 決められた道を巡回する
Chase プレイヤーを追いかける
Attack プレイヤーを攻撃する
Search プレイヤーを探す

12. 使用するセンサー

今回使うセンサーは、次の3つです。

センサー名 内容 C++向けの関数名
視界センサー プレイヤーが見えているか CheckCanSeePlayer()
攻撃範囲センサー 攻撃できる距離にいるか CheckAttackRange()
探索時間センサー 探索時間が終わったか CheckSearchTimeOver()

13. 使用するフラグ

今回使うフラグは、次の4つです。

フラグ名 意味
isFindPlayer プレイヤーを見つけた
isAttackRange 攻撃範囲に入った
isLostPlayer プレイヤーを見失った
isSearchTimeOver 探索時間が終わった

14. センサーとフラグの関係

センサーからフラグを作ると、次のようになります。

isFindPlayer = CheckCanSeePlayer();
isAttackRange = CheckAttackRange();
isSearchTimeOver = CheckSearchTimeOver();
isLostPlayer = !isFindPlayer;

!isFindPlayer は、

プレイヤーを見つけていない

という意味です。

つまり、プレイヤーが見えていなければ、見失ったと考えることができます。


15. 課題1:センサーの意味を説明する

次のセンサーについて、自分の言葉で説明しなさい。

センサー 自分の説明
視界センサー
攻撃範囲センサー
探索時間センサー

16. 課題2:視界センサーの条件を考える

視界センサーで「プレイヤーが見えている」と判断するには、どのような条件が必要ですか。

下の表を完成させなさい。

条件 説明
距離
向き

17. 課題3:状態の意味を説明する

次の状態について、自分の言葉で説明しなさい。

状態 自分の説明
Patrol
Chase
Attack
Search

18. 課題4:状態遷移を文章で整理する

次の状態遷移を、センサーやフラグの言葉を使って説明しなさい。


Patrol → Chase

説明:

巡回中に視界センサーでプレイヤーを見つけたら、追跡状態に変わる。

問題

遷移 説明
Patrol → Chase
Chase → Attack
Attack → Search
Search → Patrol

19. 課題5:状態遷移表を完成させる

次の表を完成させなさい。

現在の状態 センサー・条件 フラグ 次の状態
Patrol 視界センサーでプレイヤーを見つけた
Chase 攻撃範囲センサーで攻撃範囲に入った
Attack 視界センサーでプレイヤーを見失った
Search 探索時間センサーで時間切れになった

20. 課題6:C++向けの状態遷移表を書く

課題5を使って、C++で使いやすい形の状態遷移表を書きなさい。

現在の状態 条件 次の状態
EnemyState::Patrol EnemyState::Chase
EnemyState::Chase EnemyState::Attack
EnemyState::Attack EnemyState::Search
EnemyState::Search EnemyState::Patrol

21. 課題7:状態遷移図を描く

次の4つの状態を使って、状態遷移図を描きなさい。

Patrol
Chase
Attack
Search

矢印には、状態が変わる条件を書きなさい。


図の例

Patrol -- isFindPlayer --> Chase

作図スペース













22. 課題8:C++のswitch caseに変換する準備

次のひな形の空欄を埋めなさい。

switch (state)
{
case EnemyState::Patrol:
    if (__________)
    {
        state = EnemyState::__________;
    }
    break;

case EnemyState::Chase:
    if (__________)
    {
        state = EnemyState::__________;
    }
    break;

case EnemyState::Attack:
    if (__________)
    {
        state = EnemyState::__________;
    }
    break;

case EnemyState::Search:
    if (__________)
    {
        state = EnemyState::__________;
    }
    break;
}

23. 課題9:AIとして自然に見えるか考える

今回のAIは、次の流れでした。

Patrol
↓ 視界センサーでプレイヤーを見つけた
Chase
↓ 攻撃範囲センサーで攻撃範囲に入った
Attack
↓ 視界センサーでプレイヤーを見失った
Search
↓ 探索時間センサーで時間切れ
Patrol

このAIには、まだ不自然なところがあります。

例えば、

Chase中にプレイヤーを見失ったらどうなるのか?
Attack中に攻撃範囲から出たらどうなるのか?
Search中にプレイヤーを再発見したらどうなるのか?

などです。

このAIに追加した方がよい状態遷移を2つ考えなさい。

追加したい遷移 使うセンサー・条件 理由

24. 45分の進め方

時間 内容
0〜5分 センサー・視界・状態遷移の説明を読む
5〜10分 今回のモンスターAIの仕様を確認する
10〜17分 課題1・2:センサーと視界条件を整理する
17〜24分 課題3・4:状態と遷移を文章で説明する
24〜32分 課題5・6:状態遷移表を作る
32〜40分 課題7:状態遷移図を描く
40〜43分 課題8:switch caseの形にする
43〜45分 課題9:改善案を考える

25. 提出物

次の5つを提出しなさい。

1. センサーの説明
2. 視界センサーの条件
3. 状態遷移表
4. 状態遷移図
5. switch case のひな形

26. まとめ

今回の課題では、プログラムを書く前にAIの行動を整理しました。

重要なのは、次の流れです。

センサーで状況を調べる
↓
フラグにする
↓
状態を決める
↓
状態が変わる条件を決める
↓
状態遷移表を書く
↓
状態遷移図を書く
↓
C++のswitch caseに変換する

AIの行動は、いきなりコードを書くよりも、先に表や図で整理すると分かりやすくなります。