mate法を用いて、ナンバーリンクパズルの問題を自動生成するプログラマムを実装してみた。
(高度な枝刈りを行わない単純な)バックトラッキングに比べ、かなり高速な処理が実現でき、
バックトラッキングでは 5x5 までの問題自動生成が限度だったのが、
PCでは 9x9 まで、タブレットでは 8x8 まで、リアルタイム(0.5秒程度以下)な問題生成が可能になった。
┌─┬─┬─┬─┐ │1│ │ │2│ ├─┼─┼─┼─┤ │3│ │ │3│ ├─┼─┼─┼─┤ │ │1│2│ │ ├─┼─┼─┼─┤ │ │ │ │ │ └─┴─┴─┴─┘
┌─┬─┬─┬─┐ │1┿┓│┏┿2│ ├─┼╂┼╂┼─┤ │3│┃│┃│3│ ├╂┼╂┼╂┼╂┤ │┃│1│2│┃│ ├╂┼─┼─┼╂┤ │┗┿━┿━┿┛│ └─┴─┴─┴─┘
┌─┬─┬─┬─┬─┬─┬─┬─┬─┐ │ │ │ │ │2│ │ │ │1│ ├─┼─┼─┼─┼─┼─┼─┼─┼─┤ │ │3│ │ │ │ │ │1│2│ ├─┼─┼─┼─┼─┼─┼─┼─┼─┤ │ │ │ │ │ │4│ │ │ │ ├─┼─┼─┼─┼─┼─┼─┼─┼─┤ │7│ │ │5│ │ │ │ │ │ ├─┼─┼─┼─┼─┼─┼─┼─┼─┤ │ │ │ │ │ │ │ │ │ │ ├─┼─┼─┼─┼─┼─┼─┼─┼─┤ │6│ │ │4│ │ │ │ │3│ ├─┼─┼─┼─┼─┼─┼─┼─┼─┤ │ │ │ │ │ │8│ │ │ │ ├─┼─┼─┼─┼─┼─┼─┼─┼─┤ │ │8│ │ │ │ │ │7│ │ ├─┼─┼─┼─┼─┼─┼─┼─┼─┤ │ │ │ │ │ │6│5│ │ │ └─┴─┴─┴─┴─┴─┴─┴─┴─┘
┌─┬─┬─┬─┐ │┏┿┓│1│2│ ├╂┼╂┼╂┼╂┤ │┗┿┛│┃│┃│ ├─┼─┼╂┼╂┤ │2┿━┿┛│┃│ ├─┼─┼─┼╂┤ │1┿━┿━┿┛│ └─┴─┴─┴─┘
int g_count = 0; void solve(int ix) { // 位置 if( ix が矩形外 ) { if( 空ループ、異なる数字をリンクしていない ) ++g_count; return; } if( ix 位置に数字がある ) { if( 上方向に連結可能 ) { ix から上方向にリンク; solve(ix+1); } 左・右・下方向についても同様の処理; } else { if( ━ のそれぞれが設置可能 ) { それを配置; solve(ix+1); } ┃ ┏ ┓ ┗ ┛ についても同様の処理; } }
for(;;) { 盤面に数字をランダムに配置 if( 盤面がユニーク解を持つ ) break; }
①②③④ ⑤⑥⑦⑧ ⑨⑩⑪⑫ ⑬⑭⑮⑯
┌─┬─┬─┬─┐ │┏┿━┿┓│1│ ← この行まで処理した場合 ├╂┼─┼╂┼╂┤ │ │ │ │ │ ├─┼─┼─┼─┤ │ │ │ │ │ ├─┼─┼─┼─┤ │ │ │ │ │ └─┴─┴─┴─┘ mate[] : {0, 0, 0, 8, 7, 6, 5, 4}
本稿のアルゴリズムを使用して問題を作成したパズルをリリースしてるよ。
ここ からダウンロードできるので、よかったら遊んであげてね。