private void Super(object sender, EventArgs e)
{
m_err = false;
Super(0,m_t);
if (FIN(m_t)!=-1)
{ MessageBox.Show("解答が見つかりません。(失敗しました)");
Reset(false, m_test);
}
else Reset(true, m_test);
}
//☆ 再帰で難問を解くスーパー関数
public bool Super(int no, int[,,] t)
{ int[,,] wt = new int[9,9,11];
int x, y, k, i, cn, pt1=0, pt2=0;
int rc;
if (m_err) return false;
if (no > 8)
{
MessageBox.Show("再帰呼び出しが制限を超えました。");
m_err = true;
return false;
}
CreateHint(wt, t);
DelHint(wt);
while(true) //数字に色を設定して確定する
{
if (Analyze(wt,false)) Analyze(wt,false);
rc = HintCor(wt);
if (rc<0)
{
for (y = 0; y < 9; y++)
for (x = 0; x < 9; x++)
for (k = 0; k < 10; k++) m_t[y,x,k] = wt[y,x,k];
if (rc==-2) return false; //破綻
if (rc==-1) return true; //完成
}
if (rc==0) break; //確定出来なくなった
// 色が設定されているマスを確定する
for (y = 0; y < 9; y++)
for (x = 0; x < 9; x++)
{ for (k = 1; k < 10; k++)
if (wt[y, x, k] > 40)
{ wt[y, x, 0] = k;
for(i=0; i<9; i++) wt[y, i, k] = 0;
for(i=0; i<9; i++) wt[i, x, k] = 0;
Del33(y, x, k, wt);
}
}
}
if (m_err) return false;
// 数字を仮定して再帰呼び出し
for(y=0; y<9; y++)
for(x=0; x<9; x++)
{ if (wt[y,x,0]!=0) continue;
cn = 0;
for (k = 0; k < 9; k++)
{
if (wt[y, x, k] != 0)
{
cn++;
if (pt1 == 0) pt1 = k;
else pt2 = k;
}
}
if (cn == 2 || cn == 3)
{
wt[y, x, 0] = pt1;
if (Super(no + 1, wt)) return true;
wt[y, x, 0] = pt2;
if (Super(no + 1, wt)) return true;
wt[y, x, 0] = 0;
}
}
return false;
}
|