From 9fd26b21921bcdc516b5f4e4b29211cc4df14cd8 Mon Sep 17 00:00:00 2001 From: journich <70119791+journich@users.noreply.github.com> Date: Tue, 9 Mar 2021 15:46:17 +1030 Subject: [PATCH 1/2] Initial code for Java version of Fur Trader --- 38 Fur Trader/java/src/FurTrader.java | 408 ++++++++++++++++++++++ 38 Fur Trader/java/src/FurTraderGame.java | 7 + 38 Fur Trader/java/src/Pelt.java | 23 ++ 3 files changed, 438 insertions(+) create mode 100644 38 Fur Trader/java/src/FurTrader.java create mode 100644 38 Fur Trader/java/src/FurTraderGame.java create mode 100644 38 Fur Trader/java/src/Pelt.java diff --git a/38 Fur Trader/java/src/FurTrader.java b/38 Fur Trader/java/src/FurTrader.java new file mode 100644 index 00000000..c9bc3272 --- /dev/null +++ b/38 Fur Trader/java/src/FurTrader.java @@ -0,0 +1,408 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Scanner; + +/** + * Game of Fur Trader + *

+ * Based on the Basic game of Fur Trader here + * https://github.com/coding-horror/basic-computer-games/blob/main/38%20Fur%20Trader/furtrader.bas + *

+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing + * new features - no additional text, error checking, etc has been added. + */ +public class FurTrader { + + public static final double START_SAVINGS_AMOUNT = 600.0; + public static final int STARTING_FURS = 190; + + public static final int FORT_HOCHELAGA_MONTREAL = 1; + public static final int FORT_STADACONA_QUEBEC = 2; + public static final int FORT_NEW_YORK = 3; + + public static final String MINK = "MINK"; + public static final int MINK_ENTRY = 0; + public static final String BEAVER = "BEAVER"; + public static final int BEAVER_ENTRY = 1; + public static final String ERMINE = "ERMINE"; + public static final int ERMINE_ENTRY = 2; + public static final String FOX = "FOX"; + public static final int FOX_ENTRY = 3; + + + // Used for keyboard input + private final Scanner kbScanner; + + private enum GAME_STATE { + STARTUP, + INIT, + TRADE_AT_FORT, + TRADE_SUMMARY, + TRADE_AGAIN, + GAME_OVER + } + + // Current game state + private GAME_STATE gameState; + + private double savings; + private double minkPrice; + private double beaverPrice; + private double erminePrice; + private double foxPrice; + + private ArrayList pelts; + + public FurTrader() { + kbScanner = new Scanner(System.in); + gameState = GAME_STATE.INIT; + } + + /** + * Main game loop + */ + public void play() { + + do { + switch (gameState) { + + case INIT: + savings = START_SAVINGS_AMOUNT; + + gameStartupMessage(); + + if (yesEntered(displayTextAndGetInput("DO YOU WISH TO TRADE FURS? "))) { + gameState = GAME_STATE.STARTUP; + intro(); + } else { + gameState = GAME_STATE.GAME_OVER; + } + + System.out.println("YOU HAVE $" + savings + " SAVINGS."); + System.out.println("AND " + STARTING_FURS + " FURS TO BEGIN THE EXPEDITION."); + + break; + + case STARTUP: + + pelts = new ArrayList<>(); + + pelts.add(getPelt(MINK)); + pelts.add(getPelt(BEAVER)); + pelts.add(getPelt(ERMINE)); + pelts.add(getPelt(FOX)); + + // Determine if count of total pelts exceeds the maximum + // N.B. Original game was fine with entering less than the + // maximum so this functionality has been left in. + if (pelts.stream().mapToInt(Pelt::getNumber).sum() > STARTING_FURS) { + System.out.println("YOU MAY NOT HAVE THAT MANY FURS."); + System.out.println("DO NOT TRY TO CHEAT. I CAN ADD."); + System.out.println("YOU MUST START AGAIN."); + gameState = GAME_STATE.STARTUP; + } else { + // No cheating, so start trading + erminePrice = ((.15 * Math.random() + .95) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); + beaverPrice = ((.25 * Math.random() + 1.00) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); + gameState = GAME_STATE.TRADE_AT_FORT; + } + break; + + case TRADE_AT_FORT: + + extendedTradingInfo(); + int answer = displayTextAndGetNumber("ANSWER 1, 2, OR 3. "); + + // Now show the details of the fort they are about to trade + // and give the player the chance to NOT proceed. + // A "No" or false means they do not want to change to another fort + if (!confirmFort(answer)) { + switch (answer) { + case 1: + tradeAtFortHochelagaMontreal(); + gameState = GAME_STATE.TRADE_SUMMARY; + break; + + case 2: + tradeAtFortStadaconaQuebec(); + gameState = GAME_STATE.TRADE_SUMMARY; + break; + case 3: + // Did the player and party all die? + if(!tradeAtFortNewYork()) { + gameState = GAME_STATE.GAME_OVER; + } else { + gameState = GAME_STATE.TRADE_SUMMARY; + } + break; + } + + break; + } + + case TRADE_SUMMARY: + + double beaverTotal = beaverPrice * pelts.get(BEAVER_ENTRY).getNumber(); + System.out.println("YOUR BEAVER SOLD FOR $ " + beaverTotal); + + double foxTotal = foxPrice * pelts.get(FOX_ENTRY).getNumber(); + System.out.println("YOUR FOX SOLD FOR $ " + foxTotal); + + double erMineTotal = erminePrice * pelts.get(ERMINE_ENTRY).getNumber(); + System.out.println("YOUR ERMINE SOLD FOR $ " + erMineTotal); + + double minkTotal = minkPrice * pelts.get(MINK_ENTRY).getNumber(); + System.out.println("YOUR MINK SOLD FOR $ " + minkTotal); + + savings += beaverTotal + foxTotal + erMineTotal + minkTotal; + System.out.println(); + System.out.println("YOU NOW HAVE $" + savings + " INCLUDING YOUR PREVIOUS SAVINGS"); + + gameState = GAME_STATE.TRADE_AGAIN; + break; + + case TRADE_AGAIN: + if(yesEntered(displayTextAndGetInput("DO YOU WANT TO TRADE FURS NEXT YEAR? "))) { + gameState = GAME_STATE.STARTUP; + } else { + gameState = GAME_STATE.GAME_OVER; + } + + } + } while (gameState != GAME_STATE.GAME_OVER); + } + + /** + * Display a message about trading at each fort and confirm if the player wants to trade + * at ANOTHER fort + * @param fort the fort in question + * @return true if YES was typed by player + */ + private boolean confirmFort(int fort) { + switch(fort) { + case FORT_HOCHELAGA_MONTREAL: + System.out.println("YOU HAVE CHOSEN THE EASIEST ROUTE. HOWEVER, THE FORT"); + System.out.println("IS FAR FROM ANY SEAPORT. THE VALUE"); + System.out.println("YOU RECEIVE FOR YOUR FURS WILL BE LOW AND THE COST"); + System.out.println("OF SUPPLIES HIGHER THAN AT FORTS STADACONA OR NEW YORK."); + break; + case FORT_STADACONA_QUEBEC: + System.out.println("YOU HAVE CHOSEN A HARD ROUTE. IT IS, IN COMPARSION,"); + System.out.println("HARDER THAN THE ROUTE TO HOCHELAGA BUT EASIER THAN"); + System.out.println("THE ROUTE TO NEW YORK. YOU WILL RECEIVE AN AVERAGE VALUE"); + System.out.println("FOR YOUR FURS AND THE COST OF YOUR SUPPLIES WILL BE AVERAGE."); + break; + case FORT_NEW_YORK: + System.out.println("YOU HAVE CHOSEN THE MOST DIFFICULT ROUTE. AT"); + System.out.println("FORT NEW YORK YOU WILL RECEIVE THE HIGHEST VALUE"); + System.out.println("FOR YOUR FURS. THE COST OF YOUR SUPPLIES"); + System.out.println("WILL BE LOWER THAN AT ALL THE OTHER FORTS."); + break; + } + + System.out.println("DO YOU WANT TO TRADE AT ANOTHER FORT?"); + return yesEntered(displayTextAndGetInput("ANSWER YES OR NO ")); + + } + + /** + * Trade at the safest fort - Fort Hochelaga + * No chance of anything bad happening, so just calculate amount per pelt + * and return + */ + private void tradeAtFortHochelagaMontreal() { + savings -= 160; + System.out.println(); + System.out.println("SUPPLIES AT FORT HOCHELAGA COST $150.00."); + System.out.println("YOUR TRAVEL EXPENSES TO HOCHELAGA WERE $10.00."); + minkPrice = ((.2 * Math.random() + .7) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); + erminePrice = ((.2 * Math.random() + .65) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); + beaverPrice = ((.2 * Math.random() + .75) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); + foxPrice = ((.2 * Math.random() + .8) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); + return; + } + + + private void tradeAtFortStadaconaQuebec() { + savings -= 140; + System.out.println(); + minkPrice = ((.2 * Math.random() + .85) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); + erminePrice = ((.2 * Math.random() + .8) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); + beaverPrice = ((.2 * Math.random() + .9) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); + + // What happened during the trip to the fort? + int tripResult = (int) (Math.random()*10) + 1; + if(tripResult <= 2) { + // Find the Beaver pelt in our Arraylist + Pelt beaverPelt = pelts.get(BEAVER_ENTRY); + // Pelts got stolen, so update to a count of zero + beaverPelt.lostPelts(); + // Update it back in the ArrayList + pelts.set(BEAVER_ENTRY, beaverPelt); + + System.out.println("YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS"); + System.out.println("THE PORTAGE. YOU HAD TO LEAVE THE PELTS, BUT FOUND"); + System.out.println("THEM STOLEN WHEN YOU RETURNED."); + } else if (tripResult <= 6) { + System.out.println("YOU ARRIVED SAFELY AT FORT STADACONA."); + } else if (tripResult <= 8) { + System.out.println("YOUR CANOE UPSET IN THE LACHINE RAPIDS. YOU"); + System.out.println("LOST ALL YOUR FURS."); + // Clear out all pelts. + for(int i=0; i<3; i++) { + Pelt pelt = pelts.get(i); + pelt.lostPelts(); + pelts.set(i, pelt); + } + } else if(tripResult <= 10) { + // Fox pelts not cured + // Bug because Fox furs were not calculated above in original basic program + // Find the Beaver pelt in our Arraylist + Pelt foxPelt = pelts.get(FOX_ENTRY); + // Pelts got stolen, so update to a count of zero + foxPelt.lostPelts(); + // Update it back in the ArrayList + pelts.set(FOX_ENTRY, foxPelt); + } + + System.out.println("SUPPLIES AT FORT STADACONA COST $125.00."); + System.out.println("YOUR TRAVEL EXPENSES TO STADACONA WERE $15.00."); + } + + private boolean tradeAtFortNewYork() { + + boolean playerAlive = true; + savings -= 105; + System.out.println(); + minkPrice = ((.2 * Math.random() + 1.05) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); + foxPrice = ((.2 * Math.random() + 1.1) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); + + // What happened during the trip to the fort? + int tripResult = (int) (Math.random()*10) + 1; + if(tripResult <= 2) { + System.out.println("YOU WERE ATTACKED BY A PARTY OF IROQUOIS."); + System.out.println("ALL PEOPLE IN YOUR TRADING GROUP WERE"); + System.out.println("KILLED. THIS ENDS THE GAME."); + playerAlive = false; + } else if (tripResult <= 6) { + System.out.println("YOU WERE LUCKY. YOU ARRIVED SAFELY"); + System.out.println("AT FORT NEW YORK."); + } else if (tripResult <= 8) { + System.out.println("YOU NARROWLY ESCAPED AN IROQUOIS RAIDING PARTY."); + System.out.println("HOWEVER, YOU HAD TO LEAVE ALL YOUR FURS BEHIND."); + // Clear out all pelts. + for(int i=0; i<3; i++) { + Pelt pelt = pelts.get(i); + pelt.lostPelts(); + pelts.set(i, pelt); + } + } else if(tripResult <= 10) { + beaverPrice /= 2; + minkPrice /= 2; + System.out.println("YOUR MINK AND BEAVER WERE DAMAGED ON YOUR TRIP."); + System.out.println("YOU RECEIVE ONLY HALF THE CURRENT PRICE FOR THESE FURS."); + } + + if (playerAlive) { + System.out.println("SUPPLIES AT NEW YORK COST $80.00."); + System.out.println("YOUR TRAVEL EXPENSES TO NEW YORK WERE $25.00."); + } + + return playerAlive; + } + /** + * Return a pelt object containing the user entered number of pelts. + * + * @param peltName Type of pelt + * @return Pelt object containing name and number of pelts. + */ + private Pelt getPelt(String peltName) { + int pelts = displayTextAndGetNumber("HOW MANY " + peltName + " PELTS DO YOU HAVE? "); + return new Pelt(peltName, pelts); + } + + private void extendedTradingInfo() { + System.out.println("YOU MAY TRADE YOUR FURS AT FORT 1, FORT 2,"); + System.out.println("OR FORT 3. FORT 1 IS FORT HOCHELAGA (MONTREAL)"); + System.out.println("AND IS UNDER THE PROTECTION OF THE FRENCH ARMY."); + System.out.println("FORT 2 IS FORT STADACONA (QUEBEC) AND IS UNDER THE"); + System.out.println("PROTECTION OF THE FRENCH ARMY. HOWEVER, YOU MUST"); + System.out.println("MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS."); + System.out.println("FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL."); + System.out.println("YOU MUST CROSS THROUGH IROQUOIS LAND."); + + } + private void gameStartupMessage() { + System.out.println(simulateTabs(31) + "FUR TRADER"); + System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println(); + } + + private void intro() { + System.out.println("YOU ARE THE LEADER OF A FRENCH FUR TRADING EXPEDITION IN "); + System.out.println("1776 LEAVING THE LAKE ONTARIO AREA TO SELL FURS AND GET"); + System.out.println("SUPPLIES FOR THE NEXT YEAR. YOU HAVE A CHOICE OF THREE"); + System.out.println("FORTS AT WHICH YOU MAY TRADE. THE COST OF SUPPLIES"); + System.out.println("AND THE AMOUNT YOU RECEIVE FOR YOUR FURS WILL DEPEND"); + System.out.println("ON THE FORT THAT YOU CHOOSE."); + } + + /* + * Print a message on the screen, then accept input from Keyboard. + * Converts input to an Integer + * + * @param text message to be displayed on screen. + * @return what was typed by the player. + */ + private int displayTextAndGetNumber(String text) { + return Integer.parseInt(displayTextAndGetInput(text)); + } + + /* + * Print a message on the screen, then accept input from Keyboard. + * + * @param text message to be displayed on screen. + * @return what was typed by the player. + */ + private String displayTextAndGetInput(String text) { + System.out.print(text); + return kbScanner.next(); + } + + /** + * Simulate the old basic tab(xx) command which indented text by xx spaces. + * + * @param spaces number of spaces required + * @return String with number of spaces + */ + private String simulateTabs(int spaces) { + char[] spacesTemp = new char[spaces]; + Arrays.fill(spacesTemp, ' '); + return new String(spacesTemp); + } + + /** + * Checks whether player entered Y or YES to a question. + * + * @param text player string from kb + * @return true of Y or YES was entered, otherwise false + */ + private boolean yesEntered(String text) { + return stringIsAnyValue(text, "Y", "YES"); + } + + /** + * Check whether a string equals one of a variable number of values + * Useful to check for Y or YES for example + * Comparison is case insensitive. + * + * @param text source string + * @param values a range of values to compare against the source string + * @return true if a comparison was found in one of the variable number of strings passed + */ + private boolean stringIsAnyValue(String text, String... values) { + + return Arrays.stream(values).anyMatch(str -> str.equalsIgnoreCase(text)); + } + +} diff --git a/38 Fur Trader/java/src/FurTraderGame.java b/38 Fur Trader/java/src/FurTraderGame.java new file mode 100644 index 00000000..9c7aaa1c --- /dev/null +++ b/38 Fur Trader/java/src/FurTraderGame.java @@ -0,0 +1,7 @@ +public class FurTraderGame { + public static void main(String[] args) { + + FurTrader furTrader = new FurTrader(); + furTrader.play(); + } +} diff --git a/38 Fur Trader/java/src/Pelt.java b/38 Fur Trader/java/src/Pelt.java new file mode 100644 index 00000000..d27985b0 --- /dev/null +++ b/38 Fur Trader/java/src/Pelt.java @@ -0,0 +1,23 @@ +public class Pelt { + + private String name; + private int number; + + public Pelt(String name, int number) { + this.name = name; + this.number = number; + } + + public int getNumber() { + return this.number; + } + + public String getName() { + return this.name; + } + + public Object lostPelts() { + this.number = 0; + return null; + } +} From 1ce47dd8969e487b11c161c4000c58011598d2e4 Mon Sep 17 00:00:00 2001 From: journich <70119791+journich@users.noreply.github.com> Date: Wed, 10 Mar 2021 08:40:09 +1030 Subject: [PATCH 2/2] Final update to FurTrader Java port --- 38 Fur Trader/java/src/FurTrader.java | 178 +++++++++++++++++--------- 38 Fur Trader/java/src/Pelt.java | 12 +- 2 files changed, 130 insertions(+), 60 deletions(-) diff --git a/38 Fur Trader/java/src/FurTrader.java b/38 Fur Trader/java/src/FurTrader.java index c9bc3272..789adb25 100644 --- a/38 Fur Trader/java/src/FurTrader.java +++ b/38 Fur Trader/java/src/FurTrader.java @@ -29,7 +29,6 @@ public class FurTrader { public static final String FOX = "FOX"; public static final int FOX_ENTRY = 3; - // Used for keyboard input private final Scanner kbScanner; @@ -53,9 +52,12 @@ public class FurTrader { private ArrayList pelts; + private boolean playedOnce; + public FurTrader() { kbScanner = new Scanner(System.in); gameState = GAME_STATE.INIT; + playedOnce = false; } /** @@ -69,42 +71,70 @@ public class FurTrader { case INIT: savings = START_SAVINGS_AMOUNT; - gameStartupMessage(); + // Only display initial game heading once + if (!playedOnce) { + playedOnce = true; + gameStartupMessage(); + } + intro(); if (yesEntered(displayTextAndGetInput("DO YOU WISH TO TRADE FURS? "))) { + System.out.println("YOU HAVE $" + formatNumber(savings) + " SAVINGS."); + System.out.println("AND " + STARTING_FURS + " FURS TO BEGIN THE EXPEDITION."); + + // Create a new array of Pelts. + pelts = initPelts(); gameState = GAME_STATE.STARTUP; - intro(); } else { gameState = GAME_STATE.GAME_OVER; } - System.out.println("YOU HAVE $" + savings + " SAVINGS."); - System.out.println("AND " + STARTING_FURS + " FURS TO BEGIN THE EXPEDITION."); - break; case STARTUP: - pelts = new ArrayList<>(); + // Reset count of pelts (all types) + resetPelts(); - pelts.add(getPelt(MINK)); - pelts.add(getPelt(BEAVER)); - pelts.add(getPelt(ERMINE)); - pelts.add(getPelt(FOX)); + // This is where we will go to after processing all pelts. + gameState = GAME_STATE.TRADE_AT_FORT; - // Determine if count of total pelts exceeds the maximum - // N.B. Original game was fine with entering less than the - // maximum so this functionality has been left in. - if (pelts.stream().mapToInt(Pelt::getNumber).sum() > STARTING_FURS) { - System.out.println("YOU MAY NOT HAVE THAT MANY FURS."); - System.out.println("DO NOT TRY TO CHEAT. I CAN ADD."); - System.out.println("YOU MUST START AGAIN."); - gameState = GAME_STATE.STARTUP; - } else { - // No cheating, so start trading + int totalPelts = 0; + // Cycle through all types of pelts + for (int i = 0; i < pelts.size(); i++) { + Pelt pelt = pelts.get(i); + int number = getPeltCount(pelt.getName()); + totalPelts += number; + if (totalPelts > STARTING_FURS) { + System.out.println("YOU MAY NOT HAVE THAT MANY FURS."); + System.out.println("DO NOT TRY TO CHEAT. I CAN ADD."); + System.out.println("YOU MUST START AGAIN."); + System.out.println(); + // Restart the game + gameState = GAME_STATE.INIT; + break; + } else { + // update count entered by player and save back to ArrayList. + pelt.setPeltCount(number); + pelts.set(i, pelt); + // Its possible for the player to put all their pelt allocation + // into one or more different pelts. They don't have to use all four types. + // If we have an exact count of pelts matching the MAX + // don't bother continuing to ask for more. + if (totalPelts == STARTING_FURS) { + break; + } + } + } + + // Only move onto the trading part of the game if the player didn't add too many pelts + if (gameState != GAME_STATE.STARTUP) { + // Set ermine and beaver default prices here, depending on where you trade these + // defaults will either be used or overwritten with other values. + // check out the tradeAt??? methods for more info. erminePrice = ((.15 * Math.random() + .95) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); beaverPrice = ((.25 * Math.random() + 1.00) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); - gameState = GAME_STATE.TRADE_AT_FORT; + System.out.println(); } break; @@ -113,6 +143,8 @@ public class FurTrader { extendedTradingInfo(); int answer = displayTextAndGetNumber("ANSWER 1, 2, OR 3. "); + System.out.println(); + // Now show the details of the fort they are about to trade // and give the player the chance to NOT proceed. // A "No" or false means they do not want to change to another fort @@ -129,7 +161,7 @@ public class FurTrader { break; case 3: // Did the player and party all die? - if(!tradeAtFortNewYork()) { + if (!tradeAtFortNewYork()) { gameState = GAME_STATE.GAME_OVER; } else { gameState = GAME_STATE.TRADE_SUMMARY; @@ -142,27 +174,28 @@ public class FurTrader { case TRADE_SUMMARY: + System.out.println(); double beaverTotal = beaverPrice * pelts.get(BEAVER_ENTRY).getNumber(); - System.out.println("YOUR BEAVER SOLD FOR $ " + beaverTotal); + System.out.print("YOUR BEAVER SOLD FOR $ " + formatNumber(beaverTotal)); double foxTotal = foxPrice * pelts.get(FOX_ENTRY).getNumber(); - System.out.println("YOUR FOX SOLD FOR $ " + foxTotal); + System.out.println(simulateTabs(5) + "YOUR FOX SOLD FOR $ " + formatNumber(foxTotal)); double erMineTotal = erminePrice * pelts.get(ERMINE_ENTRY).getNumber(); - System.out.println("YOUR ERMINE SOLD FOR $ " + erMineTotal); + System.out.print("YOUR ERMINE SOLD FOR $ " + formatNumber(erMineTotal)); double minkTotal = minkPrice * pelts.get(MINK_ENTRY).getNumber(); - System.out.println("YOUR MINK SOLD FOR $ " + minkTotal); + System.out.println(simulateTabs(5) + "YOUR MINK SOLD FOR $ " + formatNumber(minkTotal)); savings += beaverTotal + foxTotal + erMineTotal + minkTotal; System.out.println(); - System.out.println("YOU NOW HAVE $" + savings + " INCLUDING YOUR PREVIOUS SAVINGS"); + System.out.println("YOU NOW HAVE $" + formatNumber(savings) + " INCLUDING YOUR PREVIOUS SAVINGS"); gameState = GAME_STATE.TRADE_AGAIN; break; case TRADE_AGAIN: - if(yesEntered(displayTextAndGetInput("DO YOU WANT TO TRADE FURS NEXT YEAR? "))) { + if (yesEntered(displayTextAndGetInput("DO YOU WANT TO TRADE FURS NEXT YEAR? "))) { gameState = GAME_STATE.STARTUP; } else { gameState = GAME_STATE.GAME_OVER; @@ -172,14 +205,30 @@ public class FurTrader { } while (gameState != GAME_STATE.GAME_OVER); } + /** + * Create all pelt types with a count of zero + * + * @return Arraylist of initialised Pelt objects. + */ + private ArrayList initPelts() { + + ArrayList tempPelts = new ArrayList<>(); + tempPelts.add(new Pelt(MINK, 0)); + tempPelts.add(new Pelt(BEAVER, 0)); + tempPelts.add(new Pelt(ERMINE, 0)); + tempPelts.add(new Pelt(FOX, 0)); + return tempPelts; + } + /** * Display a message about trading at each fort and confirm if the player wants to trade * at ANOTHER fort + * * @param fort the fort in question * @return true if YES was typed by player */ private boolean confirmFort(int fort) { - switch(fort) { + switch (fort) { case FORT_HOCHELAGA_MONTREAL: System.out.println("YOU HAVE CHOSEN THE EASIEST ROUTE. HOWEVER, THE FORT"); System.out.println("IS FAR FROM ANY SEAPORT. THE VALUE"); @@ -211,7 +260,7 @@ public class FurTrader { * and return */ private void tradeAtFortHochelagaMontreal() { - savings -= 160; + savings -= 160.0; System.out.println(); System.out.println("SUPPLIES AT FORT HOCHELAGA COST $150.00."); System.out.println("YOUR TRAVEL EXPENSES TO HOCHELAGA WERE $10.00."); @@ -219,27 +268,25 @@ public class FurTrader { erminePrice = ((.2 * Math.random() + .65) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); beaverPrice = ((.2 * Math.random() + .75) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); foxPrice = ((.2 * Math.random() + .8) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); - return; } private void tradeAtFortStadaconaQuebec() { - savings -= 140; + savings -= 140.0; System.out.println(); minkPrice = ((.2 * Math.random() + .85) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); erminePrice = ((.2 * Math.random() + .8) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); beaverPrice = ((.2 * Math.random() + .9) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); // What happened during the trip to the fort? - int tripResult = (int) (Math.random()*10) + 1; - if(tripResult <= 2) { + int tripResult = (int) (Math.random() * 10) + 1; + if (tripResult <= 2) { // Find the Beaver pelt in our Arraylist Pelt beaverPelt = pelts.get(BEAVER_ENTRY); // Pelts got stolen, so update to a count of zero beaverPelt.lostPelts(); // Update it back in the ArrayList pelts.set(BEAVER_ENTRY, beaverPelt); - System.out.println("YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS"); System.out.println("THE PORTAGE. YOU HAD TO LEAVE THE PELTS, BUT FOUND"); System.out.println("THEM STOLEN WHEN YOU RETURNED."); @@ -249,13 +296,11 @@ public class FurTrader { System.out.println("YOUR CANOE UPSET IN THE LACHINE RAPIDS. YOU"); System.out.println("LOST ALL YOUR FURS."); // Clear out all pelts. - for(int i=0; i<3; i++) { - Pelt pelt = pelts.get(i); - pelt.lostPelts(); - pelts.set(i, pelt); - } - } else if(tripResult <= 10) { + resetPelts(); + } else if (tripResult <= 10) { // Fox pelts not cured + System.out.println("YOUR FOX PELTS WERE NOT CURED PROPERLY."); + System.out.println("NO ONE WILL BUY THEM."); // Bug because Fox furs were not calculated above in original basic program // Find the Beaver pelt in our Arraylist Pelt foxPelt = pelts.get(FOX_ENTRY); @@ -272,14 +317,14 @@ public class FurTrader { private boolean tradeAtFortNewYork() { boolean playerAlive = true; - savings -= 105; + savings -= 105.0; System.out.println(); minkPrice = ((.2 * Math.random() + 1.05) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); foxPrice = ((.2 * Math.random() + 1.1) * (Math.pow(10, 2) + .5)) / Math.pow(10, 2); // What happened during the trip to the fort? - int tripResult = (int) (Math.random()*10) + 1; - if(tripResult <= 2) { + int tripResult = (int) (Math.random() * 10) + 1; + if (tripResult <= 2) { System.out.println("YOU WERE ATTACKED BY A PARTY OF IROQUOIS."); System.out.println("ALL PEOPLE IN YOUR TRADING GROUP WERE"); System.out.println("KILLED. THIS ENDS THE GAME."); @@ -291,12 +336,8 @@ public class FurTrader { System.out.println("YOU NARROWLY ESCAPED AN IROQUOIS RAIDING PARTY."); System.out.println("HOWEVER, YOU HAD TO LEAVE ALL YOUR FURS BEHIND."); // Clear out all pelts. - for(int i=0; i<3; i++) { - Pelt pelt = pelts.get(i); - pelt.lostPelts(); - pelts.set(i, pelt); - } - } else if(tripResult <= 10) { + resetPelts(); + } else if (tripResult <= 10) { beaverPrice /= 2; minkPrice /= 2; System.out.println("YOUR MINK AND BEAVER WERE DAMAGED ON YOUR TRIP."); @@ -310,15 +351,26 @@ public class FurTrader { return playerAlive; } + + /** + * Reset pelt count for all Pelt types to zero. + */ + private void resetPelts() { + for (int i = 0; i < pelts.size(); i++) { + Pelt pelt = pelts.get(i); + pelt.lostPelts(); + pelts.set(i, pelt); + } + } + /** * Return a pelt object containing the user entered number of pelts. * - * @param peltName Type of pelt - * @return Pelt object containing name and number of pelts. + * @param peltName Name of pelt (Type) + * @return number of pelts assigned by player */ - private Pelt getPelt(String peltName) { - int pelts = displayTextAndGetNumber("HOW MANY " + peltName + " PELTS DO YOU HAVE? "); - return new Pelt(peltName, pelts); + private int getPeltCount(String peltName) { + return displayTextAndGetNumber("HOW MANY " + peltName + " PELTS DO YOU HAVE? "); } private void extendedTradingInfo() { @@ -330,8 +382,10 @@ public class FurTrader { System.out.println("MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS."); System.out.println("FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL."); System.out.println("YOU MUST CROSS THROUGH IROQUOIS LAND."); + System.out.println(); } + private void gameStartupMessage() { System.out.println(simulateTabs(31) + "FUR TRADER"); System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); @@ -345,6 +399,17 @@ public class FurTrader { System.out.println("FORTS AT WHICH YOU MAY TRADE. THE COST OF SUPPLIES"); System.out.println("AND THE AMOUNT YOU RECEIVE FOR YOUR FURS WILL DEPEND"); System.out.println("ON THE FORT THAT YOU CHOOSE."); + System.out.println(); + } + + /** + * Format a double number to two decimal points for output. + * + * @param number double number + * @return formatted number as a string + */ + private String formatNumber(double number) { + return String.format("%.2f", number); } /* @@ -404,5 +469,4 @@ public class FurTrader { return Arrays.stream(values).anyMatch(str -> str.equalsIgnoreCase(text)); } - } diff --git a/38 Fur Trader/java/src/Pelt.java b/38 Fur Trader/java/src/Pelt.java index d27985b0..92c9629d 100644 --- a/38 Fur Trader/java/src/Pelt.java +++ b/38 Fur Trader/java/src/Pelt.java @@ -1,6 +1,9 @@ +/** + * Pelt object - tracks the name and number of pelts the player has for this pelt type + */ public class Pelt { - private String name; + private final String name; private int number; public Pelt(String name, int number) { @@ -8,6 +11,10 @@ public class Pelt { this.number = number; } + public void setPeltCount(int pelts) { + this.number = pelts; + } + public int getNumber() { return this.number; } @@ -16,8 +23,7 @@ public class Pelt { return this.name; } - public Object lostPelts() { + public void lostPelts() { this.number = 0; - return null; } }