public IEnumerable<BfsState> DoSimpleBfs(UnitState startState, bool backwards, bool returnStateCopies) { var queue = new Queue<UnitState>(); Debug.Assert(startState.GetCells(_unit).All(_field.IsValidCell)); _visited[startState] = new VisitInfo { MoveFuncIndex = -1, PrevState = null, AllPrevStates = new HashSet<UnitState>(), }; queue.Enqueue(startState); var moveFuncs = backwards ? UnitState.BackMoveFuncs : UnitState.MoveFuncs; BfsState returnState = new BfsState(null, null); while (queue.Count > 0) { var state = queue.Dequeue(); int blockingMove = -1; for (int funcIndex = 0; funcIndex < moveFuncs.Length; ++funcIndex) { UnitState newUnitState = moveFuncs[funcIndex](state); newUnitState.Normalize(_unit); Cell[] cells; bool isBlocking; if (!TryAddVisitedState(newUnitState, state, funcIndex, out cells, out isBlocking)) { if (isBlocking) blockingMove = funcIndex; continue; } queue.Enqueue(newUnitState); } if (blockingMove >= 0 || backwards) { if (returnStateCopies) { var retState = new BfsState(state, state.GetCells(_unit)); retState.BlockingMove = blockingMove; yield return retState; } else { returnState.UnitState = state; yield return returnState; } } } }
public IEnumerable<BfsState> DoBfs(UnitState startState, PowerPhraseInfo[] powerPhrases) { var queue = new Queue<BfsState>(); Debug.Assert(startState.GetCells(_unit).All(_field.IsValidCell)); _visited[startState] = new VisitInfo { MoveFuncIndex = -1, PrevState = null, AllPrevStates = new HashSet<UnitState>(), }; var startBfsState = new BfsState(startState, startState.GetCells(_unit)); //BfsState stateAfterPhrase = startBfsState; //if (powerPhrases != null) //{ // foreach (var phraseInfo in powerPhrases) // { // stateAfterPhrase = ApplyPhraseManyTimes(startBfsState, phraseInfo); // if (stateAfterPhrase.UnitState.Pivot != startState.Pivot || stateAfterPhrase.UnitState.Rotation != startState.Rotation) // break; // } //} var stateAfterPhrase = ApplyManyPhrasesManyTimes(startBfsState); queue.Enqueue(stateAfterPhrase); while (queue.Count > 0) { var state = queue.Dequeue(); int blockingMove = -1; for (int funcIndex = 0; funcIndex < UnitState.MoveFuncs.Length; ++funcIndex) { UnitState newUnitState = UnitState.MoveFuncs[funcIndex](state.UnitState); Cell[] cells; bool isBlocking; if (!TryAddVisitedState(newUnitState, state.UnitState, funcIndex, out cells, out isBlocking)) { if (isBlocking) blockingMove = funcIndex; continue; } queue.Enqueue(new BfsState(newUnitState, cells)); } if (blockingMove >= 0) { state.BlockingMove = blockingMove; yield return state; } } }
public BestStateInfo(Field field, Unit unit, BfsState bfsState) { Field = field; Unit = unit; BfsState = bfsState; CellsSet = new HashSet<Cell>(); foreach (var cell in Cells) CellsSet.Add(cell); CalcDistances(); CalcDounCells(); CalcJointCells(); CalcKilledRows(); CalcNewHoles(); }
private bool ApplySomePhrase(BfsState startBfsState, PowerPhraseInfo prevPhrase, out BfsState stateAfterPhrase, out PowerPhraseInfo appliedPhrase) { DebugPrinter.WriteLine("Applying some phrase from state ({0}, {1}) rot {2}", startBfsState.UnitState.Pivot.x, startBfsState.UnitState.Pivot.y, startBfsState.UnitState.Rotation); stateAfterPhrase = startBfsState; appliedPhrase = null; // apply current state of used phrases prevPhrase.PhraseCombinations.Sort(); int numFailed = 0; foreach (var comb in prevPhrase.PhraseCombinations) { DebugPrinter.WriteLine(" Next combination: phrase \"{0}\", type {1}", comb.CommandsStr, comb.CombineType); foreach (List<int> moves in EnumeratePreparationMoves(comb.CombineType)) { var movesStr = MovesPrinter.PrintMoves(moves); DebugPrinter.WriteLine(" Applying phrase \"{0}\" with additional moves {1}", comb.CommandsStr, movesStr); var cmdWithMovesStr = movesStr + comb.CommandsStr; var cmdWitmMoves = moves.Concat(comb.Commands).ToArray(); stateAfterPhrase = ApplyPhrase(startBfsState, cmdWithMovesStr, cmdWitmMoves); if (stateAfterPhrase.UnitState.Pivot != startBfsState.UnitState.Pivot || stateAfterPhrase.UnitState.Rotation != startBfsState.UnitState.Rotation) { appliedPhrase = comb.NextPhrase; appliedPhrase.WasUsed = true; DebugPrinter.WriteLine("Apply succeeded with {0} failed attempts", numFailed); return true; } ++numFailed; } } DebugPrinter.WriteLine("Apply failed with {0} failed attempts", numFailed); return false; }
private BfsState ApplyPhraseManyTimes(BfsState startState, PowerPhraseInfo phraseInfo) { BfsState lastValidState = startState; for (;;) { var newBfsState = ApplyPhrase(lastValidState, phraseInfo); if (newBfsState == lastValidState) return lastValidState; lastValidState = newBfsState; if (phraseInfo.CanRepeatImmediately) continue; if (!lastValidState.IsAbove(_field.MinFilledRow - 1)) return lastValidState; // try to move SW or SE to repeat the phrase after that for (MoveType funcIndex = MoveType.SW; funcIndex <= MoveType.SE; ++funcIndex) { UnitState newUnitState = UnitState.MoveFuncs[(int)funcIndex](lastValidState.UnitState); Cell[] cells; bool dummy; if (TryAddVisitedState(newUnitState, lastValidState.UnitState, (int)funcIndex, out cells, out dummy)) { lastValidState = new BfsState(newUnitState, cells); break; } } } }
private BfsState ApplyPhrase(BfsState startState, PowerPhraseInfo phraseInfo) { if (phraseInfo == null || string.IsNullOrEmpty(phraseInfo.Phrase)) return startState; return ApplyPhrase(startState, phraseInfo.Phrase, phraseInfo.Commands); }
private BfsState ApplyPhrase(BfsState startState, string commandsStr, int[] cmd) { Debug.Assert(commandsStr.Length == cmd.Length); var state = startState.UnitState; var oldVisited = new Dictionary<UnitState, VisitInfo>(_visited); Cell[] cells = null; for (int cmdIndex = 0; cmdIndex < cmd.Length; ++cmdIndex) { bool dummy; var nextState = UnitState.MoveFuncs[cmd[cmdIndex]](state); if (!TryAddVisitedState(nextState, state, cmd[cmdIndex], out cells, out dummy, commandsStr[cmdIndex])) { // throw new Exception(); _visited = oldVisited; return startState; } state = nextState; } var res = new BfsState(state, cells); int gap = 1; if (cmd.Length == 0 || cmd[cmd.Length - 1] >= 2) gap = 0; if (!res.IsAbove(_field.MinFilledRow - gap)) // TODO -1 ? { _visited = oldVisited; return startState; } return res; }
private BfsState ApplyManyPhrasesManyTimes(BfsState startBfsState) { PowerPhraseInfo prevPhrase = _gameData.PowerPhraseData.Phrases[0]; // empty phrase Debug.Assert(prevPhrase.Phrase == ""); BfsState lastValidState = startBfsState; for (;;) { BfsState stateAfterPhrase; PowerPhraseInfo appliedPhrase; bool phraseApplied = ApplySomePhrase(lastValidState, prevPhrase, out stateAfterPhrase, out appliedPhrase); prevPhrase = appliedPhrase; if (!phraseApplied) { // TODO rollback visited return lastValidState; } prevPhrase = appliedPhrase; //if (!stateAfterPhrase.IsAbove(_field.MinFilledRow - 1)) // return lastValidState; lastValidState = stateAfterPhrase; } }