正しく出力されない。ループする。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
pazumon_2525
記事: 17
登録日時: 9年前

正しく出力されない。ループする。

#1

投稿記事 by pazumon_2525 » 9年前

こちらに同じ質問しています。
https://oshiete.goo.ne.jp/qa/9171406.html

内容はこちらと同じですが、必要とする内容は自ら考えました。
以下がそのコードとなります。

実行すると、無限ループあるいはコアダンプが出ます。
まれに出力されますが正しく"・"が表示されません。
何回かデバッグをしましたが、どうしてかわかりません。
よろしくお願いします。デバッグ多いです。

コード:

#include "a.h"
#include<stdio.h>

struct player
{
	int y;  //y座標
	int x;  //x座標
};

struct player dir(int maze[H][W],struct player p);
void solve_maze(int maze[H][W])
{
	int x,y;
	struct player p;
	
	//スタート地点を見つける
	for(y=0;y<H;y++)
	{
		for(x=0;x<W;x++)
		{
			if(maze[y][x] == START)
			{
				printf("[%d][%d]\n",y,x);
				//上 
				if(y == 0 && maze[y][x+1] == WALL && maze[y][x-1] == WALL )
				{
					p.y = y+1;
					p.x = x;
				}
				//左
				else if(x == 0 && maze[y+1][x] == WALL && maze[y-1][x] == WALL )
				{
					p.x = x+1;
					p.y = y;
				}
				//下
				else if(y == H-1 && maze[y][x+1] == WALL && maze[y][x-1] == WALL)
				{
					p.y = y-1;
					p.x = x;
				}
				//右
				else if(x == W-1 && maze[y+1][x] == WALL && maze[y-1][x] == WALL )
				{
					p.x = x-1;
					p.y = y;
				}
			}
		}
	}
	do
	{
		p = dir(maze,p);
	}
	while(maze[p.y][p.x] != GOAL);
}
struct player dir(int maze[H][W],struct player p)
{
	int flg = 0;
	
	while(maze[p.y+1][p.x] == WALL && maze[p.y][p.x+1] != WALL && flg == 0)
	{
		//printf("a\n");
		p.x = p.x+1;
		maze[p.y][p.x] = TRACK;
		
	} 
	if(maze[p.y+1][p.x] != WALL && flg == 0)
	{
		//printf("d\n");
		maze[p.y][p.x] = TRACK;
		p.y = p.y+1;
		flg = 1;
	}
	
	while(maze[p.y][p.x+1] == WALL && maze[p.y-1][p.x] != WALL && flg == 0)
	{
		//printf("b\n");
		p.y = p.y-1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y][p.x+1] != WALL && flg == 0)
	{
		//printf("c\n");
		maze[p.y][p.x] = TRACK;
		p.x = p.x+1;
		flg = 1;
	}

	while(maze[p.y-1][p.x] == WALL && maze[p.y][p.x-1] != WALL && flg == 0)
	{
		//printf("c\n");
		p.x = p.x-1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y-1][p.x] != WALL && flg == 0)
	{
		//printf("b\n");
		maze[p.y][p.x] = TRACK;
		p.y = p.y-1;
		flg = 1;
	}
	
	while(maze[p.y][p.x-1] == WALL && maze[p.y+1][p.x] != WALL && flg == 0)
	{
		//printf("d\n");
		p.y = p.y+1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y][p.x-1] != WALL && flg == 0)
	{
		//printf("a\n");
		maze[p.y][p.x] = TRACK;
		p.x = p.x-1;
		flg = 1;	
	}
	return p;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 正しく出力されない。ループする。

#2

投稿記事 by みけCAT » 9年前

マルチポストをする場合は、相互リンクが必要です。

【追記】
よく見たら、マルチポストと言えるかどうか微妙、むしろ該当しない感じかな…。
最後に編集したユーザー みけCAT on 2016年2月10日(水) 19:50 [ 編集 1 回目 ]
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 正しく出力されない。ループする。

#3

投稿記事 by みけCAT » 9年前

配列の確保された領域の範囲外にアクセスしてはいけません。
mazeを直接参照するのではなく、添字が範囲外でないかをチェックし、
範囲内ならmazeのその場所の値を返し、範囲外なら適当な値を返す関数を作って利用すると、
この問題は改善しやすいと思います。
(詳しく見ていないので、他にも問題がある可能性を否定できません)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

pazumon_2525
記事: 17
登録日時: 9年前

