【解決】最短経路探索を諦めた時の判定について

hadhad
記事: 20
登録日時: 2016年6月09日(木) 15:55

【解決】最短経路探索を諦めた時の判定について

投稿記事by hadhad » 2016年11月03日(木) 22:04

お世話になります。

this.moveStraight(this.findDirectionTo(x,y))を移動ルートの指定にて設定すると、
最短経路探索を行ってその座標に向かってくれますよね。

しかし、Game_Character.prototype.searchLimitにて設定された距離よりも離れた所に目的地があると、
最短距離探索を諦めて普通に近づくだけになり、目的地までの間に壁があると、避けずにスタックしてしまいます。

そこで設定された各イベントごとに「最短距離探索を諦めたかどうか」を取得したいと思っています。

例えば用法としては、町のマップで住民たちが目的の家々にゆっくりと歩いて行くさい、
遠すぎて最短距離探索ができない場合はランダム移動をするようにしたいといった感じです。

どなたか、解決方法が分かりましたら教えてください。
宜しくお願い致します。
最後に編集したユーザー hadhad on 2016年11月08日(火) 04:29 [ 編集 3 回目 ]

hadhad
記事: 20
登録日時: 2016年6月09日(木) 15:55

Re: 最短経路探索を諦めた時の判定について

投稿記事by hadhad » 2016年11月04日(金) 21:21

Twitterにて、
「壁にぶつかって止まっていたら、ランダム行動するのはどうか」
という案が浮かびましたが、それではAIの挙動が間抜けですので、
問題の通り、「壁にぶつかる前に探索経路を完遂できるか調べる」方法をお願いします。

画像
アバター
トリアコンタン
記事: 2311
登録日時: 2015年11月10日(火) 21:13
お住まい: きのこ王国
連絡を取る:

Re: 最短経路探索を諦めた時の判定について(追記あり)

投稿記事by トリアコンタン » 2016年11月04日(金) 22:51

findDirectionToでゴールに辿り着いた場合、グローバル変数「goaled」がtrueに設定されます。
これを利用して事前にgoaledをfalseに設定しておき、テスト実行後にgoaledの値を確認することで
最短経路の発見に成功したかどうかを判定できます。

実行例(イベントコマンドのスクリプトから実行する場合)

コード: 全て選択

goaled = false;
this.character(0).findDirectionTo(x, y);
console.log(goaled);


ただし、グローバル変数「goaled」は、いわゆるグローバル汚染を引き起こしており、バグではないが不適切な実装となっています。
今後の改修で人知れず修正される可能性は(極めて低いですが)ゼロではないので上記方法を採用する場合はご注意ください。
プラグイン関連のトラブルが発生した際の切り分けと報告の方法です。
http://qiita.com/triacontane/items/2e227e5b5ce9503a2c30

[Blog] : http://triacontane.blogspot.jp/
[Twitter]: https://twitter.com/triacontane/
[GitHub] : https://github.com/triacontane/
アバター
トリアコンタン
記事: 2311
登録日時: 2015年11月10日(火) 21:13
お住まい: きのこ王国
連絡を取る:

Re: 最短経路探索を諦めた時の判定について(追記あり)

投稿記事by トリアコンタン » 2016年11月07日(月) 01:37

移動ルート設定のスクリプトから実行する場合のスクリプトを追記します。
指定したX座標、Y座標に到達可能な場合はそこに向かって移動し、できなかった場合はランダム移動します。

コード: 全て選択

goaled = false;
this._tempDirection = this.findDirectionTo(x, y);
goaled ? this.moveStraight(this._tempDirection) : this.moveRandom();
プラグイン関連のトラブルが発生した際の切り分けと報告の方法です。
http://qiita.com/triacontane/items/2e227e5b5ce9503a2c30

[Blog] : http://triacontane.blogspot.jp/
[Twitter]: https://twitter.com/triacontane/
[GitHub] : https://github.com/triacontane/
hadhad
記事: 20
登録日時: 2016年6月09日(木) 15:55

Re: 最短経路探索を諦めた時の判定について(追記あり)

投稿記事by hadhad » 2016年11月08日(火) 04:28

お見事です。
どちらもやってみて完璧に再現出来ました。
しかし、グローバル変数とはちょっと心配ですね。

ありがとうございました!
アバター
MEIKOI
記事: 168
登録日時: 2018年9月22日(土) 20:13
連絡を取る:

Re: 【解決】最短経路探索を諦めた時の判定について

投稿記事by MEIKOI » 2021年4月23日(金) 15:26

