private static Tuple<double, Tuple<Unit, ReachablePositionsWithWords.VisitedInfo>[]> FindBestPositions_Recursive(int unitsAhead, Map map, Unit[] units, int unitIndex, string[] powerPhrases, bool[] spelledPhrases)
        {
            if (unitsAhead < 0 || unitIndex >= units.Length)
            {
                return Tuple.Create(0.0, new Tuple<Unit, ReachablePositionsWithWords.VisitedInfo>[0]);
            }
            var reachablePositions = new ReachablePositionsWithWords(map, powerPhrases, spelledPhrases);
            //var reachablePositions = new ReachablePositions(map);
            var evaluatePositions = new EvaluatePositions2(map);
            var unit = units[unitIndex];
            var endPositions = reachablePositions.SingleEndPositions(unit);
            var estimated = new Dictionary<Unit, double>();
            double? bestScore = null;
            var topOrderedPositions = endPositions
                .Select(p =>
                        {
                            double value;
                            if (estimated.TryGetValue(p.Item1, out value))
                                return Tuple.Create(value, p);
                            var score = estimated[p.Item1] = evaluatePositions.Evaluate(p.Item1);
                            return Tuple.Create(score, p);
                        })
                //.OrderByDescending(t => t.Item1)
                .OrderByDescending(t => (int)Math.Round(t.Item1 * 100))
                .ThenByDescending(t => t.Item2.Item2.score)
                .TakeWhile(tt =>
                           {
                               if (!bestScore.HasValue)
                               {
                                   bestScore = tt.Item1;
                                   return true;
                               }
                               return Math.Abs(tt.Item1 - bestScore.Value) < 1e-6;
                           }).ToList();

            if (!topOrderedPositions.Any())
            {
                return Tuple.Create(-1e3, new Tuple<Unit, ReachablePositionsWithWords.VisitedInfo>[0]);
            }

            var bestPosistions = Tuple.Create(double.MinValue, new Tuple<Unit, ReachablePositionsWithWords.VisitedInfo>[0]);
            foreach (var position in topOrderedPositions)
            {
                var newMap = map.Clone();
                newMap.LockUnit(position.Item2.Item1);
                newMap.RemoveLines();

                var nextPositions = FindBestPositions_Recursive(unitsAhead - 1, newMap, units, unitIndex + 1, powerPhrases, position.Item2.Item2.spelledWords);

                var score = position.Item1 + nextPositions.Item1;
                if (bestPosistions.Item1 < score)
                {
                    bestPosistions = Tuple.Create(score, new[] {position.Item2}.Concat(nextPositions.Item2).ToArray());
                }
            }

            return bestPosistions;
        }
        public EvaluatePositions(Map map)
        {
            this.map = map;
            for (int y = 0; y < map.Height; ++y)
            {
                var emptyCellsInLine = new List<Cell>();
                for (int x=0; x<map.Width; ++x)
                    if (!map[x, y].filled)
                        emptyCellsInLine.Add(map[x,y]);

                emptyCellsInLines.Add(emptyCellsInLine);
            }
        }
 public EvaluatePositions2(Map map)
 {
     this.map = map;
     for (int y = 0; y < map.Height; ++y)
     {
         var emptyCellsInLine = new List<Cell>();
         for (int x = 0; x < map.Width; ++x)
             if (!map[x, y].filled)
             {
                 emptyCellsInLine.Add(map[x, y]);
                 freeInputsForCells[map[x, y]] = CountFreeInputs(map[x,y]);
             }
         emptyCellsInLines.Add(emptyCellsInLine);
         int countLockedInLine = emptyCellsInLine.Count(c => freeInputsForCells[c] == 0);
         foreach (var c in emptyCellsInLine)
             UsabilityForCells[c] = 0.1 + 1.0/emptyCellsInLine.Count - ((double)countLockedInLine)/map.Width;
     }
 }
        public EvaluatePositions3(Map map)
        {
            this.map = map;
            emptyCells = new Cell[map.Height][];
            blockedCells = new int[map.Height];
            inputsOfCells = new Dictionary<Cell, Cell[]>();

            for (int y = 0; y < map.Height; ++y)
            {
                var emptyCellsInLine = new List<Cell>();
                for (int x = 0; x < map.Width; ++x)
                    if (!map[x, y].filled)
                    {
                        emptyCellsInLine.Add(map[x, y]);
                        inputsOfCells[map[x, y]] = FreeInputs(map[x, y]).ToArray();
                    }

                emptyCells[y] = emptyCellsInLine.ToArray();
                blockedCells[y] = emptyCellsInLine.Count(c => CountFreeInputs(c) == 0);
            }
        }
        public EvaluatePositions22(Map map)
        {
            this.map = map;
               this.maxLenPath = Math.Min(Math.Min(map.Width, map.Height)/3, 6);
            for (int y = 0; y < map.Height; ++y)
            {
                var emptyCellsInLine = new List<Cell>();
                for (int x = 0; x < map.Width; ++x)
                {
                    var cell = map[x, y];

                    if (!cell.filled)
                    {
                        emptyCellsInLine.Add(map[x, y]);
                        freeInputsForCells[map[x, y]] = CountFreeInputs(map[x, y]);
                        accessablityOfCell[cell] = new Access()
                        {
                            E = FindFreeLinearPath(cell, MoveType.E),
                            W = FindFreeLinearPath(cell, MoveType.W),
                            NE = FindFreeLinearPath(cell, MoveType.NE),
                            NW = FindFreeLinearPath(cell, MoveType.NW)
                        };
                    }
                }
                emptyCellsInLines.Add(emptyCellsInLine);
                int countLockedInLine = emptyCellsInLine.Count(c => freeInputsForCells[c] == 0);
                countLockedCellsInLines.Add(countLockedInLine);
                int countBadAccessedInLine = emptyCellsInLine.Count(c => accessablityOfCell[c].Accessability().Max() < maxLenPath);
                foreach (var c in emptyCellsInLine)
                {
                    usabilityOfCells[c] = 0.1 + 1.0/emptyCellsInLine.Count - ((double)countLockedInLine) / map.Width;

                }
            }

            for (int y = 0; y < map.Height/3; ++y)
                for (int x = map.Width / 3; x <= map.Width * 3 / 4; ++x)
                    usabilityOfCells[new Cell() { x = x, y = y }] = -map.Height/4 /(1.0 + Math.Min(y, x));
        }
        private Tuple<double, Tuple<Unit, ReachablePositionsWithWords.VisitedInfo>[]> FindBestPositions_Recursive(int unitsAhead, Map map, Unit[] units, int unitIndex, string[] powerPhrases, bool[] spelledPhrases)
        {
            if (unitsAhead < 0 || unitIndex >= units.Length)
            {
                return Tuple.Create(0.0, new Tuple<Unit, ReachablePositionsWithWords.VisitedInfo>[0]);
            }
            var reachablePositions = new ReachablePositionsWithWords(map, powerPhrases, spelledPhrases);
            //var reachablePositions = new ReachablePositions(map);
            //			var evaluatePositions = new EvaluatePositions(map);
            var evaluatePositions = new EvaluatePositions2(map);
            var unit = units[unitIndex];
            var endPositions = reachablePositions.SingleEndPositions(unit);
            var estimated = new Dictionary<Unit, double>();
            var topOrderedPositions = endPositions
                .Select(p =>
                        {
                            double value;
                            if (estimated.TryGetValue(p.Item1, out value))
                                return Tuple.Create(value, p);
                            var score = estimated[p.Item1] = evaluatePositions.Evaluate(p.Item1);
                            return Tuple.Create(score, p);
                        })
                //.OrderByDescending(t => t.Item1)
                .OrderByDescending(t => (int)Math.Round(t.Item1 * 100) + t.Item2.Item2.score)
                .ToList();

            var equallyTop = GetEquallyGoodTop(topOrderedPositions);
            var positionsForLookingAhead = topOrderedPositions.Take(Math.Max(equallyTop, minTopUnitCount)).ToList();

            if (!positionsForLookingAhead.Any())
            {
                return Tuple.Create(-1e3, new Tuple<Unit, ReachablePositionsWithWords.VisitedInfo>[0]);
            }

            var bestPosistions = Tuple.Create(double.MinValue, new Tuple<Unit, ReachablePositionsWithWords.VisitedInfo>[0]);
            foreach (var position in positionsForLookingAhead)
            {
                var newMap = map.Clone();
                newMap.LockUnit(position.Item2.Item1);
                newMap.RemoveLines();

                var nextPositions = FindBestPositions_Recursive(unitsAhead - 1, newMap, units, unitIndex + 1, powerPhrases, position.Item2.Item2.spelledWords);

                var score = position.Item1 + nextPositions.Item1;
                if (bestPosistions.Item1 < score)
                {
                    bestPosistions = Tuple.Create(score, new[] {position.Item2}.Concat(nextPositions.Item2).ToArray());
                }
            }

            return bestPosistions;
        }
