Exemple #1
0
        private bool AreAllSnakePartsInTheHamiltonianCycle(ReturnData returnDatas, HamiltonianCycleData HamiltonianCycleData)
        {
            // Check whether all snake parts are in the Hamiltonia Cycle.
            for (int i = 0; i < returnDatas.SnakePositions.Count - 1; i++)
            {
                var pointA = returnDatas.SnakePositions[i];
                var pointB = returnDatas.SnakePositions[i + 1];

                if (HamiltonianCycleData.Data.PointToSequenceNumber[pointA.X, pointA.Y] == 0)
                {
                    if (HamiltonianCycleData.Data.PointToSequenceNumber[pointB.X, pointB.Y] != HamiltonianCycleData.Data.PointToSequenceNumber.Length - 1)
                    {
                        return(false);
                    }
                }
                else if (HamiltonianCycleData.Data.PointToSequenceNumber[pointA.X, pointA.Y] - 1 != HamiltonianCycleData.Data.PointToSequenceNumber[pointB.X, pointB.Y])
                {
                    return(false);
                }
            }
            // All snake parts are in the Hamiltonian Cycle.
            return(true);
        }
        public GameLogic(int playFieldWidth, int playFieldHeight)
        {
            _PlayFieldWidth  = playFieldWidth;
            _PlayFieldHeight = playFieldHeight;

            HamiltonianCycle     = new HamiltonianCycle();
            HamiltonianCycleData = HamiltonianCycle.GetHamiltonianCycleData(_PlayFieldWidth, _PlayFieldHeight);

            ShortCut = new ShortCut();

            ReturnDatas = new ReturnData
            {
                ShotCutMoveDirections = new List <MoveDirection>(),
                ResetThesePositions   = new List <Point>(),
                SnakePositions        = new List <Point>
                {
                    // new Point(0,0)
                    GetRandomPosition()
                },
                ApplePosition       = new Point(-1, -1), // Init values
                DrawApple           = true,
                IslogicalEndReached = false
            };
        }
Exemple #3
0
        // NOTICE:
        // The here used terms "above", "left", "right" and "under/below" are "seen visually".
        // Example:
        //   Snakehead.Y should be equal to  5
        // while apple.Y should be equal to 10
        // a) seen visually:
        //    The snakehaed is ABOVE the apple.
        // b) seen mathimatically:
        //    For sure snakehead.Y is less than apple.Y. So it is "under/ lower".
        //
        // Keep this in mind when reading the following comments.

        public void CalcShortCutForCase1And3(ReturnData returnDatas, HamiltonianCycleData HamiltonianCycleData)
        {
            var snakesHeadPosition = returnDatas.SnakePositions[0];
            var applePosition      = returnDatas.ApplePosition;

            if (snakesHeadPosition.X < 1 || snakesHeadPosition.Y < 1)
            {
                // No need to calculate a shortcut because snakes head is already in
                // .X == 0  -> ... the column 0
                // .Y == 0  -> ... the first row that leads the snake to column 0
                return;
            }

            if (snakesHeadPosition.Y == applePosition.Y &&
                (
                    (snakesHeadPosition.X < applePosition.X && HamiltonianCycleData.Data.MoveDirections[snakesHeadPosition.X, snakesHeadPosition.Y] == MoveDirection.Right)
                    ||
                    (snakesHeadPosition.X > applePosition.X && HamiltonianCycleData.Data.MoveDirections[snakesHeadPosition.X, snakesHeadPosition.Y] == MoveDirection.Left)
                )
                )
            {
                // No need to calculate a shortcut because snakes head is
                // already in the row that contains the apple
                // and
                // (    snakes head is left  from the apple and the snake movedirection is right towards the apple
                //      or
                //      snakes head is right from the apple and the snake movedirection is left towards the apple
                // )
                return;
            }

            // Check whether all snake parts are in the Hamiltonia Cycle. Leave if not.
            if (!AreAllSnakePartsInTheHamiltonianCycle(returnDatas, HamiltonianCycleData))
            {
                return;
            }

            if (snakesHeadPosition.Y > applePosition.Y)
            {
                // The snake is below the apple.
                // The shortcut path to be calculated here should lead the snake one row below the row that contains the apple.
                for (int y = snakesHeadPosition.Y - 1; applePosition.Y < y; y--)
                {
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Up);
                }
                // The short cut path ends here exact below the row with the apple. Check whether the apple is up next to the snakehead.
                if (snakesHeadPosition.X == applePosition.X)
                {
                    // The apple is up next to the snakehead.
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Up);
                }
                else if (snakesHeadPosition.X < applePosition.X && !Common.IsValueEven(applePosition.Y))
                {
                    // Snakes head is left from the apple
                    // AND
                    // the apple is in a row with an odd number like 1, 3, 5, 7, ...
                    // The direction in "odd rows" in right, so we can additionally lead the snake into the row with the apple
                    // because the then following non-shortcut path (aka "normal" Hamiltonian Cylce) is going to lead the snake into the apple.
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Up);
                }
                else if (snakesHeadPosition.X > applePosition.X && Common.IsValueEven(applePosition.Y))
                {
                    // Snakes head is right from the apple ... -> See previous comment.
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Up);
                }
            }
            else
            {
                // The snake is above the apple.
                // The snake should be lead to column 0.
                if (!Common.IsValueEven(snakesHeadPosition.Y))
                {
                    // Do not use:
                    //      if (HamiltonianCycleData.Data.MoveDirections[snakesHeadPosition.X, snakesHeadPosition.Y] == MoveDirection.Right)
                    // because the snake head can be in an odd row while its move direction is ".Up"!
                    // Do also not use:
                    //      if (HamiltonianCycleData.Data.MoveDirections[2, snakesHeadPosition.Y] == MoveDirection.Right)
                    // becasue the minimum square size is 2-by-2.
                    // But this would work:
                    //      if (HamiltonianCycleData.Data.MoveDirections[1, snakesHeadPosition.Y] == MoveDirection.Right)
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Up);
                }

                for (int x = snakesHeadPosition.X; x > 0; x--)
                {
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Left);
                }
            }
        }
