【C#】【数独】数独解析プログラム完成

前回までの状況はこちら。

前回の修正でほぼほぼ解析ロジックは完成したので、もうちょっと使い勝手が良いように、ファイル入出力とエラー処理に手を加えます。

まずは、いままで出力ファイル名が固定化されていたので、コマンドの第二パラメータに出力ファイルを入力するようにします。

具体的には、ファイル入出力が一つのstaticクラスで行っていたのを分割します。

入力ファイルの読み込みは、最初の1回しか実行しないので、staticクラスで、出力ファイルは何度も使用するので、通常のクラスで定義し直します。

出力クラスのコンストラクタで出力ファイル名を指定します。

    class FileOutput
    {
        private string _filename;
        public FileOutput(string filename)
        {
            _filename = filename;
            if (File.Exists(_filename) == true)
            {
                File.Delete(_filename);
            }
        }

        public void Output(Square[,] sq)
        {
            using (var stream = new StreamWriter(_filename, true))
            {
                for (int row = 0; row < 9; row++)
                {
                    for (int col = 0; col < 9; col++)
                    {
                        stream.Write(sq[row, col].GetValue());
                    }
                    stream.Write("\r\n");
                }
                stream.Write("\r\n");
            }
        }

        public void Output(bool[,] sq)
        {
            using (var stream = new StreamWriter(_filename, true))
            {
                for (int row = 0; row < 9; row++)
                {
                    for (int col = 0; col < 9; col++)
                    {
                        if (sq[row, col] == true)
                        {
                            stream.Write(1);
                        }
                        else
                        {
                            stream.Write(0);
                        }
                    }
                    stream.Write("\r\n");
                }
                stream.Write("\r\n");
            }
        }

        public void Output(int row, int col, int value)
        {
            using (var stream = new StreamWriter(_filename, true))
            {
                stream.Write("[{0},{1}] => {2}\r\n", row, col, value);
            }
        }

        public void Output(string text)
        {
            using (var stream = new StreamWriter(_filename, true))
            {
                stream.Write("{0}\r\n", text);
            }
        }

        public void Output(List<Square> list)
        {
            using (var stream = new StreamWriter(_filename, true))
            {
                stream.Write("候補 ");
                foreach (Square s in list)
                {
                    stream.Write("[{0},{1}]", s.Row, s.Col);
                }
                stream.Write("\r\n");
            }
        }
    }

メイン関数で出力ファイル名を取得します。

第二パラメータが無かった場合は、自動的に入力ファイイル名.outputというファイル名で出力させます。

        static void Main(string[] args)
        {
            // パラメータチェック
            if (args.Length < 1)
            {
                Console.WriteLine("usage : sudoku.exe [input file] [output file]");
                return;
            }

            // ファイルの存在を確認
            string filePath = Environment.CurrentDirectory + "\\" + args[0];
            if (File.Exists(filePath) == false)
            {
                Console.WriteLine("File not found.");
                return;
            }

            // 出力ファイル名
            string outfile = null;
            if (args.Length == 2)
            {
                outfile = Environment.CurrentDirectory + "\\" + args[1];
            }
            else
            {
                outfile = filePath + ".output";
            }

            var sq = FileRead.OpenFile(filePath);
            if(sq == null)
            {
                return;
            }

            Sudoku sudoku = new Sudoku(sq, outfile);
            sudoku.run();
        }

最後に、入力データのエラー処理を改善します。

具体的には、例えば、行と列が10以上あった場合、そして、数字以外の値が入っていた場合、数字が10以上入っていた場合はエラーで終了させます。

    static class FileRead
    {
        /**
         * ファイルからデータを取得する
         */
        public static Square[,] OpenFile(string filePath)
        {
            int[,] matrix = new int[9, 9];

            // ファイルを開く
            bool error = false;
            using (var stream = new StreamReader(filePath))
            {
                int row = 0;
                while (stream.EndOfStream == false)
                {
                    if (row >= 9)
                    {
                        error = true;
                        break;
                    }
                    string lineText = stream.ReadLine();
                    var val = lineText.Split(',');
                    if (val.Length > 9)
                    {
                        error = true;
                        break;
                    }
                    int col = 0;
                    foreach (var v in val)
                    {
                        int i;
                        if (int.TryParse(v, out i))
                        {
                            if(i >= 10)
                            {
                                error = true;
                                break;
                            }
                            matrix[row, col] = i;
                        }
                        else
                        {
                            error = true;
                            break;
                        }
                        col++;
                    }
                    if (error)
                    {
                        break;
                    }
                    row++;
                }
            }
            if (error)
            {
                Console.WriteLine("Illegal format.");
                return null;
            }

            Square[,] ret = new Square[9, 9];
            for (int row = 0; row < 9; row++)
            {
                for (int col = 0; col < 9; col++)
                {
                    Square sq = new Square(matrix[row, col], row, col);
                    ret[row, col] = sq;
                }
            }

            return ret;
        }
    }

そして、最終的にgitHubのようなソースになりました。

https://github.com/takishita2nd/sudoku

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください