// info  nam="SAMPLE03C"  tit="ナンプレ改"  dsc="説明用サンプル"  pro=2

BOOL chk_r0(PINT p, int v)
{ // 行 0 のチェック
  if (p[ 0] == v || p[ 1] == v || p[ 2] == v) return FALSE;
  if (p[ 3] == v || p[ 4] == v || p[ 5] == v) return FALSE;
  if (p[ 6] == v || p[ 7] == v || p[ 8] == v) return FALSE;
  return TRUE;
}

BOOL chk_r1(PINT p, int v)
{ // 行 1 のチェック
  if (p[ 9] == v || p[10] == v || p[11] == v) return FALSE;
  if (p[12] == v || p[13] == v || p[14] == v) return FALSE;
  if (p[15] == v || p[16] == v || p[17] == v) return FALSE;
  return TRUE;
}

BOOL chk_r2(PINT p, int v)
{ // 行 2 のチェック
  if (p[18] == v || p[19] == v || p[20] == v) return FALSE;
  if (p[21] == v || p[22] == v || p[23] == v) return FALSE;
  if (p[24] == v || p[25] == v || p[26] == v) return FALSE;
  return TRUE;
}

BOOL chk_r3(PINT p, int v)
{ // 行 3 のチェック
  if (p[27] == v || p[28] == v || p[29] == v) return FALSE;
  if (p[30] == v || p[31] == v || p[32] == v) return FALSE;
  if (p[33] == v || p[34] == v || p[35] == v) return FALSE;
  return TRUE;
}

BOOL chk_r4(PINT p, int v)
{ // 行 4 のチェック
  if (p[36] == v || p[37] == v || p[38] == v) return FALSE;
  if (p[39] == v || p[40] == v || p[41] == v) return FALSE;
  if (p[42] == v || p[43] == v || p[44] == v) return FALSE;
  return TRUE;
}

BOOL chk_r5(PINT p, int v)
{ // 行 5 のチェック
  if (p[45] == v || p[46] == v || p[47] == v) return FALSE;
  if (p[48] == v || p[49] == v || p[50] == v) return FALSE;
  if (p[51] == v || p[52] == v || p[53] == v) return FALSE;
  return TRUE;
}

BOOL chk_r6(PINT p, int v)
{ // 行 6 のチェック
  if (p[54] == v || p[55] == v || p[56] == v) return FALSE;
  if (p[57] == v || p[58] == v || p[59] == v) return FALSE;
  if (p[60] == v || p[61] == v || p[62] == v) return FALSE;
  return TRUE;
}

BOOL chk_r7(PINT p, int v)
{ // 行 7 のチェック
  if (p[63] == v || p[64] == v || p[65] == v) return FALSE;
  if (p[66] == v || p[67] == v || p[68] == v) return FALSE;
  if (p[69] == v || p[70] == v || p[71] == v) return FALSE;
  return TRUE;
}

BOOL chk_r8(PINT p, int v)
{ // 行 8 のチェック
  if (p[72] == v || p[73] == v || p[74] == v) return FALSE;
  if (p[75] == v || p[76] == v || p[77] == v) return FALSE;
  if (p[78] == v || p[79] == v || p[80] == v) return FALSE;
  return TRUE;
}

BOOL chk_c0(PINT p, int v)
{ // 列 0 のチェック
  if (p[ 0] == v || p[ 9] == v || p[18] == v) return FALSE;
  if (p[27] == v || p[36] == v || p[45] == v) return FALSE;
  if (p[54] == v || p[63] == v || p[72] == v) return FALSE;
  return TRUE;
}

BOOL chk_c1(PINT p, int v)
{ // 列 1 のチェック
  if (p[ 1] == v || p[10] == v || p[19] == v) return FALSE;
  if (p[28] == v || p[37] == v || p[46] == v) return FALSE;
  if (p[55] == v || p[64] == v || p[73] == v) return FALSE;
  return TRUE;
}

