第31講 数独(ナンバープレイス)問題解決ソフトVer.2の制作
(数独(ナンバープレイス)問題作成ソフトに挑戦する人は☆☆)


第5話 
問題全体構造解析のコード例

#pragma once
#include<stdlib.h>
#include<math.h>
#include<ctime>
char a[9][9],b[9][9],lst[9][9][9],rlst[9][9][9];
char s,cn;
namespace 数独問題解決ソフトVer2 {
                   ・
                   ・
                   ・

  private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
                   ・
                   ・
                   ・
           char k1=0,k2;
           DateTime^ hj=DateTime::Now; //開始時間
           for(i=0;i<13;i++){
             if(i%4==0)k1++;
               if(i%4!=0){
                 k2=0;
                 for(j=0;j<13;j++){
                    if(j%4==0)k2++;
                    if(j%4!=0){
                      if(w[i,j]!=L"")a[i-k1][j-k2]=char::Parse(w[i,j]);
                      if(w[i,j]==L""){
                      a[i-k1][j-k2]=0;
                      
cn++; //空白セル数のカウント 次の入力順構築のときに使う
                    }      
                 }
               }
             }
           }
           s=0;
           zentaikouzoukaiseki();
           
//f(0);   //問題全体構造解析がうまくいっているか確認するためいったん外しておく
           DateTime^ ow=DateTime::Now; //終了時間
           TimeSpan sa=ow->Subtract(*hj); //経過時間の計算
           dataGridView1[30,25]->Value=L"解答作成時間";
           dataGridView1[30,26]->Value=sa.TotalSeconds.ToString();
          
/*    //問題全体構造解析がうまくいっているか確認するためいったん外しておく
           if(s==2)dataGridView1[30,27]->Value=L"解答が複数存在する";
           if(s==2)dataGridView1[30,14]->Value=L"不適切な問題です。";
           if(s==0)dataGridView1[30,27]->Value=L"解答が存在しない";
           if(s==0)dataGridView1[30,14]->Value=L"不適切な問題です。";
           */       

       
 }

        void zentaikouzoukaiseki(){
          char i,j,k,l,x,y,k1=0,k2=0;
          for(i=0;i<9;i++){
            for(j=0;j<9;j++){
              if(a[i][j]==0){
                b[i][j]=0;
                for(k=0;k<9;k++){
                  lst[i][j][k]=1;  //リストするかどうかのマルバツに相当するもの 最初すべて1すなわち○にしておく。
                  rlst[i][j][k]=0; //realリストでrを付けてある。上のオンオフにしたがって、実際にリスト(登録)する配列。
                }
              }
            }
          }
          for(i=0;i<9;i++){
            y=i/3;  //ブロックが何行目(ブロック単位で数えた行数)をしめす。具体的には、0,1,2。
            for(j=0;j<9;j++){
              if(a[i][j]==0){
                for(k=0;k<9;k++)if(k!=i)if(a[k][j]>0)lst[i][j][a[k][j]-1]=0;
                for(k=0;k<9;k++)if(k!=j)if(a[i][k]>0)lst[i][j][a[i][k]-1]=0;
                x=j/3;  //ブロックが何列目(ブロック単位で数えた列数)を示す。具体的には0,1,2。
                for(k=0;k<3;k++)for(l=0;l<3;l++)if(3*y+k!=i && 3*x+l!=j)if(a[3*y+k][3*x+l]>0)lst[i][j][a[3*y+k][3*x+l]-1]=0;
                for(k=0;k<9;k++){
                  if(lst[i][j][k]==1){
                    rlst[i][j][b[i][j]]=k+1; //lstがオン(○)とき、実際にリストする。
                    b[i][j]++; //リスト個数を数える配列。
                  }
                }
              }
            }
          }
          //以降は、全体構造解析がうまくっているかを確認するためデータグリッドビューに表示させるためのもの。動作が確認されたら削除する。
          for(i=0;i<13;i++){
            if(i%4==0){
              k1++;
              for(j=0;j<13;j++)dataGridView1[j,i+14]->Value=L"*";
            }
            if(i%4>0){
              k2=0;
              for(j=0;j<13;j++){
                if(j%4==0){
                   dataGridView1[j,i+14]->Value=L"*";
                   k2++;
                }
                if(j%4>0){
                  if(a[i-k1][j-k2]==0)dataGridView1[j,i+14]->Value=b[i-k1][j-k2];
                  if(a[i-k1][j-k2]>0)dataGridView1[j,i+14]->Value=L"/";
                }
              }
            }
          }

        }
実行例
c++

入門vc++
(入力画面や出力画面が正方形でなかったので、Form1において列幅も40から27に変更してあります。
また、フォントサイズも12から14に拡大してあります。)

コードは大変難解かと思いますので、第6話と第7話において詳しく解説します。

第4話へ 第6話へ

戻る

VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)