public static void ThrowIfCrashed(eCellType[] fieldMatrix, Position position)
        {
            bool isCrashed = position.row > 7 || position.col > 7;

            if (isCrashed)
            {
                throw new CrashedInWallException();
            }

            eCellType type;

            FieldMatrix.GetCellTypeByPosition(fieldMatrix, position, out type);

            var crashTypes = new FPGA.Collections.ReadOnlyDictionary <eCellType, bool>()
            {
                { eCellType.SnakeHead, true },
                { eCellType.SnakeDown, true },
                { eCellType.SnakeUp, true },
                { eCellType.SnakeLeft, true },
                { eCellType.SnakeRight, true }
            };

            isCrashed = crashTypes[type];
            if (isCrashed)
            {
                throw new CrashedInSnakeException();
            }
        }
        public static void ApplyChange(
            eCellType[] fieldMatrix,
            Position head,
            Position tail,
            eDirectionType currentDirection,
            eDirectionType nextDirection,
            out bool expanded)
        {
            expanded = false;

            if (nextDirection == eDirectionType.None)
            {
                return;
            }

            eCellType nextDirectionCellType = eCellType.None;

            Lookups.DirectionTypeToCellType(nextDirection, ref nextDirectionCellType);

            Position nextHeadPosition = new Position();

            Lookups.ApplyDirection(head, nextHeadPosition, nextDirection);

            ThrowIfCrashed(fieldMatrix, nextHeadPosition);

            eCellType tailCellType, nextHeadCellType;

            FieldMatrix.GetCellTypeByPosition(fieldMatrix, tail, out tailCellType);
            FieldMatrix.GetCellTypeByPosition(fieldMatrix, nextHeadPosition, out nextHeadCellType);

            // move head
            FieldMatrix.SetCellTypeByPosition(fieldMatrix, head, nextDirectionCellType);
            FieldMatrix.SetCellTypeByPosition(fieldMatrix, nextHeadPosition, eCellType.SnakeHead);

            FPGA.Runtime.DeepCopy(head, nextHeadPosition);

            if (nextHeadCellType == eCellType.NextPart)
            {
                expanded = true;
                return;
            }

            // move tail
            eDirectionType tailDirection = eDirectionType.None;

            // get value at current tail

            Lookups.CellTypeToDirectionType(tailCellType, ref tailDirection);

            // clear current tail
            FieldMatrix.SetCellTypeByPosition(fieldMatrix, tail, eCellType.None);

            // move tail
            Lookups.ApplyDirection(tail, tail, tailDirection);
        }