public static void GameIteration(
            GameControlsState controlsState,
            eCellType[] fieldMatrix,
            Position head,
            Position tail,
            ref eDirectionType currentDirection,
            int randomValue,
            FPGA.Signal <bool> TXD)
        {
            eDirectionType nextDirectionFromKeypad   = eDirectionType.None;
            eDirectionType nextDirectionFromJoystick = eDirectionType.None;
            eDirectionType nextDirection             = eDirectionType.None;

            Lookups.KeyCodeToDirection(
                controlsState.keyCode,
                ref nextDirectionFromKeypad);

            Lookups.JoystickPositionToDirection(
                controlsState.adcChannel1,
                controlsState.adcChannel2,
                ref nextDirectionFromJoystick);

            bool isReverse = false;

            Lookups.IsReverse(currentDirection, nextDirection, ref isReverse);

            // TODO: variable declaration from conditional expression;
            nextDirection = isReverse
                            ? currentDirection
                            : nextDirectionFromKeypad != eDirectionType.None
                                    ? nextDirectionFromKeypad
                                        : nextDirectionFromJoystick != eDirectionType.None
                                            ? nextDirectionFromJoystick
                                            : currentDirection;

            Diagnostics.ReportState(
                controlsState,
                nextDirectionFromKeypad,
                nextDirectionFromJoystick,
                nextDirection,
                TXD);

            bool expanded = false;

            ApplyChange(
                fieldMatrix,
                head,
                tail,
                currentDirection, nextDirection,
                out expanded);

            if (expanded)
            {
                FieldMatrix.PlaceNextPiece(fieldMatrix, randomValue);
            }

            currentDirection = nextDirection;
        }
        public static void GetCellTypeByPosition(
            eCellType[] fieldMatrix,
            Position position,
            out eCellType cellType)
        {
            byte offset = 0;

            Lookups.PositionToOffset(position, ref offset);
            cellType = fieldMatrix[offset];
        }
        public static void SetCellTypeByPosition(
            eCellType[] fieldMatrix,
            Position position,
            eCellType cellType)
        {
            byte offset = 0;

            Lookups.PositionToOffset(position, ref offset);
            fieldMatrix[offset] = cellType;
        }
        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);
        }
        public static void Reset(eCellType[] fieldMatrix)
        {
            for (byte row = 0; row < 8; row++)
            {
                for (byte col = 0; col < 8; col++)
                {
                    byte offset = 0;
                    Lookups.RowColToOffset(row, col, ref offset);

                    fieldMatrix[offset] = 0;
                }
            }
        }
        public static void DrawCross(eCellType[] fieldMatrix, eCellType color)
        {
            for (byte row = 0; row < 8; row++)
            {
                for (byte col = 0; col < 8; col++)
                {
                    byte offset = 0;
                    Lookups.RowColToOffset(row, col, ref offset);

                    eCellType value = eCellType.None;

                    if (row == col || (7 - row) == col)
                    {
                        value = color;
                    }

                    fieldMatrix[offset] = value;
                }
            }
        }
        public static void Seed(
            eCellType[] fieldMatrix,
            Position head,
            Position tail)
        {
            Reset(fieldMatrix);

            tail.row = 3;
            tail.col = 2;
            FPGA.Runtime.DeepCopy(head, tail);

            const byte seedSnakeLength = 3;

            for (byte i = 0; i < seedSnakeLength - 1; i++)
            {
                SetCellTypeByPosition(fieldMatrix, head, eCellType.SnakeRight);
                Lookups.ApplyDirection(head, head, eDirectionType.Right);
            }

            SetCellTypeByPosition(fieldMatrix, head, eCellType.SnakeHead);
        }