public void PopulateAchievableStates()
        {
            // Set of moves based on actions' rules
            var jointActions = ActionGenerator.GenerateAllPossibleActions(AgentsPositions.Keys.ToList());

            foreach (var jointAction in jointActions)
            {
                var state = (State)Clone();
                var successfulActionsAppliedCounter = 0;

                foreach (var action in jointAction)
                {
                    // Is the action applicable on the map?
                    if (action.IsApplicable(state.Map, AgentsPositions[action.Agent]))
                    {
                        state = action.CreateStateWithAppliedAction(state, AgentsPositions[action.Agent]);
                        successfulActionsAppliedCounter++;
                    }
                    else
                    {
                        break;
                    }
                }

                if (successfulActionsAppliedCounter.Equals(jointAction.Count))
                {
                    AchievableStates.Add(state);
                }
            }
        }
        private (bool isReachable, Box closestBox) CheckIfGoalReachable(Goal goal, HashSet <Goal> otherUnprioritizedGoals, HashSet <Box> matchedBoxesSet)
        {
            var visited = new bool[level.Rows, level.Columns];

            visited[goal.Position.X, goal.Position.Y] = true;

            var Q = new Queue <Position>();

            Q.Enqueue(goal.Position);

            while (Q.Any())
            {
                var position = Q.Dequeue();

                foreach (var direction in ActionGenerator.AllDirections)
                {
                    var boxPosition = ActionGenerator.GeneratePositionFromDirection(position, direction);

                    // Check if in bounds
                    if (boxPosition.X < 0 || boxPosition.X >= level.Rows || boxPosition.Y < 0 || boxPosition.Y >= level.Columns)
                    {
                        continue;
                    }

                    if (!visited[boxPosition.X, boxPosition.Y])
                    {
                        var @object    = level.Map[boxPosition.X, boxPosition.Y];
                        var goalObject = level.GoalsMap[boxPosition.X, boxPosition.Y];

                        // Return if the goal is reachable
                        if (@object is Box box && box.Symbol == goal.Symbol && !matchedBoxesSet.Contains(box))
                        {
                            return(true, box);
                        }

                        // what if @object is an Agent?
                        if (@object is Wall)
                        {
                            continue;
                        }

                        if (goalObject is Goal potentialUnprioritizedGoal &&
                            otherUnprioritizedGoals.Contains(potentialUnprioritizedGoal))
                        {
                            continue;
                        }

                        visited[boxPosition.X, boxPosition.Y] = true;
                        Q.Enqueue(boxPosition);
                    }
                }
            }

            return(false, null);
        }
Esempio n. 3
0
        /// <summary>
        /// Calculates distances from all positions to all goals
        /// </summary>
        private void CalculateDistancesToGoals()
        {
            DistancesToGoal = new Dictionary <Goal, int[, ]>();

            foreach (var goal in Level.AllGoals)
            {
                // Omit if there aren't any boxes for the goal
                if (!Level.Boxes.Any(box => box.Symbol == goal.Symbol))
                {
                    continue;
                }

                var distances = new int[Level.Rows, Level.Columns];

                for (var i = 0; i < Level.Rows; i++)
                {
                    for (var j = 0; j < Level.Columns; j++)
                    {
                        distances[i, j] = int.MaxValue;
                    }
                }

                distances[goal.Position.X, goal.Position.Y] = 0;

                var Q = new Queue <Position>();
                Q.Enqueue(goal.Position);

                while (Q.Any())
                {
                    var position = Q.Dequeue();

                    foreach (var direction in ActionGenerator.AllDirections)
                    {
                        var boxPosition = ActionGenerator.GeneratePositionFromDirection(position, direction);

                        // check if in bounds
                        if (boxPosition.X < 0 || boxPosition.X >= Level.Rows || boxPosition.Y < 0 || boxPosition.Y >= Level.Columns)
                        {
                            continue;
                        }

                        if (distances[boxPosition.X, boxPosition.Y] == int.MaxValue)
                        {
                            if (!(Level.Map[boxPosition.X, boxPosition.Y] is Wall))
                            {
                                distances[boxPosition.X, boxPosition.Y] = distances[position.X, position.Y] + 1;
                                Q.Enqueue(boxPosition);
                            }
                        }
                    }
                }

                DistancesToGoal[goal] = distances;
            }
        }