Beispiel #7
0
 public virtual void ReStart()
 {
     var filledCells = problem.filled.ToDictionary(cell => Tuple.Create<int, int>(cell.x, cell.y), cell => cell.Fill());
     map = new Map(problem.width, problem.height);
     for (int x = 0; x < problem.width; x++)
         for (int y = 0; y < problem.height; y++)
         {
             Cell cell;
             if (filledCells.TryGetValue(Tuple.Create(x, y), out cell))
                 map[x, y] = cell;
             else
                 map[x, y] = new Cell { x = x, y = y };
         }
     units = problem.units;
     for (int i = 0; i < units.Length; i++)
     {
         units[i] = SpawnUnit(units[i], problem);
     }
     randomGenerator = new LinearCongruentalGenerator(seed);
     UnitIndeces = new int[problem.sourceLength];
     for (int i = 0; i < problem.sourceLength; i++)
     {
         UnitIndeces[i] = randomGenerator.GetNext()%units.Length;
     }
     state = State.WaitUnit;
     step = 0;
     currentUnit = null;
     forbiddenSequenceChecker = null;
     moves = null;
     currentUnitIndex = 0;
     currentMovesScore = 0;
     currentSpellsScore = 0;
     previouslyExplodedLines = 0;
     enteredString = new StringBuilder();
     EnteredMagicSpells = new List<string>();
 }
