ページ 11

エンカウント

Posted: 2010年1月18日(月) 11:29
by 炒飯
C言語でRPGゲームを作っているのですが、
Wikipediaにあるような『エンカウント率 (%) = 100 / 戦闘後、次の敵に遭遇するまでの平均歩数』
でコーディングしてしまうと思ったような結果が得られません。

平均5歩歩いた時にエンカウントするようにしたいのですが、
上の式を使用すると、ほぼ3歩目までにはエンカウントしてしまいます。
どなたか心地よく平均5歩でエンカウントする具体的なC言語でのコーディング例をご教授いただけませんでしょうか?

よろしくお願いします。

Re:エンカウント

Posted: 2010年1月18日(月) 12:06
by Dixq (管理人)
難しく考えないでも、
例えば3~7の乱数作って、歩数と一致いたらエンカウントでよくないですか?単純に考えて5歩平均になりそうです。
平均の幅を広げたいなら1~9作るとか。

Re:エンカウント

Posted: 2010年1月18日(月) 12:15
by 炒飯
回答ありがとうございます。

成程、難しく考えなくてもよさそうですね。。
もしよろしければ、具体的な実装例を示していただくわけにはいきませんか?

Re:エンカウント

Posted: 2010年1月18日(月) 12:18
by softya
>エンカウント率 (%) = 100 / 戦闘後、次の敵に遭遇するまでの平均歩数
この式は、あくまでエンカウント率ですのでエンカウント処理に使う事自体間違ってます。
もしエンカウント率20%で計算していたら、ほぼ100%5歩でエンカウントします。
だって、1歩20%の確率なら5歩で100%じゃないですか。
※実際には違いますが、体感上はほぼ100%のはずです。

そうですね。一番楽な方法は、次のエンカウントまでの歩数を先に計算してしまうことです。
バトル終了時にエンカウントするまでの歩数を決めてしまいましょう。
エンカウントする歩数 = 3 + 乱数(0~4)
とすれば平均5歩でエンカウントするはずです。
※ちなみに3は、短い歩数でエンカウントしないための底上げ歩数です。

他にもエンカウント計算は色々工夫しがいのあるポイントです。
プログラムのアルゴリズムの勉強にもなるので色々考えてみて下さい。

私のアイデアを書いておきます。
・一歩ごとにエンカウント率が上がっていくエンカウントシステム。
・見えない敵のいるポイントを乱数で決めておいて接触したらエンカウント。
・直進するとエンカウント率が下がり、曲がった直後だけエンカウント率が上がるシステム。

ただ、5歩はエンカウント率が高すぎる気がすますね。
実際に作って調整してみてくださいとしか言えませんが。

Re:エンカウント

Posted: 2010年1月18日(月) 12:39
by sizuma
エンカウント率20%で敵に遭遇しようとする期待値を計算すると

0.2 * 1 + (1-0.2)*0.2 * 2 + (1-0.2-(1-0.2))*0.2 * 3 + ・・・・

かな?
極限まで計算すると3になるのではないでしょうかね。
softyaさんのおっしゃる通りに、5までにエンカウントする確率が

0.2 + 0.16 + 0.128 + 0.1024 + 0.08192 + .....

6.7くらいですね。
3回に2回は5までにエンカウント、しかもカウントが少ないほうがエンカウントする確率が高い、ってことかな。 画像

Re:エンカウント

Posted: 2010年1月18日(月) 17:36
by 炒飯
回答ありがとうございます。

softyaさんやsizumaさんの理論を具体的にクールにコーディングするには
どうすればよいでしょうか?

具体例ばかり聞いて恐縮なのですが、
c言語を始めて間もないため少しでも優秀な人の組み方を参考にして
よりクールな組み方が出来るようになりたいのです。

ご教授お願いします。

Re:エンカウント

