GUI/Java組
はじめに
・動機
 ーどんなに小さなものでもいいから
   とりあえずなにか一つ形にしよう!
 -数学パズル好きだから数学パズルを解く
   ツールを作ろう
・使用言語、環境、ライブラリ
 Java、Eclipse+Visual Editor
 主にjavax.swingを使用
目標
・多機能ナンプレ解析ツール
・解析方法の選択ができる
・より早く、よりきれいに
・より使いやすいもの
ナンプレとは

・Number Placeの略
・いわゆる「数独パズル」
ルール
・空いているマスに1~9のいずれかを入
 れる
・縦横、太線で囲まれた3x3正方形に同じ
 数字が存在してはいけない
考え方
ナンプレは空白を埋めるパズル
→空白に入る可能性のある数字を集合とし
 て持ち、それが一つに定まれば確定
この集合をcell[i][j]として管理!!


1,2,3,
×   ×
4,5,6,
7,8,9
×   ×
アルゴリズム
1.データ(初期値)の読み込み
2.空白の数だけ、マスに入る可能性の数字
  の集合を用意
3.空白マスの縦横正方形をチェックし、数
  字を集合から削除
4.集合のサイズが1になったら(空白マスに
  入る数字が特定できたら)確定
5.空白マスがなくなるまで3~4を繰り返す
実際に作ってみた。
結果
     初期配置の多い簡単な問題
反省点
・解析方法がまだまだ甘い
 →他にも解析方法があるはず!!
・リセットボタンほしい
・解析方法追加するなら解析方法選べたほ
 うが便利
解析方法の追加
例


            空白マスに入る
            可能性ある数字の集合
            A={1,6}
            B={4,6,7}
            C={1,4,6,7}
            D={2,4,5,6}
A   B   C   E={1,4,5,6}
    D   E   F={1,4,5,6}
        F
解析方法の追加
1.ある空白マスの集合のある要素がその空白マ
  スの縦列の他の空白マスの集合がもっていな
  いか確認する。
2.持っていなければその要素がその空白に入る
  数字である。
3.横列、正方形でも確認する。
実際に追加してみた。
結果
     前回の簡単な問題
結果
     初期配置の少ない難しい問題
反省点
・簡単な問題は解けたけどまだまだ人が解
 くのと同レベル

→プログラムならではの方法で解かなけれ
 ば・・・




より高度な解析方法を!!
高度な解析 advanced()
・マスに入る数字が一意に定まらない時に
 使用
・可能性の集合の1つ1つを入れてみた場
 合を調べるメソッドadvanced()を作成
・数字の重複や間違いがでた時はreturnで
 抜け、可能性の集合からその要素を削除

・再帰で回せば解けない問題はない!!
というわけで
   また追加してみた。
結果
     前回の難しい問題
反省点
・配色がなんかダメ。答えが見にくい。
・出力部分、見た目を改良したい。
・解析のスピードに問題はなさそう。
というわけで改良してみた。
完成形
      ・補色等より配色、
       フォントは

      正方形:白、薄紫

      初期値:黒、太字

      答え:水色、太字
つまづいたところ
・String型の比較を
 if(str == “abc”)で行っていた

※正しくはeqauls()というメソッドで比較
つまづいたところ2
ArrayListのremoveメソッドで集合から要
  素を削除する時、nという要素を消そう
  として
~.remove(n);
  としていた。正しくは
~.remove(Integer (n));
  とするべきだった。

※~.remove(n);はn番目の要素を消す処理
つまづいたところ3
高度な解析のために新しくcell2を作り、
 cell2[i][j].value = cell[i][j].value;
 advanced(cell2); //高度な解析の処理へ

としたらデータの変更結果がcell2だけでなく
 cellにも反映されてしまった。

※複製はcloneメソッドを使わければいけない
→クラスがアドレスを参照してるから
工夫したところ
・正方形のチェック方法
   縦や横の場合
for(int i = 0; i < 9;i++){
   for(int j = 0; j < 9;j++){
       //x check
       for(int x = 0;x < 9;x++){
           if(cell[i][j].hoge == cell[x][j].hoge){
           ……..
           }
       }
       //y check
       for(……..
工夫したところ
正方形の場合
for(int i = 0; i < 9;i++){
   for(int j = 0; j < 9;j++){
        //square check
        for(int a = (i/3)*3;a < (i/3)*3+3;a++){
            for(int b = (j/3)*3;b < (j/3)*3+3;b++){
                 if(cell[i][j].hoge == cell[a][b].hoge){
                     ….


こうすることで各マスの属する正方形の
    全てのマスをチェックできる!!
工夫したところ2
・幅優先探索or深さ優先探索

ナンプレは1つのマスが決まると連鎖的に
 他が決まっていく
→1つ決まる=縦横正方形の全ての空白マ
 スの集合に影響するから

よって幅優先探索が適していると判断
まとめ
・目標は達成できたと思う
・問題の入力は面倒だが
 こればかりはしょうがないと判断
・製作期間約一カ月ほど

ナンプレ解析ツール