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

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

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

https://github.com/takishita2nd/Picross

次はこの問題を解いてみます。

解析を実行するとこうなりました。

今回はここに注目します。

10×10の問題ですが、例えば行の数字が7の場合、すでに真ん中の5マスが塗られているので、一番左の1マスは塗ることができないのが分かります。

同じ理由で、行の数字が6ならば、左2マスが塗ることができません。

なので、ここをマスクしちゃいましょう。

今回は条件を簡潔にしたいので、数字が1個の場合で、塗られている部分も1かたまりになっている場合のみとします。

        // 解析パターンその9
        // 中央の塗った場所から、塗れない場所をマスクする
        private void pattern9()
        {
            // Row
            pattern9Row();
            // Col
            pattern9Col();
        }

        private void pattern9Row()
        {
            int row = 0;
            foreach (var rowlist in rowNumbers)
            {
                if (rowlist.IsAnalyzed())
                {
                    row++;
                    continue;
                }

                // 有効な数字で一番大きいものを取り出す
                if(rowlist.AnalyzeDatas.Count != 1)
                {
                    row++;
                    continue;
                }
                int value = rowlist.AnalyzeDatas[0].Value;

                // 対象となるマスを抽出する
                List<List<BitmapData>> bitmapLists = new List<List<BitmapData>>();
                List<BitmapData> bitmaplist = new List<BitmapData>();
                for (int col = 0; col < colNumbers.Count; col++)
                {
                    // マスクとマスクの間が全て塗られていたら、そこは対象としない
                    if (_bitmapData[row, col].IsMasked())
                    {
                        if(bitmaplist.Count != 0)
                        {
                            bool done = true;
                            foreach(var bitmap in bitmaplist)
                            {
                                if(bitmap.IsPainted() == false)
                                {
                                    done = false;
                                }
                            }
                            if(done == false)
                            {
                                bitmapLists.Add(bitmaplist);
                            }
                            bitmaplist = new List<BitmapData>();
                        }
                        continue;
                    }
                    bitmaplist.Add(_bitmapData[row, col]);
                }
                if (bitmaplist.Count != 0)
                {
                    bitmapLists.Add(bitmaplist);
                }
                if(bitmapLists.Count != 1)
                {
                    row++;
                    continue;
                }

                // 塗られている場所を特定
                int leftCol = colNumbers.Count;
                int rightCol = 0;
                bool painted = false;
                foreach (var bitmap in bitmapLists[0])
                {
                    if(bitmap.IsPainted())
                    {
                        leftCol = bitmap.Col;
                        painted = true;
                    }
                    else
                    {
                        if (painted)
                        {
                            rightCol = bitmap.Col;
                            break;
                        }
                    }
                }
                // 左側をマスク
                for(int col = 0; col < rightCol - value; col++)
                {
                    if(_bitmapData[row,col].IsValid() == false)
                    {
                        _bitmapData[row, col].Mask();
                    }
                }

                // 右側をマスク
                for (int col = leftCol + value; col < colNumbers.Count; col++)
                {
                    if (_bitmapData[row, col].IsValid() == false)
                    {
                        _bitmapData[row, col].Mask();
                    }
                }

                row++;
            }
        }

        private void pattern9Col()
        {
            int col = 0;
            foreach (var collist in colNumbers)
            {
                if (collist.IsAnalyzed())
                {
                    col++;
                    continue;
                }

                // 有効な数字で一番大きいものを取り出す
                if (collist.AnalyzeDatas.Count != 1)
                {
                    col++;
                    continue;
                }
                int value = collist.AnalyzeDatas[0].Value;

                // 対象となるマスを抽出する
                List<List<BitmapData>> bitmapLists = new List<List<BitmapData>>();
                List<BitmapData> bitmaplist = new List<BitmapData>();
                for (int row = 0; row < rowNumbers.Count; row++)
                {
                    // マスクとマスクの間が全て塗られていたら、そこは対象としない
                    if (_bitmapData[row, col].IsMasked())
                    {
                        if (bitmaplist.Count != 0)
                        {
                            bool done = true;
                            foreach (var bitmap in bitmaplist)
                            {
                                if (bitmap.IsPainted() == false)
                                {
                                    done = false;
                                }
                            }
                            if (done == false)
                            {
                                bitmapLists.Add(bitmaplist);
                            }
                            bitmaplist = new List<BitmapData>();
                        }
                        continue;
                    }
                    bitmaplist.Add(_bitmapData[row, col]);
                }
                if (bitmaplist.Count != 0)
                {
                    bitmapLists.Add(bitmaplist);
                }
                if (bitmapLists.Count != 1)
                {
                    col++;
                    continue;
                }

                // 塗られている場所を特定
                int topRow = rowNumbers.Count;
                int downRow = 0;
                bool painted = false;
                foreach (var bitmap in bitmapLists[0])
                {
                    if (bitmap.IsPainted())
                    {
                        topRow = bitmap.Row;
                        painted = true;
                    }
                    else
                    {
                        if (painted)
                        {
                            downRow = bitmap.Row;
                            break;
                        }
                    }
                }
                // 左側をマスク
                for (int row = 0; row < downRow - value; row++)
                {
                    if (_bitmapData[row, col].IsValid() == false)
                    {
                        _bitmapData[row, col].Mask();
                    }
                }

                // 右側をマスク
                for (int row = topRow + value; row < rowNumbers.Count; row++)
                {
                    if (_bitmapData[row, col].IsValid() == false)
                    {
                        _bitmapData[row, col].Mask();
                    }
                }

                col++;
            }
        }

塗られている塊の部分を探し、その左端の行、列と右端の行、列を取得し、その値を数字からどこまでマスクされるかを探しています。

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

あまり大きな変化はありませんでしたが、こういうときこそ、塗ることができないマスは確実に潰していく事が、ピクロスの解析に重要です。

ちなみに、こんな問題、解けました。

「【C#】【ピクロス】【ALTSEED】解析パターンその9」への1件のフィードバック

コメントを残す

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

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