10-152-312 - Object-Oriented Programming 2

4.2 Zoo Assignment

Using Actions instead of delegates

  1. Change all existing custom delegates to Action
    1. For example, AnimalDelegate should become Action
    2. Remove all custom delegate declarations

Plugging a typed anonymous method into the BirthingRoom's OnTemperatureChange

  1. Instead of plugging a named method into the birthing room's OnTemperatureChange delegate, attach an anonymous method
  2. Type the following code in the zoo's constructor:
  3. Delete the named method that was attached to the OnTemperatureChange delegate
  4. Run the WPF application
    1. Change the temperature of the birthing room
    2. Ensure the temperature border and label still change in response to the temperature change

Changing OnTemperatureChange's typed anonymous method to an untyped one

  1. Delegates and anonymous methods offer a lot of built-in functionality, including automatic typing
  2. Instead of typing the anonymous method as an Action, remove the type entirely, as in the code below:
  3. Run the WPF application
    1. Change the temperature of the birthing room
    2. Ensure the temperature border and label still change in response to the temperature change

Anonymous methods - OnBirthingRoomTemperatureChanged in console

  1. Attach an anonymous method to the zoo's OnBirthingRoomTemperatureChanged delegate instead of a named method
  2. Copy the code inside the HandleBirthingRoomTemperatureChanged method to the body of the anonymous method
  3. Remove the HandleBirthingRoomTemperatureChanged method
  4. Run the console application
    1. Change the birthing room temperature
    2. Ensure the console still responds to the change using delegates

Anonymous methods - OnBirthingRoomTemperatureChanged in MainWindow

  1. Attach an anonymous method to the zoo's OnBirthingRoomTemperatureChanged delegate instead of a named method in the AttachDelegates method
  2. Copy the code inside the HandleBirthingRoomTemperatureChanged method to the body of the anonymous method
  3. Remove the HandleBirthingRoomTemperatureChanged method
  4. Run the WPF application
    1. Change the birthing room temperature
    2. Ensure the temperature border and label still update in response to the temperature change

Anonymous methods - move timer handler

  1. Attach an anonymous method to the animal's moveTimer Elapsed event handler instead of a named method in the CreateTimers method
  2. Event handlers, unlike delegates, require the += notation, as in the code below:
  3. Remove the MoveHandler
  4. Run the WPF application
    1. Create a few animals
    2. Show their cage
    3. Ensure the animals still move on each tick of the move timer

Anonymous methods - OnCageableUpdate in CageWindow

  1. Attach an anonymous method to the cage's OnCageableUpdate delegate instead of the named Update method
  2. Remove the Update method
  3. Run the WPF application
    1. Create a few animals
    2. Show their cage
    3. Ensure animals are still drawn correctly each time they move

Anonymous methods - OnStatusUpdate in Cage

  1. Attach an anonymous method to the cageable's OnStatusUpdate delegate instead of named method in the cage's Add method
  2. Copy the code inside the HandleCageableUpdate method to the anonymous method
  3. Remove the HandleCageableUpdate method
  4. Notice that the same code (the calling of the OnCageableUpdate delegate) now exists twice in the Add method
  5. Instead of calling the OnCageableUpdate delegate, simply call the cageable's OnStatusUpdate delegate, as in the code below:
  6. Now that the HandleCageableUpdate method doesn't exist, it can't be unplugged from the OnStatusUpdate delegate
  7. Instead, simply set the OnStatusUpdate delegate to null in the Remove method
  8. Run the WPF application
    1. Create a few animals
    2. Show their cage
    3. Ensure animals are still drawn correctly each time they move

Anonymous methods - OnBalanceChange in Guest

  1. Create a property of type Action called OnBalanceChange in the IMoneyCollector interface
  2. Implement the property in the MoneyCollector class
  3. Call the delegate in the setter of the money collector's money balance property
  4. Ensure the money collector's add and remove methods call the money balance property instead of the field
  5. Attach anonymous methods in the Wallet constructor to the money collector's OnBalanceChange property
    1. In the method, call the wallet's OnBalanceChange delegate
  6. Attach an anonymous method to the wallet's OnBalanceChange delegate instead of the named method in the guest's constructor
  7. Copy the code in the HandleBalanceChanged method to the anonymous method
  8. Remove the HandleBalanceChanged method
  9. Attach an anonymous method to the checking account's OnBalanceChange delegate
    1. Call the guest's OnTextChange delegate from inside the method
  10. Add the checking account balance to the guest's ToString method
  11. Run the WPF application
    1. Create a guest with some money and an animal
    2. Have the guest feed the animal
    3. Ensure the guest's text display updates as their money balance changes

Anonymous methods - OnAddAnimal and OnRemoveAnimal in MainWindow

  1. Attach an anonymous method to the zoo's OnAddAnimal delegate in the MainWindow's AttachDelegates method
  2. Copy the code from the OnAddAnimal method to the anonymous method
  3. Remove the OnAddAnimal method
  4. Follow the same process for the zoo's OnRemoveAnimal delegate
  5. Run the WPF application
    1. Add at least one animal
    2. Ensure the animal is added to the list box
    3. Remove at least one animal
    4. Ensure the animal is removed from the list box

Anonymous methods - OnAddGuest and OnRemoveGuest in MainWindow

  1. Attach anonymous methods to the zoo's OnAddGuest and OnRemoveGuest delegates in the MainWindow's AttachDelegates method
  2. Follow the same procedure as with the OnAddAnimal and OnRemoveAnimal delegates
  3. Run the WPF application
    1. Add at least one guest
    2. Ensure the guest is added to the list box
    3. Remove at least one guest
    4. Ensure the guest is removed from the list box

