示例#1
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)));
        }
示例#2
0
        public PhraseCombineInfo(PowerPhraseData pd, PowerPhraseInfo p1, PowerPhraseInfo p2, CombineType combineType, PhraseMetricType metricType)
        {
            PrevPhrase = p1;
            NextPhrase = p2;
            this.CombineType = combineType;
            IntersectionLen = CalcIntersectionLen(p1.Phrase, p2.Phrase);
            if (combineType == CombineType.Overlap && IntersectionLen == 0)
                throw new Exception();

            CommandsStr = p2.Phrase.Substring(IntersectionLen);

            var fakeUnitState = new UnitState(new Cell(0, 0), 0);
            Commands = MovesPrinter.GetCommands(CommandsStr);
            MinX = 0;
            MaxX = 0;
            foreach (var cmd in Commands)
            {
                fakeUnitState = UnitState.MoveFuncs[cmd](fakeUnitState);
                MinX = Math.Min(MinX, fakeUnitState.Pivot.x);
                MaxX = Math.Max(MaxX, fakeUnitState.Pivot.x);
            }
            DY = fakeUnitState.Pivot.y;

            switch (combineType)
            {
                case CombineType.Overlap:
                    EffectiveLen = pd.CalcEffectiveLen(p1.Phrase + CommandsStr) - p1.EffectiveLength;
                    break;
                case CombineType.Append:
                    EffectiveLen = p2.EffectiveLength;
                    break;
                case CombineType.MoveDownAppend:
                    EffectiveLen = p2.EffectiveLength;
                    ++DY;
                    break;
            }

            switch (metricType)
            {
                case PhraseMetricType.Div:
                    Metric = (double)EffectiveLen / DY;
                    break;
                case PhraseMetricType.Diff:
                    Metric = (double)EffectiveLen - DY;
                    break;
                case PhraseMetricType.Div2:
                    Metric = (double)EffectiveLen / (DY + LAST_MOVE_PENALTY[Commands[Commands.Length - 1]]);
                    break;
                case PhraseMetricType.Div3:
                    Metric = (double)EffectiveLen / (DY + LAST_MOVE_PENALTY[Commands[Commands.Length - 1]] * 2);
                    break;
                default:
                    throw new ArgumentOutOfRangeException("metricType");
            }

            DebugPrinter.WriteLine("Phrase combine: \"{0}\" and \"{1}\" with type {2}, effective len {3}, DY {4}, metric {5}",
                p1.Phrase, p2.Phrase, combineType, EffectiveLen, DY, Metric);
        }
示例#3
0
文件: BFS.cs 项目: martugin/tetris
        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;
                }
            }
        }
示例#4
0
文件: BFS2.cs 项目: martugin/tetris
        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;
                    }
                }
            }
        }
示例#5
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);
 }
示例#6
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);
 }
