public static double Minimize(Map before, Map after, PositionedUnit unit) { var xmin = Math.Max(0, unit.Rectangle.X - 2); var xmax = Math.Min(before.Width, unit.Rectangle.Right + 2); var ymin = Math.Max(0, unit.Rectangle.Y - 2); var ymax = Math.Min(before.Height, unit.Rectangle.Bottom + 2); var dict = new Dictionary<int, int>(); for (int i = -4; i <= 4; i++) dict[i] = 0; for(int x= xmin;x< xmax;x++) for (int y= ymin;y<ymax;y++) { var delta = FindClosureIndex(x, y, after) - FindClosureIndex(x, y, before); dict[delta]++; } double factor = 1; double result = 0; for (int i = 4; i > 0; i--) { result -= dict[i] * factor; result += dict[-i] * factor; factor /= 2; } return result; }
public static double Check(Map before, Map after, PositionedUnit unit) { if (!before.NextUnits.Any(z => z.IsLine)) return 0; if (CheckLayerFillness(before,0,2*before.Height/3) > 0.01) return 0; var any = unit.Members.Any(p => AtLine(before, p)); var all = unit.Members.All(p => AtLine(before, p)); if (!unit.Unit.IsLine) { if (any) return -1; return 0; } else { if (all) { if (CheckReadinessForLine(before) < unit.Members.Count()) return -1; return 1; } else if (any) return -1; else return 0; } }
private static OracleSuggestion TryGetSugession(Map map, PositionedUnit unit) { return GetAllDirections() .Where(dir => !map.IsValidPosition(unit.Move(dir))) .Select(dir => new OracleSuggestion(unit.Position, dir, map.LockUnit())) .FirstOrDefault(); }
public static double EraseLines(Map before, Map after, PositionedUnit unit) { if (after.Scores.ClearedLinesCountAtThisMap == 0) return 0; if (after.Scores.ClearedLinesCountAtThisMap == 1) return 0.3; if (after.Scores.ClearedLinesCountAtThisMap == 2) return 0.8; return 1; }
public static double Maximize(Map before, Map after, PositionedUnit unit) { var beforeIndex = FindLinearityIndex(before); var afterIndex = FindLinearityIndex(after); if (afterIndex < beforeIndex) return 0; if (beforeIndex < 0.01) return 1; return Math.Min(afterIndex / beforeIndex, 1); }
private Map CreateMap(string[] mapLines, Unit unit) { var f = new bool[mapLines[0].Length, mapLines.Length]; for(int y=0; y<mapLines.Length; y++) for (int x = 0; x < mapLines[0].Length; x++) f[x, y] = mapLines[y][x] == '#'; var positionedUnit = new PositionedUnit(unit, new UnitPosition(new Point(3, 0), 0)); return new Map(0, f, positionedUnit, ImmutableStack<Unit>.Empty, ImmutableHashSet<PositionedUnit>.Empty, new Scores(0, 0)); }
public static OracleSuggestion Evaluate(this IEnumerable<WeightedMetric> metrics, Map before, OracleSuggestion suggestions) { var unit = new PositionedUnit(before.Unit.Unit, suggestions.Position); var after = before.TeleportUnit(suggestions.Position).LockUnit(); return new OracleSuggestion( suggestions.Position, suggestions.LockingDirection, after, metrics.Evaluate(before, after, unit)); }
public static PositionedUnit PositionNewUnit(int width, ImmutableStack<Unit> nextUnits) { if (nextUnits.IsEmpty) return PositionedUnit.Null; var u = nextUnits.Peek(); var topmostY = u.Displacements[0].Min(m => m.ToMap().Y); var pos = new PositionedUnit(u, 0, new Point(0, -topmostY)); var leftMargin = pos.Members.Min(m => m.X); var rightMargin = width - 1 - pos.Members.Max(m => m.X); var newX = (rightMargin - leftMargin) / 2; return new PositionedUnit(u, 0, new Point(newX, -topmostY)); }
public Map(int id, bool[,] filled, PositionedUnit unit, ImmutableStack<Unit> nextUnits, ImmutableHashSet<PositionedUnit> usedPositions, Scores scores, bool died = false) { Id = id; NextUnits = nextUnits; Width = filled.GetLength(0); Height = filled.GetLength(1); Filled = filled; Unit = IsValidPosition(unit) ? unit : PositionedUnit.Null; UsedPositions = usedPositions.Add(Unit); Scores = scores; Died = died; }
public static double Index(Map _, Map map, PositionedUnit unit) { var bads = from x in Enumerable.Range(0, map.Width) from y in Enumerable.Range(0, map.Height) where !map.Filled[x, y] let cap = GetSmallCap(x, y).Where(map.IsInside) let capSize = cap.Count() let filledCapSize = cap.Count(p => map.Filled[p.X, p.Y]) select CapPenalty(filledCapSize, capSize, x == 0 || x == map.Width-1); double max = map.Width * map.Height; return (max - bads.Sum()) / max; }
public Grid(MainModel mapHistory) { this.mapHistory = mapHistory; penTypes = new Dictionary<Occupation, Pen> { [Occupation.Empty] = Pens.Black, [Occupation.Occupied] = Pens.Red, [Occupation.Unit] = Pens.LawnGreen, }; brushTypes = new Dictionary<Occupation, Brush> { [Occupation.Empty] = Brushes.White, [Occupation.Occupied] = Brushes.Gray, [Occupation.Unit] = Brushes.LawnGreen, }; DoubleBuffered = true; requestedLocation = null; }
public static double ShouldNotCreateSimpleHoles(Map before, Map after, PositionedUnit unit) { var score = unit.Members.Max(m => m.Y) // чем ниже нижняя точка, тем лучше + unit.Members.Average(m => m.Y) / 10.0 // чем ниже центр масс, тем лучше + unit.Members.Max(m => m.X)*0.2 / after.Width; // лучше двигать фигуры в одну сторону при прочих равных, а не кидать посередине // последний коэффициент при maxX подобран несколькими запусками ArensTests. // остальные выбраны наобум. if (after.Scores.ClearedLinesCountAtThisMap > 0) return score + 100; for (int i = -1; i < unit.Rectangle.Width + 1; i++) { for (int j = -1; j < unit.Rectangle.Height + 1; j++) { var point = new Point(unit.Rectangle.X + i, unit.Rectangle.Y + j); if(point.X.InRange(0, after.Width - 1) && (point.Y.InRange(0, after.Height - 1) && after.IsSimpleHole(point))) return score - 3; // за дырку штраф эквивалентный трем позициям по Y. } } return score; }
private Map(int id, bool[,] filled, PositionedUnit unit, ImmutableStack<Unit> nextUnits, Scores scores) : this(id, filled, unit, nextUnits, ImmutableHashSet<PositionedUnit>.Empty.Add(unit), scores) { }
public double Estimate(Map map, PositionedUnit unit) { return 42; }
private Map DoMove(PositionedUnit nextUnit) { return new Map(Id, Filled, nextUnit, NextUnits, UsedPositions.Add(nextUnit), new Scores(Scores.TotalScores, 0)); }
protected bool Equals(PositionedUnit other) { return Equals(Position, other.Position); }
public PositionedUnit Move(PositionedUnit pos) { var newPos = (pos.Position.Point.ToGeometry() + shift).ToMap(); return pos.WithNewPosition(new UnitPosition(newPos, (pos.Position.Angle + cw) % pos.Unit.Period)); }
public bool IsValidPosition(PositionedUnit unit) { return unit.Members.All(IsValid); }
/// new metrics public static double GoDown(Map before, Map after, PositionedUnit unit) { return unit.Members.Average(z => z.Y) / after.Height; }
public static double Evaluate(this IEnumerable<WeightedMetric> metrics, Map before, Map after, PositionedUnit unit) { return metrics.Sum(z => z.Function(before, after, unit) * z.Weight); }
void SetRequestedLocation(Point location, int angle) { if (mapHistory.Playing) return; if (requestedLocation != null && requestedLocation.Position.Point == location && requestedLocation.Position.Angle == angle) return; requestedLocation = new PositionedUnit(Map.Unit.Unit, new UnitPosition(location, angle)); IEnumerable<Directions> path = null; path = mapHistory.Solver.Finder.GetPath( Map, requestedLocation.Position); requestedLocationIsReachable = path != null; Invalidate(); }
public bool IsCatastrophicMove(PositionedUnit unit) { if (IsOver) return true; return UsedPositions.Contains(unit); }
public static double MapDown(Map before, Map after, PositionedUnit unit) { return after.AverageDepth() / after.Height; }
public static double Score(Map before, Map after, PositionedUnit arg3) { return (after.Scores.TotalScores - before.Scores.TotalScores) / 100.0; }
protected override void OnPaint(PaintEventArgs e) { var g = e.Graphics; g.Clear(Map.IsOver ? (Map.Died ? Color.LightCoral : Color.Gold) : Color.White); for (var x = 0; x < Map.Width; x++) { for (var y = 0; y < Map.Height; y++) { var p = new Point(x, y); var occupation = Map.Filled[x, y] ? Occupation.Occupied : Map.Unit.Members.Any(m => m.Equals(p)) ? Occupation.Unit : Occupation.Empty; DrawHexagon(g, x, y, penTypes[occupation], brushTypes[occupation], p.Equals(Map.Unit.Position.Point)); } } if (requestedLocation != null && !mapHistory.Playing) { IEnumerable<Directions> path = null; path = mapHistory.Solver.Finder.GetPath( Map, requestedLocation.Position); bool exist = path != null; foreach (var member in requestedLocation.Members) { DrawHexagon(e.Graphics, member.X, member.Y, Pens.Black, exist ? Brushes.Aqua : Brushes.MistyRose, false); } } foreach (var v in mapHistory.Suggestions.OraclePresense) DrawHexagon(e.Graphics, v.X, v.Y, Pens.Black, Brushes.Lime, false); if (mapHistory.Suggestions != null) { var s = mapHistory.Suggestions.GetCurrentSuggestion(); if (s!= null) { var sugg = new PositionedUnit(mapHistory.Suggestions.Unit, s.Position); foreach(var member in sugg.Members) { DrawHexagon(e.Graphics, member.X, member.Y, Pens.Black, Brushes.Yellow, false); } } } }