using System;
using System.Linq;
class Program
{
static void Main(string[] args)
{
var table = "煩悩煩悩煩煩悩煩\r\n"
+ "煩煩悩空悩悩悩悩\r\n"
+ "悩空悩空悩空悩煩\r\n"
+ "空煩煩悩悩悩煩煩\r\n"
+ "悩悩悩煩悩煩煩悩\r\n"
+ "煩悩空空悩煩悩煩\r\n"
+ "煩煩煩悩煩空悩煩";
var bt = new BonnoTable(table);
bt.DestroyBonno();
Console.Write(bt.ToString());
}
}
public class BonnoTableItem
{
public char Char { get; set; }
public int BonnoCount { get; set; }
}
public class BonnoTable
{
private BonnoTableItem[][] mRows;
public int RowCount { get { return mRows.Length; } }
public int BonnoCount { get; private set; }
public BonnoTable(string table)
{
var rows = table.Split(new[]{"\r\n"}, StringSplitOptions.RemoveEmptyEntries);
mRows = new BonnoTableItem[rows.Length][];
for (int r = 0; r < RowCount; r++)
{
var row = new BonnoTableItem[rows[r].Length];
for (int c = 0; c < row.Length; c++) row[c] = new BonnoTableItem { Char = rows[r][c] };//row[c].Char = rows[r][c];
mRows[r] = row;
}
UpdateBonnoCount();
}
public BonnoTableItem this[RowCol rc]
{
get
{
if (rc.Row < 0 || rc.Row >= RowCount) return null;
if (rc.Column < 0 || rc.Column >= mRows[rc.Row].Length) return null;
return mRows[rc.Row][rc.Column];
}
}
private BonnoTableItem[] GetNeighbors(RowCol rc)
{
return rc.GetNeighbors().Select(x => this[x]).ToArray();
}
private void UpdateBonnoCount()
{
BonnoCount = 0;
for (int r = 0; r < RowCount; r++)
{
for (int c = 0; c < mRows[r].Length; c++)
{
var rc = new RowCol(r, c);
var target = this[rc];
target.BonnoCount = 0;
char matchChar;
switch(target.Char)
{
case '煩':
matchChar = '悩';
break;
case '悩':
matchChar = '煩';
break;
default:
continue;
}
var ns = GetNeighbors(rc);
foreach (var item in ns)
if (item != null && item.Char == matchChar) target.BonnoCount++;
if (target.Char == '煩') this.BonnoCount += target.BonnoCount;
}
}
}
private RowCol? FindMaxBonnoCountCell()
{
var max = 0;
RowCol? maxCell = null;
for (int r = 0; r < RowCount; r++)
for (int c = 0; c < mRows[r].Length; c++)
{
RowCol rc = new RowCol(r, c);
if (this[rc].BonnoCount > max)
{
max = this[rc].BonnoCount;
maxCell = rc;
}
}
return maxCell;
}
private void ReplaceToKane(RowCol rc)
{
this[rc].Char = '鐘';
UpdateBonnoCount();
}
public void DestroyBonno()
{
while(BonnoCount > 0)
{
var rc = FindMaxBonnoCountCell();
ReplaceToKane(rc.Value);
}
}
public override string ToString()
{
return string.Join("\r\n", mRows.Select(row => new string(row.Select(x => x.Char).ToArray())).ToArray());
}
}
public struct RowCol
{
public int Row { get; set; }
public int Column { get; set; }
public RowCol(int row, int col)
:this()
{
Row = row; Column = col;
}
public RowCol[] GetNeighbors()
{
var ns = new RowCol[8];
var i = 0;
for (int c = -1; c < 2; c++)
for (int r = -1; r < 2; r++)
ns[r == 0 && c == 0 ? i : i++] = new RowCol(Row + r, Column + c);
return ns;
}
}