示例#7
0
        public void TestConstructor()
        {
            var f = new Field(3, 3, new Cell(0, 1), new Cell(2, 1));
            var us = new UnitState(new Cell(0, 0), 0);
            var u = new Unit(new[] {new Cell(0, 0)}, new Cell(0, 0));

            var bfss = new BestStateInfo(f, u, new BfsState(us, new Cell(0, 2)));
            Assert.AreEqual(0, bfss.KilledRows);
            Assert.AreEqual(5, bfss.JoinedCellsCount);
            Assert.AreEqual(0, bfss.NewHolesCount);

            bfss = new BestStateInfo(f, u, new BfsState(us, new Cell(1, 1)));
            Assert.AreEqual(1, bfss.KilledRows);
            Assert.AreEqual(2, bfss.JoinedCellsCount);
            Assert.AreEqual(1, bfss.NewHolesCount);

            bfss = new BestStateInfo(f, u, new BfsState(us, new Cell(1, 1), new Cell(0, 2), new Cell(1, 2), new Cell(2, 2)));
            Assert.AreEqual(2, bfss.KilledRows);
            Assert.AreEqual(9, bfss.JoinedCellsCount);
            Assert.AreEqual(0, bfss.NewHolesCount);

            bfss = new BestStateInfo(f, u, new BfsState(us,  new Cell(1, 2)));
            Assert.AreEqual(0, bfss.KilledRows);
            Assert.AreEqual(3, bfss.JoinedCellsCount);
            Assert.AreEqual(1, bfss.NewHolesCount);

            bfss = new BestStateInfo(f, u, new BfsState(us, new Cell(0, 0), new Cell(1, 0), new Cell(1, 1), new Cell(1, 2)));
            Assert.AreEqual(1, bfss.KilledRows);
            Assert.AreEqual(6, bfss.JoinedCellsCount);
            Assert.AreEqual(2, bfss.NewHolesCount);

            f = new Field(3, 3, new Cell(0, 1));
            bfss = new BestStateInfo(f, u, new BfsState(us, new Cell(1, 2), new Cell(1, 1), new Cell(2, 0)));
            Assert.AreEqual(0, bfss.KilledRows);
            Assert.AreEqual(4, bfss.JoinedCellsCount);
            Assert.AreEqual(2, bfss.NewHolesCount);

            f = new Field(4, 4, new Cell(0, 3), new Cell(1, 3), new Cell(2, 3));
            bfss = new BestStateInfo(f, u, new BfsState(us, new Cell(0, 0), new Cell(0, 1), new Cell(1, 1), new Cell(0, 2), new Cell(2, 2)));
            Assert.AreEqual(0, bfss.KilledRows);
            Assert.AreEqual(7, bfss.JoinedCellsCount);
            Assert.AreEqual(1, bfss.NewHolesCount);
        }
示例#8
0
文件: Field.cs 项目: martugin/tetris
 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;
 }
示例#9
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)));
        }
示例#10
0
文件: BFS2.cs 项目: martugin/tetris
        private bool _IsReachable(UnitState unitState, UnitState finalState, out List<int> reversedPathIfSuccess)
        {
            var oldVisited = new Dictionary<UnitState, VisitInfo>(_visited);
            bool reachable = false;
            reversedPathIfSuccess = null;

            foreach (var bfsState in DoSimpleBfs(unitState, false, false))
            {
                if (bfsState.UnitState == finalState)
                {
                    reachable = true;
                    reversedPathIfSuccess = GetMoves(finalState, unitState, true);
                    break;
                }
            }
            _visited = oldVisited;
            return reachable;
        }
示例#11
0
文件: BFS2.cs 项目: martugin/tetris
        public List<int> GetMoves(UnitState finalState, UnitState startState, bool reversed = false)
        {
            var moves = new List<int>();
            UnitState state = finalState;
            while (state != startState)
            {
                var visitedInfo = _visited[state];
                moves.Add(visitedInfo.MoveFuncIndex);
                state = visitedInfo.PrevState;
            }

            if (!reversed)
                moves.Reverse();
            return moves;
        }
示例#12
0
文件: BFS.cs 项目: martugin/tetris
        private bool _IsDuplicateState(UnitState prevState, UnitState newState)
        {
            int newCanonicalRotation = _unit.GetCanonicalRotation(newState.Rotation);

            //return _visited[prevState].AllPrevStates.Contains(new UnitState(newState.Pivot, newCanonicalRotation));

            while (prevState != null)
            {
                if (newState.Pivot == prevState.Pivot && newCanonicalRotation == _unit.GetCanonicalRotation(prevState.Rotation))
                    return true;
                Debug.Assert(_visited.ContainsKey(prevState));
                prevState = _visited[prevState].PrevState;
            }
            return false;
        }
示例#13
0
文件: BFS2.cs 项目: martugin/tetris
        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;
        }
示例#14
0
 public static UnitState TurnClockwise(UnitState state)
 {
     return new UnitState(state.Pivot, (state.Rotation + 5) % 6);
 }
