隣接マスの内容を探るアルゴリズムがわかりません。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
COG

隣接マスの内容を探るアルゴリズムがわかりません。

#1

投稿記事 by COG » 1年前

陣地のマスをそれぞれ配列で処理して
012345
6789AB
CDEFGH
という形で管理し、戦闘後に陣取りが行われるゲームを考えています。
しかし、仮に下記のようになった場合、345を自軍とすると残り3つ巴となり
012345
6789AB
CDEFGH
ランダムで敵同士の戦闘を起こそうとすると、例えば乱数が16を出し、『G』が選ばれた場合、
隣接マスはA,F,Hの3つなので、自軍に攻め込もうとしてしまう=乱数の作り直しとなり、
対応策を考えないと運が悪いと延々乱数作りを繰り返すだけになってしまいます。
こういった場合、どのような処理をすべきなのでしょうか?

アバター
usao
記事: 1529
登録日時: 6年前

Re: 隣接マスの内容を探るアルゴリズムがわかりません。

#2

投稿記事 by usao » 1年前

「内地ではない」マスの集合から選択すれば良いだけの話ではないでしょうか.

COG

Re: 隣接マスの内容を探るアルゴリズムがわかりません。

#3

投稿記事 by COG » 1年前

「内地ではない」というと、例えばターン終了時の陣地確定時、
全マスに対して『上下左右が自軍のマスである場合』=『内地なので残存敵配列から除外』といった形でしょうか?
その場合、毎ターンの処理がとても煩雑になってしまう恐れがあるのですが、上手いやり方はありませんでしょうか?

たいちう
記事: 418
登録日時: 8年前

Re: 隣接マスの内容を探るアルゴリズムがわかりません。

#4

投稿記事 by たいちう » 1年前

> その場合、毎ターンの処理がとても煩雑になってしまう恐れがあるのですが、
> 上手いやり方はありませんでしょうか?

それほど煩雑にはならないでしょう。


> 対応策を考えないと運が悪いと延々乱数作りを繰り返すだけになってしまいます。

これについてもマップがよほど大きくなければ、また、その部分にバグがなければ、
「遅い」と認識できるほどの繰り返しは起こらないはずです。


どっちにしても杞憂だと思いますので、まずは実装してはいかがですか。
煩雑だったり効率が悪かったりするプログラムが完成してから、
必要ならば改善すればよいと思います。

COG

Re: 隣接マスの内容を探るアルゴリズムがわかりません。

#5

投稿記事 by COG » 1年前

アドバイスありがとうございます。
後だしの情報になってしまって恐縮なのですが、もう一点
■がキャラクターの入る余地のある陣地、□が何もないマスとして考えておりまして
■■□■■■□□■
■■■■■■■■■
□□■■■■■■□
■■■□■□□■■
■■□■■■■■■

01□234□□5
と、□の部分を飛ばした配列に入れて処理していますが、陣地[0]の隣接は1と9、陣地[3]の隣接は4と12……と対応表を作り、何百~千行作るより、
012345678
と□を飛ばさない陣地を用意して陣地[キャラクタ変数]と別枠にした方が、for文にできて速そうな感じはしますが、処理としてはどちらがはやいのでしょうか?
キャラクタ番号と陣地位置の関係がごっちゃになり難いのは前者だと思い、長々としたコードを書いてしまっているのですが……

説明下手なのとセオリー知らずで申し訳ありません。

たいちう
記事: 418
登録日時: 8年前

Re: 隣接マスの内容を探るアルゴリズムがわかりません。

#6

投稿記事 by たいちう » 1年前

> for文にできて速そうな感じはしますが、
> 処理としてはどちらがはやいのでしょうか?

速度の事は一旦忘れて、簡単な方法を採用してみましょう。
最初から完全なものを作る必要はありません。
簡単な方法で遅すぎた場合は、改善方法を考えましょう。

アバター
usao
記事: 1529
登録日時: 6年前

Re: 隣接マスの内容を探るアルゴリズムがわかりません。

#7

投稿記事 by usao » 1年前

マスの座標(多分(x,y)的なやつですよね)から,隣接マスが自明なデータ構造の方が
楽なんじゃないかな,と個人的に思います.
オフトピック
> 陣地[0]の隣接は1と9、陣地[3]の隣接は4と12……

□の部分は番号が振られないのであれば,1の下隣の番号は9にならないような…?

乱数を振った後でそのマスが「内地ではない」とわかった時点で,
リトライ(乱数振り直し)する前に
そのマスを候補集合から除去する,という方法とかでも
> 運が悪いと延々乱数作りを繰り返す
を防げますね.

COG

Re: 隣接マスの内容を探るアルゴリズムがわかりません。

#8

投稿記事 by COG » 1年前

8*5マス作成として

for(i=0;i<40;i++){
if((領地==領地[i+1])&&n<7){
//右側は同じキャラなので何もしない
}else{

}

if()

if(n==7){
n=0;//右端に来たら初期化
}else{
n=n+1;//更新用
}
if(n==4){
}
}

for文{
if文{マス
上(-8)
右(+1)
左(-1)
下(+8)
が自分のマスと同じキャラか移動不能マスなら内地(何も起こらず次)

if文{主人公陣営のマスが含まれていたら
敵対[n]=マス
n=n+1;
}

}else{
そうでないなら内地ではないので
臨戦態勢[m]=マス
m=m++
}

x = rand(0,m);
小競り合いを起こすマス=臨戦態勢[x]
一発の乱数で敵の小競り合いが作れますね!

y = rand(0,n)
主人公に襲ってくるマス=敵対[y]

こうですね!
ついでに全キャラ見ていく際に主人公の隣接マスも調べれば攻め込んでくる敵の作り方も同時に解決する事に気付きました。ありがとうございます!

ここに手を加えると見落としが無くなりそうだよ、とかありますか?
一番上の時の-8や右端の時の+1等、気を付けなければならない点はありそうですが……

たいちう
記事: 418
登録日時: 8年前

Re: 隣接マスの内容を探るアルゴリズムがわかりません。

#9

投稿記事 by たいちう » 1年前

> ここに手を加えると見落としが無くなりそうだよ、とかありますか?
> 一番上の時の-8や右端の時の+1等、気を付けなければならない点はありそうですが……

1次元配列だと直感的ではないので、必要がないなら2次元配列を使ってはどうですか。
上が(-8)とか気を付ける必要がなくなります。

さらに、上下左右に一回り大きな配列にして周囲を壁にすると、
if文がシンプルに書けると思います。

COG

Re: 隣接マスの内容を探るアルゴリズムがわかりません。

#10

投稿記事 by COG » 1年前

「内地ではない」というアイデアや上下左右に一回り大きな配列で周囲を壁にするというアイデア、ありがとうございます!
お陰様でなんとかなりそうです。

返信

“C言語何でも質問掲示板” へ戻る