Re: 正しく出力されない。ループする。

#4

投稿記事 by pazumon_2525 » 9年前

範囲チェックを関数なしで行うことはできますか?
追加する感じで。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 正しく出力されない。ループする。

#5

投稿記事 by みけCAT » 9年前

pazumon_2525 さんが書きました:範囲チェックを関数なしで行うことはできますか?
はい。
マクロを使うこともできるでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

pazumon_2525
記事: 17
登録日時: 9年前

Re: 正しく出力されない。ループする。

#6

投稿記事 by pazumon_2525 » 9年前

あと、範囲外をアクセスしてはいけない。と指摘して頂きましたが、何処で範囲外にアクセスしてしまっておりますでしょうか?
返す値はmaze.pでは駄目ですか?
すみません。よろしくお願いします。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 正しく出力されない。ループする。

#7

投稿記事 by みけCAT » 9年前

pazumon_2525 さんが書きました:あと、範囲外をアクセスしてはいけない。と指摘して頂きましたが、何処で範囲外にアクセスしてしまっておりますでしょうか?
例えばsolve_maze関数でmaze[0][0] == START && maze[0][1] == WALLのとき、25行目で範囲外のmaze[0][-1]へのアクセスが発生します。
他のif文でも同様に範囲外にアクセスする可能性があります。
pazumon_2525 さんが書きました:返す値はmaze.pでは駄目ですか?
このプログラムで使用されているmazeは全て構造体でも共用体でもないので、駄目でしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

pazumon_2525
記事: 17
登録日時: 9年前

Re: 正しく出力されない。ループする。

#8

投稿記事 by pazumon_2525 » 9年前

方向(4つ分)の関数がないと駄目ですかね?

box
記事: 2002
登録日時: 14年前

Re: 正しく出力されない。ループする。

#9

投稿記事 by box » 9年前

pazumon_2525 さんが書きました:方向(4つ分)の関数がないと駄目ですかね?
何々じゃなきゃダメってことはないと思います。設計しだい。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

pazumon_2525
記事: 17
登録日時: 9年前

Re: 正しく出力されない。ループする。

#10

投稿記事 by pazumon_2525 » 9年前

これまで、アルゴリズムを振り返りましたが、私が書いたプログラムから全然分からなくて困っております。
曲がった際に方向を変えてやるのは分かっておりますが。
よろしくお願い致します。

pazumon_2525
記事: 17
登録日時: 9年前

Re: 正しく出力されない。ループする。

#11

投稿記事 by pazumon_2525 » 9年前

すみません。帰宅したらソース貼ります。

pazumon_2525
記事: 17
登録日時: 9年前

Re: 正しく出力されない。ループする。

#12

投稿記事 by pazumon_2525 » 9年前

ソースです。
これでもうまく動きません。指摘お願いします。



コード:

#include "a.h"
#include<stdio.h>

#define NORTH 0 //北
#define WEST 1 //西
#define SOUTH 2 //南
#define EAST 3 //東

struct player
{
	int y;  //y座標
	int x;  //x座標
	int dir; //向き     //0:北 1:西 2:南 3;東
};

struct player start(int maze[H][W],struct player p);
struct player north(int maze[H][W],struct player p);
struct player west(int maze[H][W],struct player p);
struct player south(int maze[H][W],struct player p);
struct player east(int maze[H][W],struct player p);

void solve_maze(int maze[H][W])
{
	int x,y;
	struct player p;
	
	//スタート地点を見つける
	for(y=0;y<H;y++)
	{
		for(x=0;x<W;x++)
		{
			if(maze[y][x] == START)
			{
				printf("[%d][%d]\n",y,x);
				//上 
				if(y == 0 && maze[y][x+1] == WALL && maze[y][x-1] == WALL )
				{
					p.y = y+1;
					p.x = x;
					p.dir = SOUTH;
				}
				//左	return 0;
				else if(x == 0 && maze[y+1][x] == WALL && maze[y-1][x] == WALL )
				{
					p.x = x+1;
					p.y = y;
					p.dir = WEST;
				}
				//下
				else if(y == H-1 && maze[y][x+1] == WALL && maze[y][x-1] == WALL)
				{
					p.y = y-1;
					p.x = x;
					p.dir = NORTH;
				}
				//右
				else if(x == W-1 && maze[y+1][x] == WALL && maze[y-1][x] == WALL )
				{
					p.x = x-1;
					p.y = y;
					p.dir = EAST;
				}
			}
		}
	}
	do
	{
		p = start(maze,p);
		maze[p.y][p.x] = TRACK;
		system("clear");
		print_maze(maze);
		usleep(500000);
	}
	while(maze[p.y][p.x] != GOAL);
}

