private void DfsWithoutCheckUsed(Board condition, Point point, long weight, int deep = 0)
        {
            _pointsWeight[point.X, point.Y] += weight;

            if (deep >= Parameters.DeepForRecalcWeightsUnits)
            {
                return;
            }

            List <Point> nextPoints = new List <Point>(5);

            foreach (var direction in new Move[] { Move.Down, Move.Left, Move.Right, Move.Up, Move.Stop })
            {
                Point   next    = point.Shift(direction);
                Element element = condition.GetAt(next);

                if (element == Element.WALL)
                {
                    continue;
                }

                if ((element == Element.DESTROYABLE_WALL || Utils.IsActiveBomb(element)) &&
                    deep < HandlersFacade.GetTimeToBoom(point)) // Иначе уничтожаемая стена (или бомба) будет взорвана к этому тику
                {
                    continue;
                }

                nextPoints.Add(next);
            }

            foreach (var next in nextPoints)
            {
                DfsWithoutCheckUsed(condition, next, (weight / Parameters.UnitsWeightReducer) / nextPoints.Count, deep + 1);
            }
        }
Esempio n. 2
0
        private ICollection <Move> GetDirectionsForPlant(Board condition)
        {
            Point bomberman = condition.GetBomberman();

            return((from dir in new Move[] { Move.Down, Move.Left, Move.Right, Move.Stop, Move.Up }
                    where (HandlersFacade.GetTimeToBoom(bomberman.Shift(dir)) == HandlersFacade.WillNotExploded ||
                           HandlersFacade.IsMyBoom(bomberman.Shift(dir)) &&
                           !Utils.IsActiveBomb(condition.GetAt(bomberman.Shift(dir))))
                    select dir)
                   .ToList());
        }
Esempio n. 3
0
        long GetWeightByBfs(Board condition, Point startPoint)
        {
            Dictionary <Point, int> distance = new Dictionary <Point, int>();
            long weight = 0;

            Queue <Point> q = new Queue <Point>();

            q.Enqueue(startPoint);
            distance.Add(startPoint, 1);

            while (q.Count > 0)
            {
                Point point = q.Dequeue();
                if (HandlersFacade.GetTimeToBoom(point) == HandlersFacade.WillNotExploded)
                {
                    weight += HandlersFacade.GetWeightOfPoint(point) / (Parameters.DirectionsWeightReducer * distance[point]);
                }

                if (distance[point] >= Parameters.DeepForRecalcDirectionsWeight)
                {
                    continue;
                }

                if ((condition.GetAt(point) == Element.DESTROYABLE_WALL || Utils.IsActiveBomb(condition.GetAt(point))) &&
                    distance[point] < HandlersFacade.GetTimeToBoom(point))     // Иначе уничтожаемая стена (или бомба) будет взорвана к этому тику
                {
                    continue;
                }

                foreach (var direction in new Move[] { Move.Down, Move.Left, Move.Right, Move.Up })
                {
                    Point   next    = point.Shift(direction);
                    Element element = condition.GetAt(next);

                    if (element == Element.WALL)
                    {
                        continue;
                    }

                    if (!distance.ContainsKey(next))
                    {
                        q.Enqueue(next);
                        distance.Add(next, distance[point] + 1);
                    }
                }
            }

            return(weight);
        }
Esempio n. 4
0
        private bool IsNonDeadlyMove(Board condition, int moveMask)
        {
            IReadOnlyDictionary <Point, int> newPointsAffectedByBlast = GetNewPointsAffectedByBlast(condition, moveMask, out Point? bomb);

            Point bomberman = condition.GetBomberman();
            Move  direction = Utils.GetMoveByMask(moveMask);

            Console.WriteLine($"mm: { moveMask }");

            bool isNotDeadly = false;

            CheckIsDeadly(condition.GetBomberman().Shift(direction));
            return(isNotDeadly);

            void CheckIsDeadly(Point point, int deep = 1)
            {
                if (deep >= Parameters.DeepForCheckDeadlyMoves)
                {
                    isNotDeadly = true;
                    return;
                }

                if (HandlersFacade.GetTimeToBoom(point) == deep ||
                    (newPointsAffectedByBlast.ContainsKey(point) && newPointsAffectedByBlast[point] == deep)) // Именно на этом тике будет взрыв!!
                {
                    return;
                }

                foreach (var dir in new Move[] { Move.Down, Move.Left, Move.Right, Move.Stop, Move.Up })
                {
                    Point next = point.Shift(dir);
                    if (condition.GetAt(next) == Element.WALL ||
                        (Parameters.CheckAfkPlayers && HandlersFacade.AfkPlayers.Contains(next)) ||
                        (condition.GetAt(next) == Element.DESTROYABLE_WALL && HandlersFacade.GetTimeToBoom(next) >= deep) ||
                        (Utils.IsActiveBomb(condition.GetAt(next)) && HandlersFacade.GetTimeToBoom(next) >= deep) ||
                        ((bomb != null) && next == bomb && newPointsAffectedByBlast[next] >= deep))
                    {
                        continue;
                    }

                    CheckIsDeadly(next, deep + 1);

                    if (isNotDeadly)
                    {
                        return;
                    }
                }
            }
        }
