Пример #1
0
        /// <summary>
        /// Run the simulations and save result to ViewState and JS script block
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnRunSimulations_OnClick(object sender, EventArgs e)
        {
            var deck = new Deck();
            List<int> position = Request.Form["robotPosition"].Split(',').Select(int.Parse).ToList();
            var cards = Request.Form["cards"].Split(',').Select(x => GetCardPriority(deck, x));

            var robot = new Robot
            {
                Position = new Coordinate {X = position[0], Y = position[1]},
                Facing = (Orientation)Enum.Parse(typeof(Orientation), Request.Form["robotOrientation"])
            };

            foreach (var priority in cards)
            {
                robot.DealCard(priority);
            }

            var map = MapParser.JsonToMap(LoadMapJson("~/Maps/ScottRallyMap.rrdl"));

            var game = new Game(new Map {Squares = map}, new List<Robot> {robot});
            game.Initialize();

            List<List<CardExecutionResult>> results = Simulator.Simulate(robot);
            List<List<CardExecutionResult>> productiveResults = results.Where(result => result.Last().Position.X != -1).ToList();

            ViewState["PosX"] = position[0];
            ViewState["PosY"] = position[1];
            ViewState["Facing"] = Request.Form["robotOrientation"];
            ViewState["Cards"] = Request.Form["cards"];

            ClientScript.RegisterClientScriptBlock(GetType(), "results", "results = " + JsonConvert.SerializeObject(productiveResults, Formatting.Indented), true);
        }
Пример #2
0
        public void Convey(Robot robot)
        {
            // Convey the robot a single square
            Coordinate target = robot.Position;

            if (Exit == Orientation.Bottom)
                target.Y += 1;
            else if (Exit == Orientation.Top)
                target.Y -= 1;
            else if (Exit == Orientation.Left)
                target.X -= 1;
            else
                target.X += 1;

            ITile targetTile = robot.Game.Board.GetTile(target);
            if (targetTile == null || targetTile is Pit)
            {
                // Robot conveyed off the board or into a pit
                robot.Position = new Coordinate {X = -1, Y = -1};
                return;
            }

            var conveyer = targetTile as Conveyer;
            if (conveyer != null)
            {
                Rotation rotation = conveyer.ConveyerRotation(Utilities.GetOppositeOrientation(Exit));
                if (rotation == Rotation.Clockwise)
                    robot.RotateRight();
                else if (rotation == Rotation.CounterClockwise)
                    robot.RotateLeft();
            }

            robot.Position = target;
        }
Пример #3
0
 public void Rotate(Robot robot)
 {
     if (Direction == Rotation.Clockwise)
         robot.RotateRight();
     else
         robot.RotateLeft();
 }
Пример #4
0
        protected void btnRunSimulations_OnClick(object sender, EventArgs e)
        {
            List<int> position = Request.Form["robotPosition"].Split(',').Select(int.Parse).ToList();
            var cards = Request.Form["cards"].Split(',').Select(int.Parse);

            var robot = new Robot
            {
                Position = new Coordinate {X = position[0], Y = position[1]},
                Facing = (Orientation)Enum.Parse(typeof(Orientation), Request.Form["robotOrientation"])
            };
            foreach (var c in cards)
            {
                robot.DealCard(c);
            }

            var game = new Game { Board = { Squares = Maps.GetMap(Maps.MapLayouts.ScottRallyMap) }, Robots = new List<Robot> { robot } };
            game.Initialize();

            List<List<CardExecutionResult>> results = Simulator.RunSimulations(robot);
            List<List<CardExecutionResult>> productiveResults = results.Where(result => result.Last().Position.X != -1).ToList();

            ViewState["PosX"] = position[0];
            ViewState["PosY"] = position[1];
            ViewState["Facing"] = Request.Form["robotOrientation"];
            ViewState["Cards"] = Request.Form["cards"];

            ClientScript.RegisterClientScriptBlock(GetType(), "results", "results = " + JsonConvert.SerializeObject(productiveResults, Formatting.Indented), true);
        }
Пример #5
0
        public static string RunSimulations(string body)
        {
            JToken json = JToken.Parse(body);

            var deck = new Deck();
            IEnumerable<int> cards = json["cards"].ToString().Split(',').Select(x => GetCardPriority(deck, x));
            List<int> robotPosition = json["robotPosition"].ToString().Split(',').Select(int.Parse).ToList();
            string robotOrientation = json["robotOrientation"].ToString();

            var robot = new Robot
            {
                Position = new Coordinate { X = robotPosition[0], Y = robotPosition[1] },
                Facing = (Orientation)Enum.Parse(typeof(Orientation), robotOrientation)
            };

            foreach (var priority in cards)
            {
                robot.DealCard(priority);
            }

            var map = MapParser.JsonToMap(LoadMapJson(ActiveMap));

            var game = new Game(new Map { Squares = map }, new List<Robot> { robot });
            game.Initialize();

            List<List<CardExecutionResult>> results = Simulator.Simulate(robot);
            List<List<CardExecutionResult>> productiveResults = results.Where(result => result.Last().Position.X != -1).ToList();

            return JsonConvert.SerializeObject(productiveResults, Formatting.Indented);
        }