Posted: 2010年1月18日(月) 17:59
by softya
いや、それほど難しくないですよ。
まず、
エンカウントする歩数 = 3 + 乱数(0~4)
でエンカウントする歩数を求めます。
あとは、一歩歩くごとにエンカウントする歩数から1を引いていって0になればエンカウント成立でバトル開始です。
残念ですが炒飯さんのプログラムがどうなっているか分からない以上は、これ以上のコードは書けません。

それと初心者が一番挑戦してはいけないゲーム開発はRPGと戦略シミュレーションだと思います。
なにせ作るプログラムが多い&前提とする知識が多い&ツールを作らないと手作業ではやることが多すぎるのでツール作れる技量が必要。と言う2D系ゲームで難易度最上級のプログラミング開発力が必要です。
私は経験からアクションゲーム、シューティングゲーム、アドベンチャーゲームを全て自力で作れない人にはRPGは難しすぎると思いますよ。作りたいのは止めはしませんが、地道に力を付けないと挫折します。

挫折している例(技量不足で挫折したのでは無いと思いますが。やることが多くて挫折した例かな?)。
http://inu.harisen.jp/top.html

Re:エンカウント

Posted: 2010年1月18日(月) 18:23
by sizuma
では一番簡単そうなDixqさんの考え方で書いてみます。
僕もどちらかというと初心者なので、softyaさんの回答があればきっとソッチの方がスマートです。


キャラの構造体の中に歩数をカウントする変数を追加する。
char.pedometer = 0;
マジックナンバーになりそうなエンカウント率をdefine(マクロ使いたくないけど、とりあえず)
#define ENCOUNT 5
といっても、これが歩数になるわけではないので、あくまで目安
ついでにエンカウントしない歩数は決めておく(これは確定)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ENCOUNT 5
#define DES_ENCOUNT 2

int main(){
    int petometor =0;
    int count =0;
    int ave = 0;//平均計算用
    srand((unsigned)time(NULL));
    for(count=1;count<100;count++){
        if(petometor>=ENCOUNT + DES_ENCOUNT ||
            rand()%ENCOUNT == (petometor-DES_ENCOUNT)){
            puts("encount!!");
            petometor = 0;
            ave++; //平均計算用
            continue;
        }
        puts("..walking...");
        petometor++ ;
    }
    printf("エンカウント率は%d\%\n",ave);
    printf("大体%d歩に一回エンカウントします",100/ave);
}
というわけでテスト用です。
大体これだと5、6歩に一回エンカウントするくらいですね。

#追記
コード書いてる間にsoftyaさんの投稿がありましたが、確かにエンカウントする歩数を先に決めた方が断然わかりやすいと僕は思うので、そっちで書いた方がよさそうですね。
画像

Re:エンカウント

Posted: 2010年1月18日(月) 20:21
by たかぎ
> softyaさん
> もしエンカウント率20%で計算していたら、ほぼ100%5歩でエンカウントします。
> だって、1歩20%の確率なら5歩で100%じゃないですか。
> ※実際には違いますが、体感上はほぼ100%のはずです。

そんなことはないでしょう。
平均して5歩に1回の頻度になるということは、具体的には、500万歩につき100万回になればよいわけで、これは20%の確率になります。
5歩歩いたときに遭遇する確率は、1- (1 - 0.2)^5 = 0.67232であり、約3分の2になります。

Re:エンカウント

Posted: 2010年1月18日(月) 20:27
by softya
>そんなことはないでしょう。
>平均して5歩に1回の頻度になるということは、具体的には、500万歩につき100万回になればよいわけで、これは20%の確率になります。
>5歩歩いたときに遭遇する確率は、1- (1 - 0.2)^5 = 0.67232であり、約3分の2になります。

その件はすでに指摘されてます。
確かに、確率の話は大雑把に言いすぎました。
ただ、70%ぐらいの確率になると、ほぼ体感上100%ぐらいに感じると思うんですが、どうでしょうか?
あくまで、ほぼですけどね。

Re:エンカウント

