Blog Details

Game Simulation

1. Description

The game is played with 3 dice. The objective of the game is to obtain the lowest possible score. To that end, the rules of the game are as follows:

  • All dice are thrown on a board.
  • If there are any 3’s, all 3’s are taken off the board and a score of 0 is awarded for this roll.
  • If there are not any 3’s, the lowest die is taken off the board and the value of that lowest die is awarded for this roll.
  • The remaining dice are now re-thrown and the same procedure as above is followed until there are no dice left on the board.
  • The total score for the game is the sum of all the rolls.

2. Example

  • On the first roll you throw the following: 3, 1, 3
  • Second roll, you throw 2
  • you total score is 2.

3. Solution

package com.frank.dicegame;

import java.text.DecimalFormat;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.Scanner;

/**
 * Dice Game
 * @author Frank Wang
 * @version 1.0
 * 
 */
public class DiceGame {
	/**
	 * FinalScore of the game
	 */
	private ArrayList<Integer> finalScore = new ArrayList<Integer>();
	
	private DecimalFormat decimalFormat = new DecimalFormat("#.##");
	
	/**
	 * Game entry
	 */
	public void play() {
		// Interact with users
		System.out.print("Please enter the number you play: ");
		Scanner scanner = new Scanner(System.in);
		int totalTimesPlay = scanner.nextInt();
		while(totalTimesPlay < 0) {
			System.out.print("Please enter a valid number: > 0");
			totalTimesPlay = scanner.nextInt();
		}
		System.out.print("Please enter the number of dice: ");
		int totalDice = scanner.nextInt();
		while(totalDice < 0) {
			System.out.print("Please enter a valid number: > 0");
			totalDice = scanner.nextInt();
		}
		scanner.close();
		// Initialize your finalScore list
		initializeFinalScoreList(totalDice);
		
		// Start time 
		Instant startInstant = Instant.now();
		
		// Call the simulation 
		simulatePlayGame(totalTimesPlay, totalDice);
		
		// End time
		Instant endInstant = Instant.now();
		
		double timeSpentSeconds = Duration.between(startInstant, endInstant).toMillis() / 1000.0;
		
		// Print Result
		printResult(totalTimesPlay, totalDice, timeSpentSeconds);
	}
	
	/**
	 * Initialize the arraylist of final score
	 * @param totalDice
	 */
	private void initializeFinalScoreList(int totalDice) {
		// Each dice has 6 possibilities, so final score should have 6 * dice
		for (int i = 0; i <= 6 * totalDice; i++) {
			finalScore.add(i, 0);
		}
	}
	/**
	 * Game Simulator
	 * @param totalTimsPlay
	 * @param totalDice
	 */
	private void simulatePlayGame(int totalTimesPlay, int totalDice) {
		for (int i = 0; i < totalTimesPlay; i++) {
			int curScore = 0;
			int curDice = totalDice;
			while(curDice > 0) {
				ArrayList<Integer> curDiceList = new ArrayList<Integer>();
				for(int j = 0; j < curDice; j ++) {
					curDiceList.add(new Random().nextInt(6) + 1);
				}
				// Apply the rule 
				if (curDiceList.contains(3)) {
					// Reduce the number of dice 
					for(Integer diceVal : curDiceList) {
						if (diceVal == 3) {
							curDice --;
						}
					}
				} else {
					int minScore = Collections.min(curDiceList);
					curScore += minScore;
					curDice --;
				}
			}
			finalScore.set(curScore, finalScore.get(curScore) + 1);
		}
	}
	
	/**
	 * Print final result
	 */
	private void printResult(int totalTimesPlay, int totalDice, double timeSpentSeconds) {
		System.out.println("Number of simulations was " + totalTimesPlay + " using " + totalDice + " dice.");
		for(int i = 0; i < finalScore.size(); i ++) {
			System.out.println("Total " + i + " occurs " + decimalFormat.format(1.0 * finalScore.get(i) / totalTimesPlay) + " occurred "
					+ finalScore.get(i) + " times.");
		}
		System.out.println("Total simulation took " + timeSpentSeconds + " seconds.");
	}
}

Then, run the play() function.

4. Result