BOOL chk_c2(PINT p, int v)
{ // 列 2 のチェック
  if (p[ 2] == v || p[11] == v || p[20] == v) return FALSE;
  if (p[29] == v || p[38] == v || p[47] == v) return FALSE;
  if (p[56] == v || p[65] == v || p[74] == v) return FALSE;
  return TRUE;
}

BOOL chk_c3(PINT p, int v)
{ // 列 3 のチェック
  if (p[ 3] == v || p[12] == v || p[21] == v) return FALSE;
  if (p[30] == v || p[39] == v || p[48] == v) return FALSE;
  if (p[57] == v || p[66] == v || p[75] == v) return FALSE;
  return TRUE;
}

BOOL chk_c4(PINT p, int v)
{ // 列 4 のチェック
  if (p[ 4] == v || p[13] == v || p[22] == v) return FALSE;
  if (p[31] == v || p[40] == v || p[49] == v) return FALSE;
  if (p[58] == v || p[67] == v || p[76] == v) return FALSE;
  return TRUE;
}

BOOL chk_c5(PINT p, int v)
{ // 列 5 のチェック
  if (p[ 5] == v || p[14] == v || p[23] == v) return FALSE;
  if (p[32] == v || p[41] == v || p[50] == v) return FALSE;
  if (p[59] == v || p[68] == v || p[77] == v) return FALSE;
  return TRUE;
}

BOOL chk_c6(PINT p, int v)
{ // 列 6 のチェック
  if (p[ 6] == v || p[15] == v || p[24] == v) return FALSE;
  if (p[33] == v || p[42] == v || p[51] == v) return FALSE;
  if (p[60] == v || p[69] == v || p[78] == v) return FALSE;
  return TRUE;
}

BOOL chk_c7(PINT p, int v)
{ // 列 7 のチェック
  if (p[ 7] == v || p[16] == v || p[25] == v) return FALSE;
  if (p[34] == v || p[43] == v || p[52] == v) return FALSE;
  if (p[61] == v || p[70] == v || p[79] == v) return FALSE;
  return TRUE;
}

BOOL chk_c8(PINT p, int v)
{ // 列 8 のチェック
  if (p[ 8] == v || p[17] == v || p[26] == v) return FALSE;
  if (p[35] == v || p[44] == v || p[53] == v) return FALSE;
  if (p[62] == v || p[71] == v || p[80] == v) return FALSE;
  return TRUE;
}

BOOL chk_b0(PINT p, int v)
{ // 箱 0 のチェック
  if (p[ 0] == v || p[ 1] == v || p[ 2] == v) return FALSE;
  if (p[ 9] == v || p[10] == v || p[11] == v) return FALSE;
  if (p[18] == v || p[19] == v || p[20] == v) return FALSE;
  return TRUE;
}

BOOL chk_b1(PINT p, int v)
{ // 箱 1 のチェック
  if (p[ 3] == v || p[ 4] == v || p[ 5] == v) return FALSE;
  if (p[12] == v || p[13] == v || p[14] == v) return FALSE;
  if (p[21] == v || p[22] == v || p[23] == v) return FALSE;
  return TRUE;
}

BOOL chk_b2(PINT p, int v)
{ // 箱 2 のチェック
  if (p[ 6] == v || p[ 7] == v || p[ 8] == v) return FALSE;
  if (p[15] == v || p[16] == v || p[17] == v) return FALSE;
  if (p[24] == v || p[25] == v || p[26] == v) return FALSE;
  return TRUE;
}

BOOL chk_b3(PINT p, int v)
{ // 箱 3 のチェック
  if (p[27] == v || p[28] == v || p[29] == v) return FALSE;
  if (p[36] == v || p[37] == v || p[38] == v) return FALSE;
  if (p[45] == v || p[46] == v || p[47] == v) return FALSE;
  return TRUE;
}