Esempio n. 4
0
 public ActionReactionProcessor(
     ActionGenerator actionGenerator,
     EventDetectorProcessor eventDetectorProcessor,
     IChatEmoteSoundProcessor chatEmoteSoundProcessor,
     IWaypointProcessor waypointsProcessor,
     IUnitPositionFollower unitPositionFollower,
     IUpdateObjectFollower updateObjectFollower,
     IPlayerGuidFollower playerGuidFollower,
     IAuraSlotTracker auraSlotTracker)
 {
     this.actionGenerator         = actionGenerator;
     this.eventDetectorProcessor  = eventDetectorProcessor;
     this.chatEmoteSoundProcessor = chatEmoteSoundProcessor;
     this.waypointsProcessor      = waypointsProcessor;
     this.unitPositionFollower    = unitPositionFollower;
     this.updateObjectFollower    = updateObjectFollower;
     this.playerGuidFollower      = playerGuidFollower;
     this.auraSlotTracker         = auraSlotTracker;
 }
Esempio n. 5
0
        public void DefaultPolicyTest()
        {
            var game = new GameInstance(3);

            var ability1 = new AbilityInfo(1, 1, 1, 0);
            var a1       = game.AddAbilityWithInfo(ability1);

            var ability2 = new AbilityInfo(3, 1, 1, 0);
            var a2       = game.AddAbilityWithInfo(ability2);

            var abilities1 = new List <int>();
            var abilities2 = new List <int> {
                a1,
                a2
            };

            var info1 = new MobInfo(TeamColor.Red, 5, 1, 0, abilities1);
            var info2 = new MobInfo(TeamColor.Blue, 5, 1, 1, abilities2);

            game.AddMobWithInfo(info1);
            game.AddMobWithInfo(info2);
            game.PrepareEverything();

            Assert.IsFalse(game.IsFinished);

            var uct    = new UctAlgorithm(100);
            var result = UctAlgorithm.DefaultPolicy(game, TeamColor.Red);

            Assert.AreEqual(0, result);
            ActionEvaluator.FNoCopy(game, UctAction.EndTurnAction());

            Assert.AreEqual(TeamColor.Blue, game.CurrentTeam);

            var bestAction = ActionGenerator.DefaultPolicyAction(game);

            Console.WriteLine($"Best: {bestAction}");

            var node = uct.UctSearch(game);

            Console.WriteLine(node);
        }
        public override List <List <Action> > Solve()
        {
            // Thoughts:
            // Goal pull distance doesn't work well when there are a lot of boxes.

            var actions = new List <Action>();

            var(found, goalsPrioritized, goalsUnprioritized) = CalculatePrioritizedGoals(level.AllGoals);
            if (!found)
            {
                var(lockingGoals, otherGoalsPrioritized) = FindLockingGoals(goalsUnprioritized);
                // TODO: What to do with locking goals?
                // Put the locking box as far as possible from both prioritized goals and their boxes?
                // Look at SARiddle.lvl and SALocking2.lvl
                throw new System.NotImplementedException("Whoops, look at those locking goals 🤭");
            }

            var   currentState      = new State(level.Map, level.AgentsPositions, level.BoxesPositions, level.GoalsForBox, level.AllGoals);
            State lastSolutionState = null;

            frontierSet = new HashSet <State>(new StateEqualityComparer());

            foreach (var goal in goalsPrioritized)
            {
                // 1. Get to the target box.
                // 2. Get to the target goal.
                // 3. Continue.

                var heuristic      = new AStar(level, new PrioritizeHeuristic(goal));
                var exploredStates = new HashSet <State>(new StateEqualityComparer());

                if (frontier == null)
                {
                    frontier = new PriorityQueue <State>(new StateHeuristicComparer(heuristic));
                    AddToFrontier(currentState);
                }
                else
                {
                    frontier.SetComparer(heuristic);
                }

                var solutionFound = false;

                while (!solutionFound)
                {
                    // If frontier is empty, then no solution was found
                    if (frontier.IsEmpty())
                    {
                        break;
                    }

                    // Get the next state
                    currentState = RemoveFromFrontier();

                    // Check if we reached the box
                    if (goal.IsBoxGoal)
                    {
                        var boxFound = false;

                        // Is the box within any direction from the agent?
                        foreach (var direction in ActionGenerator.AllDirections)
                        {
                            var possibleBoxPosition = ActionGenerator.GeneratePositionFromDirection(currentState.AgentPosition, direction);
                            var goalPosition        = currentState.BoxesPositions[goal.BoxForGoal];
                            if (goalPosition.Equals(possibleBoxPosition))
                            {
                                boxFound = true;
                                break;
                            }
                        }

                        if (boxFound)
                        {
                            solutionFound     = true;
                            lastSolutionState = currentState;
                        }
                    }
                    // Check if we reached the goal
                    else if (currentState.Map[goal.Position.X, goal.Position.Y] is Box box && box.Symbol == goal.Symbol)
                    {
                        solutionFound     = true;
                        lastSolutionState = currentState;
                    }

                    // Mark state as visited
                    exploredStates.Add(currentState);

                    // If solution for the current goal found
                    if (solutionFound)
                    {
                        frontier.Clear();
                        frontierSet.Clear();
                        // lastSolutionState.Print();

                        if (!goal.IsBoxGoal)
                        {
                            var stateWithFixedGoal = lastSolutionState.WithFixedGoal(goal);
                            // stateWithFixedGoal.Print();
                            AddToFrontier(stateWithFixedGoal);
                        }
                    }

                    // Add achievable and unvisited nodes to frontier
                    currentState.PopulateAchievableStates();
                    foreach (var state in currentState.AchievableStates)
                    {
                        if (LeadsToBlock(state))
                        {
                            state.Penalty += 100000;
                        }

                        if (!exploredStates.Contains(state) && !frontierSet.Contains(state))
                        {
                            AddToFrontier(state);
                        }
                    }
                }
            }

            return(new List <List <Action> >()
            {
                lastSolutionState.ActionsUsedToReachState
            });
        }
 /// <inheritdoc />
 public HeuristicPolicy(ActionGenerator heuristic, int numActions)
 {
     m_Heuristic    = heuristic;
     m_numActions   = numActions;
     m_LastDecision = new float[m_numActions];
 }
