こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

配列 隣の要素を参照するのですが

最初に
8つの要素を持つint型の配列(配列名dat)があるとして、最初全要素に「0」が代入されています。scanf関数でn番の要素に「1」が代入されたとします。n番なのでどこに「1」が代入されたかはわからないです。

問題
for文を使用して何番目に「1」が入力されたかを調べますが、以下のルールに従がわなくてなならいです。

ルール
・現在の要素から隣の要素を参照しなくてはいけない。
・参照する範囲は要素の数「0~7」番


#include<stdio.h>

void main()
{
int i, dat[8];

for(i=0;i<8;i++){
dat[i]=0;
}

i=0;
scanf("%d",&i);
dat[i] = 1;

for(i=0;i<8;i++){
if(dat[i+1] == 1){print("%d列目に「1」がありました", i+1);
}

}

でも…こうすると0番目の要素が参照されないですそれを回避するには?そして…
最大の要素(dat[7])にきたときは隣を参照しないようにするにはどうすればよいのでしょう?

投稿日時 - 2005-10-14 12:52:19

QNo.1713119

すぐに回答ほしいです

質問者が選んだベストアンサー

やりたいことと、質問内容と補足内容が合ってないので混乱が発生してますね

そもそもの質問の答えは
if(dat[i] == 1){print("%d列目に「1」がありました", i+1);
でOKだと思います

それで
>他の石と隣接しているかを調べ、一箇所も隣接してないときはNG、隣接している場所はOKとするため、隣の要素を参照して判断しようとしたのですが、端のマスだと隣を参照するとはみ出してしまい、隣接の判断がつかなくなるので困ってるのです。だからこのような質問を。

ということなので
「接近した8方向1マスのチェック」と思ってfor分はいらないと書いたのですが

>自分の置こうとしている場所(座標)から自分と同じ色の石が置かれている座標まで検索すればよいのですから

ということなのでforもしくはwhileは必要でしょう

やり方というか考え方(思いつくのは)は
・No6さんの配列を大きくしてしまう
・検索対象座標テーブルを作成して検索対象座標テーブルから検索する
(もっとあると思いますが)

私なら後者で作ります
・検索対象座標テーブル作成でルールを吸収
・検索ロジックが1箇所となる
・デバグしやすい

※話がそれているのでこの質問を閉めて再質問したらどうでしょうか?
またfor・whileどちらが適しているかですが、違いが分かればおのずと決まります よね

投稿日時 - 2005-10-15 22:35:08

ANo.7

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(8)

ANo.8

http://www.junkudo.co.jp/detail2.jsp?ID=0199227761

上記の本にオセロゲームの作り方が載っています。
参考になると思います。

参考URL:http://www.junkudo.co.jp/detail2.jsp?ID=0199227761

投稿日時 - 2005-10-16 07:36:39

お礼

オセロは四方八方に検索しますので、それを原点にもどってシミュレーションしてみた結果、この問題見事に解決しました。また、同時に検索した方向の途中で同色の石があった場合、そのマスを起点、検索を始めたマスを終点と考えれば、こんど逆方向に行けば石を反転出来る事にきがつきました。
最初は、オセロゲーム制作で悩んでいた1週間ですが、一度オセロゲーム制作から離れて考えてみたら、数時間で解決しました。
アルゴリズムで一度つまずいたら本題から離れてみて基礎から(別の場所から)考えてみるといいようです。それでも分からなかったら、ここに応援をたのむのがいいですね。そのほうがどのような質問すれば良いかまとまりますし。

みなさんありがとうございました。

#8さんオセロゲームの作りかたのURLありがとうございます。でも、あえて自分で作るから意味があると先生は言うし、私もそう思うので見るのはやめました。ご親切にありがとうございます。

投稿日時 - 2005-10-18 22:05:40

ANo.6

以前の質問は的確だったと思います。

例えば下のような感じで、座標の範囲が有効かどうかも一緒に調べてやればいいと思います。
(この質問とは全然無関係になってしまいますが)

if (
(tate > 0 && data[tate - 1][yoko] != OTHELLO_NON) || /* 上 */
(tate > 0 && yoko < 7 && data[tate - 1][yoko + 1] != OTHELLO_NON) || /* 右上 */
***以下略***
) {
return 1;
}
return 0;

前の質問の#1さんが配列を10×10にすれば範囲を絞る必要がないと言われていましたよね。
良いアドバイスだと思います。

投稿日時 - 2005-10-15 13:27:05

ANo.5

forで検索していますが、オセロとなると8方向検索となるため下記のようになりますよね
(forで検索しているからルールに無理がでているような)
(これは左右検索の一例です)

char result[3];
strcpy (&result[0], "NG");
if (0 == i) then
{
if(dat[i+1] == 1)
{
strcpy (&result[0], "OK");
}
}
elseif (7 == i) then
{
if(dat[i-1] == 1)
{
strcpy (&result[0], "OK");
}
}
else
{
if((dat[i-1] == 1) or (dat[i+1] == 1))
{
strcpy (&result[0], "OK");
}
}
print("%d列目の結果は%s\n", i, &result[0])

投稿日時 - 2005-10-15 01:15:11

補足

オセロでどこに石が置けるかを実際のオセロをしてみて検討してみたところ、置ける条件は一つ、8方向の先に自分と同じ色の石がある時に限る 事がわかりました。
という事は、自分の置こうとしている場所(座標)から自分と同じ色の石が置かれている座標まで検索すればよいのですから、for文よりwhile文が有効ですか?

投稿日時 - 2005-10-15 14:38:56

ANo.4

if(dat[i] == 1){print("%d列目に「1」がありました", i+1);

のような気がしますけど

ルールの
・現在の要素から隣の要素を参照しなくてはいけない
ですが、
「現在の要素が1の場合は0を参照」
ではないのでしょうか?

投稿日時 - 2005-10-14 19:38:16

ANo.3

No.2です。
隣の要素を参照しなくてはいけないのでしたね。すみません。m(__)m
要素MAXの場合に0を参照する様にすればいいのは

投稿日時 - 2005-10-14 13:34:26

ANo.2

気づいたこと
1.scanfで8以上の値がくることは考慮しなくていいんですか?
2.配列要素8の添字は0~7で、printの文言を列の先頭は1として表示するだけですからdatの参照する添字iに+1する必要はないですね。
 forの条件はiが8になったらぬけるのでOkです。
3.これはどうでもいいですが、1が見つかったらforから抜けてもいいかな...

投稿日時 - 2005-10-14 13:24:11

補足

言語の質問するのって結構難しくて考えてこのような例をとらせていただきました。
本来は2次元配列で、今オセロゲームを制作してるのですが、他の石と隣接しているかを調べ、一箇所も隣接してないときはNG、隣接している場所はOKとするため、隣の要素を参照して判断しようとしたのですが、端のマスだと隣を参照するとはみ出してしまい、隣接の判断がつかなくなるので困ってるのです。だからこのような質問を。
でも、これもわかりにくかったようです。
もうどう質問すればいいか自分でも分からなくなってきちゃいます><

投稿日時 - 2005-10-14 21:13:36

ANo.1

よくわかりませんが、
>0番目の要素が参照されないです
すべての要素を調べてみて1が見つからなかったら必然的に0番目の要素に1が入っている(すでに代入されたのだから)

>dat[7])にきたときは隣を参照しないようにする
i<8

i<8-1
にする
見当違いだったらすみません

投稿日時 - 2005-10-14 13:12:01

あなたにオススメの質問