/// <summary>
    /// change type lifestone unit to normal
    /// </summary>
    /// <param name="type"></param>
    /// <param name="num"></param>
    public void ChangeToNormal(LifeStoneType type, int num)
    {
        System.Random rnd       = new System.Random();
        ArrayList     candArray = new ArrayList();

        for (int j = 0; j < lifeStoneRowNum; j++)
        {
            for (int i = 0; i < 3; i++)
            {
                if (lifeStoneArray[j, i] == (int)type)
                {
                    candArray.Add(new Vector2Int(i, j));
                }
            }
        }
        while (candArray.Count > num)
        {
            candArray.RemoveAt(rnd.Next(candArray.Count));
        }
        for (int i = 0; i < candArray.Count; i++)
        {
            Vector2Int vtmp = (Vector2Int)candArray[i];
            lifeStoneArray[vtmp.y, vtmp.x] = 1;
        }
        StartCoroutine(ChangeInPhase(candArray, 1));
    }
    private void CreateLifeStone(float initialPos, Vector2Int pos, LifeStoneType type)
    {
        var temp = Instantiate(lifeStoneNormal, lifeStoneInitialPos + new Vector2(pos.x - 1, initialPos) * lifeStoneFrameOffset,
                               Quaternion.identity, lifeStoneUI).GetComponent <LifeStone>();

        temp.type = type;
        temp.pos  = pos;
        lifeStoneGrid[pos.y, pos.x] = temp;
        StartCoroutine(LifeStoneDropCoroutine(temp, lifeStoneInitialPos + new Vector2(pos.x - 1, pos.y) * lifeStoneFrameOffset));
    }
    /// <summary>
    /// count lifestoneunit in lifestoneframe by type
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public int CountType(LifeStoneType type)
    {
        int count = 0;

        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < lifeStoneRowNum; j++)
            {
                if (lifeStoneArray[j, i] == (int)type)
                {
                    count++;
                }
            }
        }
        return(count);
    }
    public void FillLifeStone(int num, LifeStoneType type)
    {
        List <Vector2Int> fillCand;
        List <KeyValuePair <Vector2Int, LifeStoneType> > fillArray = new List <KeyValuePair <Vector2Int, LifeStoneType> >();
        Vector2Int selectedPos;

        for (int n = 0; n < num; n++)
        {
            fillCand = new List <Vector2Int>();
            for (int j = 0; j < lifeStoneRowNum; j++)
            {
                for (int i = 0; i < 3; i++)
                {
                    if (
                        lifeStoneArray[j, i] == 0 &&
                        ((i - 1 >= 0 && lifeStoneArray[j, i - 1] > 0) ||
                         (i + 1 < 3 && lifeStoneArray[j, i + 1] > 0) ||
                         (j - 1 >= 0 && lifeStoneArray[j - 1, i] > 0) ||
                         (j + 1 < lifeStoneRowNum && lifeStoneArray[j + 1, i] > 0)
                        ))
                    {
                        fillCand.Add(new Vector2Int(i, j));
                    }
                }
            }
            if (fillCand.Count == 0)
            {
                break;
            }
            selectedPos = fillCand[Random.Range(0, fillCand.Count)];

            fillArray.Add(new KeyValuePair <Vector2Int, LifeStoneType>(selectedPos, type));
            lifeStoneArray[selectedPos.y, selectedPos.x] = (int)type;

            lifeStoneUnit[selectedPos.y, selectedPos.x] = Instantiate(lifeUnitPrefab, stoneSuper.transform);

            lifeStoneUnit[selectedPos.y, selectedPos.x].SetActive(false);
        }

        StartCoroutine(FillInPhase(fillArray));
    }
    public void GetLifeStone(LifeStoneInfo lifeStoneInfo)
    {
        //Check possible && lowest position of new life stone
        int minY = rowSize;
        List <Vector2Int> minPosCands = new List <Vector2Int>();

        for (int i = 0; i < 4 - lifeStoneInfo.size.x; i++)
        {
            //Make initial matrix without new life stone
            LifeStoneType[,] lifeStoneDownTest = new LifeStoneType[rowSize + lifeStoneInfo.size.y, columnSize];
            for (int y = 0; y < rowSize; y++)
            {
                for (int x = 0; x < columnSize; x++)
                {
                    lifeStoneDownTest[y, x] = lifeStoneGrid[y, x] != null ? lifeStoneGrid[y, x].type : LifeStoneType.NULL;
                }
            }

            //Push new life stone to the top of the initial matrix
            for (int y = 0; y < lifeStoneInfo.size.y; y++)
            {
                for (int x = 0; x < lifeStoneInfo.size.x; x++)
                {
                    lifeStoneDownTest[y + rowSize, x + i] = (LifeStoneType)int.Parse(lifeStoneInfo.lifeStonePos[y * lifeStoneInfo.size.x + x].ToString());
                }
            }

            //Find the lowest position of the new life stone with current x offset
            bool moveDown = true;
            for (int j = rowSize - 1; moveDown && j >= 0; j--)
            {
                for (int y = 0; moveDown && y < lifeStoneInfo.size.y; y++)
                {
                    for (int x = 0; moveDown && x < lifeStoneInfo.size.x; x++)
                    {
                        if ((LifeStoneType)int.Parse(lifeStoneInfo.lifeStonePos[y * lifeStoneInfo.size.x + x].ToString()) != LifeStoneType.NULL)
                        {
                            //Debug.Log("j : " + j + " i : " + i + " x : " + (x + i) + " y : " + (y + j) + " " + lifeStoneDownTest[y + j, x + i]);
                            if (lifeStoneDownTest[y + j, x + i] != LifeStoneType.NULL)
                            {
                                //Debug.Log("j : " + j + " i : " + i + " x : " + (x + i) + " y : " + (y + j) + " False");
                                //Mark lowest position
                                moveDown = false;
                                if (minY > j + 1)
                                {
                                    minY = j + 1;
                                    minPosCands.Clear();
                                    //Debug.Log(new Vector2Int(i, j + 1) + "accept");
                                    minPosCands.Add(new Vector2Int(i, j + 1));
                                }
                                else if (minY == j + 1)
                                {
                                    //Debug.Log(new Vector2Int(i, j + 1) + "accept");
                                    minPosCands.Add(new Vector2Int(i, j + 1));
                                }
                                break;
                            }
                            lifeStoneDownTest[y + j, x + i]     = lifeStoneDownTest[y + j + 1, x + i];
                            lifeStoneDownTest[y + j + 1, x + i] = LifeStoneType.NULL;
                        }
                    }
                }
            }

            //If the lowest pos is floor, mark floor
            if (moveDown)
            {
                if (minY > 0)
                {
                    minY = 0;
                    minPosCands.Clear();
                }
                //Debug.Log(new Vector2Int(i, 0) + "accept floor");
                minPosCands.Add(new Vector2Int(i, 0));
            }
        }

        //If current height is not enough to take the whole new life stone
        if (minY + lifeStoneInfo.size.y - 1 >= rowSize)
        {
            Debug.Log("Height exceeded");

            int    cutSize = rowSize - minY;
            string remainingLifeStoneInfo = "";

            for (int y = cutSize; y < lifeStoneInfo.size.y; y++)
            {
                for (int x = 0; x < lifeStoneInfo.size.x; x++)
                {
                    remainingLifeStoneInfo += int.Parse(lifeStoneInfo.lifeStonePos[y * lifeStoneInfo.size.x + x].ToString());
                }
            }

            //Need to work later
            //Make cut off life stone to be eaten
            Debug.Log(remainingLifeStoneInfo);

            lifeStoneInfo.size.y = cutSize;
        }

        //Randomize the lowest pos of the new life stone
        int randomizer = Random.Range(0, minPosCands.Count);

        for (int y = 0; y < lifeStoneInfo.size.y; y++)
        {
            for (int x = 0; x < lifeStoneInfo.size.x; x++)
            {
                if ((LifeStoneType)int.Parse(lifeStoneInfo.lifeStonePos[y * lifeStoneInfo.size.x + x].ToString()) != LifeStoneType.NULL)
                {
                    Vector2Int newPos = new Vector2Int(x + minPosCands[randomizer].x, y + minPosCands[randomizer].y);
                    CreateLifeStone(y + rowSize, newPos, (LifeStoneType)int.Parse(lifeStoneInfo.lifeStonePos[y * lifeStoneInfo.size.x + x].ToString()));
                    PlayerController.Instance.hp++;
                }
            }
        }
    }