public override void Act(Queue <Message> messages) { while (messages.Count > 0 && running) { Message message = messages.Dequeue(); Console.WriteLine("\t[{1} -> {0}]: {2}", this.Name, message.Sender, message.Content); FloorPlanMessage receivedMessage = JsonSerializer.Deserialize <FloorPlanMessage>(message.Content); if (message.Sender == MonitorAgent.Monitor) { HandleMessageFromMonitor(receivedMessage); } else { HandleMessageFromPeer(receivedMessage, message); } blockList = blockList.Select(kvp => new KeyValuePair <int, int>(kvp.Key, kvp.Value - 1)) .Where(kvp => kvp.Value > 0) .ToDictionary( kvp => kvp.Key, kvp => kvp.Value ); // if (state == State.WaitingForPeerResponses) // { // --waitTurns; // if (wa) // } } }
public override void Act(Queue <Message> messages) { while (messages.Count > 0) { Message message = messages.Dequeue(); Console.WriteLine("\t[{1} -> {0}]: {2}", this.Name, message.Sender, message.Content); FloorPlanMessage floorPlanMessage = JsonSerializer.Deserialize <FloorPlanMessage>(message.Content); switch (floorPlanMessage.type) { case Start: HandleStart(message.Sender, floorPlanMessage); break; case MessageType.Move: HandleChangePosition(message.Sender, floorPlanMessage); break; default: break; } guiForm.UpdatePlanetGUI(); } }
private Point PickCandidate(FloorPlanMessage receivedMessageFromMonitor) { Point candidate = null; if (state == State.MovingRandomly) { candidate = MoveRandomly(); } else { if (receivedMessageFromMonitor.exitsInFieldOfViewPositions.Count > 0) { state = State.MovingTowardsExit; candidate = MoveNear(Utils.closestPoint(receivedMessageFromMonitor.exitsInFieldOfViewPositions, this.position)); } else if (receivedMessageFromMonitor.agentsInFieldOfViewPositions.Count > 0) { receivedMessageFromMonitor.agentsInFieldOfViewPositions.ForEach(peerAgent => { var peerQuestionMessage = new FloorPlanMessage(MessageType.PeerQuestion, peerAgent.Position); if (!blockList.ContainsKey(peerAgent.Id) || (blockList.ContainsKey(peerAgent.Id) && blockList[peerAgent.Id] <= 0)) { Send("Worker " + peerAgent.Id, JsonSerializer.Serialize(peerQuestionMessage)); } }); // move in a direction until you get a response // todo: our strategy might not be the best because then we have to handle inconsistencies by getting blocked by the monitor, // but otherwise we need other stateful solution to let time pass (we focused on turns which are linked to messages received, but if we do not // send message to monitor, we don't progress) if (receivedMessageFromMonitor.type == MessageType.Block) { candidate = MoveInOtherDirection(); } else { candidate = MoveInDirection(); } state = State.WaitingForPeerResponses; } else { if (receivedMessageFromMonitor.type == MessageType.Block) { candidate = MoveInOtherDirection(); } else { candidate = MoveInDirection(); } } } return(candidate); }
public override void Setup() { Console.WriteLine("Starting worker " + Id); FloorPlanMessage positionMessage = new FloorPlanMessage(); positionMessage.type = MessageType.Start; positionMessage.position = this.position; Send(MonitorAgent.Monitor, JsonSerializer.Serialize(positionMessage)); }
private void HandleStart(string sender, FloorPlanMessage startMessage) { int senderId = Utils.ParsePeer(sender); WorkerPositions.Add(senderId, startMessage.position); numberOfPositionChanges[senderId] = 0; FloorPlanMessage ackMessage = BuildFloorPlanMessage(MessageType.Acknowledge, WorkerPositions[senderId]); Send(sender, JsonSerializer.Serialize(ackMessage)); }
private FloorPlanMessage BuildFloorPlanMessage(string type, Point position) { var planMessage = new FloorPlanMessage(); planMessage.type = type; planMessage.position = position; planMessage.exitsInFieldOfViewPositions = ExitPositions.Values .Where(exitPosition => InFieldOfView(exitPosition, position)) .ToList(); planMessage.agentsInFieldOfViewPositions = WorkerPositions .Where(agentKvp => InFieldOfView(agentKvp.Value, position) && !agentKvp.Value.Equals(position)) .Select(agentKvp => new AgentSummary(agentKvp.Key, agentKvp.Value)) .ToList(); return(planMessage); }
private void HandleMessageFromPeer(FloorPlanMessage receivedMessage, Message message) { switch (receivedMessage.type) { case MessageType.PeerQuestion: { string messageType = lastReceivedMessageFromMonitor.exitsInFieldOfViewPositions.Count > 0 ? MessageType.PeerAffirmative : MessageType.PeerNegative; // string messageType = PeerNegative; FloorPlanMessage response = new FloorPlanMessage(messageType, lastReceivedMessageFromMonitor.position); Send(message.Sender, JsonSerializer.Serialize(response)); break; } case MessageType.PeerAffirmative: { // todo: following not working right, but deadlock cooldown // is implemented by not asking that agent again for a number of turns if (state == State.WaitingForPeerResponses) { state = State.FollowingOther; var candidate = MoveNear(receivedMessage.position); FloorPlanMessage changePositionMessage = new FloorPlanMessage(MessageType.Move, candidate); Send(MonitorAgent.Monitor, JsonSerializer.Serialize(changePositionMessage)); } break; } case MessageType.PeerNegative: { blockList[Utils.ParsePeer(message.Sender)] = cooldownForTalking; break; } default: throw new NotImplementedException(); } }
private void HandleMessageFromMonitor(FloorPlanMessage receivedMessage) { this.position = receivedMessage.position; switch (receivedMessage.type) { case MessageType.Acknowledge: { var candidate = PickCandidate(receivedMessage); FloorPlanMessage changePositionMessage = new FloorPlanMessage(MessageType.Move, candidate); Send(MonitorAgent.Monitor, JsonSerializer.Serialize(changePositionMessage)); break; } case MessageType.Emergency: { state = State.MovingInConstantDirection; var candidate = PickCandidate(receivedMessage); FloorPlanMessage changePositionMessage = new FloorPlanMessage(MessageType.Move, candidate); Send(MonitorAgent.Monitor, JsonSerializer.Serialize(changePositionMessage)); break; } case MessageType.Block: { Point candidate = PickCandidate(receivedMessage); FloorPlanMessage changePositionMessage = new FloorPlanMessage(MessageType.Move, candidate); Send(MonitorAgent.Monitor, JsonSerializer.Serialize(changePositionMessage)); break; } case Exit: { running = false; break; } default: throw new NotImplementedException(); } lastReceivedMessageFromMonitor = receivedMessage; }
private void HandleChangePosition(string sender, FloorPlanMessage receivedMessage) { int senderId = Utils.ParsePeer(sender); // Block is handled regardless if in emergency or not foreach (int workerId in WorkerPositions.Keys) { if (workerId == senderId) { continue; } if (WorkerPositions[workerId].Equals(receivedMessage.position)) { var blockMessage = BuildFloorPlanMessage(MessageType.Block, WorkerPositions[senderId]); Send(sender, JsonSerializer.Serialize(blockMessage)); return; } } // todo: block if server is congested if (WorkerPositions.ContainsKey(senderId) && Utils.Distance(WorkerPositions[senderId], receivedMessage.position) > 1) { var blockMessage = BuildFloorPlanMessage(MessageType.Block, WorkerPositions[senderId]); Send(sender, JsonSerializer.Serialize(blockMessage)); return; } // Allow the requested move if (!WorkerPositions.ContainsKey(senderId)) { return; } else { WorkerPositions[senderId] = receivedMessage.position; } // Should declare emergency if (++numberOfPositionChanges[senderId] == turnsUntilEmergency) { var emergencyMessage = BuildFloorPlanMessage(MessageType.Emergency, WorkerPositions[senderId]); Send(sender, JsonSerializer.Serialize(emergencyMessage)); return; } // Exit if emergency is declared if (isEmergencyDeclared(senderId) && ExitPositions.Values.Contains(WorkerPositions[senderId])) { var exitMessage = BuildFloorPlanMessage(MessageType.Exit, WorkerPositions[senderId]); Send(sender, JsonSerializer.Serialize(exitMessage)); WorkerPositions.Remove(senderId); this.Environment.Remove(sender); if (WorkerPositions.Count == 0) { this.Stop(); } return; } // Only thing remaining to do is acknowledge the move var moveMessage = BuildFloorPlanMessage(MessageType.Acknowledge, WorkerPositions[senderId]); Send(sender, JsonSerializer.Serialize(moveMessage)); }