Esempio n. 5
0
        private IReadOnlyDictionary <Point, int> GetNewPointsAffectedByBlast(Board condition, int moveMask, out Point?bomb)
        {
            Point?bombPoint = null;

            if ((moveMask & (int)Move.ActAfter) > 0)
            {
                bombPoint = condition.GetBomberman().Shift(Utils.GetMoveByMask(moveMask));
            }
            else if ((moveMask & (int)Move.ActBefore) > 0)
            {
                bombPoint = condition.GetBomberman();
            }

            Dictionary <Point, int> result = new Dictionary <Point, int>();

            bomb = bombPoint;
            if (bombPoint == null)
            {
                return(result);
            }

            int timeToBoom = Math.Min(HandlersFacade.GetTimeToBoom((Point)bombPoint), 4);

            result.Add((Point)bombPoint, timeToBoom);

            foreach (var dir in new Move[] { Move.Down, Move.Left, Move.Right, Move.Up })
            {
                Point p = (Point)bombPoint;
                for (int i = 0; i < Parameters.BlastRadius; i++)
                {
                    p = p.Shift(dir);
                    result.Add(p, timeToBoom);

                    if (condition.GetAt(p) == Element.WALL ||
                        condition.GetAt(p) == Element.DESTROYABLE_WALL)
                    {
                        break;
                    }
                }
            }

            return(result);
        }
Esempio n. 6
0
        public static string SolveOld(Board condition)
        {
            if (_handlers == null)
            {
                Init(condition.BoardSize);
            }

            foreach (var handler in _handlers)
            {
                handler.HandleCondition(condition);
            }

            List <Move> directions = (from kvp in HandlersFacade.IsFreeDirection
                                      where kvp.Value
                                      select kvp.Key)
                                     .ToList();

            Point bomberman = condition.GetBomberman();

            directions = (from dir in directions
                          where HandlersFacade.GetTimeToBoom(bomberman.Shift(dir)) == HandlersFacade.WillNotExploded
                          select dir)
                         .ToList();

            Move direction = directions.Count > 0 ? directions.First() : Move.Stop;

            foreach (var dir in directions)
            {
                if (HandlersFacade.WeightOfDirection[dir] > HandlersFacade.WeightOfDirection[direction])
                {
                    direction = dir;
                }
            }

            foreach (var dir in directions)
            {
                Console.WriteLine($"{ HandlersFacade.WeightOfDirection[dir] } --- { dir }");
            }
            return(Utils.MoveMaskToString((int)direction));
        }
Esempio n. 7
0
        public static string Solve(Board condition)
        {
            ConfigurationManager.RefreshSection("appSettings");

            if (_handlers == null)
            {
                Init(condition.BoardSize);
            }

            foreach (var handler in _handlers)
            {
                handler.HandleCondition(condition);
            }

            IReadOnlyCollection <int> movesMasks = HandlersFacade.MovesMasks;

            ICollection <int> masks = (from mask in movesMasks
                                       where (mask & (int)(Move.ActAfter | Move.ActBefore)) > 0
                                       select mask)
                                      .ToList();

            if (masks.Count == 0)
            {
                masks = new List <int>(movesMasks);
            }

            int  moveMask = masks.Count > 0 ? masks.First() : (int)Move.Stop;
            long weight   = HandlersFacade.WeightOfDirection[Utils.GetMoveByMask(moveMask)];

            if (Parameters.CheckCollision &&
                HandlersFacade.CanMakeCollision[Utils.GetMoveByMask(moveMask)])
            {
                weight /= Parameters.CollisionReducerWeight;
            }

            foreach (int mask in masks)
            {
                long nextWeight = HandlersFacade.WeightOfDirection[Utils.GetMoveByMask(mask)];
                if (Parameters.CheckCollision &&
                    HandlersFacade.CanMakeCollision[Utils.GetMoveByMask(mask)])
                {
                    nextWeight /= Parameters.CollisionReducerWeight;
                }

                if (nextWeight > weight)
                {
                    moveMask = mask;
                    weight   = nextWeight;
                }
            }

            if ((moveMask & (int)(Move.ActAfter | Move.ActBefore)) > 0)
            {
                OnPlantBomb((moveMask & (int)Move.ActBefore) > 0 ? condition.GetBomberman() :
                            condition.GetBomberman().Shift(Utils.GetMoveByMask(moveMask)));
            }

            foreach (var d in new Move[] { Move.Down, Move.Left, Move.Right, Move.Stop, Move.Up })
            {
                Console.WriteLine($"{ d }: { HandlersFacade.GetTimeToBoom(condition.GetBomberman().Shift(d)) }");
            }
            return(Utils.MoveMaskToString(moveMask));
        }