示例#15
0
 protected bool Equals(UnitState other)
 {
     return Pivot.Equals(other.Pivot) && Rotation == other.Rotation;
 }
示例#16
0
文件: BFS2.cs 项目: martugin/tetris
        public void ReachStateUsingPhrases(UnitState startState, UnitState finalState)
        {
            var backBfs = new BFS2(_field, _unit, _gameData);
            #if false// DEBUG
            DebugPrinter.WriteLine("Checking what is reachable back from: ({0}, {1}) rot {2}", finalState.Pivot.x, finalState.Pivot.y, finalState.Rotation);
            var reachableArr = backBfs.DoSimpleBfs(finalState, true).Select(st => st.UnitState).ToArray();

            foreach (var st in reachableArr)
                DebugPrinter.WriteLine("    reachable: ({0}, {1}) rot {2}", st.Pivot.x, st.Pivot.y, st.Rotation);
            var reachableStates = new HashSet<UnitState>(reachableArr);
            #else
            var reachableStates = new HashSet<UnitState>(backBfs.DoSimpleBfs(finalState, true, false).Select(st => st.UnitState));
            #endif

            _visited[startState] = new VisitInfo
            {
                MoveFuncIndex = -1,
                PrevState = null,
                AllPrevStates = new HashSet<UnitState>(),
            };

            UnitState curState = startState;

            PowerPhraseInfo prevPhrase = _gameData.PowerPhraseData.Phrases[0]; // empty phrase

            List<int> curReversedPath = null;

            while (curState != finalState)
            {
                UnitState stateAfterPhrase;
                PowerPhraseInfo appliedPhrase;
                List<int> reversedPathAfterPhrase;
                var prevState = curState;
                bool phraseApplied = ApplySomePhrase(curState, prevPhrase, reachableStates, finalState,
                    out stateAfterPhrase, out appliedPhrase, out reversedPathAfterPhrase);
                curState = stateAfterPhrase;

                if (phraseApplied)
                {
                    //movesStr += appliedPhrase.Phrase;
                    curReversedPath = reversedPathAfterPhrase;
                    prevPhrase = appliedPhrase;
                    continue;
                }

                prevPhrase = _gameData.PowerPhraseData.Phrases[0];

                // Do BFS step
                if (curReversedPath == null)
                {
                    bool reachable = _IsReachable(curState, finalState, out curReversedPath);
                    Debug.Assert(reachable);
                }

                int move = curReversedPath[curReversedPath.Count - 1];
                var state = curState;
                curState = UnitState.MoveFuncs[move](curState);
                curState.Normalize(_unit);
                curReversedPath.RemoveAt(curReversedPath.Count - 1);

                _visited[curState] = new VisitInfo
                {
                    MoveFuncIndex = move,
                    PrevState = state,
                    MoveChar = ANY_CHAR,
                };
            }
        }
示例#17
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)));
 }
示例#18
0
文件: BFS2.cs 项目: martugin/tetris
        public Dictionary<Cell, char> GetPathCells(UnitState finalState)
        {
            var cells = new Dictionary<Cell, char>();
            UnitState state = finalState;
            while (state != null)
            {
                var visitedInfo = _visited[state];
                cells[state.Pivot] = _visited[state].MoveChar;
                state = visitedInfo.PrevState;
                if (state == null)
                    break;
            }

            return cells;
        }
示例#19
0
文件: BFS2.cs 项目: martugin/tetris
        public string GetMovesString(UnitState finalState)
        {
            var moves = "";
            UnitState state = finalState;
            while (state != null)
            {
                var visitedInfo = _visited[state];
                state = visitedInfo.PrevState;
                if (state == null)
                    break;

                if (visitedInfo.MoveChar == ANY_CHAR)
                    moves = MovesPrinter.PrintOneMove(visitedInfo.MoveFuncIndex) + moves;
                else
                    moves = visitedInfo.MoveChar + moves;
            }

            return moves;
        }
