状態遷移ふたたび
ゲーム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の行動は、いきなりコードを書くよりも、先に表や図で整理すると分かりやすくなります。
No Comments