早速ですが質問があります。
反転ゲーム(正式名称がわからないです)のクリアまでの最小回数を求めるプログラムを作っています。
反転ゲーム
①
□□□□
□□□□
□□□□
□□□□
①の状態で左上を押したら、②の状態になります。
②
■■□□
■□□□
□□□□
□□□□
②の状態で[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);
}