【C#】【ピクロス】【ALTSEED】解析パターンその1

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

最新ソースはこちら。(gitHub)

https://github.com/takishita2nd/Picross

さぁ、解析処理を作っていくぞ。

例題として、こちらの問題を用意しました。

データを入力。

まず、ピクロス解法の定石パターンとして、確実に塗れるところから塗っていくというもの。

この例題からすると、

この赤い部分は全て塗れるのは、すぐに分かりますよね。

さらに、

ここも塗れるのは分かりますでしょうか。

例えば、[1,4,3]と合った場合は、

■×■■■■×■■■

と10マスが確定しますよね?

これを公式化すると、

数字の合計+(数字の数ー1)=マスの数

※1+4+3+(3-1) = 10

となった場合、その列または行の塗れるマスは自動的に確定します。

これを実装します。

        // 解析パターンその1
        private void pattern1()
        {
            // Row
            pattern1Row();
            // Col
            pattern1Col();
        }

        /**
         * Rowに対して解析パターン1を適用
         */
        private void pattern1Row()
        {
            int row = 0;
            foreach (var rowlist in rowNumbers)
            {
                int total = 0;
                foreach (var v in rowlist)
                {
                    total += v;
                }
                total += rowlist.Count - 1;
                if (total == colNumbers.Count)
                {
                    // 塗れるマス確定
                    // リストを反転コピー
                    List<int> revRowList = new List<int>();
                    foreach (var v in rowlist)
                    {
                        revRowList.Add(v);
                    }
                    revRowList.Reverse();

                    int col = 0;
                    foreach (var v in revRowList)
                    {
                        int c;
                        for (c = 0; c < v; c++)
                        {
                            _bitmapData[row, col + c].Paint();
                        }
                        if(col + c < colNumbers.Count)
                        {
                            _bitmapData[row, col + c].Mask();
                            c++;
                        }
                        col += c;
                    }
                }
                row++;
            }
        }

        /**
         * Colに対して解析パターン1を適用
         */
        private void pattern1Col()
        {
            int col = 0;
            foreach (var collist in colNumbers)
            {
                int total = 0;
                foreach (var v in collist)
                {
                    total += v;
                }
                total += collist.Count - 1;
                if (total == colNumbers.Count)
                {
                    // 塗れるマス確定
                    // リストを反転コピー
                    List<int> revColList = new List<int>();
                    foreach (var v in collist)
                    {
                        revColList.Add(v);
                    }
                    revColList.Reverse();

                    int row = 0;
                    foreach (var v in revColList)
                    {
                        int r;
                        for (r = 0; r < v; r++)
                        {
                            _bitmapData[row + r, col].Paint();
                        }
                        if (row + r < rowNumbers.Count)
                        {
                            _bitmapData[row + r, col].Mask();
                            r++;
                        }
                        row += r;
                    }
                }
                col++;
            }
        }

列の数字データは右から順に並んでいるので、これを反転させる必要があります。

ただ、直接Reverse()を使用すると、インプットデータが壊れてしまうので、コピーを作成してからReverse()を使用します。

あとは、Listの先頭からピクロスのルールに従って塗っていきます。

実行結果はこうなりました。

解析がしやすくなるように、塗れないマスは×を表示するようにしました。

まぁ、ここまでは順調ですな。