解決済みのトピックに投稿すみませんm(_ _)m

goaled = false;
this.character(0).findDirectionTo(x, y);
console.log(goaled);

上記コンソールログを確認すると
たどり着ける経路でtrueが帰ってこないのですが
原因はどういうものでしょうか。。。


実際の設定としては、
新規マップで、イベントを座標0,0に配置して、1ページ目(並列処理)で
イベントコマンドスクリプトに
goaled = false;
this.character(0).findDirectionTo(3, 3);
console.log(goaled);

と記述しました。
仕様変更とかですかね・・・?
jp_asty
記事: 81
登録日時: 2019年11月12日(火) 15:34

Re: 【解決】最短経路探索を諦めた時の判定について

投稿記事by jp_asty » 2021年4月24日(土) 20:37

こんばんは。

1.6.2のコアを見る限り、goaledという変数は存在していないようです。
当初のやりとりが2016年のものなので恐らく初期のころのコアにあったものが削除されたものと思われます。

目的地が見つからないときランダムに移動する。
コアスクリプトを書き換える方法で良い。
の条件でOKであれば、次の代替え案で一応そういう動きになるとは思います。

rpg_object.js(1.6.2) の7378 ~ 7382行目までをコメントアウト(または削除)
その下に次のコードを追加。

コード: 全て選択

if(deltaX2 !== 0 || deltaY2 !== 0) {
      return 2 + Math.randomInt(4) * 2;
}

ランダム移動にしたいわけではなく、場合分けが目的などの場合には、ツクールの変数を操作するなどしてうまいことやる形かなと思います。

よろしくお願いします。
---------------------------------------------------------------------------------------------
プラグイン置き場 : https://github.com/ste0/RPG-Maker-MV-Plugins
アバター
MEIKOI
記事: 168
登録日時: 2018年9月22日(土) 20:13
連絡を取る:

Re: 【解決】最短経路探索を諦めた時の判定について

投稿記事by MEIKOI » 2021年4月25日(日) 09:28

jp_asty 様
こんにちは!お久しぶりです。いつもアドバイスありがとうございます。

コアスクリプト書き換えで問題ないので
早速、書き換えして試してみましたが、動作は
目的地に一目散に向かって走って行き止まりで固まりました^^;;

1.6.2の各当部分前後のデフォルトの記述は下記のようになっています。

コード: 全て選択

   
    var deltaX2 = this.deltaXFrom(goalX);
    var deltaY2 = this.deltaYFrom(goalY);
    if (Math.abs(deltaX2) > Math.abs(deltaY2)) {
        return deltaX2 > 0 ? 4 : 6;
    } else if (deltaY2 !== 0) {    //7378行目
        return deltaY2 > 0 ? 8 : 2;
    }

    return 0;                                              //7382行目
};


何かアドバイス頂けますとありがたいです。
よろしくお願いします。
jp_asty
記事: 81
登録日時: 2019年11月12日(火) 15:34

Re: 【解決】最短経路探索を諦めた時の判定について

投稿記事by jp_asty » 2021年4月25日(日) 10:35

自分のみていたプロジェクトファイルはテスト用のもので色々書き換えをしているうちに微妙に
行数がずれてしまっていたようです。失礼しました。

コード: 全て選択

if (Math.abs(deltaX2) > Math.abs(deltaY2)) {
        return deltaX2 > 0 ? 4 : 6;
} else if (deltaY2 !== 0) {
        return deltaY2 > 0 ? 8 : 2;
}
の部分を

コード: 全て選択

if(deltaX2 !== 0 || deltaY2 !== 0) {
      return 2 + Math.randomInt(4) * 2;
}
に書き換えるというものとなります。

目的地に移動できるときはそのまま目的地まで移動し、
findDirectionToメソッドの処理的に目的の経路がないと判断されたタイミングのときのみランダム移動するようになります。
---------------------------------------------------------------------------------------------
プラグイン置き場 : https://github.com/ste0/RPG-Maker-MV-Plugins
アバター
MEIKOI
記事: 168
登録日時: 2018年9月22日(土) 20:13
連絡を取る:

Re: 【解決】最短経路探索を諦めた時の判定について

投稿記事by MEIKOI » 2021年4月25日(日) 12:30

jp_asty様

無事、書き換えて、動作確認できました!
この部分が諦めた時の動作なんですね、読んでもまったく何をしているのかわかりません^^;
一旦、目的の動作を達成できたので、ありがとうございました(^^
追伸 この部分に直接、判定用のスイッチや変数の記述したらマズイですかね?

“MV:質問” へ戻る