Пример #1
0
 public bool Equals(Unit other)
 {
     if (ReferenceEquals(null, other)) return false;
     if (ReferenceEquals(this, other)) return true;
     if (!Equals(pivot, other.pivot)) return false;
     return members.Count == other.members.Count && members.All(m => other.members.Contains(m));
 }
Пример #2
0
 public IList<Tuple<Unit, IList<MoveType>>> AllPositions(Unit currentUnit)
 {
     if (!currentUnit.IsCorrect(map))
     {
         return new Tuple<Unit, IList<MoveType>>[0];
     }
     var checker = new ForbiddenSequenceChecker(currentUnit);
     var visited = new Dictionary<Unit, List<MoveType>>
     {
         { currentUnit, new List<MoveType>() },
     };
     var queue = new Queue<Unit>(new[] { currentUnit });
     while (queue.Any())
     {
         var unit = queue.Dequeue();
         foreach (var move in allowedMoves.Where(m => checker.CheckLastMove(visited[unit], m)))
         {
             var next = unit.Move(move);
             if (!next.IsCorrect(map) || visited.ContainsKey(next))
                 continue;
             queue.Enqueue(next);
             visited[next] = visited[unit].Concat(new[] { move }).ToList();
         }
     }
     return visited.Keys.Select(u => Tuple.Create(u, (IList<MoveType>)visited[u])).ToList();
 }
Пример #3
0
 public void LockUnit(Unit unit)
 {
     foreach (var cell in unit.members)
     {
         this[cell.x, cell.y].filled = true;
     }
 }
Пример #4
0
        public Tuple<double, int> _Evaluate(Unit unit)
        {
            // Уничтожаемые линии это хорошо
            var dropped = DroppedLines(unit);
            double scoreDropped = Math.Pow(dropped.Count(isDrop => isDrop)-1, 2) + dropped.Select((isDrop, i) => isDrop ? 1.0 +  ((double)i)/map.Height : 0.0).Sum();
            var droppedLines = dropped.Count(isDrop => isDrop);
            // Занимаем полезные клетки - это хорошо
            var usabilities = unit.members.Select(m => UsabilityForCells[m]).ToArray();
            double scoreOccupied = unit.members.Sum(m => UsabilityForCells[m]);
            // Ухудшаем возможность занять полезные клетки - это плохо
            var freeSurroundingCells = GetFreeSurroundingCells(unit);
            Dictionary<Cell, int> newFreeInputCells = freeSurroundingCells.ToDictionary(c => c, c => CountFreeInputs(c, unit));
            double scoreClosed = freeSurroundingCells.Select(c => (newFreeInputCells[c] - freeInputsForCells[c])*UsabilityForCells[c]).Sum();
            // Некомпактность - слишком много свободных клеток вокруг - это плохо
            double scoreCompact = ((double)-freeSurroundingCells.Length)/unit.GetSurroundingCells().Length;
            // Чем ниже тем лучше
            double scorePosHeigh = unit.members.Average(m =>((double)m.y)/map.Height);

            var score = 0.1*scoreDropped +
                        scoreOccupied +
                        0.5*scoreClosed +
                        0.2*scoreCompact +
                        0.1*scorePosHeigh+
                        0;
            return Tuple.Create(score, droppedLines);
        }
Пример #5
0
        public void LongVTest()
        {
            var problem = new Problem { width = 6 };
            var unit = new Unit
            {
                members = new HashSet<Cell>(new[]
                                      {
                                          new Cell { x = 0, y = 2 },
                                          new Cell { x = 0, y = 3 },
                                          new Cell { x = 1, y = 4 },
                                          new Cell { x = 1, y = 3 },
                                          new Cell { x = 2, y = 2 }
                                      }),
                pivot = new Cell { x = 1, y = 0 }
            };

            var placedUnit = Game.SpawnUnit(unit, problem);

            var members = placedUnit.members.ToArray();
            Assert.AreEqual(new Cell { x = 1, y = 0 }, members[0]);
            Assert.AreEqual(new Cell { x = 1, y = 1 }, members[1]);
            Assert.AreEqual(new Cell { x = 2, y = 2 }, members[2]);
            Assert.AreEqual(new Cell { x = 2, y = 1 }, members[3]);
            Assert.AreEqual(new Cell { x = 3, y = 0 }, members[4]);
            Assert.AreEqual(new Cell { x = 2, y = -2 }, placedUnit.pivot);
        }
Пример #6
0
 public IEnumerable<Tuple<Unit, IList<MoveType>>> EndPositions(Unit currentUnit)
 {
     return AllPositions(currentUnit)
         .SelectMany(p => FinalMoves(p.Item1)
             .Select(f => Tuple.Create(p.Item1, (IList<MoveType>)p.Item2.Concat(new[] { f })
                 .ToList())));
 }
