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