Пример #1
0
        /// <summary>
        /// This method makes the pig drop rope onto the current cell.
        ///
        /// Note that, when a rope is being used, the pig must
        /// call DropRope BEFORE the pig moves from its current cell,
        /// because ropes are used to keep a history of where a pig has been,
        /// which excludes its current location (unless it is revisiting a cell).
        /// </summary>
        void DropRope()
        {
            // Create the rope on the current cell
            Position  position     = Cell.Position;
            RopePiece newRopePiece = new RopePiece(PigWorld, this, position);

            // Add it to the previous rope pieces.
            ropePieces.Add(newRopePiece);
        }
Пример #2
0
        /// <summary>
        /// If a pig can not move directly towards it's food, this method examines all surrounding cells
        /// and determines which direction is the best to move in. In the following order:
        /// 1. Move towards an empty cell in the closest direction to the closest food.
        /// 2. If no cells are empty move towards the cell with the oldest rope on it.
        /// 3. Unable to move to any nearby cell. Do nothing.
        /// pre: Pig is unable to move towards the food, or there is rope in the adjacent cell.
        /// post: Pig will move to a valid location, or not at all. Depending on the above circumstances.
        /// </summary>
        private void ExamineSurroundingCells()
        {
            const double DEFAULT_LOWEST_DIRECTION_DIFFERENCE = 360.00;
            Echo         nearestPigFood            = FindNearest(typeof(PigFood));
            double       lowestDirectionDifference = 360.00;          //default value 360 is a placeholder
            Direction    closestDirectionToFood    = Direction.NORTH; //default value (Direction.NORTH) is a placeholder
            int          oldestNearbyRope          = -1;              //default value -1 is a placeholder
            Direction    oldestRopeDirection       = Direction.NORTH; //default value (Direction.NORTH) is a placeholder

            for (int i = 0; i < Direction.NUMBER_POSSIBLE; i++)
            {
                Direction direction    = Direction.GetAdjacentCellDirection(i);
                Cell      adjacentCell = Cell.GetAdjacentCell(direction);

                if (adjacentCell != null && CanMove(direction))
                {
                    RopePiece ropeInCell = GetMyRopePiece(adjacentCell);
                    if (ropeInCell == null)
                    {
                        double adjacentCellDirection = direction.Degrees;
                        double foodDirection         = nearestPigFood.direction.Degrees;
                        double differenceInDegrees   = Math.Abs(foodDirection - adjacentCellDirection);

                        // The two lines below solve the '359 degrees is right next to 0 degrees' issue using basic maths.
                        if (differenceInDegrees > 180)                       // 180 being 180 degrees (DO NOT change)
                        {
                            differenceInDegrees = 360 - differenceInDegrees; // 360 being 360 degrees (DO NOT change)
                        }
                        if (lowestDirectionDifference > differenceInDegrees)
                        {
                            lowestDirectionDifference = differenceInDegrees;
                            closestDirectionToFood    = direction;
                        }
                    }
                    else if (ropeInCell != null)
                    {
                        Pig ropeOwner = ropeInCell.OwnerPig;
                        int ropeAge   = ropeInCell.GetDistanceFromOwner();
                        if (oldestNearbyRope < ropeAge)
                        {
                            oldestNearbyRope    = ropeAge;
                            oldestRopeDirection = direction;
                        }
                    }
                }
            }
            if (lowestDirectionDifference != DEFAULT_LOWEST_DIRECTION_DIFFERENCE)   //If it has changed from default value, a valid direction has been found.
            {
                DropRope();
                Move(closestDirectionToFood);
            }
            else
            {
                DropRope();
                Move(oldestRopeDirection);
            }
        }
Пример #3
0
        /// <summary>
        /// Accesses a piece of rope on the specified cell owned by this pig.
        /// If there is more than one piece of rope on that cell owned by this pig,
        /// then the most recently placed will be returned.
        /// If no ropes owned by this pig are on that cell, null is returned.
        /// </summary>
        /// <returns> the requested rope from that Cell. </returns>
        public RopePiece GetMyRopePiece(Cell cell)
        {
            List <RopePiece> ropes         = cell.InspectAll <RopePiece>();
            RopePiece        bestRopeSoFar = null;

            foreach (RopePiece ropePiece in ropes)
            {
                if (ropePiece.OwnerPig == this)
                {
                    if (bestRopeSoFar == null)
                    {
                        bestRopeSoFar = ropePiece;
                    }
                    else
                    {
                        if (ropePiece.GetDistanceFromOwner() < bestRopeSoFar.GetDistanceFromOwner())
                        {
                            bestRopeSoFar = ropePiece;
                        }
                    }
                }
            }
            return(bestRopeSoFar);
        }
