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