無題

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

無題

#1

投稿記事 by つつ » 15年前

cで迷路を解こうとしているのですがうまくいっていません。

何かいい探索プログラムはありませんか?
とりあえず今のソースをのっけます。

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

#define MAZE_X (40)
#define MAZE_Y (40)

static CurrentState getCurrent ( void );
static void initMaze ( int, int, CurrentState );
static CurrentState findNext ( CurrentState );

static int mazeHeight = 0; // 迷路のサイズ
static int mazeWidth = 0;
static int x, y;
static int search[MAZE_X][MAZE_Y];
static CurrentState pos = { 0, 0, DirDown, MapStart }; // 現在位置

static int a = 0; //経路探索状況

// プレーヤー情報を持つ構造体
// "蒲田"の部分のみ、変更すること
static PlayerInfo player = { "YON" , initMaze, findNext, getCurrent };

// プレーヤーの情報を返す関数
// "Kamada"の部分以外、変更しないこと
PlayerInfo* getyonInfo ( void )
{
return &player;
}

// 現在位置の情報を返す関数
// 変更しないこと
static CurrentState getCurrent ( void )
{
return pos;
}

// 初期化の関数
static void initMaze ( int col, int row, // 迷路のサイズ
CurrentState start ) // スタート位置
{
// この下の3行は、変更しないこと。
// このほかに必要なものがあれば、追加することは可。
mazeWidth = col;
mazeHeight = row;
pos = start;
x = pos.x;
y = pos.y;
}

// 次に進む場所を計算する関数
// 次に進む場所を返すようになっていれば、変更可
static CurrentState findNext ( CurrentState pos )
{
CurrentState next = pos;
switch ( next.dir ){
case DirUp : next.y--; break;
case DirDown : next.y++; break;
case DirLeft : next.x--; break;
case DirRight : next.x++; break;
}

// 次に進もうとしているセルの状態をチェックする
if ( next.status = canPassThrough ( next ) ) {
pos = next;
} else {
// 上
pos.status = pos.status;
if (search[x][y-1]== MapWall)
{
pos.dir -= DirUp;
pos.status = MapAisle;
} else {
if (search[x][y-1]== MapAisle) {
pos.dir += DirDown;
}
}
// 下
if (search[x][y+1]== MapWall)
{
pos.dir += DirDown;
pos.status = MapAisle;
} else {
if (search[x][y+1]== MapAisle) {
pos.dir -= DirUp;
}
}

// 左
if (search[x-1][y]== MapWall)
{
pos.dir -= DirLeft;
pos.status = MapAisle;
} else {
if (search[x-1][y]== MapAisle) {
pos.dir += DirRight;
}
}
// 右
if (search[x+1][y]== MapWall)
{
pos.dir += DirRight;
pos.status = MapAisle;
} else {
if (search[x+1][y]== MapAisle) {
pos.dir -= DirLeft;
}
}
}
return pos;
}

softya

Re:無題

#2

投稿記事 by softya » 15年前

まず、どううまく行かないのかと意図しているアルゴリズムを箇条書きで書いてもらえますか。

つつ

Re:無題

#3

投稿記事 by つつ » 15年前

すいませんうっかり忘れていました。


状態
・壁にぶつかったとしても方向を変えない状態です。
・壁を突き破ってしまいます。

意図
・最短経路の探索
・壁にぶつからなくても方向を変更したい。

こんな感じです。
*.hファイルです。
// マップ情報
#define MazeStart 'S' // スタート地点
#define MazeGoal 'G' // ゴール
#define MazeAisle ' ' // 通路

// 自分の進行方向
#define DirUp (0) // 上
#define DirDown (1) // 下
#define DirLeft (2) // 左
#define DirRight (3) // 右
#define DirMax (4) // 方向の種類数

// mapの状況
typedef enum { MapWall = 0, MapStart = 1, MapAisle = 2, MapGoal = 3 } MapStatus;

// 現在位置と方向
typedef struct {
int x; // 位置
int y;
int dir; // 進行方向
MapStatus status; // 現在地の状況
} CurrentState;

typedef struct {
char* name;
void ( *init ) ( int, int, CurrentState );
CurrentState ( *find ) ( CurrentState );
CurrentState ( *getCurrent ) ( void );
} PlayerInfo;

MapStatus canPassThrough ( CurrentState );

つつ

Re:無題

#4

投稿記事 by つつ » 15年前

