Posts Tagged ‘Yahtzee’

Dice Game – Part 2

Wednesday, May 19th, 2010

Dice Game – Part 2.

And here are the Extensions

  • Add a high score feature. Save the top ten highest scores and names to a file and make it persistent between runs of the program. Read the file when you start and print out the hall of fame. If a player gets a score that preempts one of the early high scores, congratulate them and update the file before you quit so it is recorded for next time.
  • Incorporate the bonus scores for multiple Yahtzees in a game. As long as you have not entered a 0 in the Yahtzee box, the rules of the game give you a bonus chip worth 100 points for each additional Yahtzee you roll during the same game.
  • Beef up your Yahtzee to the variant called “Triple Yahtzee.” In this variant, each player manages three simultaneous scorecard columns, as if they were playing for three players at once. The player can assign a roll to any one of their three columns. All entries are scored normally with respect to categories and validity, but the values in the second column are doubled, and the third column values are tripled. The player’s score consists of the sum of all three columns. This would make for a three-dimensional
    array (an array of players who have any array of columns which are an array of score entries)—pretty tricky! Game play continues for 3 * 13 rounds, until all players have
    filled in all entries in all three columns. The player with the highest total score is the winner.

Top scores

The way that I approached, displaying and saving the top scores was to use a BufferedReader, which allows to read a line by line of a file, so once the file was opened I could read each line of the top 10 scores, with the scores and the name of the top person being separated by a comma e.g. 10,genux so whilst I was reading in the top scores I could find the comma and then find out the lowest value which I could pass back to the main game, here is the java code for that

System.out.println("Top 10 scores :");
while (reader.ready())
{
	scoresTop10 = reader.readLine();
	commaValue = scoresTop10.indexOf(",");
	lowestValue = Integer.parseInt(scoresTop10.substring(0,commaValue));
	System.out.println("score : " + lowestValue +" name : "+scoresTop10.substring(commaValue+1));
}
reader.close();

the reasons was so that once that game had finished I could see if the highest score was higher than the lowest score of the top 10 scores and if so update the scores file. To update the scores file I read in the scores into a two arrays, one being the score values and the other being the string of the names, but whilst reading in the scores, I inserted into the array where the new score and person name (that had played the game and scored a score that could be placed into the highest scores file), once done this then just wrote out to the file the new top 10 highest scores (by only writing out 10 of the array), this source code starts of with me inserting the new “score” and “username” into the scores/names array at the correct place, and the code below that uses the PrintWriter to out to the file.

...
	if (scoreChecker < score && !updated)
	{
		scores[insertNumber] = score;
	        names[insertNumber] = username;
		insertNumber++;
		updated = true;
	}
	scores[insertNumber] = scoreChecker;
	names[insertNumber] = scoresTop10.substring(commaNumber+1);
...
PrintWriter fileWriter = new PrintWriter(new FileWriter("top10.scores"));
for (int i =0; i < 10; i++)
	fileWriter.println(scores[i]+","+names[i]);
	fileWriter.close();
}

Bonus Yahtzee

The bonus of yahtzee for multiple yahtzees (100 points extra), I did by when I was updating the scores within the function I checked to see if the score was above 0 (which would mean that there was a score for this yahtzee) and also that the previous score was above 0 as well (e.g. there was a previous yathzee) then increase the score by 100).

here is the source code for that part

		else if (category == YahtzeeConstants.YAHTZEE && scoresUpdate[boardX][category] > 0 && score >0)
		{
			scoresUpdate[boardX][category] += (YAHTZEE_BONUS_CLIP*(boardX+1));
			score = scoresUpdate[boardX][category];
			return false;
		} else

Triple Yahtzee – x score cards

To allow for X amount of score cards ( did limit it to 3) but you could have 2 score cards and all that I did was to ask the user when they started the game to see how many score cards they wanted and then altered the scoring array to that amount. When it did come to adding the score to the board, I just questioned the user which score card to use, and then used that score card and times (*) the value accordingly. I did have to alter a couple of lines in functions to have the 3 dimensional array instead of 2 and also when updating the score cards had to alter it to place into the correct one, but could use most of the functions untouched due to how they was programmed.

I have included the score code in the zip file attached and also the PDF of the assignment requirements.

Yahtzee

Tuesday, May 18th, 2010

Yahtzee

Category 9 – Full house

Once again, I am going to bubble sort (bubble sort at the bottom of this post) the dice values, so that I can check to see if there are 3 of the same values and 2 of other values that are the same. This is very similar to counting how many values are the same with three/four of a kind, but this time need to make sure that there are only 3 / 2 split of different values, and for the scoring value we only need to return true/false since the value if it is a full house it is 25 points or 0 for nothing.

