CS106A Assignment 5 – Yahtzee

The URS.

Yatzee

  • 9 days to program

Use arrays in a variety of contexts:

  • for dice
  • for re roll
  • for player names
  • for player’s score
  • also a 2 dimensional array to handle entire score card

Game tracks player turns and dice rolls (5 dice per roll, maximum of three rolls per turn)

Dice configuration is checked against 13 categories and classified/scored based on this.  Categories are specified in Handout 35 – Assignment 5.

Player to select score category from dice roll.  Scores to be stored tracked. If wrong category selected, score is zero.

Highest score wins

When run, program to:

  • display welcome message
  • ask for player number
  • ask for player names via popup dialogue boxes
  • starting score cards displayed in graphics window
  • dice displayed in graphics window – initially with ? on their faces
  • Ones through to sixes are added as upper score.  If above 63, a bonus of 35 is given
  • Remaining categories are added as lower score
  • Upper and lower score equals total score.  Total score is calculated as the game progresses and displayed
  • Player name to be highlighted when their turn
  • “Roll dice” button needs to be clicked to…roll dice.  After that it’s “Roll again”
  • Clicking on a dice selects it to be rolled again
  • If no more rolls are wanted, player does not click any dice – player clicks on “Roll again” however

Started 15/05/2017 – completed 24/05/2017.  Most of this was updating code, testing result, removing bugs and logic errors.

Program Setup

On the face of it, this looks really complex as fancy graphics are needed and there’s a lot of tracking that needs to be done.  A precompiled class is provided that handles the graphics and event handling and this code sets the game visuals up. I need to code in the rest.

Creating the Program Including Beta Testing

I sat there for some time wondering where to begin. I mapped out the various methods that needed to be used, however I was stuck on figuring out how to track everything (brain fart?)

After scribbling the player and turn loops down on a note pad I had something I could work with:

private void playGame() {
for (int gameTurns = 0; gameTurns < N_SCORING_CATEGORIES; gameTurns++) {
for (player = 0; player < nPlayers; player++) {
//        println (“Game Turn (category tracker)” + gameTurns);
//        println (“Player Number” + player);
checkFirstDiceRoll(); // monitors for clicking on roll
checkSecondThirdDiceRoll(); // controls rolls 2 and 3
chooseScoringCategory();
createScoreArray();
saveDiceRollResults();
assignScore();
checkYahtzeeAlready();
topBonusAward();
totalEndGameScore();
}

Some of the code was redundant before I began as the Yahtzee display class takes care of things.  Once I got going, things progressed well until I got to the category check.  I could not figure out how to get the magicstub to work.  Somehow I needed to examine the selected category and compare it to the results.  Using  (YahtzeeMagicStub.checkCategory(dice, category) did not work.  Viewing the javadoc on the magicstub the next day things went “bing”.  I’d called the array that tracks dice rolls diceRoll.  Thus, the compile was happy when the code was altered to (YahtzeeMagicStub.checkCategory(diceRoll, category).  At this point, I still could not figure out how to check the diceRoll against the category.  I’d initialised categoryCheck as 0 and whenever a category in the GUI was selected, categoryCheck was always returned as 0.  I was wondering if I should put something in the () of display.waitForPlayerToSelectCategory().  Looking online for code examples gave me the answer.  My categoryCheck int needed to equal the check.  After that the switch statement I’d set up correctly produced output saying “category blah selected”.  The assignment said that was needed!  Time to print it off rather than having it on screen.

The next thing I needed to work out was how to get display.updateScorecard(category, player, score) to update the score.  Did I need to create and array of arrays for this?  Presumably I did – the “array of arrays to handle the entire scorecard” as mentioned on page 1 of the assignment.  Yes I did.

The first score I worked out was the easiest – chance.  Add up all the diceRoll[] ref from 0 to 4.

I then did the easy stuff:  calculate upper score and add all the scores up (much the same as the chance calculation, but on the score array instead).  This worked until I went, “hang on, the total score’s got to be calculated after each player’s turn.”   The now in place upper and lower and total score calcs all threw wobblies when trying to read array referenced with no values.  I thought during the lectures, if there was no value, nothing would be returned.  A println shows me gobbledgook as an unassigned array reference,  eg 7hh#Y.  Eh!  I wrote a new total score method for in play, assigned everything for each category a 0 and then things seemed to work and I also made another array to track what category had been used.

<insert photo of note pad>

Next up was three and four of a kind.   What to do?  Figure out every permutation of dice roll for each face value where there was 3 of a kind? Use some really loopy looking loop that worked somehow with three of a kind but would jump the rails if four of a kind was selected?  Nah, I was doing something wrong – back to the lectures and text book.  Here the solution was to use an ArrayList populated from the diceRoll array.  The size could be output as an in and used in a series of boolean expressions to determine 3, 4 and 5 of a kind as well as the large and small straights and the full house.

The single player game seemed to work.  The scores would total correctly and the end game score tallys would be drawn.  In multiplayer mode however, the final tally would only be drawn for the final player.

Here I needed another loop that would check for the condition of gameTurns.  For all but the last round, the final score would be drawn to the screen.  After each player’s final turn, the lower, upper and upper bonus as well as the total score would be drawn to the screen.

Following that, I needed to congratulate the winning player.  I whacked the code down in 10 minutes and the first run had the error shown below so I put in a check for a single player game to address it and then spent 5 hours trying to figure out a bug!!!

The Shipped Program

It works as required. I did not include a cheat mode so am now quite sick of playing this game!

Packaged Jar file.  Extract zipped contents and run the yahtzee.jar file if you have java installed on your system.  NOTE – THIS IS CLEARLY FOR EDUCATIONAL PURPOSES ONLY.  NOT FOR ANY OTHER USE.

The working game - all outcomes

The working game – all outcomes

Program Modifications / Extensions

  • “AI / computer player” – if one player selected, computer to play.  Might be too complex at current level.  Yep.
  • Yahtzee bonus score. Introduced bugs.
  • High score save
  • Here is the unimplemented, incomplete buggy code for the high score import/export.

/**
* ####################################################################################
*
*            This section includes any program enhancements or extensions that were thought
*            about but not implemented due to code errors I did not have the time or
*            inclination at this stage to address.
*
* ####################################################################################
*/

/*
private void loadWinningScore() {
ArrayList highScore = new ArrayList();

try{
BufferedReader rd = new BufferedReader(new FileReader(DATA_FILE));
while (true) {
Integer line = rd.readInt(); // !!–COMPILER ERROR–!!
if (line == null) break;
highScore.add(line);
}

rd.close();
}

catch (IOException ex) {
// nothing happens here
ex.printStackTrace();
}
println(“The score in the high score file is: ” + highScore);
}

private int saveWinningScore(int WinningScore) {
PrintWriter out = new PrintWriter(DATA_FILE); // !!–COMPILER ERROR–!!
out.println(winningScore);
return (winningScore);
}

*/

SummarySave

Save

Save

Summary

Again, scribbling out the methods on a pad before starting was a great way to visualize the program structure.

I needed some loops to get things working and I utilised methods were I called a value from one method for insertion into an array.

I found an inbuilt bug regarding the ability to choose more than four players which would crash the game when the score table was drawn.  I modified the supplied code to remove the bug.

I’ve begun to set my programming out in an improved manner.

Given the last two assignments have skimped on extensions, does that mean I’m a bad (or slow) programmer, or does it mean working full time etc is impacting this little project.

Lessons Learned

  • If a cheat mode can be used, use it.
  • Using one screen for a notepad++ version of code and one for Eclipse helps quite a bit.
  • I really like to get the code written properly if I can visualize the solution (eg a for loop where I’ve written out each step manually or I have a comment saying “I can do this better by coding it along the lines of bla de blah”).
  • I hate delivering a program with bugs.
  • How arrays work.

This assignment was a great demonstrator that most of the time is spent debugging.  It might have taken me 2 days to get the code down.  The rest of the time was spent running the program and fixing bugs/logic errors.