示例#20
0
文件: BFS.cs 项目: martugin/tetris
        public List<int> GetMoves(UnitState finalState)
        {
            var moves = new List<int>();
            UnitState state = finalState;
            while (state != null)
            {
                var visitedInfo = _visited[state];
                state = visitedInfo.PrevState;
                if (state != null)
                    moves.Add(visitedInfo.MoveFuncIndex);
            }

            moves.Reverse();
            return moves;
        }
示例#21
0
        public PowerPhraseInfo(string phrase, int index)
        {
            Phrase = phrase;
            Index = index;
            Commands = MovesPrinter.GetCommands(phrase);

            var visited = new HashSet<Cell>();

            var fakeUnitState = new UnitState(new Cell(0, 0), 0);
            MinX = 0;
            MaxX = 0;
            HasRotations = false;
            foreach (var cmd in Commands)
            {
                fakeUnitState = UnitState.MoveFuncs[cmd](fakeUnitState);
                MinX = Math.Min(MinX, fakeUnitState.Pivot.x);
                MaxX = Math.Max(MaxX, fakeUnitState.Pivot.x);
                HasRotations |= (cmd >= 4);
                visited.Add(fakeUnitState.Pivot);
            }
            DY = fakeUnitState.Pivot.y;

            // try to repeat
            CanRepeatImmediately = true;
            foreach (var cmd in Commands)
            {
                fakeUnitState = UnitState.MoveFuncs[cmd](fakeUnitState);
                if (visited.Contains(fakeUnitState.Pivot))
                {
                    CanRepeatImmediately = false;
                    break;
                }
            }
        }
示例#22
0
 public BfsState(UnitState unitState, params Cell[] cells)
 {
     UnitState = unitState;
     Cells = cells;
     BlockingMove = -1;
 }
示例#23
0
文件: BFS2.cs 项目: martugin/tetris
        private UnitState ApplyPhrase(UnitState startState, string commandsStr, int[] cmd)
        {
            Debug.Assert(commandsStr.Length == cmd.Length);
            var state = startState;

            for (int cmdIndex = 0; cmdIndex < cmd.Length; ++cmdIndex)
            {
                bool dummy;
                var nextState = UnitState.MoveFuncs[cmd[cmdIndex]](state);
                nextState.Normalize(_unit);
                Cell[] cells;
                if (!TryAddVisitedState(nextState, state, cmd[cmdIndex], out cells, out dummy, commandsStr[cmdIndex]))
                {
                    // throw new Exception();
                    return startState;
                }

                state = nextState;
            }

            return state;
        }
示例#24
0
文件: Field.cs 项目: martugin/tetris
 public void Update(Unit unit, UnitState state)
 {
     Update(state.GetCells(unit));
 }
示例#25
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)));
        }
示例#26
0
文件: BFS2.cs 项目: martugin/tetris
        private bool ApplySomePhrase(UnitState startState, PowerPhraseInfo prevPhrase,
            HashSet<UnitState> reachableStates, UnitState finalState,
            out UnitState stateAfterPhrase, out PowerPhraseInfo appliedPhrase, out List<int> reversedPathIfSuccess)
        {
            #if DEBUG
            DebugPrinter.WriteLine("Applying some phrase from state ({0}, {1}) rot {2}",
                startState.Pivot.x, startState.Pivot.y, startState.Rotation);
            #endif
            appliedPhrase = null;
            reversedPathIfSuccess = null;

            // apply current state of used phrases
            prevPhrase.PhraseCombinations.Sort();

            int numFailed = 0;
            int combIdx = 0;
            foreach (var comb in prevPhrase.PhraseCombinations)
            {
                ++combIdx;
                if (combIdx > 7 && comb.NextPhrase.WasUsed && _field.Height * _field.Width > 400)
                    break;

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

                    var oldVisited = new Dictionary<UnitState, VisitInfo>(_visited);

                    stateAfterPhrase = ApplyPhrase(startState, cmdWithMovesStr, cmdWitmMoves);

                    if ((stateAfterPhrase.Pivot != startState.Pivot || stateAfterPhrase.Rotation != startState.Rotation)
                        && reachableStates.Contains(stateAfterPhrase) && _IsReachable(stateAfterPhrase, finalState, out reversedPathIfSuccess))
                    {
                        appliedPhrase = comb.NextPhrase;
                        appliedPhrase.WasUsed = true;
            #if DEBUG
                        DebugPrinter.WriteLine("Apply succeeded with {0} failed attempts: phrase \"{1}\" with additional moves {2}", numFailed, comb.CommandsStr, movesStr);
            #endif
                        return true;
                    }

                    _visited = oldVisited;

                    ++numFailed;
                }
            }
            #if DEBUG
            DebugPrinter.WriteLine("Apply failed with {0} failed attempts", numFailed);
            #endif
            stateAfterPhrase = startState;
            return false;
        }
