Beispiel #1
0
        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;
                    }
                }
            }
        }
Beispiel #2
0
        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;
                }
            }
        }
Beispiel #3
0
 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();
 }
Beispiel #4
0
        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;
        }
Beispiel #5
0
        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;
                    }
                }
            }
        }
Beispiel #6
0
        private BfsState ApplyPhrase(BfsState startState, PowerPhraseInfo phraseInfo)
        {
            if (phraseInfo == null || string.IsNullOrEmpty(phraseInfo.Phrase))
                return startState;

            return ApplyPhrase(startState, phraseInfo.Phrase, phraseInfo.Commands);
        }
Beispiel #7
0
        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;
        }
Beispiel #8
0
        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;
            }
        }