Ejemplo n.º 1
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;
                }
            }
        }
Ejemplo n.º 2
0
        public void GetCells()
        {
            var u = new Unit(new[] {new Cell(0, 0), new Cell(1, 0), new Cell(1, 1)}, new Cell(0, 0));
            var us = new UnitState(new Cell(2, 2), 0);
            var cells = us.GetCells(u);
            Assert.IsTrue(cells.Contains(new Cell(2, 2)));
            Assert.IsTrue(cells.Contains(new Cell(3, 2)));
            Assert.IsTrue(cells.Contains(new Cell(3, 3)));

            us = new UnitState(new Cell(2, 2), 1);
            cells = us.GetCells(u);
            Assert.IsTrue(cells.Contains(new Cell(2, 2)));
            Assert.IsTrue(cells.Contains(new Cell(2, 1)));
            Assert.IsTrue(cells.Contains(new Cell(3, 1)));

            us = new UnitState(new Cell(2, 3), 0);
            cells = us.GetCells(u);
            Assert.IsTrue(cells.Contains(new Cell(2, 3)));
            Assert.IsTrue(cells.Contains(new Cell(3, 3)));
            Assert.IsTrue(cells.Contains(new Cell(4, 4)));

            u = new Unit(new[] { new Cell(0, 1), new Cell(1, 1), new Cell(2, 2) }, new Cell(0, 1));
            us = new UnitState(new Cell(2, 2), 0);
            cells = us.GetCells(u);
            Assert.IsTrue(cells.Contains(new Cell(2, 2)));
            Assert.IsTrue(cells.Contains(new Cell(3, 2)));
            Assert.IsTrue(cells.Contains(new Cell(3, 3)));
        }
Ejemplo n.º 3
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;
                    }
                }
            }
        }
Ejemplo n.º 4
0
 public void MoveE()
 {
     var unit = new Unit(new[] { new Cell(10, 0), new Cell(11, 1) }, new Cell(12, 2));
     var unitState = new UnitState(unit.pivot, 0);
     unitState = UnitState.MoveE(unitState);
     var cells = unitState.GetCells(unit);
     Assert.IsTrue(cells.Contains(new Cell(11, 0)));
     Assert.IsTrue(cells.Contains(new Cell(12, 1)));
     Assert.AreEqual(new Cell(13, 2), unitState.Pivot);
 }
Ejemplo n.º 5
0
 public void MoveSW()
 {
     var unit = new Unit(new[] { new Cell(10, 4), new Cell(11, 5) }, new Cell(12, 6));
     var unitState = new UnitState(unit.pivot, 0);
     unitState = UnitState.MoveSW(unitState);
     var cells = unitState.GetCells(unit);
     Assert.AreEqual(2, cells.Length);
     Assert.IsTrue(cells.Contains(new Cell(9, 5)));
     Assert.IsTrue(cells.Contains(new Cell(11, 6)));
     Assert.AreEqual(new Cell(11, 7), unitState.Pivot);
 }
Ejemplo n.º 6
0
        public void TurnClockwise()
        {
            var unit = new Unit(new[] { new Cell(3, 0) }, new Cell(2, 3));
            var unitState = new UnitState(unit.pivot, 0);
            unitState = UnitState.TurnClockwise(unitState);
            Assert.AreEqual(new Cell(2, 3), unitState.Pivot);
            Assert.AreEqual(new Cell(5, 2), unitState.GetCells(unit)[0]);
            unitState = UnitState.TurnClockwise(unitState);
            Assert.AreEqual(new Cell(4, 5), unitState.GetCells(unit)[0]);
            unitState = UnitState.TurnClockwise(unitState);
            Assert.AreEqual(new Cell(2, 6), unitState.GetCells(unit)[0]);
            unitState = UnitState.TurnClockwise(unitState);
            Assert.AreEqual(new Cell(0, 4), unitState.GetCells(unit)[0]);
            unitState = UnitState.TurnClockwise(unitState);
            Assert.AreEqual(new Cell(0, 1), unitState.GetCells(unit)[0]);

            unit = new Unit(new[] { new Cell(0, 2), new Cell(4, 2) }, new Cell(2, 2));
            unitState = new UnitState(unit.pivot, 0);
            unitState = UnitState.TurnClockwise(unitState);
            var cells = unitState.GetCells(unit);
            Assert.AreEqual(2, cells.Length);
            Assert.IsTrue(cells.Contains(new Cell(1, 0)));
            Assert.IsTrue(cells.Contains(new Cell(3, 4)));
            unitState = UnitState.TurnClockwise(unitState);
            cells = unitState.GetCells(unit);
            Assert.IsTrue(cells.Contains(new Cell(3, 0)));
            Assert.IsTrue(cells.Contains(new Cell(1, 4)));
        }