Esempio n. 8
0
 /// <inheritdoc />
 public HeuristicPolicy(ActionGenerator heuristic, int numActions)
 {
     m_Heuristic  = heuristic;
     m_numActions = numActions;
 }
Esempio n. 9
0
        public void TestRandomActions2()
        {
            var actionGenerator = new ActionGenerator();
            var rndIndex        = new System.Random();
            var rndNewNumber    = new System.Random();

            var list = new PartitionableList <int>();

            var part1 = list.CreatePartialView(Condition1);
            var part2 = list.CreatePartialView(Condition2);
            var part3 = list.CreatePartialView(Condition3);

            var maxTimeToRun = TimeSpan.FromSeconds(1);
            var watch        = new System.Diagnostics.Stopwatch();

            watch.Start();
            var  actionStatistics     = new int[6];
            long accumulatedListCount = 0;
            int  maxListCount         = 0;

            int numberOfActionsTested = 0;

            for (; watch.Elapsed < maxTimeToRun; ++numberOfActionsTested)
            {
                var action = actionGenerator.GetNextAction(list);
                ++actionStatistics[(int)action];
                int idx, idx2;
                int newNumber;
                int?oldItem = null;

                switch (action)
                {
                case ListAction.Clear:
                    part1.Clear();
                    Assert.AreEqual(0, part1.Count);

                    idx = rndIndex.Next(5);
                    if (idx == 0)
                    {
                        list.Clear();
                        idx = rndIndex.Next(10);
                        for (int i = 0; i < idx; ++i)
                        {
                            list.Add(rndNewNumber.Next(100)); // add some numbers to the parent list that not neccessarily fullfil the criterion of part1
                        }
                    }

                    break;

                case ListAction.RemoveAt:
                    if (part1.Count > 0)
                    {
                        var oldCount = part1.Count;
                        idx     = rndIndex.Next(part1.Count);
                        oldItem = part1[idx];
                        part1.RemoveAt(idx);
                        Assert.AreEqual(oldCount - 1, part1.Count);
                    }
                    break;

                case ListAction.Add:
                {
                    var oldCount = part1.Count;
                    part1.Add(newNumber = 3 * rndNewNumber.Next(100));
                    Assert.AreEqual(oldCount + 1, part1.Count);
                    Assert.AreEqual(newNumber, part1[part1.Count - 1]);
                }
                break;

                case ListAction.InsertAt:
                {
                    var oldCount = part1.Count;
                    idx = rndIndex.Next(part1.Count + 1);
                    part1.Insert(idx, newNumber = 3 * rndNewNumber.Next(100));
                    Assert.AreEqual(oldCount + 1, part1.Count);
                    Assert.AreEqual(newNumber, part1[idx]);
                }
                break;

                case ListAction.Set:
                    if (part1.Count > 0)
                    {
                        var oldCount = part1.Count;
                        idx        = rndIndex.Next(part1.Count);
                        part1[idx] = (newNumber = 3 * rndNewNumber.Next(100));
                        Assert.AreEqual(oldCount, part1.Count);
                        Assert.AreEqual(newNumber, part1[idx]);
                    }
                    break;

                case ListAction.Move:
                    if (part1.Count > 0)
                    {
                        var oldCount = part1.Count;
                        idx     = rndIndex.Next(part1.Count);
                        idx2    = rndIndex.Next(part1.Count);
                        oldItem = part1[idx];
                        part1.Move(idx, idx2);
                        Assert.AreEqual(oldCount, part1.Count);
                        Assert.AreEqual(oldItem, part1[idx2]);
                    }
                    break;

                default:
                    break;
                }

                accumulatedListCount += list.Count;
                maxListCount          = Math.Max(maxListCount, list.Count);

                bool succ1 = IsOrderingTestSuccessfull(list, part1, Condition1);
                bool succ2 = IsOrderingTestSuccessfull(list, part2, Condition2);
                bool succ3 = IsOrderingTestSuccessfull(list, part3, Condition3);

                if (!succ1)
                {
                }
                if (!succ2)
                {
                }
                if (!succ3)
                {
                }

                Assert.IsTrue(succ1);
                Assert.IsTrue(succ2);
                Assert.IsTrue(succ3);
            }

            double averageListCount = accumulatedListCount / numberOfActionsTested;

            watch.Stop();
        }
