Пример #1
0
        public static void Main()
        {
            Logger logger = LogManager.GetCurrentClassLogger();

            Configurations configurations = new Configurations();

            GameContext context = new GameContext
            {
                Player      = new Player(),
                ScoreBoard  = new TextCanvas(),
                Square      = new Canvas(),
                MovementLog = new TextCanvas()
            };

            PaintBrush brush = new PaintBrush(ConsoleGuardian);

            NPCProvider npcProvider = new NPCProvider();

            // Path finder
            PathFinderProvider pathFinder = new PathFinderProvider();

            Init(context, brush, npcProvider, pathFinder, logger).Wait();

            Timer timer = new Timer(state =>
            {
                lock (ConsoleGuardian)
                {
                    context.ScoreBoard.Clear();
                    context.ScoreBoard
                    .WriteLine($"Current Time: {DateTime.Now:hh:mm:ss}");
                    context.ScoreBoard
                    .WriteLine($"Position: [{context.Player.Position.X:000},{context.Player.Position.Y:000}]");
                }
            }, null, 0, 1000);

            Task task = null;
            CancellationTokenSource cts = null;

            do
            {
                // Wait for GUI to finish
                if (!task?.IsCompleted ?? false)
                {
                    continue;
                }

                // Shutdown Game
                if (cts?.IsCancellationRequested ?? false)
                {
                    return;
                }

                // To empty Console buffer
                while (Console.KeyAvailable)
                {
                    Console.ReadKey(true);
                }

                ConsoleKey key = Console.ReadKey(true).Key;

                cts  = new CancellationTokenSource();
                task = Task.Run(() =>
                {
                    UserAction action = GetUserAction(key, logger);

                    // Copy Players Position and Direction
                    Position newPlayerPosition = Position.Copy(context.Player.Position);
                    Position oldPosition       = Position.Copy(context.Player.Position);

                    Direction newPlayerDirection = context.Player.Direction;

                    #region Handle User Actions

                    switch (action)
                    {
                    case UserAction.DirectionUp:
                        {
                            newPlayerPosition.Y--;
                            newPlayerDirection = Direction.Up;
                            break;
                        }

                    case UserAction.DirectionDown:
                        {
                            newPlayerPosition.Y++;
                            newPlayerDirection = Direction.Down;
                            break;
                        }

                    case UserAction.DirectionLeft:
                        {
                            newPlayerPosition.X--;
                            newPlayerDirection = Direction.Left;
                            break;
                        }

                    case UserAction.DirectionRight:
                        {
                            newPlayerPosition.X++;
                            newPlayerDirection = Direction.Right;
                            break;
                        }

                    case UserAction.Reload:
                        {
                            Reload(context, brush, npcProvider, pathFinder, timer, logger);
                            return;
                        }

                    case UserAction.ShowPath:
                        {
                            brush.ShowPath(
                                context.Square,
                                PathFindingProcess(logger, context, brush, npcProvider, pathFinder).Path,
                                animated: true,
                                animationDelay: 10,
                                visibleLength: 40,
                                visibleFor: 300,
                                underlineTrail: true,
                                underlineChar: CharacterMap.LightTrail,
                                foregroundColor: ConsoleColor.Green,
                                backgroundColor: ConsoleColor.Cyan);
                            break;
                        }

                    case UserAction.QuitGame:
                        {
                            cts.Cancel();
                            break;
                        }
                    }
                    #endregion

                    TripAndCollisionLogic(context, oldPosition, newPlayerPosition, newPlayerDirection, brush);

                    Thread.Sleep(configurations.GetMainDelay);
                }, cts.Token);
            } while (true);
        }
Пример #2
0
        /// <summary>
        /// Checks if next position will be collision and handles it
        /// </summary>
        /// <param name="context"></param>
        /// <param name="lastPosition"></param>
        /// <param name="newPlayerPosition"></param>
        /// <param name="newPlayerDirection"></param>
        /// <param name="brush"></param>
        private static void TripAndCollisionLogic(
            GameContext context,
            Position lastPosition,
            Position newPlayerPosition,
            Direction newPlayerDirection,
            PaintBrush brush)
        {
            Random random = new Random(DateTime.Now.Millisecond);

            bool collided = newPlayerPosition.PredictCollision(context.Enemies.Select(enemy => enemy.Position));

            bool tripped = false;

            if (!collided)
            {
                tripped = random.Next(1, 5) == 1;                 // 25% chance
            }

            if (collided)
            {
                SimulationResult simulationResult = null;

                do
                {
                    // TODO: Move constnat numbres to App.config
                    Simulation simulation = (simulationResult?.Obstacle ?? newPlayerPosition)
                                            .SimulateCollision(
                        lastPosition,
                        newPlayerDirection,
                        3, 4);

                    newPlayerDirection = newPlayerDirection.Reverse();

                    simulationResult = context.Square.ExecuteSimulation(simulation, newPosition =>
                    {
                        return(!newPosition.PredictCollision(context.Enemies.Select(enemy => enemy.Position)));
                    }, brush);

                    lastPosition = simulationResult.LastSafePosition;
                } while (!simulationResult.HasSuccessfulyFinished);

                context.Player.Position = simulationResult.LastSafePosition;
            }
            else if (tripped)
            {
                SimulationResult simulationResult = null;

                do
                {
                    Simulation simulation;

                    // TODO: Move constnat numbres to App.config
                    if (!simulationResult?.HasSuccessfulyFinished ?? false)
                    {
                        simulation = lastPosition
                                     .SimulateCollision(
                            newPlayerPosition,
                            newPlayerDirection,
                            3, 4);

                        newPlayerDirection = newPlayerDirection.Reverse();
                    }
                    else
                    {
                        simulation = newPlayerPosition
                                     .SimulateTrip(
                            simulationResult?.LastSafePosition ?? lastPosition,
                            newPlayerDirection,
                            2, 4);
                    }

                    simulationResult = context.Square.ExecuteSimulation(simulation, newPosition =>
                    {
                        return(!newPosition.PredictCollision(context.Enemies.Select(enemy => enemy.Position)) ||
                               newPosition.Y < 0 || newPosition.X < 0);                            // TODO: Finish validation
                    }, brush, true);

                    newPlayerPosition = simulationResult.Obstacle;
                    lastPosition      = simulationResult.LastSafePosition;
                } while (!simulationResult.HasSuccessfulyFinished);

                context.Player.Position = simulationResult.LastSafePosition;
            }
            else
            {
                brush.Derender(context.Square, context.Player.Position);

                // Update position and direction
                context.Player.Direction = newPlayerDirection;
                context.Player.Position  = newPlayerPosition;

                brush.Render(context.Square, context.Player.Position, Player.BodyCharacter);
            }
        }