Posted: 2010年1月18日(月) 20:48
by sizuma
極限の計算しなきゃはっきりとした値は出せないですけど、最初に3歩でエンカウントするって質問でありましたね。
僕もrand()%5を100ループさせてみましたけど、だいたい3くらいでした。
期待値が約3なので、大体体感は3歩目でエンカウントする、ってなると僕は思います。
体感上のほぼ100%っていうのが分かりにくい気がしますね。

5歩目で100%になるなら、その真ん中ぐらい(1~5の間)の3歩目が体感するエンカウントの歩数だと思います。

Re:エンカウント

Posted: 2010年1月18日(月) 20:58
by たかぎ
> その件はすでに指摘されてます。

すみません。行ったり来たりしている間に見落としていました。
画像

Re:エンカウント

Posted: 2010年1月19日(火) 11:34
by 炒飯
皆さん、意義のある議論をしてくださってありがとうございます。
とてもためになります。

sizumaさんに教授頂いたコードをどのように改変すれば、
皆さんの議論の結果をより反映することができますでしょうか?
スマートな組み方を拝見したいので、是非ともどなたかご教授願います。

Re:エンカウント

Posted: 2010年1月19日(火) 12:01
by softya
うーん。
それを聞いてくるC言語の知識レベルだと、多分書いても自分のプログラムに反映出来ないんじゃないかと思うんですけどね。
今話しに出ているエンカウントの方法だとスマートとか、そんな問題じゃないんですよ。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ENCOUNT 5
#define DES_ENCOUNT 3

int main(){
int petometor =0;
int count =0;
int ave = 0;//平均計算用
srand((unsigned)time(NULL));
// エンカウントする歩数 = 3 + 乱数(0~4)
petometor = DES_ENCOUNT + rand()%ENCOUNT;
for(count=1;count<100;count++){
if(petometor==0) {
puts("encount!!");
// エンカウントする歩数 = 3 + 乱数(0~4)
petometor = DES_ENCOUNT + rand()%ENCOUNT;
ave++; //平均計算用
continue;
}
puts("..walking...");
petometor--;
}
printf("エンカウント率は%d\%%\n",ave);
printf("大体%f歩に一回エンカウントします",100.0f/(float)ave);
}

Re:エンカウント

Posted: 2010年1月19日(火) 16:16
by lbfuvab
エンカウント率をaとして

平均歩数 = 1Σn ( a * k * ((1-a)^(k-1)) )

でnを無限に向かう時のaを求めれば良いと思いますよ(ただの期待値です)
計算は高校数学程度と思いますので。

Re:エンカウント

Posted: 2010年1月19日(火) 19:25
by やそ
クールとかスマートとかあいまいな表現が多く、結局丸投げぽい投稿ですね^^;

rand()%5
で0だったらエンカウント
でいいじゃないですか。
1歩目からエンカウントしたっていいじゃないですか。

製作中のRPGはクリアまでにエンカウントフィールドを何歩くらい歩く想定なのでしょうか?

1万歩?
100万歩?

種をいろいろ変えて100万回ずつ検証してみてはいかがでしょう。
きっとそれなりになると思いますよ。

そもそも20%で遭遇する確率が適正なのかというところも考えたほうがいいのかも。

今のトピ主さんの発言から推測するレベルではsoftyaさんも指摘しているとおり、ここで得た回答を反映させようとしても余計なトラブル(バグ)を招きかねません。


しんぷるいずべすと

です。
自分の理解できるレベルで望みましょう。

>Wikipediaにあるような『エンカウント率 (%) = 100 / 戦闘後、次の敵に遭遇するまでの平均歩数』
でコーディングしてしまうと思ったような結果が得られません。

>平均5歩歩いた時にエンカウントするようにしたいのですが、
上の式を使用すると、ほぼ3歩目までにはエンカウントしてしまいます。

で作成したソースをさらしてみてはいかがでしょう?
あなたのレベルにあった回答が得られやすくなるでしょう。