Esempio n. 10
0
        public void TestRandomActions1()
        {
            var actionGenerator = new ActionGenerator();
            var rndIndex        = new System.Random();
            var rndNewNumber    = new System.Random();

            var list = new PartitionableList <int>();

            var part1 = list.CreatePartialView(Condition1);
            var part2 = list.CreatePartialView(Condition2);
            var part3 = list.CreatePartialView(Condition3);

            var maxTimeToRun = TimeSpan.FromSeconds(1);
            var watch        = new System.Diagnostics.Stopwatch();

            watch.Start();
            var  actionStatistics     = new int[Enum.GetValues(typeof(ListAction)).Length];
            long accumulatedListCount = 0;
            int  maxListCount         = 0;

            int numberOfActionsTested = 0;

            for (; watch.Elapsed < maxTimeToRun; ++numberOfActionsTested)
            {
                var action = actionGenerator.GetNextAction(list);
                ++actionStatistics[(int)action];
                int idx;
                int idx2;
                int newNumber;
                int?oldItem = null;

                switch (action)
                {
                case ListAction.Clear:
                    list.Clear();
                    Assert.AreEqual(0, list.Count);
                    break;

                case ListAction.RemoveAt:
                    if (list.Count > 0)
                    {
                        var oldCount = list.Count;
                        idx     = rndIndex.Next(list.Count);
                        oldItem = list[idx];
                        list.RemoveAt(idx);
                        Assert.AreEqual(oldCount - 1, list.Count);
                    }
                    break;

                case ListAction.Add:
                {
                    var oldCount = list.Count;
                    list.Add(newNumber = rndNewNumber.Next(100));
                    Assert.AreEqual(oldCount + 1, list.Count);
                    Assert.AreEqual(newNumber, list[list.Count - 1]);
                }
                break;

                case ListAction.InsertAt:
                {
                    var oldCount = list.Count;
                    idx = rndIndex.Next(list.Count + 1);
                    list.Insert(idx, newNumber = rndNewNumber.Next(100));
                    Assert.AreEqual(oldCount + 1, list.Count);
                    Assert.AreEqual(newNumber, list[idx]);
                }
                break;

                case ListAction.Set:
                    if (list.Count > 0)
                    {
                        var oldCount = list.Count;
                        idx       = rndIndex.Next(list.Count);
                        oldItem   = list[idx];
                        list[idx] = (newNumber = rndNewNumber.Next(100));
                        Assert.AreEqual(oldCount, list.Count);
                        Assert.AreEqual(newNumber, list[idx]);
                    }
                    break;

                case ListAction.Move:
                    if (list.Count > 0)
                    {
                        var oldCount = list.Count;
                        idx     = rndIndex.Next(list.Count);
                        idx2    = rndIndex.Next(list.Count);
                        oldItem = list[idx];
                        list.Move(idx, idx2);
                        Assert.AreEqual(oldCount, list.Count);
                        Assert.AreEqual(oldItem, list[idx2]);
                    }
                    break;

                default:
                    break;
                }

                accumulatedListCount += list.Count;
                maxListCount          = Math.Max(maxListCount, list.Count);

                bool succ1 = IsOrderingTestSuccessfull(list, part1, Condition1);
                bool succ2 = IsOrderingTestSuccessfull(list, part2, Condition2);
                bool succ3 = IsOrderingTestSuccessfull(list, part3, Condition3);

                if (!succ1)
                {
                }
                if (!succ2)
                {
                }
                if (!succ3)
                {
                }

                Assert.IsTrue(succ1);
                Assert.IsTrue(succ2);
                Assert.IsTrue(succ3);
            }

            double averageListCount = accumulatedListCount / numberOfActionsTested;

            watch.Stop();
        }
