forループで回した変数について
Posted: 2014年5月13日(火) 21:41
いつもお世話になってます。
本日は4X4ボードゲームというものを作成してる途中に問題が発生したので、お聞きしたいと思います。
関数swapでint型変数x,yを使ってscanfで得た値を二次元配列上で検索し、該当したらそのループを抜けるように書いたのですが、出力してみると、目的の値が0列目にあるとき、妙なことになってしまいます。詳しくは以下の出力になります
-------------------------------------------------
b******@imc2o-014:~/soft$ ./fin
1 13 3 15
2 5 7 4
10 11 12 14
6 0 8 9
入力して下さい:6
0:0:in roop
0:1:in roop
0:2:in roop
0:3:in roop
1:0:in roop
1:1:in roop
1:2:in roop
1:3:in roop
2:0:in roop
2:1:in roop
2:2:in roop
2:3:in roop
2:4:out roop
2:4:out roop
3:0:after
1 13 3 15
2 5 7 4
10 11 12 14
0 6 8 9
入力して下さい:
----------------------------------------------------
in roopとついてるものがループ中に出力したx,yです
out roopとなっているものがforループを一つづつ抜けた時のx,yです
afterとなってるものが、適切な処理をした後のx,yです
ここで言う適切な処理は、想定している二次元配列a[4][4]の範疇に収める操作です。
例えば最後のout roopでは2;4になってますがこれは二次元配列では何故か、a[2][4]==a[3][0]というふうに認識されてるようなので、後者の方に変換する必要がありました。
しかし良く考えてみると、for文内でのbreakの条件では、a[2][3]まで進んだ時には該当の値が見つからないため、一旦for文を抜けて一個上のfor文を通過し、a[3][0]==目的の値となり、breakするはずです
なのでしょうがなくこのようなif処理をしましたが、どうも納得がいかないので、どなたか教えてください。よろしくおねがいします。
本日は4X4ボードゲームというものを作成してる途中に問題が発生したので、お聞きしたいと思います。
#include<stdio.h>
#define N 4
void search(int a[N][N],int *i,int *j);
int check(int a[N][N]);
int out(int a[N][N]);
void swap(int a[N][N],int *i,int *j);
int main(){
int as=0,bs=0;
int *i,*j;
i=&as;
j=&bs;
int a[4][4]={{1,13,3,15},{2,5,7,4},{10,11,12,14},{6,0,8,9}};//ランダムに初期化
out(a);//出力
while(1){
search(a,i,j);//*i,*jは現在の0要素のグリッド
swap(a,i,j);//この処理によって入れ替えが実行される
out(a);//出力
if(check(a)==1){
break;//すべての要素が条件を満たした時にbreakする
}
}
return 0;
}
/*空き要素(0)の特定*/
void search(int a[N][N],int *i,int *j){
for((*i)=0;(*i)<4;(*i)++){
for((*j)=0;(*j)<4;(*j)++){
if(a[(*i)][(*j)]==0){
return;//*i==*j==0からループを回して要素が0の時に関数を終了
}
}
}
}
int check(int a[N][N]){
int s,t;
int b[4][4]={{1,13,3,15},{2,5,7,4},{10,11,12,14},{6,0,8,9}};
for(t=0;t<4;t++){
for(s=0;s<4;s++){
if(a[t][s] != b[t][s]){
return 0;
}
}
}
return 1;
}
int out(int a[N][N]){
int s,t;
for(t=0;t<4;t++){
for(s=0;s<4;s++){
printf("%4d",a[t][s]);
}
printf("\n");
}
}
void swap(int a[N][N],int *i,int *j)
{
int x,y,z;
int as=0;
printf("入力して下さい:");
scanf("%d",&z);
for(x=0;x<=3;x++){
for(y=0;y<=3;y++){
printf("%d:%d:in roop\n",x,y);
if(a[x][y]==z){
break;
}
}
if(a[x][y]==z){
printf("%d:%d:out roop\n",x,y);
break;
}
}
printf("%d:%d:out roop\n",x,y);
/*配列の処理*/
if(y==4){
x++;
y=0;
}
printf("%d:%d:after\n",x,y);
printf("\n");
if(a[x+1][y]==0 || a[x-1][y]==0 || a[x][y+1]==0 || a[x][y-1]==0){
if(((a[x][y+1]==0)&&(y==3))||((a[x][y-1]==0)&&(y==0))){
return;
}
as=a[(*i)][(*j)];
a[(*i)][(*j)]=a[x][y];
a[x][y]=as;
}
}
-------------------------------------------------
b******@imc2o-014:~/soft$ ./fin
1 13 3 15
2 5 7 4
10 11 12 14
6 0 8 9
入力して下さい:6
0:0:in roop
0:1:in roop
0:2:in roop
0:3:in roop
1:0:in roop
1:1:in roop
1:2:in roop
1:3:in roop
2:0:in roop
2:1:in roop
2:2:in roop
2:3:in roop
2:4:out roop
2:4:out roop
3:0:after
1 13 3 15
2 5 7 4
10 11 12 14
0 6 8 9
入力して下さい:
----------------------------------------------------
in roopとついてるものがループ中に出力したx,yです
out roopとなっているものがforループを一つづつ抜けた時のx,yです
afterとなってるものが、適切な処理をした後のx,yです
ここで言う適切な処理は、想定している二次元配列a[4][4]の範疇に収める操作です。
例えば最後のout roopでは2;4になってますがこれは二次元配列では何故か、a[2][4]==a[3][0]というふうに認識されてるようなので、後者の方に変換する必要がありました。
しかし良く考えてみると、for文内でのbreakの条件では、a[2][3]まで進んだ時には該当の値が見つからないため、一旦for文を抜けて一個上のfor文を通過し、a[3][0]==目的の値となり、breakするはずです
なのでしょうがなくこのようなif処理をしましたが、どうも納得がいかないので、どなたか教えてください。よろしくおねがいします。