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); }
/// <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; } }
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; }
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]; }
/// <inheritdoc /> public HeuristicPolicy(ActionGenerator heuristic, int numActions) { m_Heuristic = heuristic; m_numActions = numActions; }
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(); }
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(); }
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); }