Esempio n. 11
0
        protected override CommandDictionary <CommandCode> GetDictionary()
        {
            var d = new CommandDictionary <CommandCode>();

            Action <CommandCode, Predicate <int>, CodeAdder> add = (code, predicate, action) =>
                                                                   d[(byte)code] = new CommandRecord <CommandCode>(predicate, action((byte)code));

            // TODO: commands here
            add(CommandCode.CPU_Status, eq(4), sync(raw => new CPUStatusReply(raw[1], raw[2])));
            // strangely 4 bytes
            add(CommandCode.HVE, eq(4), sync(raw => new HighVoltagePermittedStatusReply(raw[2] == 0 ? true : false)));
            add(CommandCode.PRGE, eq(3), sync(raw => OperationBlockReply.Parse(raw[1])));
            add(CommandCode.TIC_Retransmit, moreeq(28), sync(raw => {
                var expression = new Regex(@"^=V902 ([0-7]);[0-7];[0-9]+;[0-9]+;[0-9]+;([0-4]);([0-4]);([0-4]);([0-9]+);[0-9]+\r$");
                Match match;
                var command = Encoding.ASCII.GetString(trim(raw).ToArray());
                match       = expression.Match(command);
                if (match.Success)
                {
                    GroupCollection groups = match.Groups;
                    var turbo  = groups[1].Value == "4";
                    var relay1 = groups[2].Value == "4";
                    var relay2 = groups[3].Value == "4";
                    var relay3 = groups[4].Value == "4";
                    int alert;
                    try {
                        alert = int.Parse(groups[5].Value);
                    } catch (FormatException) {
                        //error. wrong alert format.
                        alert = 0;
                    }
                    return(new TICStatusReply(turbo, relay1, relay2, relay3, alert));
                }
                else
                {
                    OnErrorCommand(raw, "Wrong TIC status");
                    return(null);
                }
            }));
            add(CommandCode.TIC_GetStatus, moreeq(21), sync(raw => {
                var expression = new Regex(@"^([0-7]);[0-7];[0-9]+;[0-9]+;[0-9]+;([0-4]);([0-4]);([0-4]);([0-9]+);[0-9]+$");
                Match match;
                var command = Encoding.ASCII.GetString(trim(raw).ToArray());
                match       = expression.Match(command);
                if (match.Success)
                {
                    GroupCollection groups = match.Groups;
                    var turbo  = groups[1].Value == "4";
                    var relay1 = groups[2].Value == "4";
                    var relay2 = groups[3].Value == "4";
                    var relay3 = groups[4].Value == "4";
                    int alert;
                    try {
                        alert = int.Parse(groups[5].Value);
                    } catch (FormatException) {
                        //error. wrong alert format.
                        alert = 0;
                    }
                    return(new VacuumStatusReply(turbo, relay1, relay2, relay3, alert));
                }
                else
                {
                    OnErrorCommand(raw, "Wrong TIC status");
                    return(null);
                }
            }));

            add(CommandCode.SEMV1, eq(3), sync(raw => new Valve1Reply(raw[1])));

            add(CommandCode.SEMV2, eq(3), sync(raw => new Valve2Reply(raw[1])));
            add(CommandCode.SEMV3, eq(3), sync(raw => new Valve3Reply(raw[1])));
            add(CommandCode.SPUMP, eq(3), sync(raw => new MicroPumpReply(raw[1])));

            add(CommandCode.SPI_PSIS_SetVoltage, eq(2), sync(raw => new IonSourceSetReply()));
            add(CommandCode.SPI_DPS_SetVoltage, eq(2), sync(raw => new DetectorSetReply()));
            add(CommandCode.SPI_PSInl_SetVoltage, eq(2), sync(raw => new InletSetReply()));
            add(CommandCode.SPI_PSIS_GetVoltage, eq(4), sync(raw => IonSourceGetReply.Parse(trim(raw))));
            add(CommandCode.SPI_DPS_GetVoltage, eq(4), sync(raw => DetectorGetReply.Parse(trim(raw))));
            add(CommandCode.SPI_PSInl_GetVoltage, eq(4), sync(raw => InletGetReply.Parse(trim(raw))));

            add(CommandCode.SPI_Scan_SetVoltage, eq(2), sync(raw => new ScanVoltageSetReply()));
            add(CommandCode.SPI_CP_SetVoltage, eq(2), sync(raw => new CapacitorVoltageSetReply()));

            add(CommandCode.SPI_GetAllVoltages, eq(29), sync(raw => new AllVoltagesReply(trim(raw))));

            add(CommandCode.RTC_StartMeasure, eq(3), sync(raw => new SendMeasureReply(raw[1])));
            add(CommandCode.RTC_DelayedStart, eq(3), sync(raw => new DelayedMeasureReply(raw[1])));
            add(CommandCode.RTC_ReceiveResults, eq(18), sync(raw => new CountsReply(trim(raw))));

            // BAD temporary solution
            ActionGenerator <ServicePacket <CommandCode> > service = gen => (code => (list => {
                switch (list[1])
                {
                case 1:
                case 10:
                    OnSyncErrorReceived(code, gen(list) as SyncError <CommandCode>);
                    break;

                case 20:
                case 21:
                case 22:
                case 23:
                    OnAsyncCommandReceived(code, gen(list) as Async <CommandCode>);
                    break;

                case 30:
                case 31:
                    OnAsyncErrorReceived(code, gen(list) as AsyncError <CommandCode>);
                    break;

                case 41:
                case 42:
                    OnAsyncErrorReceived(code, gen(list) as AsyncError <CommandCode>);
                    break;

                default:
                    break;
                }
            }));

            add(CommandCode.Service_Message, moreeq(3), service(raw => {
                byte code = raw[1];
                switch (code)
                {
                case 1:
                case 10:
                    return(new SyncErrorReply(code));

                case 20:
                case 21:
                case 22:
                    return(LAMEvent.Parse(code));

                case 23:
                    return(LAMEvent.Parse(code, raw[2]));

                case 30:
                case 31:
                    return(new LAMCriticalError(code));

                case 41:
                case 42:
                    return(new LAMInternalError(code));

                default:
                    return(null);
                }
            }));
            //add(CommandCode.Sync_Error, eq(4), syncerr(raw => new SyncErrorReply(raw[1])));

            //add(CommandCode.LAM_Event, eq(3), async(raw => new LAMEvent(raw[1])));

            //add(CommandCode.LAM_CriticalError, eq(3), asyncerr(raw => new LAMCriticalError(raw[1])));
            // TODO: check length!
            //add(CommandCode.LAM_InternalError, eq(3), asyncerr(raw => new LAMInternalError(raw[1])));

            return(d);
        }