Пример #4
0
        /// <summary>
        /// Draws the RopePiece on the screen.
        /// (Doesn't use an image from a file).
        ///
        /// Overrides the Paint method in the base class, ThingView.
        /// </summary>
        /// <param name="graphics"> the Graphics object on which the animal's image is displayed. </param>
        protected override void Paint(Graphics graphics)
        {
            PigWorld pigWorld             = ropePiece.PigWorld;
            Position thisPos              = ropePiece.Cell.Position;
            int      indexOfThisRopePiece = ropePiece.GetIndex();

            // Get RopePiece dropped just before this one (if any).
            RopePiece previousRopePiece = ropePiece.OwnerPig.ropePieces.ElementAtOrDefault(indexOfThisRopePiece - 1);
            // Is null when this element does not exist.

            // Get RopePiece dropped just after this one (if any).
            RopePiece nextRopePiece = ropePiece.OwnerPig.ropePieces.ElementAtOrDefault(indexOfThisRopePiece + 1);
            // Is null when this element does not exist.

            int viewWidth  = thingViewRectangle.Width;
            int viewHeight = thingViewRectangle.Height;

            Point midPoint = new Point(viewWidth / 2, viewHeight / 2);

            // Set the starting point for the line to be drawn.
            Point startPoint = new Point();

            // If there is a previous piece of rope, use its position.
            if (previousRopePiece != null)
            {
                Position previousPos = previousRopePiece.Cell.Position;
                startPoint.X = midPoint.X + (viewWidth / 2) * (previousPos.Column - thisPos.Column);
                startPoint.Y = midPoint.Y + (viewHeight / 2) * (previousPos.Row - thisPos.Row);
            }
            else
            {
                // Else, start in the middle of the cell.
                startPoint = midPoint;
            }

            // Set the ending point for the line to be drawn.
            Point    endPoint = new Point();
            Position nextPos;

            // If there is a next piece of rope, use its position.
            if (nextRopePiece != null)
            {
                nextPos = nextRopePiece.Cell.Position;
            }
            else
            {
                // Else, use the pig's current position.
                nextPos = ropePiece.OwnerPig.Cell.Position;
            }
            endPoint.X = midPoint.X + (viewWidth / 2) * (nextPos.Column - thisPos.Column);
            endPoint.Y = midPoint.Y + (viewHeight / 2) * (nextPos.Row - thisPos.Row);

            // Use a rope width of 2 because the default width of 1 isn't always visible in small windows.
            const float penWidth = 2f;

            using (Pen ropePen = new Pen(ropePiece.Color, penWidth)) {
                // If the line would be only along the edge of the cell, then draw two lines to make the rope clearer.
                if ((startPoint.X == endPoint.X && (startPoint.X == 0 || startPoint.X == viewWidth)) ||
                    (startPoint.Y == endPoint.Y && (startPoint.Y == 0 || startPoint.Y == viewHeight)))
                {
                    graphics.DrawLine(ropePen, startPoint.X, startPoint.Y, midPoint.X, midPoint.Y);
                    graphics.DrawLine(ropePen, midPoint.X, midPoint.Y, endPoint.X, endPoint.Y);
                }
                else
                {
                    // Else draw just one line.
                    graphics.DrawLine(ropePen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
                }
            }
        }
Пример #5
0
        private RopePiece ropePiece;  // The ropePiece being displayed.

        /// <summary>
        /// Constructs a RopeView.
        ///
        /// The constructor must include a PigWorldView parameter so that all views
        /// created by the CreateView method(s) have similar signatures.
        /// </summary>
        /// <param name="ropePiece"> the ropePiece to view. </param>
        public RopePieceView(PigWorldView pigWorldView, RopePiece ropePiece)
            : base(ropePiece)
        {
            this.ropePiece = ropePiece;
        }