Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package model;
- import java.util.Arrays;
- public class Yatzy {
- // Face values of the 5 dice.
- // 1 <= values[i] <= 6.
- private int[] values = new int[5];
- // private int[] frequencies = new int[7]
- // Number of times the 5 dice have been thrown.
- // 0 <= throwCount <= 3.
- private int throwCount = 0;
- public Yatzy() {
- //
- }
- /**
- * Returns the 5 face values of the dice.
- */
- public int[] getValues() {
- return values;
- }
- /**
- * Sets the 5 face values of the dice. Req: values contains 5 face values in
- * [1..6]. Note: This method is only meant to be used for test, and therefore
- * has package visibility.
- */
- void setValues(int[] values) {
- this.values = values;
- }
- /**
- * Returns the number of times the 5 dice has been thrown.
- */
- public int getThrowCount() {
- return throwCount;
- }
- /**
- * Resets the throw count.
- */
- public void resetThrowCount() {
- throwCount = 0;
- }
- /**
- * Rolls the 5 dice. Only roll dice that are not hold. Req: holds contain 5
- * boolean values.
- */
- public void throwDice(boolean[] holds) {
- // Iterates each item in values, and updates the element if the same index is
- // false in the holds array
- for (int i = 0; i < values.length; i++) {
- if (!holds[i])
- values[i] = (int) (Math.random() * 6 + 1);
- }
- throwCount++;
- }
- // -------------------------------------------------------------------------
- /**
- * Returns all results possible with the current face values. The order of the
- * results is the same as on the score board. Note: This is an optional method.
- * Comment this method out, if you don't want use it.
- */
- public int[] getResults() {
- int[] results = new int[15];
- for (int i = 0; i <= 5; i++) {
- results[i] = this.sameValuePoints(i + 1);
- }
- results[6] = this.onePairPoints();
- results[7] = this.twoPairPoints();
- results[8] = this.threeSamePoints();
- results[9] = this.fourSamePoints();
- results[10] = this.fullHousePoints();
- results[11] = this.smallStraightPoints();
- results[12] = this.largeStraightPoints();
- results[13] = this.chancePoints();
- results[14] = this.yatzyPoints();
- return results;
- }
- // -------------------------------------------------------------------------
- // Returns an int[7] containing the frequency of face values.
- // Frequency at index v is the number of dice with the face value v, 1 <= v
- // <= 6.
- // Index 0 is not used.
- public int[] calcCounts() {
- int[] frequencies = new int[7];
- Arrays.fill(frequencies, 0);
- for (int i = 0; i < values.length; i++) {
- frequencies[values[i]]++; // For each element n in values, index n in frequencies gets incremented by one
- }
- return frequencies;
- }
- /**
- * Returns same-value points for the given face value. Returns 0, if no dice has
- * the given face value. Requires: 1 <= value <= 6;
- */
- public int sameValuePoints(int value) {
- int[] frequencies = calcCounts();
- // Finds the amount of occurrences for 'value' and multiplies it by itself
- // in order to calculate the sum
- return frequencies[value] * value;
- }
- /**
- * Returns points for one pair (for the face value giving highest points).
- * Returns 0, if there aren't 2 dice with the same face value.
- */
- public int onePairPoints() {
- int[] frequencies = calcCounts();
- int maxPoints = 0;
- // Calculates the pair sum if a elements in frequencies is equal or greater than 2
- // If a new pair is found the sum is reset and summed again
- for (int i = 1; i < frequencies.length; i++)
- if (frequencies[i] >= 2) {
- maxPoints = 2 * i;
- }
- return maxPoints;
- }
- /**
- * Returns points for two pairs (for the 2 face values giving highest points).
- * Returns 0, if there aren't 2 dice with one face value and 2 dice with a
- * different face value.
- */
- public int twoPairPoints() {
- int sum = 0;
- int[] frequencies = calcCounts();
- int pairsFound = 0;
- // For each pair found increase the sum by the given pair sum
- // only return 'sum' if two pairs are found
- for (int i = 1; i < frequencies.length; i++) {
- if (frequencies[i] >= 4) // minor performance tweak, should be commented if values array's length is <5
- return 0;
- if (frequencies[i] >= 2) {
- sum += 2 * i;
- pairsFound++;
- }
- if (pairsFound >= 2)
- return sum;
- }
- return 0;
- }
- /**
- * Returns points for 3 of a kind. Returns 0, if there aren't 3 dice with the
- * same face value.
- */
- public int threeSamePoints() {
- // If three of kind is found; return the sum of them
- int[] frequencies = calcCounts();
- for (int i = 1; i < frequencies.length; i++) {
- if (frequencies[i] >= 3)
- return i * 3;
- }
- return 0;
- }
- /**
- * Returns points for 4 of a kind. Returns 0, if there aren't 4 dice with the
- * same face value.
- */
- public int fourSamePoints() {
- // If four of kind is found; return the sum of them
- int[] frequencies = calcCounts();
- for (int i = 1; i < frequencies.length; i++) {
- if (frequencies[i] >= 4)
- return i * 4;
- }
- return 0;
- }
- /**
- * Returns points for full house. Returns 0, if there aren't 3 dice with one
- * face value and 2 dice a different face value.
- */
- public int fullHousePoints() {
- int[] frequencies = calcCounts();
- boolean twoOfKind = false;
- boolean threeofKind = false;
- // Iterates for each element in frequencies expect index 0, if frequencies
- // if either 0,2 or 3 doesn't exist in any given element return 0 immediately
- // if two of kind and three of kind is found return the dice sum
- for (int i = 1; i < frequencies.length; i++) {
- if (frequencies[i] == 3)
- twoOfKind = true;
- else if (frequencies[i] == 2) {
- if (threeofKind)
- break; // Very minor performance tweak
- threeofKind = true;
- } else if (frequencies[i] != 0)
- break;
- if (twoOfKind && threeofKind) {
- int sum = 0;
- for (int j = 0; j < 5; j++)
- sum += this.values[j];
- return sum;
- }
- }
- return 0;
- }
- /**
- * Returns points for small straight. Returns 0, if the dice are not showing
- * 1,2,3,4,5 (sorted).
- */
- public int smallStraightPoints() {
- int[] frequencies = calcCounts();
- // If values is equal to 1,2,3,4,5 (sorted), frequencies must be equal to {0,1,1,1,1,1,0}
- int[] smallStraight = new int[] { 0, 1, 1, 1, 1, 1, 0 };
- if (Arrays.equals(frequencies, smallStraight))
- return 15;
- return 0;
- }
- /**
- * Returns points for large straight. Returns 0, if the dice is not showing
- * 2,3,4,5,6.
- */
- public int largeStraightPoints() {
- int[] frequencies = calcCounts();
- // If values is equal to 2,3,4,5,6 (sorted), frequencies must be equal to {0,0,1,1,1,1,1}
- int[] largeStraight = new int[] { 0, 0, 1, 1, 1, 1, 1 };
- if (Arrays.equals(frequencies, largeStraight))
- return 20;
- return 0;
- }
- /**
- * Returns points for chance.
- */
- public int chancePoints() {
- // Return the sum for all elements in values
- int sum = 0;
- for (int i = 0; i < 5; i++)
- sum += this.values[i];
- return sum;
- }
- /**
- * Returns points for yatzy. Returns 0, if there aren't 5 dice with the same
- * face value.
- */
- public int yatzyPoints() {
- int[] frequencies = calcCounts();
- // Iterates for each element in frequencies expect index 0, if frequencies
- // if 5 exists in frequencies a yatzy has occurred
- for (int i = 1; i < frequencies.length; i++) {
- if (frequencies[i] == 5)
- return 50;
- if (frequencies[i] != 0)
- return 0;
- }
- return -1; // In theory should't be necessary given 'values' is valid according to the Yatzy rules
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement