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); } }
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()); }
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); }
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; } } } }
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); }
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)); }
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)); }