Пример #7
0
 public void Test(HashSet<Cell> unitCells, HashSet<Cell> surround)
 {
     Unit unit = new Unit(){members = unitCells, pivot = new Cell(){x=0,y=0}};
     var surrounding = unit.GetSurroundingCells();
     Assert.IsTrue(surround.Count == surrounding.Length);
     foreach (var surroundCell in surrounding)
         Assert.IsTrue(surround.Contains(surroundCell));
 }
        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;
        }
Пример #9
0
        public void SmallBacteriaTest()
        {
            var problem = new Problem { width = 10 };
            var unit = new Unit { members = new HashSet<Cell>(new[] { new Cell { x = 1, y = 1 } }), pivot = new Cell { x = 2, y = 2 } };

            var placedUnit = Game.SpawnUnit(unit, problem);
            Assert.AreEqual(new Cell { x = 4, y = 0 }, placedUnit.members.Single());
            Assert.AreEqual(new Cell { x = 4, y = 1 }, placedUnit.pivot);
        }
Пример #10
0
        public void SinglePointTest_5()
        {
            var problem = new Problem { width = 5 };
            var unit = new Unit { members = new HashSet<Cell>(new[] { new Cell { x = 5, y = 5 } }), pivot = new Cell { x = 5, y = 5 } };

            var placedUnit = Game.SpawnUnit(unit, problem);

            Assert.AreEqual(new Cell { x = 2, y = 0 }, placedUnit.members.Single());
            Assert.AreEqual(new Cell { x = 2, y = 0 }, placedUnit.pivot);
        }
Пример #11
0
 private int CountFreeInputs(Cell cell, Unit unit = null)
 {
     int nfree = 0;
     foreach (var move in up)
     {
         var c = cell.Move(move);
         if (c.x < 0 || c.y < 0 || c.x >= map.Width || c.y >= map.Height) continue;
         if (!map[c].filled && (unit == null || !unit.members.Contains(c))) nfree++;
     }
     return nfree;
 }
Пример #12
0
        public void CountUnit()
        {
            var unit = new Unit {members = new HashSet<Cell>(new[] {new Cell {x = 1, y = 1}, new Cell {x = 2, y = 2}})};

            Assert.AreEqual(2, ScoreCounter.GetMoveScore(unit, 0, 0));
            Assert.AreEqual(102, ScoreCounter.GetMoveScore(unit, 1, 0));
            Assert.AreEqual(302, ScoreCounter.GetMoveScore(unit, 2, 0));
            Assert.AreEqual(602, ScoreCounter.GetMoveScore(unit, 3, 0));
            Assert.AreEqual(102, ScoreCounter.GetMoveScore(unit, 1, 1));
            Assert.AreEqual(112, ScoreCounter.GetMoveScore(unit, 1, 2));
            Assert.AreEqual(362, ScoreCounter.GetMoveScore(unit, 2, 3));
        }
Пример #13
0
 private bool[] DroppedLines(Unit unit)
 {
     bool[] dropped = emptyCellsInLines.Select(c => false).ToArray();
     var rect = unit.GetSurroundingRectangle();
     for (int l = rect.Item1.y; l <= rect.Item2.y; ++l)
     {
         var emptyCellsInLine = emptyCellsInLines[l];
         if (emptyCellsInLine.Count > unit.members.Count) continue;
         if (emptyCellsInLine.TrueForAll(c => unit.members.Contains(c)))
             dropped[l] = true;
     }
     return dropped;
 }
Пример #14
0
 public double Evaluate(Unit unit)
 {
     var dropped = DroppedLines(unit);
     int[] freedomInts = CountFreeInputsForSurroundingPoints(unit);
     int[] byCountFree = new int[5];
     foreach (var nfree in freedomInts)
         byCountFree[nfree]++;
     int scoreDropped = dropped.Select((isDrop, i) => isDrop ? 100+10*i : 0).Sum();
     int scorePosHeigh = unit.GetSurroundingRectangle().Item1.y;
     var score = scoreDropped  + scorePosHeigh
         //- 3*byCountFree[0] - 1*byCountFree[1] /* -2*byCountFree[2] - 1*byCountFree[3]*/
         ;
     return score;
 }
