+1 (315) 557-6473 

Create A Game of Milton Bradley’s Yahtzee in Java Assignment Solution.


Instructions

Objective
Write a program to create a game of Milton Bradley’s Yahtzee in java.

Requirements and Specifications

Program to create a game of Milton Bradley’s Yahtzee in java language

Source Code

DICE CUP

public class DiceCup {

 /**

  * Default number of dice

  */

 public static final int DEFAULT_NUMBER = 5;

 /**

  * Number of dice in cup

  */

 private int number;

 /**

  * Array, containing die objects

  */

 private final Die[] dice;

 /**

  * Constructor, creating cup with default number of dice

  */

 public DiceCup() {

  this(DEFAULT_NUMBER);

 }

 /**

  * Constructor, creating cup with given number of dice

  * @param number of dice in cup to create

  */

 public DiceCup(int number) {

  this.number = number;

  this.dice = new Die[number];

  for (int i = 0; i<number; i++) {

   this.dice[i] = new Die();

  }

 }

 /**

  * Method for rolling all dice in cup

  */

 public void roll() {

  roll(new boolean[number]);

 }

 /**

  * Method for rolling selected dice in cup

  * @param keep boolean array to select which dice to roll

  */

 public void roll(boolean[] keep) {

  for (int i = 0; i<number; i++) {

   if (!keep[i]) {

    dice[i].roll();

   }

  }

 }

 /**

  * Method returning current dice values as int array

  * @return dice value array

  */

 public int[] show() {

  int[] result = new int[number];

  for (int i = 0; i<number; i++) {

   result[i] = dice[i].read();

  }

  return result;

 }

 /**

  * Overridden toString method

  * @return string representation of dice cup

  */

 @Override

 public String toString() {

  StringBuilder builder = new StringBuilder("Roll: ");

  for (int i = 0; i<number; i++) {

   builder.append(" ").append((i+1)).append(":[").append(dice[i].read()).append("]");

  }

  return builder.toString();

 }

}

DIE

import java.util.Random;

public class Die {

 /**

  * Default number of sides

  */

 public static final int DEFAULT_SIDES = 6;

 /**

  * Number of sides of this dice

  */

 private final int sides;

 /**

  * Current value shown on die

  */

 private int shows;

 /**

  * Constructor, creating die with default number of sides

  */

 public Die() {

  this(DEFAULT_SIDES);

 }

 /**

  * Constructor, creating die with given number of sides

  * @param sides number of sides of this dice

  */

 public Die(int sides) {

  this.sides = sides;

  roll();

 }

 /**

  * Method for making die roll

  */

 public void roll() {

  // choosing random value in range with random

  Random random = new Random();

  shows = random.nextInt(sides) + 1;

 }

 /**

  * Method, returning current value shown by die

  * @return current value

  */

 public int read() {

  return shows;

 }

}

GAME

import java.util.Arrays;

import java.util.List;

import java.util.Scanner;

import java.util.stream.Collectors;

public class Game {

 /**

  * Scanner object to read user input

  */

 private final Scanner scanner;

 /**

  * Number of players in game

  */

 private final int numPlayers;

 /**

  * Array, containing player objects

  */

 private final Player[] players;

 /**

  * Dice Cup, which is used for playing

  */

 private final DiceCup diceCup;

 /**

  * Constructor, creating game instance for given number of player

  * @param scanner to scan user input

  * @param numPlayers number of players in game

  */

 public Game(Scanner scanner, int numPlayers) {

  this.scanner = scanner;

  this.numPlayers = numPlayers;

  this.players = new Player[numPlayers];

  for (int i = 0; i < numPlayers; i++) {

   players[i] = new Player(i + 1);

  }

  diceCup = new DiceCup();

 }

 /**

  * Auxiliary method for generating string out of boolean keep array

  * @param keep boolean array to generate string for

  * @return string representation of boolean array

  */

 private String generateKeepString(boolean[] keep) {

  StringBuilder builder = new StringBuilder("Keep?:");

  for (int i = 0; i < keep.length; i++) {

   builder.append(" ").append((i + 1)).append(": ").append(keep[i] ? 'y' : 'n').append(" ");

  }

  builder.append(System.lineSeparator());

  return builder.toString();

 }

 /**

  * Auxiliary method for reading user int input

  * @param prompt string prompt to ask user with

  * @param min minimum allowed value

  * @param max maximum allowed value

  * @return valid user input

  */