示例#27
0
 public static UnitState TurnCounter(UnitState state)
 {
     return new UnitState(state.Pivot, (state.Rotation + 1) % 6);
 }
示例#28
0
文件: BFS2.cs 项目: martugin/tetris
        private IEnumerable<List<int>> EnumeratePreparationMoves(CombineType combineType)
        {
            var moves = new List<int>();
            if (combineType != CombineType.MoveDownAppend)
            {
                yield return moves;
            }

            if (combineType != CombineType.Overlap)
            {
                int maxDepth = 10; //_field.Width  + 5;
                int[] firstMoves = combineType == CombineType.Append ? NON_DOWN_MOVES : DOWN_MOVES;

                var visited = new HashSet<UnitState>();

                var stack = new List<MoveInfo>();
                foreach (int firstMove in firstMoves)
                {
                    var unitState = new UnitState(new Cell(0, 0), 0);
                    UnitState newState = UnitState.MoveFuncs[firstMove](unitState);
                    newState.Normalize(_unit);
                    if (visited.Contains(newState))
                        continue;
                    visited.Add(newState);

                    stack.Add(new MoveInfo { Move = firstMove, NextMoveIdx = -1, UnitState = newState });
                    moves.Add(firstMove);

                    while (stack.Count > 0)
                    {
                        var moveInfo = stack[stack.Count - 1];

                        if (moveInfo.NextMoveIdx == -1)
                            yield return moves;

                        ++moveInfo.NextMoveIdx;
                        if (moveInfo.NextMoveIdx < NON_DOWN_MOVES.Length && stack.Count < maxDepth)
                        {
                            int move = NON_DOWN_MOVES[moveInfo.NextMoveIdx];
                            newState = UnitState.MoveFuncs[move](moveInfo.UnitState);
                            newState.Normalize(_unit);
                            if (visited.Contains(newState))
                                continue;
                            visited.Add(newState);
                            stack.Add(new MoveInfo { Move = move, NextMoveIdx = -1, UnitState = newState });
                            moves.Add(move);
                        }
                        else
                        {
                            stack.RemoveAt(stack.Count - 1);
                            moves.RemoveAt(moves.Count - 1);
                        }
                    }
                }
            }
        }
示例#29
0
 public static UnitState MoveSW(UnitState state)
 {
     return new UnitState(Moves.MoveSW(state.Pivot), state.Rotation);
 }