Beispiel #8
0
 public void DrawMap(Map map, Unit unit, bool locked = false)
 {
     for (int i = 0; i < 3 * map.Height + 1; i++)
     {
         var row = i / 3;
         if (i % 3 == 0)
         {
             console.BackgroundColor = ConsoleColor.Black;
             console.Write(" ");
             for (int col = 0; col < map.Width; ++col)
             {
                 if (row % 2 == 1)
                 {
                     var viewInfo = GetViewInfo(map, unit, col, row - 1, locked);
                     console.ForegroundColor = viewInfo.ForegroundColor;
                     console.BackgroundColor = viewInfo.BackgroundColor;
                     console.Write(new string(viewInfo.Char, 2));
                 }
                 if (row < map.Height)
                 {
                     var viewInfo = GetViewInfo(map, unit, col, row, locked);
                     console.ForegroundColor = viewInfo.ForegroundColor;
                     console.BackgroundColor = viewInfo.BackgroundColor;
                     console.Write(new string(viewInfo.Char, 2));
                 }
                 else
                 {
                     console.BackgroundColor = ConsoleColor.Black;
                     console.Write("  ");
                 }
                 if (row == 0)
                 {
                     console.BackgroundColor = ConsoleColor.Black;
                     console.Write("  ");
                 }
                 else if (row % 2 == 0)
                 {
                     var viewInfo = GetViewInfo(map, unit, col, row - 1, locked);
                     console.ForegroundColor = viewInfo.ForegroundColor;
                     console.BackgroundColor = viewInfo.BackgroundColor;
                     console.Write(new string(viewInfo.Char, 2));
                 }
             }
         }
         else
         {
             if (row % 2 == 1)
             {
                 console.BackgroundColor = ConsoleColor.Black;
                 console.Write("  ");
             }
             for (int col = 0; col < map.Width; ++col)
             {
                 var viewInfo = GetViewInfo(map, unit, col, row, locked);
                 console.ForegroundColor = viewInfo.ForegroundColor;
                 console.BackgroundColor = viewInfo.BackgroundColor;
                 console.Write(new string(viewInfo.Char, 4));
             }
         }
         console.WriteLine();
     }
 }
Beispiel #9
0
 private CellViewInfo GetViewInfo(Map map, Unit unit, int col, int row, bool locked)
 {
     var result = GetMapViewInfo(map[col, row]);
     if (unit != null)
     {
         var unitCell = unit.members.SingleOrDefault(x => x.x == col && x.y == row);
         if (unitCell != null)
         {
             result = new CellViewInfo
             {
                 BackgroundColor = locked ? ConsoleColor.Green : ConsoleColor.Red,
                 Char = ' '
             };
         }
         var isPivot = unit.pivot.x == col && unit.pivot.y == row;
         if (isPivot)
             result.Char = 'X';
     }
     return result;
 }
Beispiel #10
0
 public void DrawUnit(Unit unit)
 {
     var minY = unit.members.Concat(new[]{unit.pivot}).Min(cell => cell.y);
     while (minY > 0)
     {
         unit = unit.Move(MoveType.NE);
         minY--;
     }
     while (minY < 0)
     {
         unit = unit.Move(MoveType.SE);
         minY++;
     }
     var minX = unit.members.Min(cell => cell.x);
     while (minX > 0)
     {
         unit = unit.Move(MoveType.W);
         minX--;
     }
     while (minX < 0)
     {
         unit = unit.Move(MoveType.E);
         minX++;
     }
     var map = new Map(unit.members.Concat(new[] { unit.pivot }).Max(cell => cell.x) + 1, unit.members.Concat(new[] { unit.pivot }).Max(cell => cell.y) + 1);
     console.WriteLine();
     DrawMap(map, unit);
 }
 public ReachablePositionsWithWords(Map map, string[] powerPhrases, bool[] powerPhrasesSpelled)
 {
     this.map = map;
     this.powerPhrases = powerPhrases;
     this.powerPhrasesSpelled = powerPhrasesSpelled;
 }
 public ReachablePositions(Map map)
 {
     this.map = map;
 }
Beispiel #13
0
 public bool IsCorrect(Map map)
 {
     return !members.Any(cell => cell.x < 0 || cell.y < 0 || cell.x >= map.Width || cell.y >= map.Height || map[cell.x, cell.y].filled);
 }