Ejemplo n.º 7
0
 public void MoveW()
 {
     var unit = new Unit(new[] { new Cell(10, 0), new Cell(11, 0) }, new Cell(12, 0));
     var unitState = new UnitState(unit.pivot, 0);
     unitState = UnitState.MoveW(unitState);
     var cells = unitState.GetCells(unit);
     Assert.IsTrue(cells.Contains(new Cell(9, 0)));
     Assert.IsTrue(cells.Contains(new Cell(10, 0)));
 }
Ejemplo n.º 8
0
        public void TurnCounter()
        {
            var unit = new Unit(new[] { new Cell(3, 0) }, new Cell(2, 3));
            var unitState = new UnitState(unit.pivot, 0);
            unitState = UnitState.TurnCounter(unitState);
            var cells = unitState.GetCells(unit);
            Assert.AreEqual(3, unitState.Pivot.y);
            Assert.AreEqual(2, unitState.Pivot.x);
            Assert.AreEqual(1, cells[0].y);
            Assert.AreEqual(0, cells[0].x);
            unitState = UnitState.TurnCounter(unitState);
            Assert.AreEqual(new Cell(0, 4), unitState.GetCells(unit)[0]);
            unitState = UnitState.TurnCounter(unitState);
            Assert.AreEqual(new Cell(2, 6), unitState.GetCells(unit)[0]);
            unitState = UnitState.TurnCounter(unitState);
            Assert.AreEqual(new Cell(4, 5), unitState.GetCells(unit)[0]);
            unitState = UnitState.TurnCounter(unitState);
            Assert.AreEqual(new Cell(5, 2), unitState.GetCells(unit)[0]);

            unit = new Unit(new[] { new Cell(0, 2), new Cell(4, 2) }, new Cell(2, 2));
            unitState = new UnitState(unit.pivot, 0);
            unitState = UnitState.TurnCounter(unitState);
            cells = unitState.GetCells(unit);
            Assert.IsTrue(cells.Contains(new Cell(1, 4)));
            Assert.IsTrue(cells.Contains(new Cell(3, 0)));
            unitState = UnitState.TurnCounter(unitState);
            cells = unitState.GetCells(unit);
            Assert.IsTrue(cells.Contains(new Cell(3, 4)));
            Assert.IsTrue(cells.Contains(new Cell(1, 0)));
        }
Ejemplo n.º 9
0
        private bool TryAddVisitedState(UnitState newState, UnitState state, int funcIndex, out Cell[] cells, out bool isBlockingMove, char moveChar = ANY_CHAR)
        {
            cells = null;
            isBlockingMove = false;
            if (_visited.ContainsKey(newState))
                return false;

            cells = newState.GetCells(_unit);

            if (!cells.All(_field.IsValidCell))
            {
                isBlockingMove = true;
                return false;
            }

            //if (_IsDuplicateState(state, newState))
            //    return false;

            var vi = new VisitInfo
                {
                    MoveFuncIndex = funcIndex,
                    PrevState = state,
                    MoveChar = moveChar,
                    //AllPrevStates = _visited[state].AllPrevStates
                    //   AllPrevStates = new HashSet<UnitState>(_visited[state].AllPrevStates)
                };
              //  vi.AllPrevStates.Add(new UnitState(state.Pivot, _unit.GetCanonicalRotation(state.Rotation)));

            _visited[newState] = vi;
            return true;
        }
Ejemplo n.º 10
0
 public void Update(Unit unit, UnitState state)
 {
     Update(state.GetCells(unit));
 }
Ejemplo n.º 11
0
 public UnitState SpawnUnit(Unit unit)
 {
     int ymin = unit.members[0].y;
     foreach (var cell in unit.members)
         if (cell.y < ymin) ymin = cell.y;
     var us = new UnitState(new Cell(unit.pivot.x, unit.pivot.y - ymin), 0);
     var cells = us.GetCells(unit);
     int xmin = cells[0].x, xmax = cells[0].x;
     foreach (var cell in cells)
     {
         if (cell.x < xmin) xmin = cell.x;
         if (cell.x > xmax) xmax = cell.x;
     }
     int x0 = (Width - 1 - (xmax - xmin)) / 2;
     us = new UnitState(new Cell(us.Pivot.x - xmin + x0, us.Pivot.y), 0);
     foreach (var cell in us.GetCells(unit))
         if (!IsValidCell(cell)) return null;
     us.Normalize(unit);
     return us;
 }
