前回までの状況はこちら。
最新ソースはこちら。(gitHub)
https://github.com/takishita2nd/Picross
つぎはどう攻めていくかというと、ここに注目しましょう。
ここも塗れるのが確定していますよね。
ここを塗るための条件を確認しましょう。
マスクされていないマスを数え、連続したマスの数と、範囲の数が全て一致した場合、確定とする。
つまり、
マスクされていないマスが2個、1個、2個と並んでいて、これらが全て左の数字と一致するため、この開いているマスは全て塗ることができます。
これをコーディングします。
// 解析パターンその2
private void pattern2()
{
// Row
pattern2Row();
// Col
pattern2Col();
}
private void pattern2Row()
{
int row = 0;
foreach (var rowlist in rowNumbers)
{
if (rowlist.IsAnalyzed())
{
row++;
continue;
}
// マスクされていない連続したマスを数える
int col = 0;
int count = 0;
List<int> countList = new List<int>();
while (col < colNumbers.Count)
{
if (_bitmapData[row, col].IsMasked() == false)
{
count++;
}
else
{
if (count != 0)
{
countList.Add(count);
count = 0;
}
}
col++;
if(col == colNumbers.Count)
{
countList.Add(count);
}
}
// 数えた数字が全て一致すれば確定とする
bool result = true;
if (rowlist.AnalyzeDatas.Count != countList.Count)
{
row++;
continue;
}
for (int i = 0; i < countList.Count; i++)
{
if (rowlist.AnalyzeDatas[i].Value != countList[i])
{
result = false;
}
}
if (result)
{
// 開いているところを塗る
col = 0;
while (col < colNumbers.Count)
{
if(_bitmapData[row, col].IsValid() == false)
{
_bitmapData[row, col].Paint();
}
col++;
}
rowlist.Analyzed();
}
row++;
}
}
private void pattern2Col()
{
int col = 0;
foreach (var collist in colNumbers)
{
if (collist.IsAnalyzed())
{
col++;
continue;
}
// マスクされていない連続したマスを数える
int row = 0;
int count = 0;
List<int> countList = new List<int>();
while (row < rowNumbers.Count)
{
if (_bitmapData[row, col].IsMasked() == false)
{
count++;
}
else
{
if (count != 0)
{
countList.Add(count);
count = 0;
}
}
row++;
if (row == rowNumbers.Count)
{
countList.Add(count);
}
}
// 数えた数字が全て一致すれば確定とする
bool result = true;
if (collist.AnalyzeDatas.Count != countList.Count)
{
col++;
continue;
}
countList.Reverse();
for (int i = 0; i < countList.Count; i++)
{
if (collist.AnalyzeDatas[i].Value != countList[i])
{
result = false;
}
}
if (result)
{
// 開いているところを塗る
row = 0;
while (row < rowNumbers.Count)
{
if (_bitmapData[row, col].IsValid() == false)
{
_bitmapData[row, col].Paint();
}
row++;
}
collist.Analyzed();
}
col++;
}
}
数える→数を確認する→塗るの順で処理しています。
少しデータの持ち方も変えています。
private List<AnalyzeListData> rowNumbers;
private List<AnalyzeListData> colNumbers;
class AnalyzeListData
{
private bool _analyzed;
public List<AnalyzeData> AnalyzeDatas;
public AnalyzeListData()
{
_analyzed = false;
AnalyzeDatas = new List<AnalyzeData>();
}
public bool IsAnalyzed()
{
return _analyzed;
}
public void Analyzed()
{
_analyzed = true;
}
class AnalyzeData
{
private bool _analyzed;
public int Value { get; }
public AnalyzeData(int value)
{
Value = value;
_analyzed = false;
}
public bool IsAnalyzed()
{
return _analyzed;
}
public void Analyzed()
{
_analyzed = true;
}
}
どのデータを塗ったかどうかを確認できるようにしています。
実行結果はこうなりました。
うん、順調ですね。