Electric Boogaloo Monty Hall Problem Worksheet – Description
Pokemon 3 – Electric Boogaloo
This assignment is about evaluating strategies in the “Monty Hall Problem”. You will employ subclasses to represent different strategies and use the Monte Carlo method to determine which, if any, strategy is best.
Before doing anything else, please watch the video intro to this project, then take the quiz.
Instructions
In this assignment we’ll start with the code from Pokemon 2 and will create Pokeplayer, a sub-class of the Pokemon class which adds methods to allow it to play “Let’s Make a Deal”. We will also create two sub-classes of Pokeplayer which will employ different strategies. The Pokemon compete in a game and each class will implement a different strategy.
In the game, our Pokemon will be presented with three doors to choose from. Behind one of the doors is a prize. Behind the other two doors are zonks (nothing of value).
First, our Pokemon will pick one of the three doors.
Next, before the Pokemon finds out what’s behind the door they chose, Monty reveals one of the two un-chosen doors – showing it to be a zonk. Monty always reveals a zonk.
Finally, our Pokemon will be offered the opportunity to trade their door for the remaining, unopened, door.
A pokemon scores a point if the door they’ve selected has the prize behind it.
What do you think? Is it better to switch doors? Does it matter? Doing this assignment should settle this question.
Design for the Pokeplayer class hierarchy
Pokemon
Copy the pokemon.h and pokemon.cpp from the prior assignment. If your last project pokemon class had many issues flagged by me, either address those comments with fixes, or consider using the solution code. No other changes will be necessary for these files.
Pokeplayer
Declare Pokeplayer, a public subclass of Pokemon.
Give it a constructor that calls the Pokemon constructor. Code that as follows:
Pokeplayer(string name, int id, string ability, string gender, double height) : Pokemon(name, id, ability, gender, height) {}
Declare three methods which can be overridden by subclasses:
A method, strategyName that takes no parameters and returns a short string describing the pokemon’s strategy.
A method, decideDoor, that takes no parameters and returns an int (1, 2, or 3) which is the door this pokemon initially chooses. See Utilities.h for a class method that will return a random door number (omit the excluding parameter).
A method, decideSwitch, which takes three int parameters: chosenDoor, revealedDoor, and offerDoor. chosenDoor is the door the pokemon initially chose. revealedDoor is the door which was revealed to be a zonk, and offerDoor is the door which remains unopened. This method should return an int (1, 2, or 3), which is the door the pokemon wishes to continue with. I.e. it would return chosenDoor to stick with their initial choice or offerDoor to switch. The Pokeplayer class should make this decision randomly, with a 50-50 probabilty to switch or stick. Not sure how to do this? Be sure to read Hints below.
StubbornPlayer
Declare StubbornPlayer, a public subclass of Pokeplayer.
Give it a constructor that calls the Pokeplayer constructor. Code that as follows:
StubbornPlayer(string name, int id, string ability, string gender, double height)
: Pokeplayer(name, id, ability, gender, height) {}
It should override methods of Pokeplayer as needed.
It will require a constructor that takes values for all of the pokemon attributes. All it must do is call Pokeplayer’s constructor.
Stubborn pokemon’s don’t change their minds after they’ve made an initial guess.
ShrewdPlayer
Declare ShrewdPlayer, a public subclass of Pokeplayer.
Give it a constructor that calls the Pokeplayer constructor. Code that as follows:
ShrewdPlayer(string name, int id, string ability, string gender, double height)
: Pokeplayer(name, id, ability, gender, height) {}
It should override methods of Pokeplayer as needed.
It will require a constructor that takes values for all of the pokemon attributes. All it must do is call Pokeplayer’s constructor.
Shrewd pokemon’s are coded with an understanding of the ideal strategy to play the Monty Hall game. What’s the ideal strategy? Watch the !(https://deanza.instructure.com/courses/29693/pages/watch-monte-carlo-meets-monty-hall?module_item_id=2532826)
MontyHall Class
There’s no code to write. It is provided by the exercise (in MontyHall.h & MontyHall.cpp). Just read and understand and use it.
The MontyHall object is instantiated with an instance of the Pokeplayer that will play the game. It knows how to playNGames which tests the pokemon it was constructed with. The winPercentage method answers how well the Pokeplayer did.
To complete the assignment, complete these few tasks:
In the main.cpp, create a list to hold Pokeplayer pointers. You can use an array or vector.
Populate the array with three Pokeplayers – one for each of the three classes: Pokeplayer, StubbornPlayer, & ShrewdPlayer.
Initialize the Pokeplayers with these attributes:
For Pokeplayer use: “Randy”, 64, “Unpredictability”, “female”, 1.0
For StubbornPlayer use: “Sticky”, 65, “Dependability”, “male”, 1.0
For ShrewdPlayer use: “Wiley”, 66, “Flexibility”, “female”, 1.0
For each Pokeplayer in the list:
Create an instance of MontyHall to be used to test that player.
Play ITERATION_COUNT games for that player.
Print out the player, their strategy, and their winning percentage.
Observe which strategy performed best. Is this what you anticipated?
Example Output
The percentage scores below are roughly what should be expected. The Stubborn player has a 1/3 chace of winning with their selected door. Though it’s not intuitive, the player who always switches wins twice as often. The “random” strategy alternates between the two so its win percentage splits the difference between 2/3 and 1/3, which is 1/2.
Randy 64 Unpredictability female 1 – Random scored: 50.64%
Sticky 65 Dependability male 1 – Stubborn scored: 33.63%
Wiley 66 Flexibility female 1 – Shrewd scored: 66.83%
Hints
Mark methods you want sub-classes to override as virtual.
For virtual methods to work, we must use object pointers. The following does not work as you might expect: Pokeplayer p = StubbornPokemon(…); p.someVirtualMethod(); // calls wrong method – the one in base class
The problem is the variable p is of the class Pokeplayer. It is initialized by creating a StubbornPokemon and using that object to initialize p. Since p is a Pokeplayer, the methods of the Pokeplayer class get invoked.
We can fix this by using a Pokeplayer pointer.
Pokeplayer *p = new StubbornPokemon(…);
p->someVirtualMethod(); // calls method from derived class
In this case the right thing happens because p is a pointer that can point to a Pokeplayer or one of its sub-classes. The code creates a StubbornPokemon and sets p to point to it. Since p is actually pointing to a StubbornPokemon, the methods of the StubbornPokemon class get invoked.
Subclass method declarations can use override as a hint to the compiler that they’re intending to override a virtual method. This is not required, but is a good idea as it may result in better error messages if your code is incorrect.
The class called Utilities (in Utilities.cpp and Utilities.h) is useful. It provides two static methods, RandomDoor and CoinFlip which can be used to choose a random door or to flip a coin to make a 50-50 decision. Remember how to call a class/static method? ClassName::methodName().
The post Electric Boogaloo Monty Hall Problem Worksheet first appeared on .