前回までの状況はこちら。
最新ソースはこちら。(gitHub)
https://github.com/takishita2nd/Picross
今回注目したのはここです。
ここはどのように塗っていくかというと、
空いているマスが4マスに対して、数字は3なので、
真ん中の2マスは確実に塗れることが分かります。
なので、これを実装します。
処理を単純化させるため、解析対象となる数字が行、列で1つの場合のみを、このロジックの対象とします。
また、このロジックを適用するマスを抽出するのですが、
マスクとマスクの間が全て塗られていた場合は処理済みと判断してスキップさせます。
その結果、対象のマスが1つの場合のみ、このロジックの対象とします。
この様な説明で分かってもらえるかどうか分からないけど、そういうことをやっています。
// 解析パターンその8
// 数字が大きい場合、真ん中の方を塗る
private void pattern8()
{
// Row
pattern8Row();
// Col
pattern8Col();
}
private void pattern8Row()
{
int row = 0;
foreach (var rowlist in rowNumbers)
{
if (rowlist.IsAnalyzed())
{
row++;
continue;
}
// 有効な数字を取り出す
List<int> values = new List<int>();
foreach(var data in rowlist.AnalyzeDatas)
{
if (data.IsAnalyzed())
{
continue;
}
values.Add(data.Value);
}
if(values.Count != 1)
{
row++;
continue;
}
// 対象となるマスを抽出する
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 value = values[0];
List<BitmapData> bitmaps = bitmapLists[0];
if(value < bitmaps.Count && value * 2 > bitmaps.Count)
{
int paintNum = value * 2 - bitmaps.Count;
int countMax = 0;
if(paintNum % 2 == 1)
{
countMax = paintNum / 2 + 1;
}
else
{
countMax = paintNum / 2;
}
for (int count = -paintNum / 2; count < countMax; count++)
{
bitmaps[bitmaps.Count / 2 + count].Paint();
}
}
row++;
}
}
private void pattern8Col()
{
int col = 0;
foreach (var collist in colNumbers)
{
if (collist.IsAnalyzed())
{
col++;
continue;
}
// 有効な数字を取り出す
List<int> values = new List<int>();
foreach (var data in collist.AnalyzeDatas)
{
if (data.IsAnalyzed())
{
continue;
}
values.Add(data.Value);
}
if (values.Count != 1)
{
col++;
continue;
}
// 対象となるマスを抽出する
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 value = values[0];
List<BitmapData> bitmaps = bitmapLists[0];
if (value < bitmaps.Count && value * 2 > bitmaps.Count)
{
int paintNum = value * 2 - bitmaps.Count;
int countMax = 0;
if (paintNum % 2 == 1)
{
countMax = paintNum / 2 + 1;
}
else
{
countMax = paintNum / 2;
}
for (int count = -paintNum / 2; count < countMax; count++)
{
bitmaps[bitmaps.Count / 2 + count].Paint();
}
}
col++;
}
}
public BitmapData[,] Run()
{
pattern1();
while (checkPainedCount())
{
pattern2();
pattern3();
pattern4();
pattern5();
pattern6();
pattern7();
pattern8();
doMask();
}
return _bitmapData;
}
実行結果はこうなりました。
全て埋まりましたね。
解けたようです。
やったぁ。