Using anonymous methods in the zoo's FindXxx methods

  1. Replace the contents of the following methods in the Zoo class by calling .Find or .FindAll with anonymous methods
    1. FindAnimal (all overloads)
    2. FindEmployee
    3. FindGuest
    4. GetAnimals

Make animals hungry using a timer

  1. Add an enumeration called HungerState to the Cageable package
    1. Satisfied
    2. Hungry
    3. Starving
    4. Unconscious
  2. Add a read-only property on ICageable called HungerState of type HungerState
    1. Implement the property as read/write in Animal
    2. Implement the property as read-only in Guest and always return Satisfied
  3. Add a hunger timer to Animal
  4. Add a method to handle the timer's elapsed event called HungerHandler
    1. In the handler, switch to the next hunger state (e.g. if the current state is Hungry, then switch to Starving)
  5. In the CreateTimers method:
    1. Initialize the timer and set it to a random value between 10 and 20 seconds
    2. Plug in the HungerHandler to the timer's Elapsed event
    3. Start the timer
  6. Disable the timer when the animal is suspended
  7. Add the animal's hunger state to its ToString method
  8. Call the animal's OnTextChange delegate when its hunger state is set
  9. Run the WPF application
    1. Create a few animals
    2. Wait for the hunger timer to go off and ensure that each animal's display text changes in the list box

Make animals slow down or stop based on hunger state

  1. Animals move differently based upon their hunger state, so make these changes to the MoveHorizontally and MoveVertically helper methods
    1. Satisfied animals move as before
    2. Hungry animals move at 1/4 the normal rate
    3. Starving and unconscious animals do not move
  2. The contents of the hover behavior should only occur if the animal is not unconscious
  3. Run the WPF application
    1. Create a few animals of one type
    2. Show their cage
    3. Ensure that the animals move at their normal speed, slow down and then stop as the hunger timer goes off

Skew unconscious animals

  1. Unconscious animals are drawn differently
    1. Use a SkewTransform to skew them at a 30-degree angle in the direction they are facing (either 30 or -30)
    2. Use a ScaleTransform to scale them at 50% of their height and 75% of their width
    3. Create a TransformGroup
    4. Add these two transforms and the existing flip transform to the TransformGroup
    5. Set the viewbox's render transform to the new transform group, which may or may not contain some transformations
  2. Run the WPF application
    1. Create a few animals of one type
    2. Show their cage
    3. Ensure that unconscious animals are skewed in the direction that they are facing

Revive animals by feeding them

  1. In the animal's Eat method:
    1. Reset the animal's hunger state to satisfied
    2. Stop and restart the hunger timer
  2. Run the WPF application
    1. Open a cage window with at least one animal in it
    2. Let the animal slow down, stop or become unconscious
    3. Feed the animal
    4. Ensure that the animal begins moving again at regular speed after it is fed

Create a Func to provide a vending machine

  1. Create a VendingMachine Func called GetVendingMachine on the guest
  2. Attach an anonymous method to the guest's delegate upon adding a guest to the zoo
    1. In the method, return the zoo's animal snack machine
  3. In the MainWindow's feed animal button click, call the guest's GetVendingMachine delegate instead of using the AnimalSnackMachine property
  4. Do the same in the console application's feed command
  5. Remove the zoo's AnimalSnackMachine property
  6. Run the WPF application
    1. Have a guest feed an animal
    2. Ensure the feeding of animals still works
  7. Run the console application
    1. Have a guest feed an animal
    2. Ensure the feeding of animals still works

Allow guests to automatically feed their adopted animal

  1. Create an animal Action called OnHunger on the animal
  2. Call the action from the hunger handler
  3. Create a feed timer on the guest and set its interval to 5 seconds
  4. Set the timer's Elapsed event to an anonymous method that feeds the adopted animal and stops the timer
  5. In the guest's AdoptedAnimal setter:
    1. First, if there already was an adopted animal, unplug the feed hungry animal method from the animal's on hunger delegate/li>
    2. Then, set the new value as the adopted animal
    3. Then, if the new adopted animal exists, attach an anonymous method to the animal's on hunger delegate
      1. In the method, start the feed timer if the passed-in animal is starving or unconscious
    4. Last, call the guest's on text change delegate
  6. Run the WPF application
    1. Create at least one animal and one guest
    2. Open the animal's cage window
    3. Have the guest adopt the animal
    4. Ensure that, as the animal starves or becomes unconscious, the guest automatically feeds it and the animal begins moving again at full speed

Fix serialization

  1. Mark the guest's feed timer as nonserialized
  2. Refactor the guest's feed timer initialization to a method called CreateTimers
  3. Create an OnDeserialized method on the guest and model it after the animal's OnDeserialized method
  4. Call the CreateTimers method from the OnDeserialized method
  5. Run the application
    1. Create at least one guest and one animal
    2. Have the guest adopt the animal
    3. Stop the application and re-run it
    4. Ensure that the guest and animal are deserialized correctly and the guest automatically feeds its adopted animal as it becomes starving or unconscious

Grading and Submission

  1. Build/compile your program
  2. Debug/test your program against the following rubric:
  3. PNG image of 4.2 Zoo rubric
  4. Make your code StyleCop-compliant
  5. Close your Visual Studio solution
  6. Compress your Visual Studio solution to a zip file
  7. Submit the zip file via Blackboard