/// <summary>Creates a robot, which is placed at a given location with the room.</summary> /// <param name="pt">Where the robot should be placed, in RoomPoint coordinates.</param> void CreateRobot(RoomPoint pt) { // Do nothing if there's already a robot here if (_roomCells[pt.X, pt.Y] != null) { return; } // Create the new robot Robot robot = new Robot() { Location = pt, Element = new Ellipse() { Width = 1.0 / ROOM_SIZE, Height = 1.0 / ROOM_SIZE, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, Fill = new SolidColorBrush(_nextColor) } }; // Set the position of the robot within Room SetRobotElementPosition(robot, pt); // Add the robot to Room Room.Children.Add(robot.Element); // Add the robot to our data structures _robots.Add(robot); _roomCells[pt.X, pt.Y] = robot; // Advance _nextColor to the next color to use MoveNextColor(); }
/// <summary>Performs one step of the simulation for one robot.</summary> /// <param name="r">The robot to perform the simulation step for.</param> void SimulateOneStep(Robot r) { // Set ptR to the location of the robot in room coordinates RoomPoint ptR = r.Location; double vectorX = 0, vectorY = 0; foreach (Robot s in _robots) { if (r == s) { continue; } RoomPoint ptS = s.Location; double inverseSquareDistance = 1.0 / RoomPoint.Square(ptR.DistanceTo(ptS)); double angle = ptR.AngleTo(ptS); vectorX -= inverseSquareDistance * Math.Cos(angle); vectorY -= inverseSquareDistance * Math.Sin(angle); } double degrees = Math.Atan2(vectorY, vectorX) * 180 / Math.PI; degrees += 22.5; while (degrees < 0) { degrees += 360; } while (degrees >= 360) { degrees -= 360; } int direction = (int)(degrees * 8 / 360); if ((direction == 7) || (direction == 0) || (direction == 1)) { ptR.X = Math.Min(ptR.X + 1, ROOM_SIZE - 1); } else if ((direction == 3) || (direction == 4) || (direction == 5)) { ptR.X = Math.Max(ptR.X - 1, 0); } if ((direction == 1) || (direction == 2) || (direction == 3)) { ptR.Y = Math.Min(ptR.Y + 1, ROOM_SIZE - 1); } else if ((direction == 5) || (direction == 6) || (direction == 7)) { ptR.Y = Math.Max(ptR.Y - 1, 0); } if (((ptR.X != r.Location.X) || (ptR.Y != r.Location.Y)) && _roomCells[ptR.X, ptR.Y] == null) { _roomCells[r.Location.X, r.Location.Y] = null; _roomCells[ptR.X, ptR.Y] = r; r.Location = new RoomPoint(ptR.X, ptR.Y); } }
/// <summary>Sets the position of the Robot.Element for a given robot to a given point.</summary> /// <param name="robot">The robot.</param> /// <param name="pt">The location in RoomPoint coordinates.</param> void SetRobotElementPosition(Robot robot, RoomPoint pt) { Canvas.SetLeft(robot.Element, ((double)pt.X) / ROOM_SIZE); Canvas.SetTop(robot.Element, ((double)pt.Y) / ROOM_SIZE); }
/// <summary> /// Returns the angle from this point to another point, measured in clockwise radians from /// the ray pointing to the right of this point. /// </summary> /// <param name="other">The other point.</param> public double AngleTo(RoomPoint other) { return(Math.Atan2(other.Y - Y, other.X - X)); }
/// <summary> /// Returns the distance from this point to another point. /// </summary> /// <param name="other">The other point.</param> public double DistanceTo(RoomPoint other) { return(Math.Sqrt(Square(other.X - X) + Square(other.Y - Y))); }