BOOL chk_b4(PINT p, int v)
{ // 箱 4 のチェック
  if (p[30] == v || p[31] == v || p[32] == v) return FALSE;
  if (p[39] == v || p[40] == v || p[41] == v) return FALSE;
  if (p[48] == v || p[49] == v || p[50] == v) return FALSE;
  return TRUE;
}

BOOL chk_b5(PINT p, int v)
{ // 箱 5 のチェック
  if (p[33] == v || p[34] == v || p[35] == v) return FALSE;
  if (p[42] == v || p[43] == v || p[44] == v) return FALSE;
  if (p[51] == v || p[52] == v || p[53] == v) return FALSE;
  return TRUE;
}

BOOL chk_b6(PINT p, int v)
{ // 箱 6 のチェック
  if (p[54] == v || p[55] == v || p[56] == v) return FALSE;
  if (p[63] == v || p[64] == v || p[65] == v) return FALSE;
  if (p[72] == v || p[73] == v || p[74] == v) return FALSE;
  return TRUE;
}

BOOL chk_b7(PINT p, int v)
{ // 箱 7 のチェック
  if (p[57] == v || p[58] == v || p[59] == v) return FALSE;
  if (p[66] == v || p[67] == v || p[68] == v) return FALSE;
  if (p[75] == v || p[76] == v || p[77] == v) return FALSE;
  return TRUE;
}

BOOL chk_b8(PINT p, int v)
{ // 箱 8 のチェック
  if (p[60] == v || p[61] == v || p[62] == v) return FALSE;
  if (p[69] == v || p[70] == v || p[71] == v) return FALSE;
  if (p[78] == v || p[79] == v || p[80] == v) return FALSE;
  return TRUE;
}