すいません意図の部分に追加です

意図
・一度通った場所を記憶して二度通らなくしたいです。

つつ

Re:無題

#5

投稿記事 by つつ » 15年前

地図はこんなのを使用しています。

"+-----+---+------+---------+----+------+",
"S*****|***|******|*********|****|******|",
"+-+*******|***|******------+****+-----*|",
"G*|***|*******|**|*********************|",
"|*+---+---+---+**+---+---------------*-+",
"|*********|**********|*****************|",
"|*+*+*+*+*|**********|*-*-*-*-*-*-*-*-*|",
"|*********|**********|*****************|",
"|*+*+*+*+*+----------+------+------+-*-+",
"|***************************|******|***|",
"+---+---+-----------------+***+--+*|***|",
"|***|***|*****************|-+-*****+-+*|",
"|*|***|****+*+*+*+*+*+*+*+|*|**|*****|*|",
"|*|*|***|*****************|***-+*--+-+*|",
"+-+*|*|*|*|*|*|*|*|*|*|*|*|*|**|***|***|",
"|***|***+-+-+-+-+*+-+-+-+-+*+-*|*+*|***|",
"|***|*|*|*****|*****|*****|*|**|***|***|",
"|***|***|*-+-*|*-+-*|*-+-*+***-+---+-*-+",
"|***|*|*|**|**|**|**|**|**|*|**|***|***|",
"+-+*|***|**|*-+-*|*-+-*|**|*+-*|***|***|",
"|*|*|*|*|**|**|**|**|**|**|*|**|***|***|",
"|*|*|***|*-+-*|*-+-*|*-+-*|***-+***+--*|",
"|*|*+---+**|**|**|**|**|**|*|**|*******|",
"|***|***|**|*-+-*|*-+-*|**|*+-*|*******|",
"|***|***|**|**|**|**|**|**|*|**|***+-*-+",
"+-*-+***|*-+-*|*-+-*|*-+-*|***-+***|***|",
"|*******|**|**|**|**|**|**|*|**|***|***|",
"|*******|**|*-+-*|*-+-*|**|*+-*+---+*|*|",
"|*--+***|**|*****|*****|**|*|**|***|*|*|",
"|***|***+--+-----+-----+--+***-+*|*|*|*|",
"|***|***|*****************|*|**|***|*+-+",
"+-*-+---+---+----+----+-*-+-+-*|*|*|***|",
"|***********|*********|*****|**|***|***|",
"|*-*-*-*-*-*|*********|***|*|**|*|*|***|",
"|***********|*********|***|****|***|***|",
"+-*---------+--+**+---+---+*+--+*|*|*+-+",
"|**************|**|***|***|*|**|***|*|*|",
"|*--+****+---*****|*******+-+****|***|*|",
"|***|****|*****|******|********|***|***|",
"+---+----+-----+------+--------+---+---+"

「*」を空白に置き換えていただければ使用できます。 画像

softya

Re:無題

#6

投稿記事 by softya » 15年前

これは、アルゴリズムの箇条書きじゃないですね。
日本語で、文章だけでアルゴリズムを書いてもらえますか。

つつ

Re:無題

#7

投稿記事 by つつ » 15年前

すいません。

1:移動中に壁があるか探します。
2:探した結果、壁がない方向に進みます。
3:移動中の経路を記憶。
4:ゴールが見つからなかったら、探索経路を消去して再探索を行う。
1~4の繰り返し。
5:ゴールが見つかったら終了。


こんな感じでよろしいでしょうか?

softya

Re:無題

#8

投稿記事 by softya » 15年前

main部分が掲載されていないので、全体がどうやって動いているか分からないんでzip添付の形で動くのに必要なものを全てもらえませんか?

あと確認したいことがあります。

>1:移動中に壁があるか探します。
これは歩く1歩前だけを調べていますか?
それと壁が無い限り方向転換しないんでしょうか?

>2:探した結果、壁がない方向に進みます。
方向転換するアルゴリズムは、右回り、左回り、ランダム、それ以外の何れでしょう?

>3:移動中の経路を記憶。
アルゴリズムの記述に出来ていませんが、記憶した経路はどの様に利用されていますか?

>4:ゴールが見つからなかったら、探索経路を消去して再探索を行う。
今まで探索した経路情報は全て消去してしまうのでしょうか?

つつ

Re:無題

#9

投稿記事 by つつ » 15年前