struct player start(int maze[H][W],struct player p)
{
	if(p.dir == NORTH)
	{
		north(maze, p);
	}
	else if(p.dir == WEST)
	{
		west(maze, p);
	}
	else if(p.dir == SOUTH)
	{
		south(maze, p);
	}
	else if(p.dir == EAST)
	{
		east(maze, p);
	}
	
	return p;
}

struct player north(int maze[H][W],struct player p)
{
	int flg = 0;
	
	/* 東が前で南が右 */
	while(p.x<W-1 && maze[p.y+1][p.x] == WALL && maze[p.y][p.x+1] != WALL && flg == 0)
	{
		p.x = p.x+1;
		maze[p.y][p.x] = TRACK;
		
	} 
	if(maze[p.y+1][p.x] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.y = p.y+1;
		flg = 1;
	}
	
	/* 北が前で東が右 */
	while(p.y>0 && maze[p.y][p.x+1] == WALL && maze[p.y-1][p.x] != WALL && flg == 0)
	{
		p.y = p.y-1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y][p.x+1] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.x = p.x+1;
		flg = 1;
	}

	/* 西が前で北が右*/
	while(p.x>0 && maze[p.y-1][p.x] == WALL && maze[p.y][p.x-1] != WALL && flg == 0)
	{
		p.x = p.x-1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y-1][p.x] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.y = p.y-1;
		flg = 1;
	}
	
	/* 南が前で西が右 */
	while(p.y<H-1 && maze[p.y][p.x-1] == WALL && maze[p.y+1][p.x] != WALL && flg == 0)
	{
		p.y = p.y+1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y][p.x-1] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.x = p.x-1;
		flg = 1;	
	}
	
	return p;
}

struct player west(int maze[H][W],struct player p)
{
	int flg = 0;
	
	/* 南が前で西が右 */
	while(p.y<H-1 && maze[p.y][p.x-1] == WALL && maze[p.y+1][p.x] != WALL && flg == 0)
	{
		p.y = p.y+1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y][p.x-1] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.x = p.x-1;
		flg = 1;	
	}
	
	/* 東が前で南が右 */
	while(p.x<W-1 && maze[p.y+1][p.x] == WALL && maze[p.y][p.x+1] != WALL && flg == 0)
	{
		p.x = p.x+1;
		maze[p.y][p.x] = TRACK;
	} 
	if(maze[p.y+1][p.x] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.y = p.y+1;
		flg = 1;
	}
	/* 北が前で東が右 */
	while(p.y>0 && maze[p.y][p.x+1] == WALL && maze[p.y-1][p.x] != WALL && flg == 0)
	{
		p.y = p.y-1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y][p.x+1] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.x = p.x+1;
		flg = 1;
	}
	/* 西が前で北が右*/
	while(p.x>0 && maze[p.y-1][p.x] == WALL && maze[p.y][p.x-1] != WALL && flg == 0)
	{
		p.x = p.x-1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y-1][p.x] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.y = p.y-1;
		flg = 1;
	}
	return p;
}

struct player south(int maze[H][W],struct player p)
{
	int flg = 0;
	
	/* 西が前で北が右*/
	while(p.x>0 && maze[p.y-1][p.x] == WALL && maze[p.y][p.x-1] != WALL && flg == 0)
	{
		p.x = p.x-1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y-1][p.x] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.y = p.y-1;
		flg = 1;
	}
	
	/* 南が前で西が右 */
	while(p.y<H-1 && maze[p.y][p.x-1] == WALL && maze[p.y+1][p.x] != WALL && flg == 0)
	{
		p.y = p.y+1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y][p.x-1] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.x = p.x-1;
		flg = 1;	
	}
	
	/* 東が前で南が右 */
	while(p.x<W-1 && maze[p.y+1][p.x] == WALL && maze[p.y][p.x+1] != WALL && flg == 0)
	{
		p.x = p.x+1;
		maze[p.y][p.x] = TRACK;
		
	} 
	if(maze[p.y+1][p.x] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.y = p.y+1;
		flg = 1;
	}
	
	/* 北が前で東が右 */
	while(p.y>0 && maze[p.y][p.x+1] == WALL && maze[p.y-1][p.x] != WALL && flg == 0)
	{
		p.y = p.y-1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y][p.x+1] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.x = p.x+1;
		flg = 1;
	}
	
	return p;
}