示例#30
0
        public void TestUpdate()
        {
            var f = new Field(2, 2);
            var u = new Unit(new[] {new Cell(0, 0)}, new Cell(0, 0));
            var us = new UnitState(new Cell(1, 1), 0);
            Assert.AreEqual(2, f.MinFilledRow);
            f.Update(u, us);
            Assert.AreEqual(true, f[1][1]);
            Assert.AreEqual(false, f[1][0]);
            Assert.AreEqual(1, f.MinFilledRow);
            Assert.IsTrue(f.RowCells(1).Contains(1));
            Assert.IsFalse(f.RowCells(1).Contains(0));
            Assert.AreEqual(f.RowCells(1).Count, 1);
            Assert.IsFalse(f.RowCells(0).Contains(0));
            Assert.IsFalse(f.RowCells(0).Contains(1));
            Assert.AreEqual(f.RowCells(0).Count, 0);
            Assert.AreEqual(1, f.Score);

            u = new Unit(new[] { new Cell(0, 0), new Cell(1, 0), new Cell(0, 1) }, new Cell(0, 0));
            us = new UnitState(new Cell(0, 0), 0);
            f.Update(u, us);
            Assert.AreEqual(false, f[0][0]);
            Assert.AreEqual(false, f[0][1]);
            Assert.AreEqual(false, f[1][0]);
            Assert.AreEqual(false, f[1][1]);
            Assert.AreEqual(2, f.MinFilledRow);
            Assert.IsFalse(f.RowCells(1).Contains(1));
            Assert.IsFalse(f.RowCells(1).Contains(0));
            Assert.IsFalse(f.RowCells(0).Contains(0));
            Assert.IsFalse(f.RowCells(0).Contains(1));
            Assert.AreEqual(304, f.Score);

            u = new Unit(new[] { new Cell(0, 0), new Cell(1, 0), new Cell(0, 1), new Cell(1, 1) }, new Cell(0, 0));
            us = new UnitState(new Cell(0, 0), 0);
            f.Update(u, us);
            Assert.AreEqual(false, f[0][0]);
            Assert.AreEqual(false, f[0][1]);
            Assert.AreEqual(false, f[1][0]);
            Assert.AreEqual(false, f[1][1]);
            Assert.AreEqual(2, f.MinFilledRow);
            Assert.IsFalse(f.RowCells(1).Contains(1));
            Assert.IsFalse(f.RowCells(1).Contains(0));
            Assert.IsFalse(f.RowCells(0).Contains(0));
            Assert.IsFalse(f.RowCells(0).Contains(1));
            Assert.AreEqual(638, f.Score);

            u = new Unit(new[] {new Cell(1, 0), new Cell(0, 1), new Cell(1, 1) }, new Cell(0, 0));
            us = new UnitState(new Cell(0, 0), 0);
            f.Update(u, us);
            Assert.AreEqual(false, f[0][0]);
            Assert.AreEqual(false, f[0][1]);
            Assert.AreEqual(false, f[1][0]);
            Assert.AreEqual(true, f[1][1]);
            Assert.AreEqual(1, f.MinFilledRow);
            Assert.IsTrue(f.RowCells(1).Contains(1));
            Assert.IsFalse(f.RowCells(1).Contains(0));
            Assert.IsFalse(f.RowCells(0).Contains(0));
            Assert.IsFalse(f.RowCells(0).Contains(1));
            Assert.AreEqual(751, f.Score);

            u = new Unit(new[] { new Cell(0, 0), new Cell(1, 0) }, new Cell(0, 0));
            us = new UnitState(new Cell(0, 0), 0);
            f.Update(u, us);
            Assert.AreEqual(false, f[0][0]);
            Assert.AreEqual(false, f[0][1]);
            Assert.AreEqual(false, f[1][0]);
            Assert.AreEqual(true, f[1][1]);
            Assert.AreEqual(1, f.MinFilledRow);
            Assert.IsTrue(f.RowCells(1).Contains(1));
            Assert.IsFalse(f.RowCells(1).Contains(0));
            Assert.IsFalse(f.RowCells(0).Contains(0));
            Assert.IsFalse(f.RowCells(0).Contains(1));
            Assert.AreEqual(853, f.Score);

            Assert.AreEqual(13, f.TotalBricks);
            Assert.AreEqual(2, f.RowsKilled[1]);
            Assert.AreEqual(2, f.RowsKilled[2]);
        }