第7講 左右対称形・上下対称形・点対称形・左右にも上下に対称・ハート型
第11話 上下対称第2案
テキストファイル自動実験版
テキストファイル手動実験版
void jyogetaisyou(char a) {
char k = hnt / 9;//中央列の個数の平均
char s[3] = { k - 1,k,k + 1 };//平均がk
char p;
if (hnt % 2 == 1) {//中央列以外は上下対称であるためにセルの個数は必ず偶数になるから
//セルの総数を奇数にするためには中央列の個数を奇数にしなければならない
while (1) {
p = s[rand() % 3]; //{ k - 1, k, k + 1}から1つを選ぶ
if (p % 2 == 1)break;//ヒント数が奇数の場合中央列はのセルの個数は奇数にするしかない
}
}
if (hnt % 2 == 0) {
while (1) {
p = s[rand() % 3];
if (p % 2 == 0)break;
}
}
char e[9];//大は小を兼ねる Y[a][]の過去を記録
char i = 0;
while (i <= p) {//すでに入っているセルとの重複を避ける
Y[a][i] = 4;
if (i == 0) {
X[a][i] = rand() % 9;
e[i] = Y[a][i];
}
if (i > 0) {
while (1) {
X[a][i] = rand() % 9;
char h = 1;
for (char j = 0; j < i; j++) {
if (X[a][i] == e[j]) {
h = 0;//1つでも一致したらwhile文は継続させる
break;
}
}
if (h == 1) {//hが 1 ということは過去のいずれとも一致しないので
//while文を終了させる
e[i] = X[a][i];
break;
}
}
}
i++;
}
if (p == 0)cout << "中央列には1個も入りません。";
for (char j = 0; j < p; j++) {
sudoku[a][Y[a][j]][X[a][j]] = 1;
}
char st = rand() % 36;
char tbk[8] = { 5,7,11,13,17,19,23,29 };
char tb = tbk[rand() % 8];
for (i = 0; i < (hnt - p) / 2; i++) {
Y[a][i] = ((st + tb * i) % 36) / 9;
//例えば、st = 20、tb = 13とすると
//20,33,10,23,0,13,26,3,16,29,6,19,32,
//9,22,35,12,25,2,15,28,5,18,31,8,21,34,11,24,1,14,27,4,17,30,7
//以下同じ循環を繰り返すが、重複なしに1巡目で0,1,2,・・・,35もれなく並べられること
//この手法を私たちは何度も使ってきた
X[a][i] = ((st + tb * i) % 36) % 9;
Y[a][i + 1] = 8 - Y[a][i];//上下に対称な位置
X[a][i + 1] = X[a][i];
sudoku[a][Y[a][i]][X[a][i]] = 1;
sudoku[a][Y[a][i + 1]][X[a][i + 1]] = 1;
}
}
第10話へ 第12話へ
トップへ