/* * LuckTester.java * * Created on January 7, 2003, 2:51 PM * * Modify this file, and turn in it. Do not change the package name, class name, * or any method signatures. */ package project1; //don't change import java.util.*; //just for testing turnin import javax.swing.*; //just for testing turnin //import uwcse.*; //just for testing turnin /** Does the God/Godess of Luck know you? Methods to help answer this urgent * question. * * @author dickey */ public class LuckTester implements IOracle { /** Creates a new instance of LuckTester */ public LuckTester() { } /** Wrapper for checkInitials(); see that method for details. (From the IOracle interface). See if some data is suitable to be presented to the oracle. * * @param requestData the data, as a string; exact format and requirements * are oracle-dependent. * @return true iff the requestData is acceptable (can be processed without * error) by the oracle. */ public boolean checkRequestData(String initials) { return checkInitials(initials); // all the work is done there. } /** Check a string to see if it is a pair of uppercase letters. * * @param initials A person's initials: must be exactly two uppercase English letters. * @return true iff both initials are valid (thus avoiding the wrath of the gods). */ public static boolean checkInitials(String initials) { if (initials.length() != 2) { return false; } char firstI = initials.charAt(0); char secondI = initials.charAt(1); if (CharGenerator.isEnglishUpperCase(firstI) && CharGenerator.isEnglishUpperCase(secondI)) { return true; } return false; //end checkInitialsArg } /** Given a person's initials, how long does it take the God/Goddess of luck * to recognize that person? Algorithm: Generate pairs of characters randomly until the desired initials are observed. * @param initials A string of exactly two uppercase alphabetic characters; invalid initials risk inciting the wrath of the gods. * @return the number of random pairs which were generated before the initials * were generated. The minimum possible value is 0. * To avoid infinite loops, at most 1,000,000 pairs are tested. SPECIFIC CONTRACT FOR THIS CLASS: Search the entrails and return the omen found. * It should never go into an infinite loop. * @param requestData The information (typically a name) about which the oracle * is searching for information (for an omen). * @return an omen, or null if there is no omen at all. */ public IOmen searchEntrailsForOmen(String initials) { final int maxTrials = 1000000; final int matchesNeeded = 1; final int count = matchInitialsRandomly(initials, matchesNeeded, maxTrials); final String shortInterpretation = this.interpret(count); final IOmen retOmen = new LuckTesterOmen(count, shortInterpretation); return retOmen; //end search } /** This helper function is intended to be of use to both the LuckTester * and the LuckyOccurrenceCounter oracles. Leaving it in this class * is a bad idea -- Utilities class might have been better. For general * specifications, see LuckTester.SearchEntrailsForOmen. * @param matchesNeeded the method should stop as soon as it has found * this many matches to the input. * @param maxTrials the method should stop as soon as it has conducted * this many trials. * @return if matchesNeeded is 1, then return the number of trials needed * before success. If matchesNeeded is >1, return the number of matches * found. Yes, a bit awkward... */ public static int matchInitialsRandomly(final String initials, final int matchesNeeded, final int maxTrials) { assert initials.length() == 2; final char char1 = initials.charAt(0); final char char2 = initials.charAt(1); int tryCount = 0; int matchCount = 0; while (tryCount < maxTrials) { final char c1 = CharGenerator.randomUpperChar(); final char c2 = CharGenerator.randomUpperChar(); if (c1 == char1 && c2 == char2) { matchCount++; //have found the pair! if (matchCount == matchesNeeded) { break; //leave the loop BEFORE incrementing the trycount } } tryCount++; } //out of the while loop if (matchesNeeded == 1) { return tryCount; } else { return matchCount; } } /** Report on how lucky a result is. @param a value representing the number of trials needed before the god or * goddess recognized someone's initials; these values are on the same * scale as those produced by the tryUntilSuccess method. * @return an English message explaining or evaluating the result. For example, * it could be "You are truly beloved of Fortuna" or "You need to increase * your offerings or disaster will befall", as appropriate. */ private String interpret(double score) { final double aSize = 26.0; if (score <= (aSize/4) * (aSize/4)) { return "Incredible Luck! You are truly beloved of the gods."; } if (score < (aSize/2) * (aSize/2)) { return "The gods smile upon you."; } if (score <= aSize * (aSize/2)) { return "The gods of luck are just a tiny bit displeased."; } if (score <= aSize * aSize) { return "Caution -- luck does not favor you."; } else { return "EXTREME DANGER -- the gods are wrathful unto thee."; } //end interpret } /** Tell the name of this oracle. * @return A short string with the name of the oracle; there should be * no leading or trailing whitespace. */ public String getName() { return "Gods of Luck"; } //end LuckTester }