Ejemplo n.º 12
0
        public void SimulateUnit(Unit unit, UnitState startState, string movesStr, bool debugWrite = false)
        {
            var visited = new List<VisitedInfo>();
            Cell[] prevCells = null;
            Cell[] curCells = startState.GetCells(unit);
            Cell curPivot = startState.Pivot;
            visited.Add(new VisitedInfo(curPivot, curCells));
            if (!curCells.All(_field.IsValidCell))
            {
                throw new Exception("Start state is invalid");
            }

            var moveCommands = MovesPrinter.GetCommands(movesStr);

            for (int moveIdx = 0; moveIdx < moveCommands.Length; ++moveIdx)
            {
                prevCells = curCells;
                int move = moveCommands[moveIdx];
                switch (move)
                {
                    case 0:
                        curPivot = Moves.MoveW(curPivot);
                        curCells = curCells.Select(Moves.MoveW).ToArray();
                        break;
                    case 1:
                        curPivot = Moves.MoveE(curPivot);
                        curCells = curCells.Select(Moves.MoveE).ToArray();
                        break;
                    case 2:
                        curPivot = Moves.MoveSW(curPivot);
                        curCells = curCells.Select(Moves.MoveSW).ToArray();
                        break;
                    case 3:
                        curPivot = Moves.MoveSE(curPivot);
                        curCells = curCells.Select(Moves.MoveSE).ToArray();
                        break;
                    case 4:
                        curCells = curCells.Select(c => Moves.TurnClockwise(c, curPivot)).ToArray();
                        break;
                    case 5:
                        curCells = curCells.Select(c => Moves.TurnCounter(c, curPivot)).ToArray();
                        break;
                }

                bool isLast = moveIdx == moveCommands.Length - 1;
                if (!curCells.All(_field.IsValidCell))
                {
                    if (!isLast)
                    {
                        throw new Exception(string.Format("move number {0} is not the last but leads to invalid cells", moveIdx));
                    }
                }
                else
                {
                    if (isLast)
                    {
                        throw new Exception(string.Format("Last move number {0} doesn't lock the unit", moveIdx));
                    }

                    Array.Sort(curCells);

                    if (debugWrite)
                    {
                        DebugPrinter.Write("After move #{0} {1} ({2}) pivot: ({3}, {4}), cells: ", moveIdx, move, movesStr[moveIdx], curPivot.x, curPivot.y);
                        foreach (Cell c in curCells)
                            DebugPrinter.Write("({0}, {1}), ", c.x, c.y);
                        DebugPrinter.WriteLine("");
                    }

                    bool duplicate = false;
                    int visIdx = 0;
                    for (; visIdx < visited.Count; ++visIdx)
                    {
                        var vi = visited[visIdx];
                        bool equal = true;
                        if (vi.Pivot != curPivot)
                        {
                            equal = false;
                            continue;
                        }

                        for (int i = 0; i < vi.Members.Length; ++i)
                        {
                            if (vi.Members[i] != curCells[i])
                            {
                                equal = false;
                                break;
                            }
                        }

                        if (equal)
                        {
                            duplicate = true;
                            break;
                        }
                    }

                    if (duplicate)
                    {
                        if (!debugWrite)
                            SimulateUnit(unit, startState, movesStr, true);
                        else
                            throw new Exception(string.Format("move number {0} introduces a duplicate with move {1}", moveIdx, visIdx));
                    }

                    visited.Add(new VisitedInfo(curPivot, curCells));
                }
            }

            _field.Update(prevCells);
        }
Ejemplo n.º 13
0
 public static string PrettyPrintBeforeUpdate(Field field, Unit unit, UnitState state, Dictionary<Cell, char> pathCells = null)
 {
     string res = "";
     var cells = state.GetCells(unit);
     for (int y = 0; y < field.Height; ++y)
     {
         if (y % 2 == 1)
             res += " ";
         for (int x = 0; x < field.Width; ++x)
         {
             Cell c = new Cell(x, y);
             if (pathCells != null && pathCells.ContainsKey(c))
                 res += pathCells[c] + " ";
             else if (field[y][x])
                 res += "* ";
             else if (cells.Contains(c))
                 res += "@ ";
             else
                 res += ". ";
         }
         res += "|\n";
     }
     return res;
 }