• 締切済み

8パズル

C++のプログラミングの勉強をしています。 ネットなどを利用して勉強してるところなんですが、わからないところがあります。 8パズルの探索プログラムなんですがネットで見つけたものは初期値が最初から入ってるものでした。 自分で入力して実行したいのですがそれがうまくいきません。 読み込んでるつもりなのですがメモリに記憶されてないみたいです。 変数がメイン文の中にない場合の入力がわかってないからできないのだと思います。 どなたか下のプログラムを最初に自分で値を入力する方法を教えていただけないでしょうか?? #include <stdio.h> #include <string.h> #include <time.h> #define TRUE 1 #define FALSE 0 #define GOAL 2 #define SIZE 9 /* 状態数 (9! / 2) */ #define MAX_STATE 181440 /* 隣接リスト */ const char adjacent[SIZE][5] = { 1, 3,-1,-1,-1, 0, 4, 2,-1,-1, 1, 5,-1,-1,-1, 0, 4, 6,-1,-1, 1, 3, 5, 7,-1, 2, 4, 8,-1,-1, 3, 7,-1,-1,-1, 4, 6, 8,-1,-1, 5, 7,-1,-1,-1, }; /* キュー */ char state[MAX_STATE + 1][SIZE]; /* +1 はワーク領域 */ char space_postion[MAX_STATE]; int prev_state[MAX_STATE]; /* 同一局面チェックテーブル */ char check_table[MAX_STATE * 2]; /* 初期状態 */ char init_state[SIZE] = { 8, 6, 7, 2, 5, 4, 3, 0, 1 }; char final_state[SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8, 0 }; /* 結果を出力 */ void print_answer( int n ) { int i, j; if( n != 0 ) print_answer( prev_state[n] ); for( i = 0; i < 3; i++ ){ for( j = 0; j < 3; j++ ){ printf("%d ", state[n][i * 3 + j] ); } printf("\n"); } printf("\n"); } /* 番号に変換 */ int change_number( char *board ) { char work[SIZE]; static int fact_table[SIZE] = { 40320, 5040, 720, 120, 24, 6, 2, 1, 0, }; int j, k, value = 0; memcpy( work, board, SIZE ); for( j = 0; j < SIZE - 1; j++ ){ value += fact_table[j] * work[j]; for( k = j + 1; k < SIZE; k++ ){ if( work[j] < work[k] ) work[k]--; } } return value; } /* 探索 */ void search( void ) { int front = 0, rear = 1; /* 初期化 */ memcpy( state[0], init_state, SIZE ); space_postion[0] = 7; prev_state[0] = -1; check_table[ change_number( init_state ) ] = TRUE; check_table[ change_number( final_state ) ] = GOAL; /* キューにデータがある間繰り返す */ while( front < rear ){ int s = space_postion[front]; int i, k, n; for( i = 0; (n = adjacent[s][i]) != -1; i++ ){ /* 状態をコピー */ memcpy( state[rear], state[front], SIZE ); /* 移動 */ state[rear][s] = state[rear][n]; state[rear][n] = 0; space_postion[rear] = n; prev_state[rear] = front; k = change_number( state[rear] ); if( check_table[k] == GOAL ){ /* 発見 */ print_answer( rear ); printf("状態数 %d 個\n", rear ); return; } else if( !check_table[k] ){ /* キューに登録 */ check_table[k] = TRUE; rear++; } } front++; } } int main() { int start, end; /* * 静的変数が 0 に初期化される場合は不用だが * 初期化することは悪いことではない。 */ memset( check_table, 0 , MAX_STATE * 2 ); start = clock(); search(); end = clock(); printf("時間 %d \n", end - start ); return 0; }

みんなの回答

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★アドバイス >ネットなどを利用して勉強してるところなんですが、わからないところがあります。 >8パズルの探索プログラムなんですがネットで見つけたものは初期値が最初から入ってるものでした。  ↑  参考にしているサイトのURLを載せて欲しいですね。 >読み込んでるつもりなのですがメモリに記憶されてないみたいです。  ↑  これはどんな感じで読み込んで、どう確認しましたか?  ソースを見ると adjacent、init_state の2つを初期化しないといけない気がします。  回答者 No.1 さんも init_state については触れていますが、adjacent の配列情報も  必要な気がしますけど?ここの配列情報は初期化しましたか? ・コメントによると『隣接リスト』となっていますから init_state と一緒に adjacent の  情報も必要だと思います。まずは参考にしているというサイトのURLを教えて下さい。  そうしないと0~8、-1の意味が分かりません。 ・以上。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.2

> 入力するためのコードはいろいろ自分なりにやったつもりです。 まさにその箇所を見せてくださると、もしも正しくない箇所があれば 指摘できるかもしれないのですけれど。 「いろいろやってみた」だけですと、結局今どういう状況で うまくいっていないかが伝わらないのです。

tachikoma0
質問者

補足

メイン文の中に scanf("%s",&init_state); を入れたり、上のほうでchar init_stateを定義してるところで同じくscanfで読み込んでみましたができませんでした。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.1

> 自分で入力して実行したいのですがそれがうまくいきません。 init_state[]にご自分で入力したい、ということでしょうか? > 読み込んでるつもりなのですがメモリに記憶されてないみたいです。 その、読み込んでいるつもりのコードを提示してみる、 というお考えはありますか?

tachikoma0
質問者

補足

はいinit_state[]に自分で入力したいというとです。 入力するためのコードはいろいろ自分なりにやったつもりです。 メイン文にscanf文を書いて読み込もうとしたり、init_state[]を定義している文の次の行にscanfを書いたりということはやりました。 メイン文で定義した変数しか暑かったことが無いのでこのようなプログラムはわからないのです。

関連するQ&A