trying to get areasConnected to display. As you can see I have attemped (poorly I know) to substitute this method with the nextArea method. Will post the GameWorld class below this one. Please note that I DO NOT want someone to do the work for me, just point me in the right direction.
/**
* Auto Generated Java Class.
*/
import java.util.Scanner;
public class WereWolfenstein2D {
GameWorld gameOne = new GameWorld(true);
private boolean tracing = false;
Scanner sc = new Scanner(System.in);
String input, answer, restart;
int walk, current;
char area;
public void explain() {
System.out.print("You are a hunter, defend the village and capture the Werewolf by shooting it three times. ");
System.out.println("If you get bitten visit the village to be cured. " +
"If you get bitten twice you'll turn." +
"If none of the town folk survive, you lose. " +
"Now choose how what circumstances you're willing to work in.");
}
public void pickDifficulity(){
{
System.out.println("Easy, Normal or Hard?");
input = sc.nextLine();
input = input.toUpperCase();
if (input.equals("EASY")){
System.out.println(Difficulty.EASY);
}
else if (input.equals("NORMAL")) {
System.out.println(Difficulty.NORMAL);
}
else if (input.equals("HARD")) {
System.out.println(Difficulty.HARD);
}
}
}
public void preMove(){
System.out.println("current stats");
// no. of actions until dawn
gameOne.checkForDawn();
// current population
gameOne.getVillagePopulation();
// if they can hear village
gameOne.isVillageNear();
// if not bitten:
gameOne.getShotCount();
// current area no.
gameOne.getCurrentArea();
// number of connecting areas
// gameOne.nextArea(char direction);
//gameOne.areasConnected(int s1, int s2);
// no of times werewolf shot
// no. of bullets left
gameOne.getShotCount();
// if the player can smell the wolf
gameOne.werewolfNear();
}
public void pickMove(){
System.out.print("walk shoot, quit or reset?");
answer = sc.nextLine();
//walk
//if area not connected: alert
//if into village: alert that they are healed
//if containing wolf: altert they are bitten, if already bitten game ends
switch(answer) {
case "walk": System.out.println("Pick a direction to walk in south(s), east(e), north(n), west(w)");
current = gameOne.getCurrentArea(); //current area they are in
char direction = sc.next().charAt(current); //direction they wish to travel
// char area = sc.next().charAt(current);
char area1 = 's';
char area2 = 'e';
char area3 = 'n';
char area4 = 'w';
System.out.println("the area to the south is: " + gameOne.nextArea(area1));
System.out.println("the area to the east is: " + gameOne.nextArea(area2));
System.out.println("the area to the north is: " + gameOne.nextArea(area3));
System.out.println("the area to the west is: " + gameOne.nextArea(area4));
System.out.println(current +"<< >>" + direction);
System.out.println("pick again");
int newcurrent = direction;
direction = sc.next().charAt(newcurrent);
System.out.println(newcurrent + "<< new >>" + direction);
break;
case "shoot":
break;
case "quit": System.out.print("would you like to start again? (yes/no)");
restart = sc.nextLine();
if (restart.equals("yes")) {
gameOne.reset();
}
else {
System.out.println("Thanks for playing");
}
break;
case "reset": //gameOne.reset();
this.pickDifficulity();
break;
}
}
public void play() {
this.explain();
this.pickDifficulity();
this.preMove();
this.pickMove();
// gameOne.reset();
}
public void setTracing(boolean onOff) {
tracing = onOff;
}
public void trace(String message) {
if (tracing) {
System.out.println("WereWolfenstein2D: " + message);
}
}
}
GAMEWORLD CLASS>>>
public class GameWorld {
// Final instance variables
public final int NIGHT_LENGTH = 3; // three actions until dawn arrives (day is instantaneous)
private final int MAX_SHOTS_NEEDED = 3; // successful hits required to subdue werewolf
//This map is _deliberately_ confusing, although it actually a regular layout
private int[] east = {1,2,0,4,5,3,7,8,6}; // areas to east of current location (index)
private int[] west = {2,0,1,5,3,4,8,6,7}; // areas to west of current location (index)
private int[] north = {6,7,8,0,1,2,3,4,5}; // areas to north of current location (index)
private int[] south = {3,4,5,6,7,8,0,1,2}; // areas to south of current location (index)
private int numAreas = south.length; // number of areas in the "world"
// Non-final instance variables
private int currentArea; // current location of player
private int villagePos; // area where the village is located
private int wolfPos; // area where the werewolf can be found
private Difficulty level; // difficulty level of the game
private int villagerCount; // number of villagers remaining
private int stepsUntilDawn; // number of actions until night falls
private boolean isBitten; // is the player currently bitten and in need of treatment?
private int hitsRemaining; // number of shots still needed to subdue the werewolf
private Random generator; // to use for random placement in areas
private boolean tracing; // switch for tracing messages
/**
* Creates a game world for the WereWolfenstein 2D game.
* #param traceOnOff whether or not tracing output should be shown
*/
public GameWorld(boolean traceOnOff) {
trace("GameWorld() starts...");
generator = new Random();
generator.setSeed(101); //this default setting makes the game more predictable, for testing
setTracing(traceOnOff); //this may replace random number generator
trace("...GameWorld() ends");
}
/**
* Returns the number of the current area.
* #return which area number player is within
*/
public int getCurrentArea() {
trace("getCurrentArea() starts... ...and ends with value " + currentArea);
return currentArea;
}
/**
* Returns the number of shot attempts, formatted as "total hits/total required"
* #return the fraction of shots that have hit the werewolf (out of the required number of hits)
*/
public String getShotCount() {
String count; // formatted total
trace("getShotCount() starts...");
count = (MAX_SHOTS_NEEDED - hitsRemaining) + "/" + MAX_SHOTS_NEEDED;
trace("getShotCount() ...ends with value " + count);
return count;
}
/**
* Returns the current number of villagers.
* #return the villager count, >= 0
*/
public int getVillagePopulation() {
return villagerCount;
}
/**
* Returns the number of actions remaining until dawn arrives.
* #return actions remaining until dawn event
*/
public int getActionsUntilNight() {
return stepsUntilDawn;
}
/**
* Randomly determines a unique starting location (currentArea), village
* position (villagePos) and werewolf position (wolfPos).
* #param difficulty - the difficulty level of the game
* #return the starting location (area)
*/
public int newGame(Difficulty difficulty) {
trace("newGame() starts...");
level = difficulty;
//determine village location and initialise villagers and night length
villagePos = generator.nextInt(numAreas);
stepsUntilDawn = NIGHT_LENGTH;
villagerCount = level.getVillagerCount();
// determine player's position
if (level.getPlayerStartsInVillage()) {
//place player in village
currentArea = villagePos;
} else {
//pick a random location for player away from the village
do {
currentArea = generator.nextInt(numAreas);
} while (currentArea == villagePos);
}
trace("player starts at " + currentArea);
// determine werewolf's position
trace("calling resetTargetPosition()");
resetWolfPosition();
// define player's status
trace("player is not bitten");
isBitten = false;
trace("werewolf is not hit");
hitsRemaining = MAX_SHOTS_NEEDED;
trace("...newGame() ends with value " + currentArea);
return currentArea;
}
/** Randomly determines a unique location for werewolf (wolfPos). */
private void resetWolfPosition() {
int pos; // werewolf position
trace("resetWolfPosition() starts...");
pos = generator.nextInt(numAreas);
while (pos == currentArea || pos == villagePos) {
trace("clash detected");
// avoid clash with current location
pos = generator.nextInt(numAreas);
}
wolfPos = pos;
trace("werewolf position is " + wolfPos);
trace("...resetWolfPosition() ends");
}
/**
* Returns the nearness of the werewolf.
* #return Status of werewolf's location
* BITTEN: if player is currently bitten (and delirious)
* NEAR: if werewolf is in a connected area
* FAR: if werewolf is elsewhere
*/
public Result werewolfNear() {
trace("werewolfNear() starts");
if (isBitten) {
trace("werewolfNear(): player is still delirious from a bite so cannot sense nearness of werewolf");
return Result.BITTEN;
}
trace("werewolfNear() returning result of nearnessTo(" + wolfPos + ")");
return nearnessTo(wolfPos);
}
/**
* Returns true if the village is near the player (in an adjacent area),
* false otherwise.
* #return true if the player is near (but not in) the village, false otherwise.
*/
public boolean isVillageNear() {
trace("villageNear() starts and returns result of nearnessTo(" + villagePos + ") == Result.NEAR");
return nearnessTo(villagePos) == Result.NEAR;
}
/**
* Returns the nearness of the player to the nominated area.
* #param area the area (werewolf or village) to assess
* #return Nearness of player to nominated area
* NEAR: if player is adjacent to area
* FAR: if player is not adjacent to the area
*/
private Result nearnessTo(int area) {
Result closeness; // closeness of player to area
trace("nearnessTo() starts...");
if ((east[currentArea] == area) ||
(west[currentArea] == area) ||
(north[currentArea] == area) ||
(south[currentArea] == area))
{
// player is close to area
closeness = Result.NEAR;
trace("area is close");
} else {
// player is not adjacent to area
closeness = Result.FAR;
trace("area is far");
}
trace("...nearnessTo() ends with value " + closeness);
return closeness;
}
/**
* Try to move the player to another area. If the move is not IMPOSSIBLE
* then the number of actions remaining before dawn arrives is decremented.
* #param into the area to try to move into
* #return Result of the movement attempt
* SUCCESS: move was successful (current position changed)
* VILLAGE: move was successful and player has arrived in the village (and is not longer bitten)
* BITTEN: move was successful but player encountered the werewolf
* FAILURE: move was successful but already bitten player encountered the werewolf again
* IMPOSSIBLE: move was impossible (current position not changed)
*/
public Result tryWalk(int into) {
Result result; // outcome of walk attempt
trace("tryWalk() starts...");
if (areasConnected(currentArea, into)) {
trace("move into area " + into );
currentArea = into;
if (currentArea != wolfPos) {
// werewolf not found
trace("werewolf not encountered");
result = Result.SUCCESS;
if (currentArea == villagePos) {
isBitten = false;
result = Result.VILLAGE;
}
} else {
// werewolf encountered
if (isBitten) {
trace("werewolf encountered again");
result = Result.FAILURE;
} else {
// not bitten
trace("werewolf encountered");
result = Result.BITTEN;
isBitten = true;
resetWolfPosition();
}
}
stepsUntilDawn--; //one more action taken
} else { // area not connected
trace("move not possible");
result = Result.IMPOSSIBLE;
}
trace("...tryWalk() ends with value " + result);
return result;
}
/**
* Try to shoot a silver bullet at the werewolf from the current area.
* If the shot is not IMPOSSIBLE then the number of actions remaining
* before dawn arrives is decremented.
* #param into the area to attempt to shoot into
* #return status of attempt
* CAPTURED: werewolf has been subdued and captured
* SUCCESS: werewolf has been hit but is not yet captured
* VILLAGE: the shot went into the village and a villager has died
* FAILURE: werewolf not present
* IMPOSSIBLE: area not connected
*/
public Result shoot(int into) {
Result result; // outcome of shooting attempt
trace("shoot() starts...");
if (areasConnected(currentArea, into)) {
// area connected
trace("shoot into area " + into );
if (into == villagePos) {
result = Result.VILLAGE;
villagerCount--;
trace("shot into village");
} else if (into != wolfPos) {
// not at werewolf location (but at least didn't shoot into the village!)
result = Result.FAILURE;
trace("werewolf not present");
} else {
// at werewolf location
hitsRemaining--;
if (hitsRemaining == 0) {
// last hit required to subdue the werewolf
trace("werewolf subdued and captured");
result = Result.CAPTURED;
} else {
// not the last shot
result = Result.SUCCESS;
if (level.getWolfMovesWhenShot()) {
resetWolfPosition();
}
trace("werewolf found but not yet captured");
}
}
stepsUntilDawn--; //one more action taken
} else {
// not at valid location
result = Result.IMPOSSIBLE;
trace("area not present");
}
trace("...shoot() ends with value " + result);
return result;
}
/**
* Checks if there are no more actions left until dawn arrives. If dawn is
* here then decrements the number of villagers, repositions the werewolf
* and resets the number of actions until dawn arrives again. Returns true
* if dawn occurred, false if it did not.
* #return true if dawn just happened, false if has not yet arrived
*/
public boolean checkForDawn() {
if (stepsUntilDawn == 0) {
if (villagerCount > 0) { //dawn may arrive after shooting the last villager
villagerCount--;
}
stepsUntilDawn = NIGHT_LENGTH;
resetWolfPosition();
return true;
}
return false;
}
/**
* Returns true if areas s1 and s2 are connected, false otherwise.
* Also returns false if either area is an invalid area identifier.
* #param s1 the first area
* #param s2 the second area
* #return true if areas are connected, false otherwise
*/
private boolean areasConnected(int s1, int s2) {
if (Math.min(s1, s2) >= 0 && Math.max(s1, s2) < numAreas) { //valid areas...
//...but are they connected?
return east[s1] == s2 || north[s1] == s2 || west[s1] == s2 || south[s1] == s2;
}
//Either s1 or s2 is not a valid area identifier
return false;
}
/**
* Determine ID number of an adjacent area given its direction from the
* current area.
* #param direction the direction to look (n for north, e for east, s for south, w for west)
* #return number of the area in that direction
* #throws IllegalArgumentException if direction is null
*/
public int nextArea(char direction) {
int nextIs; // area number of area in indicated direction
//Valid values
final char N = 'n', E = 'e', S = 's', W = 'w';
trace("nextArea() starts...");
// examine adjacent areas
switch (direction) {
case N: trace("determining number of area to the north");
nextIs = north[currentArea];
break;
case E: trace("determining number of area to the east");
nextIs = east[currentArea];
break;
case S: trace("determining number of area to the south");
nextIs = south[currentArea];
break;
case W: trace("determining number of area to the west");
nextIs = west[currentArea];
break;
default: throw new IllegalArgumentException("Direction must be one of " + N + ", " + E + ", " + S + " or " + W);
}
trace("...nextArea() ends with value for '" + direction + "' of " + nextIs);
return nextIs;
}
/** Resets all game values. */
public void reset() {
trace("reset() starts...");
// reset all game values
trace("resetting all game values");
newGame(level); //start a new game with the same difficulty
trace("...reset() ends");
}
/**
* Turn tracing messages on or off. If off then it is assumed that
* debugging is not occurring and so a new (unseeded) random number
* generator is created so the game is unpredictable.
* #param shouldTrace indicates if tracing messages should be displayed or not
*/
public void setTracing(boolean shouldTrace) {
if (! shouldTrace) { // not tracing so get an unseeded RNG
generator = new Random();
}
tracing = shouldTrace;
}
/**
* Prints the given tracing message if tracing is enabled.
* #param message the message to be displayed
*/
public void trace(String message) {
if (tracing) {
System.out.println("GameWorld: " + message);
}
}
}
You can use reflection. Actually, it's the only way out if you want to directly access the private methods/fields of an object or a class.
Related
I can't get the output to print, I've tried many diff. things to try and get it to print but it won't work. It's supposed to print error messages if I put in a negative # for height or edge. Also the output for valid #'s won't print either. I'm not sure where to put the block of code for that one. Can someone help me?
My Program: https://pastebin.com/D8FQv1yR
import java.util.Scanner;
/**
*The App for the Decagonal Prism program.
* #author Kathleen Tumlin - Fundamentals of Computing I - 1210
* #version 9/17/21
*/
public class DecagonalPrismApp {
//fields
String label = "";
double edge = 0;
double height = 0;
double edgeIn = 0;
double heightIn = 0;
// constuctor
/** Shows public decagonal prism, setLabel, and setEdge.
* #param labelIn takes input for label in the constructor.
* #param edgeIn takes input for the edge in the constructor.
*/
public DecagonalPrismApp(String labelIn, double edgeIn, double heightIn) {
setLabel(labelIn);
setEdge(edgeIn);
setHeight(heightIn);
}
//methods
/** Shows the return for label variable.
* #return returns the label variable.
*/
public String getLabel() {
return label;
}
/** Shows the set label.
* #param labelIn takes the labelIn for the method.
* #return returns the boolean if the variable was set.
*/
public boolean setLabel(String labelIn) {
if (labelIn != null) {
label = labelIn.trim();
return true;
} else {
return false;
}
}
/** Shows the return for the edge variable.
* #return returns the value for the variable edge.
*/
public double getEdge() {
return edge;
}
/** Shows the set edge.
* #param edgeIn takes the edgein and sets it as the edge variable.
* #return returns the boolean if the variable was set.
*/
public boolean setEdge(double edgeIn) {
if (edgeIn > -1) {
edge = edgeIn;
return true;
}
else {
System.out.println("Error: edge must be non-negative.");
return false;
}
}
/** Shows the return for the height variable.
*#return returns the value for the variable edge.
*/
public double getHeight() {
return height;
}
/** Shows the set height.
* #param heightIn takes the heightin and sets it as the height variable.
* #return returns the boolean if the variable was set.
*/
public boolean setHeight(double heightIn) {
if (heightIn > -1) {
height = heightIn;
return true;
}
else {
System.out.println("Error: height must be non-negative.");
return false;
}
}
public void start() {
do {
System.out.print("Error: height must be non-negative." );
} while (heightIn > -1);
do {
System.out.print("Error: edge must be non-negative." );
} while (edgeIn > -1);
}
public static void main(String[] args) {
/**
*Shows what prints.
* #param args not used.
*/
Scanner scan = new Scanner(System.in);
System.out.println("Enter label, edge, and height length for a "
+ "decagonal prism.");
System.out.print("\tlabel: ");
String label = scan.nextLine();
System.out.print("\tedge: ");
double edge = scan.nextDouble();
System.out.print("\theight: ");
double height = scan.nextDouble();
}
}
Valid #'s code: https://pastebin.com/DPuSpMEq
public String toString() {
DecimalFormat fmt = new DecimalFormat("#,##0.0##");
return "A decagonal prism \"" + label
+ "with edge = " + edge + " units.\n\t"
+ "and height = " + height + " units.\n\t has:"
+ "surface area = " + fmt.format(surfaceArea()) + " square units\n\t"
+ "base area = " + fmt.format(baseArea()) + " square units \n\t"
+ "lateral surface area = "
+ fmt.format(lateralSurfaceArea()) + " square units\n\t"
+ "volume = " + fmt.format(volume()) + " cubic units \n\t";
I am trying to create a "dragon curve" that uses left and right turns to create a shape on the drawing panel. The directions are generated recursively, where for a certain number of iterations or "levels" the direction adds on the previous string of turns to a single right turn plus the reverse complement of the previous string: previous string + "R" + the reverse complement of the previous string.
Based on my result, my complement method is not correctly making the reverse complement and I am not sure why. Here's is my code.
public static void main (String[] args)
{
Scanner scan = new Scanner(System.in);
intro();
int level = userlevel(scan);
int size = userSize(scan);
String fileName = BASE + level + TXT;
recursion(level, fileName);
drawDragon(fileName, size, level);
}
/**
* Prints the introductory message
**/
public static void intro()
{
System.out.println("This program will generate a fractal called the Dragon Curve");
System.out.println("first explored by John Heighway, Bruce Banks, and William Harter");
System.out.println("at Nasa in teh 1960's");
}
/**
* Inputs the user's desired level for the dragon curve
* #param the Scanner object for recieving user inputs
* #return the user's desired level
**/
public static int userlevel(Scanner scan)
{
String levelPrompt = "Enter the level of the fractcal you'd like to see (1-25): ";
int level = MyUtils.getNumber(scan, levelPrompt, MINLEVEL, MAXLEVEL);
return level;
}
/**
* Inputs the user's desired drawing panel width and height
* #param the Scanner object for recieving user inputs
* #return the user's desired drawing panel size
**/
public static int userSize(Scanner scan)
{
String panelPrompt = "Enter the size of your drawing panel, in pixels (100-2000): ";
int size = MyUtils.getNumber(scan, panelPrompt, MINSIZE, MAXSIZE);
return size;
}
/**
* Creates the reverse complement of the previous dragon curve string
* #param the previous string used the in the recursive loop
* #return the new reverse complement string
**/
public static String complement(String previousString)
{
StringBuilder newString = new StringBuilder();
char letter = '\0';
for (int i=previousString.length(); i<0; i--)
{
letter = previousString.charAt(i);
if (letter == 'L')
newString.append('R');
else if (letter == 'R')
newString.append('L');
}
return newString.toString();
}
/**
* Creates the string of directions for the dragon curve using recursion
* #param level - the user's desired level
* #param fileName - the file in which the dragon curve string is located
* #return the new set of directions for the curve after each loop
**/
public static String recursion(int level, String fileName)
{
PrintStream output = MyUtils.createOutputFile(fileName);
String newDirection = "";
String directions = "";
if (level==1)
{
directions = "R";
output.print(directions);
}
else
{
String previousString = recursion(level-1, fileName);
String nextComplement = complement(previousString);
newDirection = previousString + "R" + nextComplement;
output.print(newDirection);
System.out.println(newDirection);
//output.flush();
//output.close();
}
return newDirection;
}
/**
* Draws the dragon curve on the drawing panel
* #param fileName - the file where the dragon curve directions are located
* #param size - the width and height of the drawing panel
* #param level - the user's desired level
**/
public static void drawDragon(String fileName, int size, int level)
{
Scanner fileScan = MyUtils.getFileScanner(fileName);
System.out.println("Path generated, writing to file " + fileName + "...");
String direction = fileScan.nextLine();
System.out.println("Drawing Curve...");
DragonDraw dd = new DragonDraw(size);
dd.drawCurve(fileName, level);
}
}
Here is the error: I am only getting repeated "R"'s.
Enter the level of the fractcal you'd like to see (1-25): 20
Enter the size of your drawing panel, in pixels (100-2000): 500
R
RR
RRR
RRRR
RRRRR
RRRRRR
RRRRRRR
RRRRRRRR
RRRRRRRRR
RRRRRRRRRR
RRRRRRRRRRR
RRRRRRRRRRRR
RRRRRRRRRRRRR
RRRRRRRRRRRRRR
RRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRR
Path generated, writing to file dragon20.txt...
Drawing Curve...
Thanks so much!
Take a look at your for loop inside complement method. It is running while the variable i is less than zero, this should run while this variable is greater than zero. So change this for (int i=previousString.length(); i<0; i--) to for (int i=previousString.length() - 1; i >= 0; i--) and it shall work fine.
I am using the template method. I have a driver that was supplied to me that creates a Game and passes through one of two switching classes, AlwaysSwitch or NeverSwitch. The driver then creates a trial for Always Switch and a separate trial of NeverSwitch. Each trial runs 100 times and tallies how many times each case wins the game.
Both of these classes extend Game. Game has an abstract method called switching(). Both switching classes inherit this method. I put a simple print statement in both classes. AlwaysSwitch has "I would like to switch", while NeverSwitch has "I will stay."
My problem is even in the Always switch trial which creates a new Game g = new AlwaysSwitch();, the output is always "I will stay." and in the new Game g = new NeverSwitch();, the output again is "I will stay.".
I have tried commenting out the NeverSwitch trial in the driver and only then will the AlwaysSwitch trial work.
I don't understand why the neverSwitch class is overriding the alwaysSwitch class?
public class Host {
private Door prizeDoor;
/**
* Choose a random prize door and keep it secret.
*/
public void choosePrizeDoor() {
prizeDoor = Door.randomDoor();
}
/**
* Reveal a door that does not contain the prize and does not
* match the one the contestant chose.
*/
public Door revealADoor(Door contestantChoice) {
Door result = contestantChoice;
// Randomly pick a door. Might iterate few times.
while (result == contestantChoice || result == prizeDoor) {
result = Door.randomDoor();
}
return result;
}
/**
* Determine if the contestant's door wins or loses.
*/
public boolean isAWinner(Door contestantChoice) {
return prizeDoor == contestantChoice;
}
}
/**
* An enum representing a door. Left = 1, center = 2, right = 3.
* Can also choose random doors here.
*
* #author Todd Whittaker
* #version 20180110
*/
public enum Door {
LEFT(1),
CENTER(2),
RIGHT(3);
private int value;
private static final Random r = new Random();
Door(int value) {
this.value = value;
}
/**
* Find the door that matches the number.
*/
public static Door valueOf(int num) {
switch (num) {
case 1: return LEFT;
case 2: return CENTER;
default: return RIGHT;
}
}
/**
* return the number matching this door.
*/
public int valueOf() {
return value;
}
/**
* Pick a random door (LEFT, CENTER, RIGHT).
*/
public static Door randomDoor() {
return Door.valueOf(r.nextInt(3)+1);
}
}
public abstract class Game {
private Host host;
public Door contestantChoice;
public Door revealedDoor;
/**
* Creates the game and its host.
*/
public Game () {
this.host = new Host();
}
/**
* Implements the algorithm for the game:
* 1. The host chooses which door has a prize at random.
* 2. The contestant picks a door (left, center, or right) at random.
* 3. The host reveals one of the two other doors that does not contain
the prize.
* 4. The contestant can then switch to the other door or keep their
current door.
* 5. The prize is revealed and the contestant wins or loses.
*/
final boolean runGame() {
host.choosePrizeDoor(); //1
System.out.println("Let's Play");
contestantChoice = contestantChoice.randomDoor();//2
System.out.println("Contestant chooses " + contestantChoice);
revealedDoor = host.revealADoor(contestantChoice); //3
System.out.println("reveal door " + revealedDoor);
System.out.println("would you like to switch?");
switching();
if(host.isAWinner(contestantChoice) == true)
{
System.out.println("Winner!! \n");
return true;
}
System.out.println("Sorry you lose \n");
return false;
}
abstract void switching();
}
public class AlwaysSwitch extends Game {
void switching()
{
System.out.println("I would like to switch" );
}
}
public class NeverSwitch extends Game {
void switching()
{
System.out.println("I will stay." );
}
}
public class Driver {
private static final int TRIALS = 100;
public static void main(String [] args) {
int switchWins = 0;
int stayWins = 0;
for (int i = 0; i < TRIALS; ++i) {
Game g = new AlwaysSwitch();
if (g.runGame()) {
++switchWins;
}
}
for (int i = 0; i < TRIALS; ++i) {
Game g = new NeverSwitch();
if (g.runGame()) {
++stayWins;
}
}
System.out.println("Out of " + TRIALS + " trials:");
System.out.println(" Switch won " + switchWins + " times.");
System.out.println(" Stay won " + stayWins + " times.");
}
}
All results say "I will stay."
To complete the code, you could change the signature of switching() to:
abstract Door switching(Door contestantsChoice, Door revealedDoor);
Then you would call it in Game.runGame() like this:
contestantsChoice = switching(contestantsChoice, revealedDoor);
Your AlwaysSwitch implementation would be:
Door switching(Door contestantChoice, Door revealedDoor)
{
System.out.println("I would like to switch" );
return selectRemainingDoor(contestantChoice, revealedDoor);
}
private Door selectRemainingDoor(Door contestantChoice, Door revealedDoor) {
List<Door> doors = new ArrayList<>(asList(LEFT, CENTER, RIGHT));
doors.remove(contestantChoice);
doors.remove(revealedDoor);
return doors.get(0);
}
And your NeverSwitch implementation would like like this:
Door switching(Door contestantChoice, Door revealedDoor)
{
System.out.println("I will stay." );
return contestantChoice;
}
I need to extend the class Room such that a room can contain zero or many characters by adding a field and a method in Room class that adds characters to rooms created. I already created an enum class called Character as can be seen below but I don't know how to use that in my Room class to add characters to a Room object.
I already created a HashMap field for storing the characters called charactersroom. The method in my code for adding characters is called addCharacter.
Room Class
public class Room
{
private String description;
private HashMap<Direction, Room> exits; // stores exits of this room.
private HashMap<Character, Room> charactersroom;
/**
* Create a room described "description". Initially, it has
* no exits. "description" is something like "a kitchen" or
* "an open court yard".
* #param description The room's description.
* Pre-condition: description is not null.
*/
public Room(String description)
{
assert description != null : "Room.Room has null description";
this.description = description;
exits = new HashMap<Direction, Room>();
charactersroom = new HashMap<Character, Room>();
sane();
}
public void addCharacter(Character character)
{
}
/**
* Class invariant: getShortDescription() and getLongDescription() don't return null.
*/
public void sane()
{
assert getShortDescription() != null : "Room has no short description" ;
assert getLongDescription() != null : "Room has no long description" ;
}
/**
* Define an exit from this room.
* #param direction The direction of the exit.
* #param neighbor The room to which the exit leads.
* Pre-condition: neither direction nor neighbor are null;
* there is no room in given direction yet.
*/
public void setExit(Direction direction, Room neighbor)
{
assert direction != null : "Room.setExit gets null direction";
assert neighbor != null : "Room.setExit gets null neighbor";
assert getExit(direction) == null : "Room.setExit set for direction that has neighbor";
sane();
exits.put(direction, neighbor);
sane();
assert getExit(direction) == neighbor : "Room.setExit has wrong neighbor";
}
/**
* #return The short description of the room
* (the one that was defined in the constructor).
*/
public String getShortDescription()
{
return description;
}
/**
* Return a description of the room in the form:
* You are in the kitchen.
* Items: map
* Exits: north west
* #return A long description of this room
*/
public String getLongDescription()
{
return "You are " + description + ".\n" + getExitString();
}
/**
* Return a string describing the room's exits, for example
* "Exits: north west".
* #return Details of the room's exits.
*/
private String getExitString()
{
String returnString = "Exits:";
Set<Direction> keys = exits.keySet();
for(Direction exit : keys) {
returnString += " " + exit;
}
return returnString;
}
/**
* Return the room that is reached if we go from this room in direction
* "direction". If there is no room in that direction, return null.
* #param direction The exit's direction.
* #return The room in the given direction.
* Pre-condition: direction is not null
*/
public Room getExit(Direction direction)
{
assert direction != null : "Room.getExit has null direction";
sane();
return exits.get(direction);
}
}
Character enum class
public enum Character
{
LAURA("Laura",Item.SANDWICH),SALLY("Sally", Item.CRISPS),ANDY("Andy", Item.DRINK),ALEX("Alex", null);
private String charDescription;
private Item item;
private Character(String Chardescription, Item item) {
this.charDescription = charDescription;
this.item = item;
}
public String toString()
{
return charDescription+item;
}
/**
* Takes the indicated item from the character
* #return true if successful
*
*/
public boolean take(Item item)
{
if (item == this.item) {
this.item = null;
return true;
}
return false;
}
}
EDIT: This method is in my superclass Game for creating the rooms and their exits:
/**
* Create all the rooms and link their exits together.
*/
private void createRooms()
{
Room trafalgarSquare, chinatown, oxfordStreet, soho, coventGarden,
britishMuseum, stPancras, kingsCross, britishLibrary, leicesterSquare;
// create the rooms
trafalgarSquare = new Room("on Trafalgar Square");
chinatown = new Room("in Chinatown");
oxfordStreet = new Room("on Oxford Street");
soho = new Room("in Soho");
coventGarden = new Room("in Covent Garden");
britishMuseum = new Room("in the British Museum");
stPancras = new Room("in St Pancras");
kingsCross = new Room("in Kings Cross");
britishLibrary = new Room("in the British Library");
leicesterSquare = new Room("on Leicester Square");
// initialise room exits
kingsCross.setExit(Direction.WEST, stPancras);
stPancras.setExit(Direction.EAST, kingsCross);
stPancras.setExit(Direction.WEST, britishLibrary);
britishLibrary.setExit(Direction.EAST, stPancras);
britishLibrary.setExit(Direction.SOUTH, britishMuseum);
britishMuseum.setExit(Direction.NORTH, britishLibrary);
britishMuseum.setExit(Direction.WEST, oxfordStreet);
oxfordStreet.setExit(Direction.EAST, britishMuseum);
britishMuseum.setExit(Direction.SOUTH, coventGarden);
coventGarden.setExit(Direction.NORTH, britishMuseum);
oxfordStreet.setExit(Direction.SOUTH, soho);
soho.setExit(Direction.NORTH, oxfordStreet);
soho.setExit(Direction.SOUTH, chinatown);
chinatown.setExit(Direction.NORTH, soho);
chinatown.setExit(Direction.SOUTH, leicesterSquare);
leicesterSquare.setExit(Direction.NORTH, chinatown);
leicesterSquare.setExit(Direction.EAST, coventGarden);
coventGarden.setExit(Direction.WEST, leicesterSquare);
leicesterSquare.setExit(Direction.SOUTH, trafalgarSquare);
trafalgarSquare.setExit(Direction.NORTH, leicesterSquare);
currentRoom = stPancras; // start game at St Pancras
}
The unreachable statement is: thisCustomer = findCustomer(theCustomerID);. I cannot figure out why. thisCustomer is an attribute of Customer object, findCustomer() is a method listed below, and theCustomerID is the parameter of the method this statement is in. The problem is in rentOutApt(int theAptID, int theCustomerID, int theMonthsToRent) //3. This code is toward the bottom.
import java.util.ArrayList;
import java.util.Iterator; // If you choose to use one.
/**
* .AptRentalAgency.
* Controller class.
*
* Name:
* Comment:
*
* For Dr. Nikhil Srinivasan's MIST 4600 Exam02 on 20140321.
*
* #author Dr. Nikhil Srinivasan
* #version 20140317
*
*/
public class AptRentalAgency
{
// instance variables
private int currentDate;
// These match the Customer objects:
private int customerID;
private String customerName;
private double customerBalance;
private int customerAptID; // 0 if he or she does not currently have a apartment.
private int customerCreditRating;
// These match the Apartment objects:
private int aptID;
private String aptName;
private String aptAddress;
private int aptSize;
private double aptRent;
// ****** The following are set when the apt is rented:
private int aptCustomerID; // 0 if not rented.
private double aptDeposit; // 0 if not rented
private int aptMonthsRented; // 0 if not rented.
private int aptRentalDate; // 0 if not rented.
// There are a number of important nonfields that are to be computed
// in their accessor (get) methods as needed:
private double aptDepositMultiplier;
private double aptTotalCost;
// These are for the current Customer and current Apt objects:
Customer thisCustomer;
Apartment thisApt;
// These are the needed ArrayLists:
ArrayList<Customer> customers;
ArrayList<Apartment> apts;
// ReadFile objects:
private ReadFile aptReader; // Declare a ReadFile object to read from the AptData.txt file.
private ReadFile customerReader; // Declare a ReadFile object to read from the customerData.txt file.
/**
* AptRentalAgency Constructor
*/
public AptRentalAgency()
{
// Set the currentDate:
currentDate = 20140321;
// Create the ArrayLists:
customers = new ArrayList<Customer>();
apts = new ArrayList<Apartment>();
// Read in the Apt objects and Customer objects. Load them into the ArrayLists.
readApts();
readCustomers();
}
/**
* .readApts.
* Reads in the Apt objects.
*/
private void readApts()
{
aptReader = new ReadFile("AptData.txt");
aptReader.setSeparator(",");
// Read and Load the Data:
for(aptReader.readInputLine(); !aptReader.eof(); aptReader.readInputLine())
{
// Load the data into fields
aptID = aptReader.getIntField(1);
aptName = aptReader.getStringField(2);
aptAddress = aptReader.getStringField(3);
aptSize = aptReader.getIntField(4);
aptRent = aptReader.getDoubleField(5);
aptCustomerID = aptReader.getIntField(6);
aptDeposit = aptReader.getDoubleField(7);
aptMonthsRented = aptReader.getIntField(8);
aptRentalDate = aptReader.getIntField(9);
// Construct thisApt
thisApt = new Apartment(aptID, aptName, aptAddress, aptSize, aptRent,
aptCustomerID, aptDeposit, aptMonthsRented, aptRentalDate);
// Add thisApt to the apts ArrayList.
apts.add(thisApt);
}
// End of Loop
System.out.println("\nAll apts read from the file and added to the ArrayList.\n");
}
/**
* .readCustomers.
* Reads in the Customer objects.
*/
private void readCustomers()
{
customerReader = new ReadFile("CustomerData.txt");
customerReader.setSeparator(",");
// Read and Load the Data:
for(customerReader.readInputLine(); !customerReader.eof(); customerReader.readInputLine())
{
// Load the data into fields
customerID = customerReader.getIntField(1);
customerName = customerReader.getStringField(2);
customerBalance = customerReader.getDoubleField(3);
customerAptID = customerReader.getIntField(4);
customerCreditRating = customerReader.getIntField(5);
// Construct thisCustomer
thisCustomer = new Customer(customerID, customerName, customerBalance, customerAptID, customerCreditRating);
// Add thisCustomer to the customers ArrayList.
customers.add(thisCustomer);
}
// End of Loop
System.out.println("\nAll customers read from the file and added to the ArrayList.\n");
}
/**
* .printAllCustomers.
*/
public void printAllCustomers()
{
// Print a header, then the list.
System.out.println("\nCurrent Customer List on " + currentDate + "\n");
System.out.println("CustID Name Balance Apt ID CreditRating");
System.out.println("------ ----------------- ------- ------- ------------");
for(Customer theCustomer: customers)
{
theCustomer.printInfo();
}
System.out.println("\nEnd of Customer List. \n");
}
/**
* .printAllApts.
*/
public void printAllApts()
{
// Print a header, then the list.
System.out.println("\nCurrent Apt List on " + currentDate + "\n");
System.out.println("AptID Apt Name Address Size Rent RenterID Deposit MonthsRented RentalDate");
System.out.println("----- ------------------- -------------------------- ---- ------- -------- ------- ------------ ----------");
for(Apartment theApt: apts)
{
theApt.printInfo();
}
System.out.println("\nEnd of Apt List. \n");
}
// ****************** Do your work after this point ********************************
/**
* .find a customer.
*/
public Customer findCustomer(int theCustomerID)
{
for(Customer theCustomer: customers)
{
if (theCustomer.getCustomerID() == theCustomerID)
{
return theCustomer;
}
}
return null;
}
/**
* .find Apartment.
*/
public Apartment findApartment(int theAptID)
{
for(Apartment theApt: apts)
{
if (theApt.getAptID() == theAptID)
{
return theApt;
}
}
return null;
}
/**
* .customerAddMoney.
* Part a
*/
public void customerAddMoney(int theCustomerID, double theAmountToAdd)
{
// Find the customer, If the Customer does not exist print a message and return(exit the method)
thisCustomer = findCustomer(theCustomerID);
// Check the amount provided to see if it is less than zero. If it is less than zero then print a message and return(exit the method)
if( thisCustomer == null)
{
System.out.println("Customer " + theCustomerID + " does not exist. Returning!");
return;
}
// Update the customer balance by adding the amount to the existing customer balance.
double customerBalance = thisCustomer.getCustomerBalance() + theAmountToAdd;
thisCustomer.setCustomerBalance(customerBalance);
}
/**
* .checkOutApt.
* Parts b and c.
*/
public void rentOutApt(int theAptID, int theCustomerID, int theMonthsToRent)
{
// PART B:
// 1 Find the specific theAptID Apartment object and load it into thisApt.
// If null, print a message that the apt does not exist and return.
thisApt = findApartment(theAptID);
// 2 Verify that thisApt Apartment is available (not rented out to a customer).
// If not, print a message that the apt is already rented out and return.
if(thisApt.getAptRentalDate() == 0)
{
System.out.println("Apartment " + theAptID + " is available. Returning!");
return;
}
else
{
System.out.println("Apartment " + theAptID + " is rented out. Returning!");
return;
}
// 3 Find the specific theCustomerID object and load it into thisCustomer.
// If null, print a message that the customer does not exist and return.
thisCustomer = findCustomer(theCustomerID);
if(thisCustomer == null)
{
System.out.println("Customer " + theCustomerID + " does not exist. Returning!");
return;
}
// 4 Verify that thisCustomer Customer does not already have an apartment.
// If he or she does, print a message that the customer already has an apartment
// and return.
if(thisCustomer.getCustomerAptID() != 0)
{
System.out.println("*** Customer is already living in: " + customerAptID);
return;
}
// 5 Verify that the thisCustomer Customer has enough money to rent the apt.
// The initial payment from a customer to rent an apartmentis the sum of the calculated
// deposit based on customer credit rating (the getAptDepositAmount method)
// and the first month's rent.
//
// You will need to get the theCustomer’s balance and compare it to the sum of
// thisApt (getAptRent and getAptDepositAmount methods).
double customerBalance = thisApt.getAptDepositAmount(thisCustomer.getCustomerCreditRating()) + thisApt.getAptRent();
if(customerBalance > thisCustomer.getCustomerBalance())
{
System.out.println();
System.out.println("The customer does not have enough money.");
System.out.println("The customer is " + customerBalance + " short.");
System.out.println();
return;
}
// PART C:
// 6 Now check out theAptID Apt object to thisCustomer Customer object.
// In thisCustomer, set customerAptID to theAptID.
thisCustomer.setCustomerAptID(theAptID);
// In thisApt, set
// * aptCustomerID to theCustomerID
thisApt.setAptCustomerID(theCustomerID);
// In thisApt, set
// * aptDeposit to the deposit amount you find after using the
// getAptDepositAmount(int custCreditRating) method in Apartment Class
thisApt.setAptDeposit(thisApt.getAptDepositAmount(thisCustomer.getCustomerCreditRating()));
// set * aptMonthsRented theMonthsToRent
thisApt.setAptMonthsRented(theMonthsToRent);
// * aptRentalDate to currentDate
thisApt.setAptRentalDate(currentDate);
}
}
Lines 237-246 are:
if(thisApt.getAptRentalDate() == 0)
{
System.out.println("Apartment " + theAptID + " is available. Returning!");
return;
}
else
{
System.out.println("Apartment " + theAptID + " is rented out. Returning!");
return;
}
This is guaranteed to return. The output is different depending on the result of thisApt.getAptRentalDate(), but both conditions return.
Everything after that is therefore unreachable code. Since thisCustomer = findCustomer(theCustomerID); is on line 250, it is unreachable, as well as all other code in that method.