Пример #15
0
        public double Evaluate(Unit unit)
        {
            //Ценность занимаемых ячеек
            //Чем меньше остается пустых ячеек в строке - тем лучше
            //Чем меньше в данной стороке "глухих ячек" - тем лучше
            int score = 0;
            int nLinesDropped = 0;
            int[] occupied = new int[map.Height];
            foreach (var occupiedCellsInLine in unit.members.GroupBy(m => m.y))
            {
                var y = occupiedCellsInLine.Key;
                occupied[y] = occupiedCellsInLine.Count();
                var newEmptyCells = emptyCells[y].Except(occupiedCellsInLine);
                int nEmpty = 0, nBlocked = 0;
                foreach (var c in newEmptyCells)
                    if (CountFreeInputs(c, unit) == 0) nBlocked++;
                    else nEmpty++;
                int lineScore = (int) (map.Width - nEmpty - nBlocked)*occupied[y];
                if (nEmpty + nBlocked == 0) nLinesDropped++;
                if (lineScore > 0) score += lineScore;
            }
            score += map.Width*nLinesDropped*(nLinesDropped+1);

            // Насколько хорошая позиция юнита
            // Если рядом стена или заполненная ячейка - отлично
            // Если рядом пустая ячейка, то ее ценность - сколько у нее входов
            int surroundingScore = 0;
            foreach (var surroundingCellsInLine in unit.GetSurroundingCells().GroupBy(c => c.y))
            {
                foreach (var cell in surroundingCellsInLine)
                {

                var cellScore = 0;
                if (!IsCorrect(cell) || map[cell].filled) cellScore= 10;
                else cellScore =  4*CountFreeInputs(cell, unit);
                    if (cellScore == 0) cellScore= -(map.Width - emptyCells[cell.y].Length + occupied[cell.y] + (map.Width - emptyCells[cell.y].Length - blockedCells[cell.y] + occupied[cell.y] > map.Width*3/4 ? 10 : 0));
                surroundingScore += cellScore;

                }
            }

            // Не находится ли юнит рядом с входом
            int posScore = 0;
            if (unit.members.Any(cell =>
                (Math.Abs(cell.x - map.Width/2) < 3 && cell.y < 3)))
                if (nLinesDropped == 0) posScore = -2*map.Width;

            score = score + surroundingScore + posScore;
            return score;
        }
Пример #16
0
 private int[] CountFreeInputsForSurroundingPoints(Unit unit)
 {
     List<int> countOfInputs = new List<int>();
     foreach (var cell in unit.GetSurroundingCells())
         if (cell.x < 0 || cell.y < 0 || cell.x >= map.Width || cell.y >= map.Height) continue;
         else if (map[cell].filled) continue;
         else
         {
             int nfree = 0;
             foreach (var move in up)
             {
                 var c = cell.Move(move);
                 if (c.x < 0 || c.y < 0 || c.x >= map.Width || c.y >= map.Height) continue;
                 if (!map[c].filled && !unit.members.Contains(c)) nfree++;
             }
             countOfInputs.Add(nfree);
         }
     return countOfInputs.ToArray();
 }
Пример #17
0
 public double Evaluate(Unit unit)
 {
     return _Evaluate(unit).Item1;
 }
Пример #18
0
 private Cell[] GetFreeSurroundingCells(Unit unit)
 {
     return unit.GetSurroundingCells().Where(c => freeInputsForCells.ContainsKey(c)).ToArray();
 }
Пример #19
0
 private int CountFreeInputs(Cell cell, Unit unit = null)
 {
     if (unit == null) return inputsOfCells[cell].Length;
     int nfree = 0;
     foreach (var c in inputsOfCells[cell])
         if (unit.members.Contains(c)) continue;
         else nfree++;
     return nfree;
 }
 public IList<Tuple<Unit, VisitedInfo>> EndPositions(Unit currentUnit)
 {
     return AllPositions(currentUnit)
         .SelectMany(p => FinalMoves(p.Item1).Select(f => Tuple.Create(p.Item1,
             new VisitedInfo
             {
                 path = p.Item2.path.Concat(new[] { f }).ToList(),
                 score = p.Item2.score,
                 spelledWords = p.Item2.spelledWords
             }))).ToList();
 }
Пример #21
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>();
 }
Пример #22
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();
     }
 }
Пример #23
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;
 }