 private int getOption(String prompt, int min, int max) {

  while (true) {

   try {

    // asking user

    System.out.print(prompt + ": ");

    // trying to parse input as int

    int choice = Integer.parseInt(scanner.nextLine());

    // if it's out of bounds, throwing an exception

    if (choice < min || choice > max) {

     throw new IllegalArgumentException();

    }

    // input is valid, returning choice

    return choice;

   } catch (Exception e) {

    // exception was thrown - keep asking and showing error

    System.out.println("Invalid input");

   }

  }

 }

 /**

  * Main play method. Performs all game process

  */

 public void play() {

  // iterating over rounds

  for (int round = 0; round <= 12; round++) {

   // iterating over players

   for (int turn = 0; turn < numPlayers; turn++) {

    // showing current state

    Player currPlayer = players[turn];

    System.out.println(currPlayer.getName() + "'s turn!");

    System.out.println();

    System.out.println(currPlayer.getName() + " Scorecard");

    System.out.println(currPlayer.getScoreSheet());

    System.out.println();

    System.out.println("Turn #" + (round + 1));

    System.out.println("Roll #1");

    diceCup.roll();

    System.out.println(diceCup);

    // asking user, which dice to keep

    boolean[] keep = new boolean[DiceCup.DEFAULT_NUMBER];

    for (int roll = 0; roll < 2; roll++) {

     System.out.println(generateKeepString(keep));

     System.out.println("Which die do you want to keep?");

     int choice = getOption("Enter 1 - 5 to toggle that die or 0 to roll", 0, DiceCup.DEFAULT_NUMBER);

     while (choice > 0) {

      keep[choice-1] = !keep[choice-1];

      System.out.println(generateKeepString(keep));

      choice = getOption("Enter 1 - 5 to toggle that die or 0 to roll", 0, DiceCup.DEFAULT_NUMBER);

     }

     System.out.println("Roll #" + (roll + 2));

     diceCup.roll(keep);

     System.out.println(diceCup);

    }

    System.out.println("Scoring " + currPlayer.getName() + " turn " + (round + 1));

    System.out.println();

    System.out.println(diceCup);

    System.out.println();

    System.out.println("Where would you like to score this roll?");

    System.out.println(currPlayer.getScoreSheet());

    while (!currPlayer.getScoreSheet().evaluate(getOption("Choose 1 - 13 to score your roll", 1, 13), diceCup.show())) {

     System.out.println("This option is already scored");

     System.out.println("Where would you like to score this roll?");

     System.out.println(currPlayer.getScoreSheet());

    }

    System.out.println();

   }

  }

  // finding max score

  int maxScore = Arrays.stream(players).mapToInt(Player::getTotal).max().orElse(0);

  // searching for players with max score

  List<Player> winners = Arrays.stream(players).filter(p -> p.getTotal() == maxScore).collect(Collectors.toList());

  // printing winners

  System.out.println("Winner(s):");

  for (Player winner : winners) {

   System.out.println(winner.getName());

  }

  System.out.println("with score " + maxScore);

 }

 public static void main(String[] args) {

  try (Scanner scanner = new Scanner(System.in)) {

   // asking for number of players

   System.out.print("Please, enter number of players: ");

   int players = Integer.parseInt(scanner.nextLine());

   System.out.println();

   // starting game

   Game game = new Game(scanner, players);

   game.play();

  }

 }

}

PLAYER

public class Player {

 /**

  * Player number

  */

 private final int number;

 /**

  * Player score sheet

  */

 private final ScoreSheet scoreSheet;

 /**

  * Constructor, creating player with given number

  * @param number for player to create

  */

 public Player(int number) {

  this.number = number;

  scoreSheet = new ScoreSheet();

 }

 /**

  * Method, returning player name

  * @return player name

  */

 public String getName() {

  return "Player #" + number;

 }

 /**

  * Method for getting current player total score

  * @return player total score

  */

 public int getTotal() {

  return scoreSheet.getTotal();

 }

 /**

  * Getter method for scoreSheet field

  * @return player score sheet

  */

 public ScoreSheet getScoreSheet() {

  return scoreSheet;

 }

}

SCORESHEET

import java.util.Arrays;

import java.util.HashMap;

import java.util.Map;

public class ScoreSheet {

 /**

  * Array of combination names

  */

 private final static String[] NAMES = new String[]{"Ones", "Twos", "Threes", "Fours", "Fives", "Sixes",

 "Triple", "Quad", "Full House", "Small Straight", "Large Straight", "Yahtzee", "Chance"};