Exemple #4
0
        public void CalcShortCutForCase2(ReturnData returnDatas, HamiltonianCycleData HamiltonianCycleData)
        {
            var snakesHeadPosition = returnDatas.SnakePositions[0];
            var applePosition      = returnDatas.ApplePosition;

            if (snakesHeadPosition.X < 1 || snakesHeadPosition.Y < 1)
            {
                // No need to calculate a shortcut because snakes head is already in
                // .X == 0  -> ... the column 0
                // .Y == 0  -> ... the first row that leads the snake to column 0
                return;
            }

            if (snakesHeadPosition.X == applePosition.X &&
                (
                    (snakesHeadPosition.Y < applePosition.Y && HamiltonianCycleData.Data.MoveDirections[snakesHeadPosition.X, snakesHeadPosition.Y] == MoveDirection.Down)
                    ||
                    (snakesHeadPosition.Y > applePosition.Y && HamiltonianCycleData.Data.MoveDirections[snakesHeadPosition.X, snakesHeadPosition.Y] == MoveDirection.Up)
                )
                )
            {
                // No need to calculate a shortcut because snakes head is
                // already in the column that contains the apple
                // and
                // (    snakes head is above the apple and the snake movedirection is down towards the apple
                //      or
                //      snakes head is under the apple and the snake movedirection is up   towards the apple
                // )
                return;
            }

            if (!AreAllSnakePartsInTheHamiltonianCycle(returnDatas, HamiltonianCycleData))
            {
                return;
            }

            if (snakesHeadPosition.X < applePosition.X)
            {
                // The snake is to the left of the apple.
                // The shortcut path to be calculated here should lead the snake one column before the column that contains the apple.
                for (int x = snakesHeadPosition.X; x < applePosition.X - 1; x++)
                {
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Right);
                }
                // The short cut path ends here exact one column before the row with the apple. Check whether the apple is right next to the snake head.
                if (snakesHeadPosition.Y == applePosition.Y)
                {
                    // The apple is right next to the snake head.
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Right);
                }
                else if (snakesHeadPosition.Y < applePosition.Y && Common.IsValueEven(applePosition.X))
                {
                    // Snakes head is above the apple
                    // AND
                    // the apple is in a column with an even number like 2, 4, 6, 8, ...
                    // The direction in "even columns" in down, so we can additionally lead the snake into this apple containing column
                    // because the then following non-shortcut path (aka "normal" Hamiltonian Cylce) is going to lead the snake into the apple.
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Right);
                }
                else if (snakesHeadPosition.Y > applePosition.Y && !Common.IsValueEven(applePosition.X))
                {
                    // Snakes head is below the apple ... -> See previous comment.
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Right);
                }
                else if (applePosition.Y == 0)
                {
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Right);
                    // snake head is no in the same column as the apple.
                    // Lead the snake up into the apple.
                    for (int y = snakesHeadPosition.Y; y > 0; y--)
                    {
                        returnDatas.ShotCutMoveDirections.Add(MoveDirection.Up);
                    }
                }
            }
            else
            {
                // The snake is to the right of the apple.
                // The snake should be lead to row 0.
                if (Common.IsValueEven(snakesHeadPosition.X))
                {
                    // Snake head is a "even column".
                    // The move direction of "even columns" is down, so go one step to the right, to a "odd column.
                    // The move direction of "odd  columns" is up.
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Right);
                }

                for (int y = snakesHeadPosition.Y; y > 0; y--)
                {
                    returnDatas.ShotCutMoveDirections.Add(MoveDirection.Up);
                }
            }
        }