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