前回までの状況はこちら。
最新ソースはこちら。(gitHub)
https://github.com/takishita2nd/Picross
次は、ここに注目します。
数字が、2,6と並んでいます。
ということは、下の6の数字では、上3マス(数字の2マスとマスク分1マス)は絶対に塗ることはできません。
なので、6という数字については、上の3マスを除いた7マスの間で中心を塗る、解析パターン8と同じロジックが適用できます。
// 解析パターンその10
// 中央の塗った場所から、塗れない場所をマスクする(数字が2個の場合)
private void pattern10()
{
// Row
pattern10Row();
// Col
pattern10Col();
}
private void pattern10Row()
{
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 != 2)
{
row++;
continue;
}
// 対象となるマスを抽出する
List<List<BitmapData>> bitmapLists = extractTargetBitmapListsCol(row);
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;
}
}
}
var bitmaplist = bitmapLists[0];
if(bitmaplist.Count <= 1)
{
row++;
continue;
}
// 塗る対象は右側か、左側か?
int bigValue = 0;
int smallValue = 0;
if (values[0] > values[1])
{
bigValue = values[0];
smallValue = values[1];
bitmaplist.RemoveRange(0, smallValue + 1);
}
else
{
bigValue = values[1];
smallValue = values[0];
bitmaplist.RemoveRange(bitmaplist.Count - (smallValue + 1), smallValue + 1);
}
paintCenter(bigValue, ref bitmaplist);
row++;
}
}
private void pattern10Col()
{
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 != 2)
{
col++;
continue;
}
// 対象となるマスを抽出する
List<List<BitmapData>> bitmapLists = extractTargetBitmapListsRow(col);
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;
}
}
}
var bitmaplist = bitmapLists[0];
if (bitmaplist.Count <= 1)
{
col++;
continue;
}
// 塗る対象は右側か、左側か?
int bigValue = 0;
int smallValue = 0;
if (values[0] > values[1])
{
bigValue = values[0];
smallValue = values[1];
bitmaplist.RemoveRange(0, smallValue + 1);
}
else
{
bigValue = values[1];
smallValue = values[0];
bitmaplist.RemoveRange(bitmaplist.Count - (smallValue + 1), smallValue + 1);
}
paintCenter(bigValue, ref bitmaplist);
col++;
}
}
今回は数字が2個の場合で、数字が大きい方のみを対象としました。
パターン8、9、10で共通化できる処理があったので、サブルーチンで共通化しています。
private List<List<BitmapData>> extractTargetBitmapListsCol(int row)
{
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);
}
return bitmapLists;
}
private List<List<BitmapData>> extractTargetBitmapListsRow(int col)
{
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);
}
return bitmapLists;
}
private void paintCenter(int value, ref List<BitmapData> bitmaps)
{
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();
}
}
}
実行結果はこうなりました。
これはウサギかな?
解けたようです。