Пример #6
0
        public void Push(Robot robot, int register)
        {
            if (!Registers.Contains(register))
                return;

            Coordinate target = robot.Position;
            var floorTile = robot.Game.Board.Tile<Floor>(robot.Position);

            if (floorTile == null)
                return;

            foreach (var edge in floorTile.Edges)
            {
                if (edge.Item2 == this)
                {
                    if (edge.Item1 == Orientation.Top)
                        target.Y += 1;
                    else if (edge.Item1 == Orientation.Bottom)
                        target.Y -= 1;
                    else if (edge.Item1 == Orientation.Left)
                        target.X += 1;
                    else
                        target.X -= 1;

                    if (floorTile.GetEdge(Utilities.GetOppositeOrientation(edge.Item1)) != null)
                    {
                        // There is an opposite edge. I'm not exactly sur ewhat is supposed to happen. Most likely just not move
                        return;
                    }

                    ITile targetTile = robot.Game.Board.Tile(target);
                    if (targetTile == null || targetTile is Pit)
                    {
                        // pushed to death;
                        robot.Position = Coordinate.OutOfBounds;
                        return;
                    }

                    var targetFloor = (Floor) targetTile;
                    if (targetFloor.GetEdge(edge.Item1) != null)
                    {
                        // blocked from entering!
                        return;
                    }

                    robot.Position = target;

                    return;
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Runs simulations on moves based on the cards the robot currently has assigned. 
        /// Robot is expected to be initialized and part of an existing Game.
        /// The robot will not be in the same state after simulation is executed.
        /// </summary>
        /// <param name="robot">Robot to run simulations for</param>
        /// <returns>List of results</returns>
        public static List<List<CardExecutionResult>> Simulate(Robot robot)
        {
            var results = new List<List<CardExecutionResult>>();
            List<List<ProgramCardType>> permutations = CalculateMovePermutations(robot);
            Coordinate position = robot.Position;
            Orientation facing = robot.Facing;

            foreach (var permutation in permutations)
            {
                robot.Position = position;
                robot.Facing = facing;
                robot.Damage = 0;
                robot.PickUpCards();

                var deck = new Deck();
                var permutationResult = new List<CardExecutionResult>();
                for (int i = 0 ; i < permutation.Count; ++i)
                {
                    var card = deck.GetCard(permutation[i]);
                    robot.DealCard(card.Priority, i + 1);
                }

                robot.Game.StartTurn(false /* Deal Cards */);
                int previousDamage = 0;

                while (true)
                {
                    int registersLeft = robot.Game.ExecuteNextRegister();

                    permutationResult.Add(new CardExecutionResult
                    {
                        Card = permutation[permutationResult.Count],
                        Position = robot.Position,
                        Facing = robot.Facing,
                        Damage = robot.Damage - previousDamage
                    });

                    previousDamage = robot.Damage;

                    if (registersLeft == 0)
                        break;
                }

                robot.Game.EndTurn();

                results.Add(permutationResult);
            }

            return results;
        }
Пример #8
0
        /// <summary>
        /// Calculate all possible move permutations given a robots set of cards
        /// </summary>
        /// <param name="robot">Robot</param>
        /// <returns>List of permutations</returns>
        internal static List<List<ProgramCardType>> CalculateMovePermutations(Robot robot)
        {
            var permutations = new List<List<ProgramCardType>>();

            // This is the list of cards that can be placed. Locked registers are not included in this list
            // and should be appended to the end of each list if necessary
            IEnumerable<ProgramCardType> cards = robot.CardsToPlace().Select(ProgramCard.GetCardTypeByPriority);
            var root = new PermutationNode();

            BuildCardPermutationTree(root, cards);

            BuildCardPermutationList(permutations, root);

            return permutations;
        }
Пример #9
0
        public void Simulator_CalculateMovePermutations_6UniqueCards()
        {
            // Arrange
            var robot = new Robot();
            robot.DealCard(10);		// UTurn
            robot.DealCard(70);		// RotateLeft
            robot.DealCard(80);		// RotateRight
            robot.DealCard(430);	// BackUp
            robot.DealCard(490);	// Move1
            robot.DealCard(790);	// Move3

            // Act
            var moves = Simulator.CalculateMovePermutations(robot);

            // Assert
            Assert.AreEqual(720, moves.Count);
        }
Пример #10
0
        public void Simulator_CalculateMovePermutations_7Cards_2TypeRepeatedTwice()
        {
            // Arrange
            var robot = new Robot();
            robot.DealCard(10);		// UTurn
            robot.DealCard(20);		// UTurn
            robot.DealCard(70);		// RotateLeft
            robot.DealCard(80);		// RotateRight
            robot.DealCard(430);	// BackUp
            robot.DealCard(490);	// Move1
            robot.DealCard(500);	// Move1

            // Act
            var moves = Simulator.CalculateMovePermutations(robot);

            // Assert
            Assert.AreEqual(690, moves.Count);
        }
Пример #11
0
        public void Simulator_PermutationCounts_7Cards_2TypeRepeatedTwice()
        {
            // Arrange
            var robot = new Robot();
            robot.DealCard(10);		// UTurn
            robot.DealCard(20);		// UTurn
            robot.DealCard(70);		// RotateLeft
            robot.DealCard(80);		// RotateRight
            robot.DealCard(430);	// BackUp
            robot.DealCard(490);	// Move1
            robot.DealCard(500);	// Move1

            // Act
            int permutations = PermutationCounts(robot);

            // Assert
            Assert.AreEqual(630, permutations);
        }
Пример #12
0
        public void Simulator_RunSimulations_7Cards2TypeRepeatedTwice()
        {
            // Arrange
            var robot = new Robot();
            robot.DealCard(10);		// UTurn
            robot.DealCard(20);		// UTurn
            robot.DealCard(70);		// RotateLeft
            robot.DealCard(80);		// RotateRight
            robot.DealCard(430);	// BackUp
            robot.DealCard(490);	// Move1
            robot.DealCard(500);	// Move1
            var game = new Game(new Map {Squares = Maps.GetMap(Maps.MapLayouts.ScottRallyMap)}, new List<Robot> {robot});
            game.Initialize();

            // Act
            List<List<CardExecutionResult>> results = Simulator.Simulate(robot);

            // Assert
            Assert.AreEqual(690, results.Count);
        }
Пример #13
0
        protected void Convey(Robot robot)
        {
            Coordinate target = TargetCoordinate(robot.Position);

            ITile targetTile = robot.Game.Board.Tile(target);
            if (targetTile == null || targetTile is Pit)
            {
                // Robot conveyed off the board or into a pit
                robot.Position = Coordinate.OutOfBounds;
                return;
            }

            var conveyer = targetTile as Conveyer;
            if (conveyer != null)
            {
                Rotation rotation = conveyer.ConveyerRotation(Utilities.GetOppositeOrientation(Exit));
                if (rotation == Rotation.Clockwise)
                    robot.Facing = Utilities.ClockwiseRotation(robot.Facing);
                else if (rotation == Rotation.CounterClockwise)
                    robot.Facing = Utilities.CounterclockwiseRotation(robot.Facing);
            }

            robot.Position = target;
        }
Пример #14
0
        private static int PermutationCounts(Robot robot)
        {
            // BUG: This math does not match our function for calculating permutations. FWIW, I trust the code more than this math.

            // Calculate the number of unique permutations possible with the cards to place.
            // For example, if we need to place the following cards
            // (2) Rotate Left, (1) Rotate Right, (1) Move 1, (1) Move 2 and (2) Move 3
            // Given there are 7 cards to place and the number of cards we need is 5
            // we are calculating P(n,r) where n = 7 and r = 5.
            // Also, given Rotate Left is repeated twice we have x1 = 2 and x2 = 2 for the
            // Move 3 repetitions.
            // Permutations = P(n,r) / (x1!x2!)
            // Permutations = P(7,5) / (2!2!)
            // Permutations = (7! / (7 - 5)!) / (2!2!)
            // Permutations = (5040 / 2) / (4)
            // Permutations = 2520 / 4
            // Permutations = 630

            List<int> cardsToPlace = robot.CardsToPlace().ToList();
            List<ProgramCardType> cardTypesToPlace = cardsToPlace.Select(ProgramCard.GetCardByPriority).ToList();
            int n = cardTypesToPlace.Count();
            int r = Math.Min(n, Constants.RobotRegisters);
            List<Tuple<ProgramCardType, int>> cardDuplicateCounts = Permutations.GetDuplicateItemCounts(cardTypesToPlace).ToList();

            double dividend = (Permutations.Factorial(n) / Permutations.Factorial(n - r));
            double divisor = cardDuplicateCounts.Aggregate<Tuple<ProgramCardType, int>, double>(1, (current, dupe) => current * Permutations.Factorial(dupe.Item2));

            return (int)(dividend / divisor);
        }