public static void Setup(
            GameControlsState controlsState,
            eCellType[] fieldMatrix,
            Position head,
            Position tail,
            ref eDirectionType currentDirection,
            int randomValue,
            ref eGameMode gameMode,
            ref byte baseColor)
        {
            // seed initial state
            FieldMatrix.Seed(fieldMatrix, head, tail);
            currentDirection = eDirectionType.None;

            switch (controlsState.keyCode)
            {
            case KeypadKeyCode.GO:
                FieldMatrix.PlaceNextPiece(fieldMatrix, randomValue);
                gameMode = eGameMode.Play;
                break;

            case KeypadKeyCode.D2:
                baseColor = (byte)(baseColor < 10 ? baseColor + 1 : baseColor);
                break;

            case KeypadKeyCode.D8:
                baseColor = (byte)(baseColor > 1 ? baseColor - 1 : baseColor);
                break;
            }
        }
        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();
            }
        }
Exemple #3
0
        public static async Task Aggregator(
            // banks
            FPGA.OutputSignal <bool> Bank1,
            FPGA.OutputSignal <bool> Bank2,

            // blinker
            FPGA.OutputSignal <bool> LED1,

            // WS2812
            FPGA.OutputSignal <bool> DOUT
            )
        {
            QuokkaBoard.OutputBank(Bank1);
            QuokkaBoard.InputBank(Bank2);

            IsAlive.Blink(LED1);

            bool internalDOUT = false;

            FPGA.Config.Link(internalDOUT, DOUT);

            byte state = 0;

            eCellType[] fieldMatrix = new eCellType[64];

            Sequential handler = () =>
            {
                state++;
                FieldMatrix.Reset(fieldMatrix);

                switch (state)
                {
                case 1:
                    fieldMatrix[0]  = eCellType.RedCross;
                    fieldMatrix[63] = eCellType.GreenCross;
                    break;

                case 2:
                    FieldMatrix.DrawCross(fieldMatrix, eCellType.GreenCross);
                    break;

                case 3:
                    FieldMatrix.DrawCross(fieldMatrix, eCellType.RedCross);
                    break;

                case 4:
                    Position head = new Position(), tail = new Position();
                    FieldMatrix.Seed(fieldMatrix, head, tail);
                    break;

                default:
                    state = 0;
                    break;
                }

                Graphics.DrawFieldMatrix(1, fieldMatrix, out internalDOUT);
            };

            FPGA.Config.OnTimer(TimeSpan.FromSeconds(1), handler);
        }
        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 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 SnakeControl(
            GameControlsState controlsState,
            FPGA.OutputSignal <bool> DOUT,
            FPGA.OutputSignal <bool> TXD)
        {
            bool internalDOUT = false;

            FPGA.Config.Link(internalDOUT, DOUT);

            FPGA.Register <int> randomValue = 0;
            RandomValueGenerator.MakeRandomValue(controlsState, randomValue);

            eCellType[]    fieldMatrix      = new eCellType[64];
            var            head             = new Position();
            var            tail             = new Position();
            eDirectionType currentDirection = eDirectionType.None;
            byte           baseColor        = 0x1;
            eGameMode      gameMode         = eGameMode.Setup;

            // drawing
            Sequential drawHandler = () =>
            {
                try
                {
                    switch (gameMode)
                    {
                    case eGameMode.Setup:
                    {
                        GameEngine.Setup(
                            controlsState,
                            fieldMatrix,
                            head,
                            tail,
                            ref currentDirection,
                            randomValue,
                            ref gameMode,
                            ref baseColor);
                    }
                    break;

                    case eGameMode.Play:
                    {
                        GameEngine.GameIteration(
                            controlsState,
                            fieldMatrix,
                            head,
                            tail,
                            ref currentDirection,
                            randomValue,
                            TXD);
                    }
                    break;

                    default:
                        if (controlsState.keyCode == Drivers.KeypadKeyCode.PWR)
                        {
                            gameMode = eGameMode.Setup;
                        }

                        break;
                    }
                }
                catch (GameCompletedException)
                {
                    FieldMatrix.DrawCross(fieldMatrix, eCellType.GreenCross);
                    gameMode = eGameMode.Completed;
                }
                catch (Exception)
                {
                    FieldMatrix.DrawCross(fieldMatrix, eCellType.RedCross);
                    gameMode = eGameMode.Failed;
                }

                Graphics.DrawFieldMatrix(baseColor, fieldMatrix, out internalDOUT);
            };

            FPGA.Config.OnTimer(TimeSpan.FromMilliseconds(400), drawHandler);
        }