Пример #24
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 IList<Tuple<Unit, VisitedInfo>> AllPositions(Unit currentUnit)
 {
     if (!currentUnit.IsCorrect(map))
     {
         return new Tuple<Unit, VisitedInfo>[0];
     }
     var checker = new ForbiddenSequenceChecker(currentUnit);
     var visited = new Dictionary<Unit, VisitedInfo>
     {
         { currentUnit, new VisitedInfo
         {
             path = new List<MoveType>(),
             spelledWords = powerPhrasesSpelled
         } }
     };
     var queue = new Queue<Unit>(new[] { currentUnit });
     while (queue.Any())
     {
         var unit = queue.Dequeue();
         var currentInfo = visited[unit];
         for (int wordIndex = 0; wordIndex < powerPhrases.Length; wordIndex++)
         {
             var powerPhrase = powerPhrases[wordIndex];
             var next = unit;
             bool invalid = false;
             var moves = currentInfo.path.ToList();
             foreach (var c in powerPhrase)
             {
                 var move = MoveTypeExt.Convert(c).Value;
                 if (!checker.CheckLastMove(moves, move))
                 {
                     invalid = true;
                     break;
                 }
                 next = next.Move(move);
                 if (!next.IsCorrect(map) /*|| visited.ContainsKey(next)*/)
                 {
                     invalid = true;
                     break;
                 }
                 moves.Add(move);
             }
             if (!invalid)
             {
                 VisitedInfo prevInfo;
                 var newScore = currentInfo.score;
                 if (!currentInfo.spelledWords[wordIndex])
                     newScore += 300;
                 newScore += 2 * powerPhrase.Length;
                 if (!visited.TryGetValue(next, out prevInfo) || prevInfo.score < newScore)
                 {
                     queue.Enqueue(next);
                     var newSpelledWords = new bool[currentInfo.spelledWords.Length];
                     Array.Copy(currentInfo.spelledWords, newSpelledWords, newSpelledWords.Length);
                     newSpelledWords[wordIndex] = true;
                     visited[next] = new VisitedInfo
                     {
                         path = moves,
                         score = newScore,
                         spelledWords = newSpelledWords
                     };
                 }
             }
         }
         foreach (var move in allowedMoves.Where(m => checker.CheckLastMove(currentInfo.path, m)))
         {
             var next = unit.Move(move);
             if (!next.IsCorrect(map))
                 continue;
             VisitedInfo prevInfo;
             if (!visited.TryGetValue(next, out prevInfo) || prevInfo.score < currentInfo.score)
             {
                 queue.Enqueue(next);
                 visited[next] = new VisitedInfo
                 {
                     path = currentInfo.path.Concat(new[] { move }).ToList(),
                     score = currentInfo.score,
                     spelledWords = currentInfo.spelledWords
                 };
             }
         }
     }
     return visited.Keys.Select(u => Tuple.Create(u, visited[u])).ToList();
 }
 public IEnumerable<Tuple<Unit, VisitedInfo>> SingleEndPositions(Unit currentUnit)
 {
     return EndPositions(currentUnit).GroupBy(t => t.Item1).Select(g => g.First());
 }
        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;
        }
Пример #28
0
 public void Step()
 {
     ++step;
     switch (state)
     {
         case State.WaitUnit:
             if (currentUnitIndex++ >= problem.sourceLength)
             {
                 state = State.End;
                 return;
             }
             spawnedUnitIndex = UnitIndeces[currentUnitIndex - 1];
             var spawnedUnit = units[spawnedUnitIndex];
             if (!spawnedUnit.IsCorrect(map))
             {
                 state = State.End;
                 return;
             }
             currentUnit = spawnedUnit;
             forbiddenSequenceChecker = new ForbiddenSequenceChecker(currentUnit);
             moves = new List<MoveType>();
             state = State.UnitInGame;
             return;
         case State.UnitInGame:
             char move;
             if (!TryGetNextMove(out move))
             {
                 state = State.End;
                 return;
             }
             var moveType = MoveTypeExt.Convert(move);
             if (moveType == null)
             {
                 state = State.EndInvalidCommand;
                 return;
             }
             enteredString.Append(move);
             ParseNewMagicSpells();
             var movedUnit = currentUnit.Move(moveType.Value);
             if (!movedUnit.IsCorrect(map))
             {
                 LockUnit(currentUnit);
                 currentUnit = null;
                 state = State.WaitUnit;
                 return;
             }
             if (!forbiddenSequenceChecker.CheckLastMove(moves, moveType.Value))
             {
                 state = State.EndPositionRepeated;
                 return;
             }
             moves.Add(moveType.Value);
             currentUnit = movedUnit;
             return;
         case State.EndInvalidCommand:
             return;
         case State.End:
             return;
         default:
             throw new ArgumentOutOfRangeException();
     }
 }
 private List<MoveType> FinalMoves(Unit unit)
 {
     return allowedMoves.Where(m => !unit.Move(m).IsCorrect(map)).ToList();
 }
Пример #30
0
 private static int FirstInUnit(Cell[] cells, Unit unit)
 {
     int i = 0;
     foreach (var cell in cells)
     {
         if (unit.members.Contains(cell)) return i;
         ++i;
     }
     return i;
 }