struct player east(int maze[H][W],struct player p)
{
	int flg = 0;
	
	/* 北が前で東が右 */
	while(p.y>0 && maze[p.y][p.x+1] == WALL && maze[p.y-1][p.x] != WALL && flg == 0)
	{
		p.y = p.y-1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y][p.x+1] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.x = p.x+1;
		flg = 1;
	}
	
	/* 西が前で北が右*/
	while(p.x>0 && maze[p.y-1][p.x] == WALL && maze[p.y][p.x-1] != WALL && flg == 0)
	{
		p.x = p.x-1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y-1][p.x] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.y = p.y-1;
		flg = 1;
	}
	/* 南が前で西が右 */
	while(p.y<H-1 && maze[p.y][p.x-1] == WALL && maze[p.y+1][p.x] != WALL && flg == 0)
	{
		p.y = p.y+1;
		maze[p.y][p.x] = TRACK;
	}
	if(maze[p.y][p.x-1] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.x = p.x-1;
		flg = 1;	
	}
	
	/* 東が前で南が右 */
	while(p.x<W-1 && maze[p.y+1][p.x] == WALL && maze[p.y][p.x+1] != WALL && flg == 0)
	{
		p.x = p.x+1;
		maze[p.y][p.x] = TRACK;
		
	} 
	if(maze[p.y+1][p.x] != WALL && flg == 0)
	{
		maze[p.y][p.x] = TRACK;
		p.y = p.y+1;
		flg = 1;
	}
	
	return p;
}		
		
最後に編集したユーザー pazumon_2525 on 2016年2月15日(月) 22:30 [ 編集 1 回目 ]

hoge

Re: 正しく出力されない。ループする。

#13

投稿記事 by hoge » 9年前

36行目の if(y == 0 && maze[y][x+1] == WALL && maze[y][x-1] == WALL )は[0][W-1]の場合[0][W]となり範囲外アクセスが発生しますね。

gooの投稿を見る限り、スタートとゴールは外周上にのみ存在するようなので、スタートの位置(0なりW-1なり...)から向きを決めるといいかもしれません。
オフトピック
ex9.h...課題9ですかね

pazumon_2525
記事: 17
登録日時: 9年前

Re: 正しく出力されない。ループする。

#14

投稿記事 by pazumon_2525 » 9年前

struct player startでスタート位置から向きを指定しています。
これではダメですか?

pazumon_2525
記事: 17
登録日時: 9年前

Re: 正しく出力されない。ループする。

#15

投稿記事 by pazumon_2525 » 9年前

範囲外チェックはどうしたらよいですか?

pazumon_2525
記事: 17
登録日時: 9年前

Re: 正しく出力されない。ループする。

#16

投稿記事 by pazumon_2525 » 9年前

コンパイルすると右に壁がなかったときに止まってしまうんですよね。

hoge

Re: 正しく出力されない。ループする。

#17

投稿記事 by hoge » 9年前

pazumon_2525 さんが書きました:範囲外チェックはどうしたらよいですか?
範囲外を参照しなければ大丈夫です。

どうしたらいいのかを聞くのではなく、なにがどのように分からないのかを言ってください。
オフトピック
ex9.h変更されてるし学校の課題だったのかな。
学校の課題だったら担当の教授なり先生なりに聞くのが早いと思うんだけどなぁ

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: 正しく出力されない。ループする。

#18

投稿記事 by usao » 9年前

オフトピック
このトピックって,「何の話なの?」っていうのが明確な状況なのですか?

明確な問題設定や,
それに対してどういう方法(アルゴリズム)を実装しようとしているのか等に関しての
説明等も見つけることができませんし,
>ex9.h
がどうのとかいう話も一体何の話をしているのか全く謎……


リンク先を見ても

>ランダムなSからGまで・をたどっていくようにしたいです

とかいう,ものすごく曖昧な一文しか無いわけですが.
この一文を読むと
「入力データには少なくとも{ 'S', 'G', '・' }が含まれていて,
 複数の '・' が,'S'から'G'までの道筋を示す形に連なって分布している」
という状況を思い浮かべますが,そういう感じでもなさそうだし……?

閉鎖

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