/** Chuck-a-luck and Exercises. * * AUTHORS * * Original: John P. Spurgeon with support from Akil, Jonathan, Kai, Katherine, and Leon. * This version: John P. Spurgeon. * * VERSION LINEAGE * * 0. https://apcsafreeresponsequestions.blogspot.com/2019/02/original-chuck-a-luck.html. (ORIGINAL) * 1. https://apcsafreeresponsequestions.blogspot.com/2019/02/chuck-a-luck.html. (EXERCISES) * 2. https://apcsafreeresponsequestions.blogspot.com/2019/02/chuck-a-luck-answers.html. (ANSWERS TO EXERCISES 1-4) * 3. https://apcsafreeresponsequestions.blogspot.com/2019/02/chuck-a-luck-or-risk.html. (ANSWERS TO EXERCISES 1-5) * * DESCRIPTION * * This is the version of Chuck-a-luck that Mr. Spurgeon presented to his * AP Computer Science A class on Tuesday, 12 February 2019. Students had the * entire class period (45 minutes) to attempt the exercises in teams of 2 or 3. * Each team used one computer. Team members took turns making changes to the * source code while the other team members watched and assisted. At the end of * the class period each team sent a single working program containing answers * to the exercises they completed to Mr. Spurgeon via email. * * CHANGE SUMMARY * * - Look-and-Feel. * Changed ASCII die faces (reduced size). * - Interfaces (NEW). * Added Die. * Added CarnivalGame. * Added DiceGame. * - Classes. * Removed Dice: obsoleted by new classes. * Changed ChuckALuck: no longer public; added constructor. * Added AbstractDie. * Added AbstractFairDie. * Added FairSixSidedDie. * Added FairSixSidedAsciiDie. * Added Carny. * Added Dealer (public). * - Exercises (NEW). * Added exercises 1-5. * * NOTE ON THE EXERCISES * * The five exercises found at the bottom of this page are somewhat vaguely * worded and can be answered in many different ways. The intent is to * encourage students to be creative and ask questions when necessary. Real- * world programming rarely begins with a clean slate or a perfect program. * In addition to providing exposure to a variety of object-oriented Java * programming constructs and techniques--interfaces, constructors, inheritance, * abstract classes and methods, etc.--the exercises are designed to provide * practice that is needed to develop practical skills including: having * constructive conversations with bearers of problems, becoming familiar with * existing source code that is far from perfect, working within constraints, * and identifying and considering alternate solutions to problems. */ import java.util.*; interface Die { Die roll(); Integer valueOf(); } interface CarnivalGame { CarnivalGame recordBets(String[] bets); void announceWinners(); } interface DiceGame { DiceGame analyzeDice(); DiceGame rollDice(); DiceGame showDice(); } abstract class AbstractDie implements Die { private Integer value; protected AbstractDie() { value = nextValue(); } public abstract int numberOfSides(); public final Die roll() { value = nextValue(); return this; } public String toString() { return value.toString(); } public final Integer valueOf() { return value; } protected abstract int nextValue(); } abstract class AbstractFairDie extends AbstractDie { protected final int nextValue() { return (int)(1 + Math.random() * numberOfSides()); } } class FairSixSidedDie extends AbstractFairDie { public int numberOfSides() { return 6; } } class FairSixSidedAsciiDie extends FairSixSidedDie { private static final String[] sides = { "---------\n" + "| |\n" + "| * |\n" + "| |\n" + "---------" , "---------\n" + "| * |\n" + "| |\n" + "| * |\n" + "---------" , "---------\n" + "| * |\n" + "| * |\n" + "| * |\n" + "---------" , "---------\n" + "| * * |\n" + "| |\n" + "| * * |\n" + "---------" , "---------\n" + "| * * |\n" + "| * |\n" + "| * * |\n" + "---------" , "---------\n" + "| * * |\n" + "| * * |\n" + "| * * |\n" + "---------" }; public String toString() { return sides[valueOf() - 1]; } } /** Chuck-a-luck is played with three standard dice that are kept in a device * shaped somewhat like an hourglass that resembles a wire-frame bird cage * and pivots about its centre. The dealer rotates the cage end over end, * with the dice landing on the bottom. Wagers are placed based on possible * combinations that can appear on the three dice. * * Source: https://en.wikipedia.org/wiki/Chuck-a-luck * * WAGERS * * Single: A specific number will appear. * Triple: Any of the triples (all three dice show the same number) will appear. * Big: The total score will be 11 (alternatively 12) or higher and not a triple. * Small: The total score will be 10 (alternatively 9) or lower and not a triple. * Field: The total score will be outside the range of 8 to 12 (inclusive). */ class ChuckALuck implements DiceGame, CarnivalGame { public static final String Triple = "Triple", Big = "Big", Small = "Small", Field = "Field"; private final Die[] dice; private final List<String> results = new LinkedList<String>(); private String[] bets; public ChuckALuck(FairSixSidedDie[] dice) { if (dice.length != 3) { throw new IllegalArgumentException("Wrong number of dice."); } this.dice = dice; } public ChuckALuck analyzeDice() { final Integer v1 = dice[0].valueOf(), v2 = dice[1].valueOf(), v3 = dice[2].valueOf(); final int sum = v1 + v2 + v3; results.clear(); if (v1 == v2 && v2 == v3) { results.add(Triple); } else if (sum >= 11) { results.add(Big); } else if (sum <= 10 ) { results.add(Small); } if (sum < 8 || sum > 12) { results.add(Field); } return this; } public void announceWinners() { for (int i = 0; i < bets.length; i++) { String bet = bets[i]; if (results.indexOf(bet) >= 0) { System.out.println("Bet " + (i + 1) + " (" + bet + ") wins!"); } } } public ChuckALuck recordBets(String[] bets) { this.bets = bets; return this; } public ChuckALuck rollDice() { for (Die die : dice) die.roll(); return this; } public ChuckALuck showDice() { for (Die die : dice) System.out.println(die); return this; } public String toString() { return "Chuck-a-luck"; } } final class Carny { public static void acceptBets(CarnivalGame game, String[] bets) { game.recordBets(bets); } public static void payWinners(CarnivalGame game) { game.announceWinners(); } public static void playGame(DiceGame game) { game.rollDice(); game.showDice(); game.analyzeDice(); } } public class Dealer { private static final FairSixSidedDie[] diceCage = { new FairSixSidedDie(), new FairSixSidedDie(), new FairSixSidedDie() }; public static void main(String args[]) { final ChuckALuck game = new ChuckALuck(diceCage); System.out.println(game); Carny.acceptBets(game, args); Carny.playGame(game); Carny.payWinners(game); } }
Exercises
- Change the program above so that it displays ASCII images of die faces instead of their values.
- Create a class called Dodecahedron and use it in place of FairSixSidedDie.
- Create a class called AlternateChuckALuck that defines analyzeDice based on the alternate wager conditions described above.
- Create a class called AbstractChuckALuck where analyzeDice is abstract. Define ChuckALuck and AlternateChuckALuck such that they both extend AbstractChuckALuck.
- Create a different type of dice game that also implements the DiceGame and CarnivalGame interfaces. Modify the Dealer class so that it plays either your new game or Chuck-A-Luck depending on the value of the first command line argument.