please help me with my computer science homework

profileabutid
pig-part2.docx

The project description can be found on this page (Pig Project Assignment Details) in case this is difficult to read.

 

http://people.westminstercollege.edu/faculty/ggagne/fall2015/cmpt201/project/pig-small.jpg PIG - PART 2

Add a computer player

 

Pig (Links to an external site.) is a folk jeopardy dice game described by John Scarne in 1945, and was an ancestor of the modern game Pass the Pigs® (originally called PigMania®). 

Here are the rules: two players race to reach 100 points. Each turn, a player repeatedly rolls a die until either a 1 is rolled or the player holds and scores the sum of the rolls (i.e. the turn total). At any time during a player's turn, the player is faced with a choice: roll or hold.

· Roll - If the player rolls a

· 1: the player scores nothing and it becomes the opponent's turn.

· 2 - 6: the number is added to the player's turn total and the player's turn continues.

· Hold - The turn total is added to the player's score and it becomes the opponent's turn.

Your program should already consist of the following classes:

· Die - has a static method to roll a die

· PigPlayer - an abstract class representing the player's name, current score, and win record.

· UserPigPlayer - a class that asks the user if they want to roll or hold

· SimpleHoldPlayer - a computer player that uses a strategy to roll until a value is reached (the first of four computer strategies)

· PigGame - plays Pig

In this part you will add:

· Simulations - runs several simulations to find out which strategies work well

· FourTurnsPlayer - the second of four computer strategies

· WatchOpponentPlayer - the third of four computer strategies

· StrategicPlayer - the fourth of four computer strategies

· PigGameGUI - a graphical user interface for the PigGame. I have written this class for you, but you will need to make sure you write your classes exactly to specifications for your code to work with my interface.

When you have finished, you will have two ways of running your program. The text program will be run by running themain() method in PigGame. You will also be able to run a graphical version, by running the main method inPigGameGUI.

You will write three separate classes that will "have" each other as instance variables or local variables: Die, PigGameand Simulations. A PigGame "has" two PigPlayer objects, and a Simulations "has a"PigGame. These three classes will not be related to each other through inheritance. You will also write an abstract PigPlayer class that has five child classes:

http://people.westminstercollege.edu/faculty/ggagne/fall2015/cmpt201/project/UML.png

This is the last 2 weeks of your four week project. I would suggest using the following deadlines to keep yourself on track. (Completing the class includes testing and debugging! Don't wait until the last week to test and debug!)

Week 1: complete the SimpleHoldPlayer and PigGame classes to allow the computer to play (against a user or against a player), and run your first Simulation. Make sure your code works with PigGameGUI

 

Week 2: complete and debug the three remaining computer strategy classes and Simulations

 

If you prefer, you can write the classes in another order, by using stub methods and classes instead.

SimpleHoldPlayer

 Write the SimpleHoldPlayer class. This class should have one instance variable (the hold value). It should have three constructors and the isRolling() method. The three constructors are:

· a default constructor - sets the hold value to 20

· a constructor that takes a String (the name of the player)

· a constructor that takes a String and an int (the name and the hold value)

The isRolling() method should be automated. It will NOT need to prompt the user or print anything to to the screen. Instead, it will return true if the die should be rolled, by checking if the game is not yet won and if the turn total has not yet reached the hold value.

Test this code before continuing to the next step.

PigGame: Allow a User to Play Against a Computer

Now go back to the PigGame and add two methods:

· public static void userVsComputer() - allows the user to play against the computer. This method should use Math.random to decide which player gets to go first.

· public static void computerVsComputer() - plays the computer against itself. Name the two computer players "Player 1" and "Player 2".

Call each of these methods from the main method in PigGame to make sure everything works correctly. 

Simulations

Now you are ready for your first simulation! We want to answer the question:

1. How much of an advantage does the first player have?

We will use a Monte Carlo method (Links to an external site.) to find the answer to this question. You should run the same computer strategy against itself, thousands of times, to see what percentage of games are won by the first player. If there is no advantage, the first player would win approximately half the time. The more simulations you run, the more accurate your simulation will be.

Create a Simulations class. Eventually, it will have several static methods, the first of which is:

public static void firstAdvantage(long simulations)

This method should take the number of simulations to be run as an argument. In the method, you should create two SimpleHoldPlayer objects. Run simulations where these two players repeatedly play against each other (with the same player as the first player) by calling the playGame method from PigGame. At the end, calculate the advantage that the first player has over the second (by printing out the percentage of games won by the first player).

To debug this, you'll want to first run the program with a small number of simulations (four works well). Check that the correct number of wins are being reported by each player.

Once you are sure the simulation is running correctly, you'll want to remove the printing in PigGame. But you don't want to completely remove the printing, because sometimes you'll still want it to print. Instead, create a new static boolean variable in the PigGame class: verbose. Then all throughout the PigGame class, add an if-statement in front of all System.out.println calls. (You don't need to add verbose to userVsUser or userVsComputer.) For example:

if (verbose) { System.out.println("Roll: " + roll);` }

You should add a mutator method for verbose (a set method) to the PigGame class.

Then increase the number of simulations to determine what advantage the player who rolls first has over the other player. You'll want to run at least 10,000 simulations, although it doesn't hurt to run more.

Find the Best Hold Value

The next question we want to answer is:

2. What is the best hold value to use for the SimpleHoldPlayer?

You should begin by writing a method in the Simulation class:

public static double comparePlayers(long simulations, PigPlayer first, PigPlayer second)

This method should run half the simulations with "first" PigPlayer first, and half the simulations with "second" PigPlayer first. This removes the bias favoring the player who rolls first.

The comparePlayers method should return the fraction of games won by the first PigPlayer. So if the "first" PigPlayer is better, it will return a number greater than 0.5, and if the "second" PigPlayer is better, it will return a number less than 0.5.

Write another static method that calls comparePlayers multiple times using different SimpleHoldPlayers. Ideally you should use a loop to find the best hold value, but if you need to run the code multiple times instead, you may. Record your findings in your ReadMe, explaining what code you ran (don't delete the code when you're done) and how you decided on the best hold value.

A New Strategy: Win in Four Turns 

The SimpleHoldPlayer has a very simple strategy. Write a new PigPlayer child class that will try to win in four scoring turns. 

The FourTurnsPlayer should keep track of the number of turns in which it has held so far (not rolled a 1). At the start of the game (or as long as this player has not yet "held" a turn), the player will use a hold value that is the GOAL / 4. After one scoring turn, the player will use a hold value that is the number of points it needs to win / 3, and so on. Using this strategy, this player will win on its fourth SCORING turn (although rolling a 1 too many times may mean their opponent will win first). 

To test this method, go back to PigGame. Modify the userVsComputer method in PigGame so the user is playing against FourTurnsPlayer. Check that your new strategy works correctly. Don't forget to turn verbose on again!

Once you are confident FourTurnsPlayer works, go back to the Simulation class. Write another static method that compares FourTurnsPlayer to SimpleHoldPlayer (with the best hold value you found in the previous simulation). This should be a very simple method that calls comparePlayers. FourTurnsPlayer should win more often than SimpleHoldPlayer. If it doesn't, you've implemented it incorrectly. 

Two More Strategies for the Computer

Write two more classes (one at a time) for the computer to play pig:

· WatchOpponentPlayer - this player is very concerned about its opponent's score and tries to make sure that its score is never too much smaller than its opponent's score. See below for more hints.

· StrategicPlayer - develop your own strategy and implement it. 

WatchOpponentPlayer:

This player will have two strategies based on whether either player is close to winning.

a. If a player is close to winning (either this player or the opponent), this player will roll until the GOAL is reached.

b. If neither player is close to winning, then this player will use a hold value that is based on how far ahead is the opponent. Use a hold value that begins at a reasonable hold value, but then add to it if the opponent is winning (because this player will be more willing to take risks) and subtract from it if the opponent is losing. Hint: the amount you should add/subtract to the original hold value should be a fraction of the difference between the the opponent's score and your score.

holdValue = reasonable + (opponentScore - myScore)/number

Notice for the above strategies, there are three important values:

1. in (a), how you determine what is "close to winning"

2. in (b)'s equation for holdValue, a reasonable initial hold value

3. in (b)'s equation for holdValue, the number you want to divide the difference by

All three of these important values should be instance variables in your WatchOpponentPlayer. Then write a constructor that allows you to set all three of these instance variables.

You'll need to run some simulations to find a good values for these three instance values. Write a static method called findGoodWatchValues in Simulations, and have it try values between 5-50 for all three values. (If you are using "close to winning" as a constant value, then use 50-95; if you are use "close to winning" as the difference between your score and the GOAL, then use 5-50.) You should call comparePlayers, and test different versions of WatchOpponentPlayers against a SimpleHoldPlayer. When you find what values work best, use those for your default constructor in your WatchOpponentPlayer.

[UPDATED - YOU MAY FIND IT DIFFICULT TO DETERMINE ALL THREE VALUES AS THIS REQUIRES 3 NESTED FOR LOOPS. I SUGGEST USING A "CLOSE TO WINNING" VALUE OF APPROXIMATELY 75.]

Be sure to write up what your findings were in your Project Writeup.

StrategicPlayer:

As you write the StrategicPlayer, compare your strategy to SimpleHoldPlayer. You should tweak your strategies so they do well against SimpleHoldPlayer. The student with the best StrategicPlayer this year earns an automatic A in the class (as long as they have completed the project and write-up satisfactorily). If your StrategicPlayer does not win against SimpleHoldPlayer, you'll still earn most of the credit on StrategicPlayer if you defend the reasoning behind your strategy in your Project Writeup.

After you have finalized your strategies, you will need to include a description of your three strategies in your Project Writeup. 

Run more simulations

We have one more questions to answer:

2. Which is the best strategy: SimpleHoldPlayer (using the best hold value determined in the above simulation), WatchOpponentPlayer, FourTurnsPlayer, or StrategicPlayer? Provide percentages of how they perform against the other strategies. To calculate these percentages, you should be calling comparePlayers.

All four strategies should be good (when played against each other, none of the strategies should lose more than 55% of their games). If one of these strategies is losing more than 55% of their games, first try running more simulations. If it's still happening consistently, you probably have a bug with your strategy. 

Run the Graphical Version of Pig Game

At any time after you have SimpleHoldPlayer working, you can check to make sure your program works with the graphical user interface.

1. Begin by downloading this zip file View in a new window.

2. Extract the zip files contents into the SAME folder as your PigGame java code. When you are done, you should have (in this folder): PigGame.java, PigPlayer.java, SimpleHoldPlayer.java, Die.java, PigGameProgram.java, and my three class files (all beginning with PigGameGUI). You should also have a folder called images, with several png files inside it.

3. Compile PigGameProgram.java. If you get the error "cannot find symbol", or if you compile successfully but then get this error when you run the program:

Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: Die

your class names, method names, or variable names do not follow the specifications in the assignment.

4. The PigGameGUI program relies on:

1. the roll() method from your Die class

2. the PigGame.GOAL constant

3. the isRolling method from the SimpleHoldPlayer

You can modify PigGame.GOAL to make the game easier to test. You can also modify line 16 to use a different strategy for the computer.

 

Test Your Code with Unit Tests

Here are three classes of unit tests for you to use to check your code. They assume that PigGame.GOAL is 100.

· PigPlayerTest Preview the document View in a new window - tests your PigPlayer methods (getName, setName, addPoints, etc). You must have PigPlayer and UserPigPlayer completed to run these unit tests.

· TestAllPigPlayers Preview the document View in a new window - tests your playTurn (from PigGame) and isRolling methods. You must have most of your classes completed, including PigGame, SimpleHoldPlayer, FourTurnsPlayer, WatchOpponentPlayer, StrategicPlayer and Simulations. You'll can always comment out the later tests to test your SimpleHoldPlayer and FourTurnsPlayer classes earlier. After you determine the best hold value, modify line 8 of this unit test. You should also set verbose to false before running the unit test. (This test has been modified on 11/17 to reflect the new comparePlayer method.)

· DieTest Preview the document View in a new window - tests your Die methods

If you fail unit tests from the second file, remember that your isRolling method should return false if the player has won already. For example, if the player had 90 points, and then rolls 10 points, your isRolling should return false at this point (because the player has already won the game).

Remember if you fail a unit test, you should move that code into a main method and replace any "assert" calls with System.out.println.

If you're having trouble downloading these two Java files, try copying and pasting all the Java code from your internet browser into Dr. Java.

Use doctor java only!!