コード例 #1
0
        private Tuple <State, BoardUndo> MoveOneStep(Point dir, BoardUndo undo = null)
        {
            var newPosition = Position + dir;

            var item = Board.Get(newPosition);

            if (item == Board.Wall &&
                (DrillTime == 0 || !Board.IsInBounds(newPosition)))
            {
                return(null);
            }

            Position = newPosition;

            undo = undo ?? new BoardUndo();

            if (item == Board.Wall)
            {
                Board.Set(newPosition, Board.Empty, undo);
            }
            else if ("BFLR".Contains(item))
            {
                Boosts = Boosts.ToList();
                Boosts.Add(item);
                Board.Set(newPosition, Board.IsPainted(newPosition) ? Board.Empty : Board.UnpaintedEmpty, undo);
                ++BoostsCollected;
            }

            Paint(undo);

            return(Tuple.Create(this, undo));
        }
コード例 #2
0
 public void Set(Point p, char c, BoardUndo undo)
 {
     if (IsInBounds(p) && Map[p.X, p.Y] != c)
     {
         undo.Points.Add(Tuple.Create(p, Map[p.X, p.Y]));
         Map[p.X, p.Y] = c;
     }
 }
コード例 #3
0
        public BoardUndo Redo(BoardUndo undo)
        {
            var ans = new BoardUndo();

            foreach (var i in undo.Points)
            {
                Set(i.Item1, i.Item2, ans);
            }
            return(ans);
        }
コード例 #4
0
        public BoardUndo GetRedo(BoardUndo undo)
        {
            var ans = new BoardUndo();

            if (undo != null)
            {
                ans.Points = undo.Points
                             .Select(p => Tuple.Create(p.Item1, Map[p.Item1.X, p.Item1.Y]))
                             .ToList();
            }

            return(ans);
        }
コード例 #5
0
        private void Paint(BoardUndo undo)
        {
            var initialCount = undo.Count;

            Board.Paint(Position, undo);
            foreach (var dir in Robot)
            {
                if (Blockers(dir).All(i => !Board.IsWall(Position + i)))
                {
                    Board.Paint(Position + dir, undo);
                }
            }

            UnpaintedCount -= undo.Count - initialCount;
        }
コード例 #6
0
        public static Board GenerateBoard(MapSpecification spec)
        {
            var random = new Random();

            var board = new Board(spec.Size, spec.Size);

            var fill = 100;//  spec.Size * spec.Size / 3;

            var middle = new Point(spec.Size / 2, spec.Size / 2);

            foreach (var p in spec.ExcludePoints)
            {
                board.Set(p, Board.Wall, new BoardUndo());
            }

            foreach (var i in Enumerable.Range(0, fill))
            {
                var allowedPoints = board.AllPoints
                                    .Where(p => !spec.IncludePoints.Contains(p))
                                    .Where(p => !board.IsWall(p) && p.AdjacentPoints().Any(board.IsWall))
                                    .ToList();

                while (allowedPoints.Any())
                {
                    var index       = random.Next() % allowedPoints.Count;
                    var chosenPoint = allowedPoints[index];

                    var undo = new BoardUndo();
                    board.Set(chosenPoint, Board.Wall, undo);

                    if (chosenPoint.AdjacentPoints().All(p =>
                                                         board.IsWall(p) || board.PathFind(p, middle) != null))
                    {
                        break;
                    }

                    board.Undo(undo);
                    allowedPoints.RemoveAt(index);
                }

                if (!allowedPoints.Any())
                {
                    break;
                }
            }

            return(board);
        }
コード例 #7
0
        public void Undo(BoardUndo undo)
        {
            if (undo == null)
            {
                return;
            }

            var reversePoints = undo.Points.ToList();

            reversePoints.Reverse();

            foreach (var i in reversePoints)
            {
                Map[i.Item1.X, i.Item1.Y] = i.Item2;
            }
        }
コード例 #8
0
        public Tuple <State, BoardUndo> AddManipulator(Point where)
        {
            var oldBoard = Board.Clone();

            var newState = CloneNextStep();

            newState.Robot = newState.Robot.ToList();
            newState.Robot.Add(where);
            newState.Boosts = newState.Boosts.ToList();
            newState.Boosts.Remove(Board.Manipulator);

            var undo = new BoardUndo();

            newState.Paint(undo);
            Board = oldBoard;

            return(Tuple.Create(newState, undo));
        }
コード例 #9
0
        public void TestPathFinding()
        {
            var board = new Board(30, 30);
            var undo  = new BoardUndo();

            board.Set(new Point(0, 1), Board.Wall, undo);
            board.Set(new Point(1, 0), Board.Wall, undo);
            var middle     = new Point(15, 15);
            var bottomLeft = new Point(0, 0);
            var topRight   = new Point(29, 29);

            var path = board.PathFind(bottomLeft, middle);

            Assert.IsNull(path);

            path = board.PathFind(topRight, middle);
            Assert.AreEqual(29, path.Count);
            Assert.AreEqual(path.First(), topRight);
            Assert.AreEqual(path.Last(), middle);
        }
コード例 #10
0
        // Returns null if move is possible or state does not change
        // Mutates this.Board -- returns a BoardUndo that can revert the changes
        public Tuple <State, BoardUndo> Move(char move)
        {
            State     newState;
            BoardUndo undo = null;

            switch (move)
            {
            case 'W':     // up
                return(Move(new Point(0, 1)));

            case 'S':     // down
                return(Move(new Point(0, -1)));

            case 'A':     // left
                return(Move(new Point(-1, 0)));

            case 'D':     // right
                return(Move(new Point(1, 0)));

            case 'E':     // CW
            case 'Q':     // CCW
                newState       = CloneNextStep();
                newState.Robot = newState.Robot
                                 .Select(p => move == 'E' ? p.RotateRight() : p.RotateLeft())
                                 .ToList();
                newState.Direction = (newState.Direction + (move == 'E' ? 1 : 3)) % 4;
                undo = new BoardUndo();
                newState.Paint(undo);
                return(Tuple.Create(newState, undo));

            case 'F':     // fast wheels
                if (!Boosts.Any(i => i == Board.FastWheels))
                {
                    return(null);
                }

                newState = CloneNextStep();
                newState.FastWheelsTime = Math.Max(newState.FastWheelsTime + 50, 50);
                newState.Boosts         = newState.Boosts.ToList();
                newState.Boosts.Remove(Board.FastWheels);
                return(Tuple.Create(newState, undo));

            case 'L':     // drill
                if (!Boosts.Any(i => i == Board.Drill))
                {
                    return(null);
                }

                newState           = CloneNextStep();
                newState.DrillTime = Math.Max(newState.DrillTime + 30, 30);
                newState.Boosts    = newState.Boosts.ToList();
                newState.Boosts.Remove(Board.Drill);
                return(Tuple.Create(newState, undo));

            case 'R':     // teleport
                if (!Boosts.Any(i => i == Board.Teleport))
                {
                    return(null);
                }

                newState        = CloneNextStep();
                newState.Boosts = newState.Boosts.ToList();
                newState.Boosts.Remove(Board.Teleport);
                newState.Teleports = newState.Teleports.ToList();
                newState.Teleports.Add(Position);
                return(Tuple.Create(newState, (BoardUndo)null));

            case 'Z':
                return(Tuple.Create(CloneNextStep(), (BoardUndo)null));
            }

            return(null);
        }
コード例 #11
0
 public void Paint(Point p, BoardUndo undo)
 {
     Set(p, char.ToUpperInvariant(Get(p)), undo);
 }