ひょんなことから、「数独を解くプログラム」を作ることになり、
以下のC/C++(開発の関係上C++だが、ほとんどC言語のつもりで書きました)プログラムを書いてみました。
ですが、実行してみると途中で動作が止まってしまいます。
何度も見直してみましたが、とても一人では見つけられそうにないのでこちらに質問させていただきました。
なぜ、止まってしまうのか、コードのどこが原因なのか教えていただきたいです。
また、そもそも数独を解くプログラムとして機能できているのかも教えて欲しいです。
#include "stdafx.h"
#include "stdio.h"
#include <time.h>
#include <iostream>
using namespace std;
#define Size 9
int ban[Size][Size], randoms[Size];
//ここにresetBan(),Show(),Input()があります(問題あるとは考えられないので省略)
void makeRandomNumbers(){//1~9の値をランダムな順に格納
srand((unsigned int)time(NULL));//乱数初期値の初期化
for (int i = 0; i < Size; i++)
randoms[i] = i + 1;
for (int j = 0; j < Size; j++){
int k = rand() % 9;
int temp = randoms[j];
randoms[j] = randoms[k];
randoms[k] = temp;
}
}
bool checkLinCol(int Column, int Line, int value) {//行・列の重複を調べる
for (int i = 0; i < Size; i++) {
// 同じマスは調べない。
if (i != Column)
if (ban[Line][i] == value)
return true;
if (i != Line)
if (ban[i][Column] == value)
return true;
}
return false;
}
bool checkBox(int Column, int Line, int value) {
// マスにおける3x3ブロックの一番左上を計算。
int startLine = Line / 3 * 3;
int startColumn = Column / 3 * 3;
// 3x3ブロックの中のこのマス以外を調べる。
for (int i = startLine; i < startLine + 3; i++){
for (int j = startColumn; j < startColumn + 3; j++) {
if (!(i == Line && j == Column)) {
if (ban[i][j] == value)
return true;
}
}
}
return false;
}
bool solve(int Column, int Line) {
// 最終地点まで来た
if (Line == Size)
return true;
// 空白でない
if (ban[Line][Column] != 0) {
// 次のマスに進む。
if (solve(Column == 8 ? (Line + 1) : Line, (Column + 1) % 9))
return true;
}
else {//空白である(まだ埋めていない)
makeRandomNumbers();
for (int i = 0; i < Size; i++) {
// この行・列・3x3ブロックにこの数字が重複しない
if (!checkLinCol(Column, Line, randoms[i]) && !checkBox(Column, Line, randoms[i])) {
ban[Line][Column] = randoms[i];
// 次のマスに進む。
if (solve(Column == 8 ? (Line + 1) : Line, (Column + 1) % 9))
return true;
else
ban[Line][Column] = 0;
}
}
}
return false;
}
int _tmain(int argc, const char * argv[]) {
resetBan();
Input();
solve(0,0);//この関数に問題があると考えられる
Show();
return 0;
}