BOOL chk_i(PINT p, int i, int v)
{ // 枡 i のチェック
  switch (i) {
  case  0: return chk_r0(p, v) && chk_c0(p, v) && chk_b0(p, v);
  case  1: return chk_r0(p, v) && chk_c1(p, v) && chk_b0(p, v);
  case  2: return chk_r0(p, v) && chk_c2(p, v) && chk_b0(p, v);
  case  3: return chk_r0(p, v) && chk_c3(p, v) && chk_b1(p, v);
  case  4: return chk_r0(p, v) && chk_c4(p, v) && chk_b1(p, v);
  case  5: return chk_r0(p, v) && chk_c5(p, v) && chk_b1(p, v);
  case  6: return chk_r0(p, v) && chk_c6(p, v) && chk_b2(p, v);
  case  7: return chk_r0(p, v) && chk_c7(p, v) && chk_b2(p, v);
  case  8: return chk_r0(p, v) && chk_c8(p, v) && chk_b2(p, v);
  case  9: return chk_r1(p, v) && chk_c0(p, v) && chk_b0(p, v);
  case 10: return chk_r1(p, v) && chk_c1(p, v) && chk_b0(p, v);
  case 11: return chk_r1(p, v) && chk_c2(p, v) && chk_b0(p, v);
  case 12: return chk_r1(p, v) && chk_c3(p, v) && chk_b1(p, v);
  case 13: return chk_r1(p, v) && chk_c4(p, v) && chk_b1(p, v);
  case 14: return chk_r1(p, v) && chk_c5(p, v) && chk_b1(p, v);
  case 15: return chk_r1(p, v) && chk_c6(p, v) && chk_b2(p, v);
  case 16: return chk_r1(p, v) && chk_c7(p, v) && chk_b2(p, v);
  case 17: return chk_r1(p, v) && chk_c8(p, v) && chk_b2(p, v);
  case 18: return chk_r2(p, v) && chk_c0(p, v) && chk_b0(p, v);
  case 19: return chk_r2(p, v) && chk_c1(p, v) && chk_b0(p, v);
  case 20: return chk_r2(p, v) && chk_c2(p, v) && chk_b0(p, v);
  case 21: return chk_r2(p, v) && chk_c3(p, v) && chk_b1(p, v);
  case 22: return chk_r2(p, v) && chk_c4(p, v) && chk_b1(p, v);
  case 23: return chk_r2(p, v) && chk_c5(p, v) && chk_b1(p, v);
  case 24: return chk_r2(p, v) && chk_c6(p, v) && chk_b2(p, v);
  case 25: return chk_r2(p, v) && chk_c7(p, v) && chk_b2(p, v);
  case 26: return chk_r2(p, v) && chk_c8(p, v) && chk_b2(p, v);
  case 27: return chk_r3(p, v) && chk_c0(p, v) && chk_b3(p, v);
  case 28: return chk_r3(p, v) && chk_c1(p, v) && chk_b3(p, v);
  case 29: return chk_r3(p, v) && chk_c2(p, v) && chk_b3(p, v);
  case 30: return chk_r3(p, v) && chk_c3(p, v) && chk_b4(p, v);
  case 31: return chk_r3(p, v) && chk_c4(p, v) && chk_b4(p, v);
  case 32: return chk_r3(p, v) && chk_c5(p, v) && chk_b4(p, v);
  case 33: return chk_r3(p, v) && chk_c6(p, v) && chk_b5(p, v);
  case 34: return chk_r3(p, v) && chk_c7(p, v) && chk_b5(p, v);
  case 35: return chk_r3(p, v) && chk_c8(p, v) && chk_b5(p, v);
  case 36: return chk_r4(p, v) && chk_c0(p, v) && chk_b3(p, v);
  case 37: return chk_r4(p, v) && chk_c1(p, v) && chk_b3(p, v);
  case 38: return chk_r4(p, v) && chk_c2(p, v) && chk_b3(p, v);
  case 39: return chk_r4(p, v) && chk_c3(p, v) && chk_b4(p, v);
  case 40: return chk_r4(p, v) && chk_c4(p, v) && chk_b4(p, v);
  case 41: return chk_r4(p, v) && chk_c5(p, v) && chk_b4(p, v);
  case 42: return chk_r4(p, v) && chk_c6(p, v) && chk_b5(p, v);
  case 43: return chk_r4(p, v) && chk_c7(p, v) && chk_b5(p, v);
  case 44: return chk_r4(p, v) && chk_c8(p, v) && chk_b5(p, v);
  case 45: return chk_r5(p, v) && chk_c0(p, v) && chk_b3(p, v);
  case 46: return chk_r5(p, v) && chk_c1(p, v) && chk_b3(p, v);
  case 47: return chk_r5(p, v) && chk_c2(p, v) && chk_b3(p, v);
  case 48: return chk_r5(p, v) && chk_c3(p, v) && chk_b4(p, v);
  case 49: return chk_r5(p, v) && chk_c4(p, v) && chk_b4(p, v);
  case 50: return chk_r5(p, v) && chk_c5(p, v) && chk_b4(p, v);
  case 51: return chk_r5(p, v) && chk_c6(p, v) && chk_b5(p, v);
  case 52: return chk_r5(p, v) && chk_c7(p, v) && chk_b5(p, v);
  case 53: return chk_r5(p, v) && chk_c8(p, v) && chk_b5(p, v);
  case 54: return chk_r6(p, v) && chk_c0(p, v) && chk_b6(p, v);
  case 55: return chk_r6(p, v) && chk_c1(p, v) && chk_b6(p, v);
  case 56: return chk_r6(p, v) && chk_c2(p, v) && chk_b6(p, v);
  case 57: return chk_r6(p, v) && chk_c3(p, v) && chk_b7(p, v);
  case 58: return chk_r6(p, v) && chk_c4(p, v) && chk_b7(p, v);
  case 59: return chk_r6(p, v) && chk_c5(p, v) && chk_b7(p, v);
  case 60: return chk_r6(p, v) && chk_c6(p, v) && chk_b8(p, v);
  case 61: return chk_r6(p, v) && chk_c7(p, v) && chk_b8(p, v);
  case 62: return chk_r6(p, v) && chk_c8(p, v) && chk_b8(p, v);
  case 63: return chk_r7(p, v) && chk_c0(p, v) && chk_b6(p, v);
  case 64: return chk_r7(p, v) && chk_c1(p, v) && chk_b6(p, v);
  case 65: return chk_r7(p, v) && chk_c2(p, v) && chk_b6(p, v);
  case 66: return chk_r7(p, v) && chk_c3(p, v) && chk_b7(p, v);
  case 67: return chk_r7(p, v) && chk_c4(p, v) && chk_b7(p, v);
  case 68: return chk_r7(p, v) && chk_c5(p, v) && chk_b7(p, v);
  case 69: return chk_r7(p, v) && chk_c6(p, v) && chk_b8(p, v);
  case 70: return chk_r7(p, v) && chk_c7(p, v) && chk_b8(p, v);
  case 71: return chk_r7(p, v) && chk_c8(p, v) && chk_b8(p, v);
  case 72: return chk_r8(p, v) && chk_c0(p, v) && chk_b6(p, v);
  case 73: return chk_r8(p, v) && chk_c1(p, v) && chk_b6(p, v);
  case 74: return chk_r8(p, v) && chk_c2(p, v) && chk_b6(p, v);
  case 75: return chk_r8(p, v) && chk_c3(p, v) && chk_b7(p, v);
  case 76: return chk_r8(p, v) && chk_c4(p, v) && chk_b7(p, v);
  case 77: return chk_r8(p, v) && chk_c5(p, v) && chk_b7(p, v);
  case 78: return chk_r8(p, v) && chk_c6(p, v) && chk_b8(p, v);
  case 79: return chk_r8(p, v) && chk_c7(p, v) && chk_b8(p, v);
  case 80: return chk_r8(p, v) && chk_c8(p, v) && chk_b8(p, v);
  }
  return FALSE;
}

