#region DigitMatrix
using System.Collections.Generic;
using System.Text;
using System;
using UnityEngine.UIElements;
using Unity.VisualScripting;
/// <summary>
/// 数字矩阵
/// </summary>
public class DigitMatrixShort
{
    #region 属性
    public DigitMatrixSetBack back = null;
    public DigitMatrixIsEqual<short> isEqualItem = null;
    public bool isPause = false;
    /// <summary>
    /// 行数
    /// </summary>
    public short RowCount { get; private set; }

    /// <summary>
    /// 列数
    /// </summary>
    public short ColumnCount { get; private set; }

    public short[,] Data { get; private set; }
    #endregion
    bool onDefDigitMatrixSetBack(short x, short y, short c)
    {
        return false;
    }
    public DigitMatrixShort(int rowCount, int columnCount)
    {
        back = null;
        RowCount = (short)rowCount;
        ColumnCount = (short)columnCount;

        Data = new short[RowCount, ColumnCount];
    }
    public DigitMatrixShort Clone()
    {
        DigitMatrixShort ret = new DigitMatrixShort(RowCount, ColumnCount);
        ret.Data = (short[,])Data.Clone();        
        return ret;
    }
    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        for (short r = 0; r < RowCount; r++)
        {
            string line = "";
            for (short c = 0; c < ColumnCount; c++)
            {
                line += Data[r, c];
            }
            sb.AppendLine(line);
        }
        return sb.ToString();
    }
    public void PeekFloodFill8WithStack(short r, short c, short newValue, short oldValue,
        DigitMatrixSetBack backStack,
        short bianLun = -1)
    {
        List<Tuple<short, short>> tempPts = new List<Tuple<short, short>>();
        FloodFill8WithStack(r, c, newValue, oldValue, (short x, short y, short t) => {
            //tempPts.Add(new Tuple<short, short>(x, y));
            return backStack(x, y, t);
        }, bianLun, false);
        FloodFill8WithStack(r, c, oldValue, newValue, (short x, short y, short t) =>
        {
            return false;
        }, bianLun, false);
        //foreach (var item in tempPts)
        //{
        //    Data[item.Item1, item.Item2] = oldValue;//恢复
        //}
    }
    #region FloodFill8WithStack
    /// <summary>
    /// 漫水填充(基于堆的8邻域填充)
    /// </summary>
    /// <param name="r">行</param>
    /// <param name="c">列</param>
    /// <param name="newValue"></param>
    /// <param name="oldValue"></param>
    /// <param name="matrix"></param>
    public void FloodFill8WithStack(short r, short c, short newValue, short oldValue,DigitMatrixSetBack backStack,short bianLun =-1, bool isinclude1 = false)
    {
        var stackRow = new Stack<short>();
        var stackColumn = new Stack<short>();
        stackRow.Push(r);
        stackColumn.Push(c);

        bool CheckNewSeedShort(short r1, short c1)
        {
            if (r1 >= 0 && r1 < RowCount && c1 >= 0 && c1 < ColumnCount)
            {
                short itemValue = Data[r1, c1];
                bool isBianLun = itemValue == bianLun;
                if ((itemValue == oldValue && itemValue != newValue) || (isinclude1 && isBianLun))
                {
                    if (isBianLun == false)
                    {
                        Data[r1, c1] = newValue;
                        stackRow.Push(r1);
                        stackColumn.Push(c1);
                    }
                    if (backStack != null)
                        backStack(r1, c1, newValue);
                    return true;
                }
            }
            return false;
        }
        bool CheckNewSeed(int r1, int c1)
        {
            return CheckNewSeedShort((short)r1, (short)c1);
        }
        int tryValues = 0;
        while (true)
        {
            if (stackRow.Count <= 0)
            {
                break;
            }
            r = stackRow.Pop();
            c = stackColumn.Pop();
            CheckNewSeed(r, c);
            CheckNewSeed(r + 1, c);
            CheckNewSeed(r - 1, c);
            CheckNewSeed(r, c + 1);
            CheckNewSeed(r, c - 1);
            CheckNewSeed(r + 1, c + 1);
            CheckNewSeed(r - 1, c - 1);
            CheckNewSeed(r - 1, c + 1);
            CheckNewSeed(r + 1, c - 1);
            tryValues = tryValues + 1;
            if (tryValues > 4096 * 4096 * 10) break;//基本死循环了
        }
    }
    #endregion
}
#endregion