So, the way that I have done it, is with checking to see if values are the same within the array (whilst scanning from the start to end) and if they are increment the count (counting of similar values), if the values changes then check to see if the count is equal to 3 or 2 (which is the full house requirements) and if so set a boolean value to true and keep on checking. To get to return true, need to see if both the 3 and 2 boolean values are true then we know that we have a full house.

	// need to check for 3 of the same value and then 2 of the same value
	private Boolean checkFullHouse(int[] dice)
	{
		int count =1;
		Boolean found3 = false, found2 = false;
		for (int i=1; i < YahtzeeConstants.N_DICE;i++)
		{
			if (dice[i] == dice[i-1]) 
				count++;
			else
			{
				if (count == 3)
					found3 = true;
				else if (count == 2)
					found2 = true;
				count=1;
			}
		}
		if (count == 3)
			found3 = true;
		else if (count == 2)
			found2 = true;
		if (found3 && found2) return true;
		return false;
	}

Categories 10,11 – Small/Large straight

The last two are very similar and because once again I am using the bubble sort to organise the array into a order then we just need to check the array by going through it from start to finish checking to make sure that the value before is 1 minus the present value in the array ( e.g. array being 3,4,5, present value is the 4 and the previous value is 3 which is correct), then add up these correct placements within the array and if the consecutive values are either 4 (small straight) or 5 (large straight) return true or false accordingly.

	// consecutiveValues = how many in a straight line
	private Boolean checkStraight(int[] dice, int consecutiveValues)
	{
		int inLine =1;
		for (int i =1; i < YahtzeeConstants.N_DICE; i++)
		{
			if ((dice[i-1]+1) == dice[i]) inLine++;
		}
		if (inLine >= consecutiveValues) return true;
		return false;
	}

The main thing within the program is to make sure that you are always accounting for the difference with the categories numbers (which start from 1) and the scoring values (which start from 0) or the dice numbers (which start from 0 again), of course could make the size of those arrays 1 bigger.

To create the score array and also so we know what is a score value of 0 or not, then the score array is setup with all values of -1.

	/* setup the scores to a value of -1, default value */
	private void setupScores(int[][] scoresSetup, int playersNum, int totalValues)
	{
		for (int i=0; i < playersNum; i++)
			for (int j=0; j < totalValues;j++)
				scoresSetup[i][j] = -1;
	}

So that when you are selecting a category to place the score of your dice and you try to select a category already selected, then just need to check the score for -1 and if so we know it is a category not already used.

	private Boolean updateScore(int[] scoresUpdate, int category, int score)
	{
		// default is -1, since cannot get this score value
		if (scoresUpdate[category] == -1)
		{
			scoresUpdate[category] = score;
			return false;
		}
		else
		{
			display.printMessage("Category already selected, please select another");
			return true;
		}
	}

Also within the source code, I have included a cheat mode so that you can insert the values of the dice in runtime (when you are asked about the number of players type in -99 and the cheat mode is activated and there is only 1 player setup).

The next post is the extensions of this assignment.

Yahtzee

Tuesday, May 18th, 2010

Yahtzee, over the next two posts going to explain about the thoughts behind working out the categories within the game, e.g. yahtzee, straight etc. And then in the 3rd post I am going to do the extensions of the assignment.

So to start with here are the different types of categories that the 5 dice can fall into with also there score associated value. ( the number at the start is the category that the dice would fall into)

  • 1. Ones. Any dice configuration is valid for this category. The score is equal to the sum of all of the 1’s showing on the dice, which is 0 if there are no 1’s showing.
  • 2–6. Twos, Threes, Fours, Fives, and Sixes. (same as above but for different values). Any dice configuration is valid for these categories. The score is equal to the sum of the 2’s, 3’s, 4’s, and so on, showing on the dice.
  • 7. Three of a Kind. At least three of the dice must show the same value. The score is equal to the sum of all of the values showing on the dice.
  • 8. Four of a Kind. At least four of the dice must show the same value. The score is equal to the sum of all of the values showing on the dice.
  • 9. Full House. The dice must show three of one value and two of another value. The score is 25 points.
  • 10. Small Straight. The dice must contain at least four consecutive values, such as the sequence 2-3-4-5. The score is 30 points.
  • 11. Large Straight. The dice must contain five consecutive values, such as the sequence 1-2-3-4-5. The score is 40 points.
  • 12. Yahtzee! All of the dice must show the same value.. The score is 50 points.
  • 13. Chance. Any dice configuration is valid for this category. The score is equal to the sum of all of the values showing on the dice.

There is a few hints within the assignment

  • There’s not much difference between determining the validity for Three of a Kind, Four of a Kind, Yahtzee, and Full House.
  • There’s not much difference between determining the validity for Small Straight and Large Straight.
  • Any dice configuration is valid for Ones, Twos, Threes, Fours, Fives, Sixes, and Chance.
  • A dice configuration assigned to a category where it doesn’t meet the requirements receives a score of 0.

