早速ですが質問があります。
反転ゲーム(正式名称がわからないです)のクリアまでの最小回数を求めるプログラムを作っています。
反転ゲーム
①
□□□□
□□□□
□□□□
□□□□
①の状態で左上を押したら、②の状態になります。
②
■■□□
■□□□
□□□□
□□□□
②の状態で[0][2]を押したら、③の状態になります。
③
■□■■
■□■□
□□□□
□□□□
これを繰り返して、すべて■にしたらゲームクリアです。
今できているプログラムが
①ランダムな所を指定し、反転させる。
②ゲームクリアまで繰り返します。
③ゲームクリアまでの回数をカウントします。
④カウントが一番小さい数を記憶し、①に戻ります。
このやり方ですと、確実な最小回数がでない可能性があります。
もっと効率の良い方法はないでしょうか?
どうぞよろしくお願いします。
環境
CPad for Borland C++ Compiler
C言語
WindowsXP
です。
#include<stdio.h> #include<conio.h> #include<stdlib.h> #include<time.h> #define BLUE -1 #define RED 1 #define MASS 4 #define KAISUU 1000 void flip(int [/url][MASS],int ,int ); void draw(int [/url][MASS]); int judge(int [/url][MASS]); int main(){ srand((unsigned)time(NULL)); int b[MASS][MASS]; //配列の初期化 for(int i=0;i<MASS;i++){ for(int j=0;j<MASS;j++){ b[j] = BLUE; } } //最小値の初期化 これ以上大きい数はないはず… //いままでやった中の最小回数を記録 int min = 2147483647; for(int k=0;k<KAISUU;k++){ //全部REDになるまでの回数を記録 int count = 0; while(1){ //反転している数を記録 int sum = 0; //draw(b); //適当な所していして、反転させる flip(b, rand()%MASS, rand()%MASS); sum = judge(b); count++; if(sum == MASS*MASS)break; //getch(); } //minの記録 if(count < min){ min = count; } printf("%d回でできました。 現在の最小回数は%dです。\n",count,min); //getch(); //初期化 count = 0; for(int i=0;i<MASS;i++){ for(int j=0;j<MASS;j++){ b[j] = BLUE; } } } printf("最小回数は%dです。\n",min); getch(); return 0; } //[j]の数を判定させる void flip(int ary[/url][MASS],int i,int j){ ary[j] *= -1; if(i-1 >= 0) ary[i-1][j] *= -1; if(i+1 <= MASS-1) ary[i+1][j] *= -1; if(j-1 >= 0) ary[j-1] *= -1; if(j+1 <= MASS-1) ary[j+1] *= -1; } //現在の状態を表示する void draw(int ary[/url][MASS]){ for(int i=0;i<MASS;i++){ for(int j=0;j<MASS;j++){ if(ary[j] == BLUE) printf("□"); if(ary[j] == RED) printf("■"); } printf("\n"); } printf("\n"); } //反転している物の数を返す int judge(int ary[/url][MASS]){ int count = 0; for(int i=0;i<MASS;i++){ for(int j=0;j<MASS;j++){ if(ary[j] == RED){ count++; } } } return (count); }