main部分が掲載されていないので、全体がどうやって動いているか分からないんでzip添付の形で動くのに必要なものを全てもらえませんか?

あと確認したいことがあります。

>1:移動中に壁があるか探します。
歩く一歩前のことです。
壁が有っても方向転換させていただけるとうれしいです。

>2:探した結果、壁がない方向に進みます。
ランダムでお願いします。

>3:移動中の経路を記憶。
記憶した経路を使いプログラム上で迷路を作成します。

>4:ゴールが見つからなかったら、探索経路を消去して再探索を行う。
すべて消してしまって結構です。

softya

Re:無題

#10

投稿記事 by softya » 15年前

将来どうしたいかじゃなくて今のアルゴリズムをお聞きしていますので、今のアルゴリズムを教えてください。
[訂正]今C言語で組み込んでいるつもりのアルゴリズムを書いて下さい。あるいは、組み込んでいないなら未作成と書いて下さい。

>>1:移動中に壁があるか探します。
>歩く一歩前のことです。
>壁が有っても方向転換させていただけるとうれしいです。
今のアルゴリズムは?

>>2:探した結果、壁がない方向に進みます。
>ランダムでお願いします。
今はどうしていますか?

>>3:移動中の経路を記憶。
>記憶した経路を使いプログラム上で迷路を作成します。
今のアルゴリズムと、この意味が分からないので説明してもらえますか?
プログラム上で迷路を作成してどうするのですか?経路情報を表示する?それとも別の意味?
元の迷路はmapファイル上にあるんですよね?

>>4:ゴールが見つからなかったら、探索経路を消去して再探索を行う。
>すべて消してしまって結構です。
今のアルゴリズムでお願いします。

画像

つつ

Re:無題

#11

投稿記事 by つつ » 15年前

今わ
1:移動中は必ず1歩前の状態を見ています。(壁か道か)
未作成

2:未作成

3:未作成

4:未作成

すいませんこんな状態で。

softya

Re:無題

#12

投稿記事 by softya » 15年前

これについての詳細もお願いします。

>>>3:移動中の経路を記憶。
>>記憶した経路を使いプログラム上で迷路を作成します。
>この意味が分からないので説明してもらえますか?
>プログラム上で迷路を作成してどうするのですか?経路情報を表示する?それとも別の意味?
>元の迷路はmapファイル上にあるんですよね?

意図が分からないんで、お願いします。

つつ

Re:無題

#13

投稿記事 by つつ » 15年前

>>記憶した経路を使いプログラム上で迷路を作成します。
このことは忘れてください。
・一度通ったとこを通らないようにしてください。

元の迷路はmapファイル上には、あります。

たいちう

Re:無題

#14

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

> 何かいい探索プログラムはありませんか?

プログラム自体はググるなり、ご自分で作成するなりしてもらうとして、
単純なアルゴリズムを書きます。

1.迷路の各マス目に対応する2次元配列を用意する。
2.2次元配列を0で初期化する。
3.スタートのマスに対応する2次元配列の要素に1を代入する。
4.1に隣接している0の要素に2を代入する。
5.2に隣接している0の要素に3を代入する。
...
6.nに隣接している0の要素に(n+1)を代入する。
7.ゴールのマスに数字が入るまで、手順6を繰り返す。
8.ゴールのマスから数字を降順に辿りスタートまでの順路を見つける。

softya

Re:無題

#15

投稿記事 by softya » 15年前

ほとんど未完成と考えて良いですね。

では、私は今出来ているものに近いアルゴリズムを提案します。
1.移動済みをマークする2次元配列を用意する。0クリアしておく。
2.移動分岐点をマークするスタックを用意する。
3.スタート地点をマークする。
4.今の位置から移動出来る方向を調べる。壁と移動済みの場所には移動出来ない。
5.移動先にゴールがあればゴールに移動して終了。
6.どこにも移動出来ない場合は、スタックから移動分岐点を取り出して4へ。
7.移動出来る方向が複数あったら、スタックに移動分岐点を記録する。
8.複数の移動方向の中の内からランダムで移動方向を決定する。1つしか無いならその方向を選択。
9.その方向に移動して移動済みをマークする。4へ戻る。

つつ

Re:無題

#16

投稿記事 by つつ » 15年前

わざわざありがとうございます。

参考に打ってみます。

つつ

Re:無題

#17

投稿記事 by つつ » 15年前

ありがとうございました

閉鎖

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