which kinder give some basic help, on how to figure out the different categories.

Categories 1-6, counting single values

From the start I am going to figure out the first 6 categories, which means that if any of the values within the 5 dice are from 1-6 (each category) then add that dice value into that score. So, what we need to do is loop thought the dice’s and then sum up the dice that meet that requirement (e.g. either a 1 or 2 or 3 depending on that category), so a basic function would require the dice array and also the category (number) to check against and if any of the dice are in that category then add that value of the dice to the returning value. Also since the 13th category, (chance), adds up all of the values of the dice, then can use this function as well. Below is my java function to achieve these categories

	// add single categories e.g. 1,2,3,4,5 and only the dice that have those values
	private int addSingle(int[] dice, int category)
	{
		int sum =0;
		for (int i =0; i < YahtzeeConstants.N_DICE; i++) 
		{
			if (category == dice[i]) sum+=dice[i];
			if (category == YahtzeeConstants.CHANCE)sum+=dice[i]; 
		}
		return sum;
	}

Categories 7,8, 12 – Three/Four of a kind, and Yahtzee

Next, we are going to tackle the 3/4/5(Yahtzee) of a kind, e.g. to start with, I thought that if we had the array dice in a sorted array (e.g. 2,2,2,4,5 as such) then it would be easier to find the groups of dices that are the same, but I am using the sorting for other categories as well, so the sorting function is lower in this post. So once the dice are ordered, what we need to do is to count up the values of the dice (the sum value below) which is going to be return value if there is the correct amount of found dice in the dice array. Finding the correct amount (X being 3/4/5 of dice), we need to count up the number of dice that are of the same value, so we need to have a count value and also whilst going through the array check with the present dice with the previous value, if they are the same increment the count value, otherwise if they are not then re-set the counting value to 1 ONLY if we are below the categories check e.g. three of a kind (3), or four of a kind (4) or yahtzee (5), and then check at the end of the function if the count is above the X value (the categories value) and if so return the sum’d value of the dice array or return 0.

So here it is, the java code that will find out if there is 3 / 4 / 5 dice of the same value and return the sum of the dice.

	// X being the three / four / five (Yahtzee!!)
	private int checkXOfAKind(int[] dice, int X)
	{
		// if count = 3 then there is a three of a kind 
		int count =1, sum = dice[0];
		for (int i =1; i < YahtzeeConstants.N_DICE; i++)
		{
			// if the same value
			if (dice[i] == dice[i-1])
			{
				count++;
			}
			else
			{
				if (count < X) 
					count = 1; 
			}
			sum += dice[i];
		}
		if (count >= X) 
			return sum;
		else 
			return 0;
	}

Bubble sort

Here is am sorting the array of dice into a order, using the bubble sort algorithm, which makes it easier to find the groups of dice values, bubble sort will basically move (bubble) up the array if that value is the highest in the array or find the place where it would fit, for example if you had a array of 5 values

4 , 3 , 5 , 2 , 1

and the first time though the bubble you select the number 4 (since that is at the start of the array, and call the position in the array to be checked positionCheck) and check against the next value, 3 in this case and since 4 is greater than 3 then it will swap those values, so after the first check the new values would be

3, 4, 5, 2, 1

but in the second check on this first run, the next value is 4 (since we have moved one up in the array, and after the swap, it is 4 again and positionCheck is 2 now) but now the next value is 5 which is greater than 4 and so we do not need to swap them values, so positionCheck moves up one more (value of 3) and 5 is greater than 2, thus swap and then again since positionCheck would be 4 and this value is 5 (after the swapping of 5 and 2) which once again 5 is greater than 1, so swap .. so after the first run though we have found the highest number and moved that to the end, so the new array would be

3, 4, 2, 1, 5

so we would need to do the bubble of few more times (length of array amount of times minus 1, since the highest value is moved to the top at the start), but in the code I have not taken off the minus 1 since it just looks slightly better at times, not much of a waste of CPU cycles this time around since there is only 5 dice to check.

	// to find the values, first order the dice, thus able to create the straight and also if the dice are
	// sorted then can easily find the ones, twos etc.
	private void orderDice(int[] dice)
	{
		// use the bubble sort
		for (int i =0; i < YahtzeeConstants.N_DICE; i++)
		{
			for (int j =0; j < YahtzeeConstants.N_DICE; j++)
			{
				// swap if right value is greater than the left
				if (dice[i] < dice[j])
				{
					int temp = dice[i];
					dice[i] = dice[j];
					dice[j] = temp; 
				}
			}
		}
	}

the next post will include the other categories, and here is link to the second post about the yahtzee game.