BOOL solve(PINT p)
{ // 試行
  int i, v, m[9*9];

  for (i = 0; i < NELEM(m); i++) {
    m[i] = (p[i] != 0);
  }
  i = 0;
  goto _S;
 _F:
  i++; 
  if (i >= NELEM(m)) return TRUE;
 _S: 
  if (m[i]) goto _F;
  for (v = 1; v <= 9; v++) {
    if (chk_i(p, i, v)) { p[i] = v; goto _F;}
  }
 _B:
  i--; 
  if (i < 0) return FALSE;
  if (m[i]) goto _B;
  for (v = p[i] + 1; v <= 9; v++) {
    if (chk_i(p, i, v)) { p[i] = v; goto _F;}
  }
  p[i] = 0;
  goto _B;
}

BOOL load_p(PINT p, PCSTR nam)
{ // 問題読込
  int re;
  HANDLE hf;

  if (!(hf = open_file(nam, OP_RDO))) return FALSE;
  re = read_file(hf, p, 9 * 9 * sizeof(int));
  close_file(hf);
  return re;
}

BOOL save_p(PINT p, PCSTR nam)
{ // 解答書出
  int re;
  HANDLE hf;

  if (!(hf = open_file(nam, OP_WRI))) return FALSE;
  re = write_file(hf, p, 9 * 9 * sizeof(int));
  close_file(hf);
  return re;
}

void CommandMain(HWND hwnd)
{ // ナンプレソルバー
  int re, p[9*9];

  if (!load_p(p, "MON.BTB")) {
    ErrorBox(hwnd, "問題の読込に失敗しました。", NULL); return;
  }
  BusyMsg(hwnd, "計算中です。");
  re = solve(p);
  EndBusy(hwnd);
  if (!re) {
    OkBox(hwnd, "解けません。", NULL);
  } else if (save_p(p, "KAI.BTB")) {
    OkBox(hwnd, "解けました。", NULL);
  } else {
    ErrorBox(hwnd, "解答の書出に失敗しました。", NULL);
  }
}