 /**

  * Array of points scored

  */

 private final int[] scores;

 /**

  * Constructor, creating empty scoresheet

  */

 public ScoreSheet() {

  scores = new int[13];

  for (int i = 0; i<13; i++) {

   scores[i] = -1;

  }

 }

 /**

  * Method, performing evaluation of current dice with given combination option

  * @param choice chosen combination

  * @param dice dice score array

  * @return true, if given option was not evaluated yet, false - otherwise

  */

 public boolean evaluate(int choice, int[] dice) {

  int option = choice - 1;

  // checking, if option is valid

  if (scores[option] >= 0) {

   return false;

  }

  // counting entries of each possible score

  Map<Integer, Integer> counters = new HashMap<>();

  for (int die : dice) {

   counters.merge(die, 1, Integer::sum);

  }

  switch (option) {

   // evaluating simple options

   case 0:

   case 1:

   case 2:

   case 3:

   case 4:

   case 5:

    scores[option] = (option + 1) * counters.get(option + 1);

    break;

   case 6:

    // there must be at least 1 value with count at least 3

    scores[option] = (counters.values().stream().anyMatch(i -> i >= 3)) ? Arrays.stream(dice).sum() : 0;

    break;

   case 7:

    // there must be at least 1 value with count at least 4

    scores[option] = (counters.values().stream().anyMatch(i -> i >= 4)) ? Arrays.stream(dice).sum() : 0;

    break;

   case 8:

    // looking for two values: one with count 2, another with count 3

    boolean fullHouseFound = false;

    for (int i = 1; i<=Die.DEFAULT_SIDES; i++) {

     if (counters.getOrDefault(i, 0) != 2) {

      continue;

     }

     for (int j = 1; j<=Die.DEFAULT_SIDES; j++) {

      if (counters.getOrDefault(i, 0) == 3) {

       fullHouseFound = true;

       break;

      }

     }

     if (fullHouseFound) {

      break;

     }

    }

    scores[option] = fullHouseFound ? 25 : 0;

    break;

   case 9:

    // trying to find large straight, starting from 1,2,3

    boolean smallStraightFound = false;

    for (int i = 1; i<=Die.DEFAULT_SIDES - 3; i++) {

     boolean found = true;

     for (int j = 0; j<4; j++) {

      if (!counters.containsKey(i+j)) {

       found = false;

       break;

      }

     }

     if (found) {

      smallStraightFound = true;

      break;

     }

    }

    scores[option] = smallStraightFound ? 30 : 0;

    break;

   case 10:

    // trying to find large straight, starting from 1,2

    boolean largeStraightFound = false;

    for (int i = 1; i<=Die.DEFAULT_SIDES - 4; i++) {

     boolean found = true;

     for (int j = 0; j<DiceCup.DEFAULT_NUMBER; j++) {

      if (!counters.containsKey(i+j)) {

       found = false;

       break;

      }

     }

     if (found) {

      largeStraightFound = true;

      break;

     }

    }

    scores[option] = largeStraightFound ? 40 : 0;

    break;

   case 11:

    // there must be at least 1 value with count at least 5

    scores[option] = (counters.values().stream().anyMatch(i -> i >= 5)) ? 50 : 0;

    break;

   case 12:

    // just summing up all values

    scores[option] = Arrays.stream(dice).sum();

    break;

   default:

    throw new IllegalArgumentException();

  }

  return true;

 }

 /**

  * Method for getting total score from score sheet

  * @return total points scored

  */

 public int getTotal() {

  int total = 0;

  for (int i = 0; i<13; i++) {

   if (scores[i] >= 0) {

    total += scores[i];

   }

  }

  return total;

 }

 /**

  * Overridden toString method

  * @return string representation of score sheet

  */

 @Override

 public String toString() {

  StringBuilder builder = new StringBuilder();

  for (int i = 0; i<13; i++) {

   builder.append(String.format("%-23s", NAMES[i] + ":")).append("[");

   if (scores[i] >= 0) {

    builder.append(String.format("%2d", scores[i]));

   }

   else {

    builder.append("--");

   }

   builder.append("]").append(System.lineSeparator());

  }

  builder.append("---------------------------").append(System.lineSeparator());

  builder.append(String.format("%-23s%3d", "Total:", getTotal()));

  return builder.toString();

 }

}