diff --git a/07 Basketball/javascript/basketball.html b/07 Basketball/javascript/basketball.html new file mode 100644 index 00000000..e9eedab3 --- /dev/null +++ b/07 Basketball/javascript/basketball.html @@ -0,0 +1,9 @@ + +
++ * Based on the Basic game of BatNum here + * https://github.com/coding-horror/basic-computer-games/blob/main/08%20Batnum/batnum.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 BatNum { + + private enum GAME_STATE { + STARTING, + START_GAME, + CHOOSE_PILE_SIZE, + SELECT_WIN_OPTION, + CHOOSE_MIN_AND_MAX, + SELECT_WHO_STARTS_FIRST, + PLAYERS_TURN, + COMPUTERS_TURN, + ANNOUNCE_WINNER, + GAME_OVER + } + + // Used for keyboard input + private final Scanner kbScanner; + + // Current game state + private GAME_STATE gameState; + + private int pileSize; + + // How to win the game options + enum WIN_OPTION { + TAKE_LAST, + AVOID_LAST + } + + // Tracking the winner + enum WINNER { + COMPUTER, + PLAYER + } + + private WINNER winner; + + private WIN_OPTION winOption; + + private int minSelection; + private int maxSelection; + + // Used by computer for optimal move + private int rangeOfRemovals; + + public BatNum() { + + gameState = GAME_STATE.STARTING; + + // Initialise kb scanner + kbScanner = new Scanner(System.in); + } + + /** + * Main game loop + */ + public void play() { + + do { + switch (gameState) { + + // Show an introduction and optional instructions the first time the game is played. + case STARTING: + intro(); + gameState = GAME_STATE.START_GAME; + break; + + // Start new game + case START_GAME: + gameState = GAME_STATE.CHOOSE_PILE_SIZE; + break; + + case CHOOSE_PILE_SIZE: + System.out.println(); + System.out.println(); + pileSize = displayTextAndGetNumber("ENTER PILE SIZE "); + if (pileSize >= 1) { + gameState = GAME_STATE.SELECT_WIN_OPTION; + } + break; + + case SELECT_WIN_OPTION: + int winChoice = displayTextAndGetNumber("ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: "); + if (winChoice == 1) { + winOption = WIN_OPTION.TAKE_LAST; + gameState = GAME_STATE.CHOOSE_MIN_AND_MAX; + } else if (winChoice == 2) { + winOption = WIN_OPTION.AVOID_LAST; + gameState = GAME_STATE.CHOOSE_MIN_AND_MAX; + } + break; + + case CHOOSE_MIN_AND_MAX: + String range = displayTextAndGetInput("ENTER MIN AND MAX "); + minSelection = getDelimitedValue(range, 0); + maxSelection = getDelimitedValue(range, 1); + if (maxSelection > minSelection && minSelection >= 1) { + gameState = GAME_STATE.SELECT_WHO_STARTS_FIRST; + } + + // Used by computer in its turn + rangeOfRemovals = minSelection + maxSelection; + break; + + case SELECT_WHO_STARTS_FIRST: + int playFirstChoice = displayTextAndGetNumber("ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST "); + if (playFirstChoice == 1) { + gameState = GAME_STATE.COMPUTERS_TURN; + } else if (playFirstChoice == 2) { + gameState = GAME_STATE.PLAYERS_TURN; + } + break; + + case PLAYERS_TURN: + int playersMove = displayTextAndGetNumber("YOUR MOVE "); + + if (playersMove == 0) { + System.out.println("I TOLD YOU NOT TO USE ZERO! COMPUTER WINS BY FORFEIT."); + winner = WINNER.COMPUTER; + gameState = GAME_STATE.ANNOUNCE_WINNER; + break; + } + + if (playersMove == pileSize && winOption == WIN_OPTION.AVOID_LAST) { + winner = WINNER.COMPUTER; + gameState = GAME_STATE.ANNOUNCE_WINNER; + break; + } + + // Check if players move is with the min and max possible + if (playersMove >= minSelection && playersMove <= maxSelection) { + // Valid so reduce pileSize by amount player entered + pileSize -= playersMove; + + // Did this move result in there being no more objects on pile? + if (pileSize == 0) { + // Was the game setup so the winner was whoever took the last object + if (winOption == WIN_OPTION.TAKE_LAST) { + // Player won + winner = WINNER.PLAYER; + } else { + // Computer one + winner = WINNER.COMPUTER; + } + gameState = GAME_STATE.ANNOUNCE_WINNER; + } else { + // There are still items left. + gameState = GAME_STATE.COMPUTERS_TURN; + } + } else { + // Invalid move + System.out.println("ILLEGAL MOVE, REENTER IT "); + } + break; + + case COMPUTERS_TURN: + int pileSizeLeft = pileSize; + if (winOption == WIN_OPTION.TAKE_LAST) { + if (pileSize > maxSelection) { + + int objectsToRemove = calculateComputersTurn(pileSizeLeft); + + pileSize -= objectsToRemove; + System.out.println("COMPUTER TAKES " + objectsToRemove + " AND LEAVES " + pileSize); + gameState = GAME_STATE.PLAYERS_TURN; + } else { + System.out.println("COMPUTER TAKES " + pileSize + " AND WINS."); + winner = WINNER.COMPUTER; + gameState = GAME_STATE.ANNOUNCE_WINNER; + } + } else { + pileSizeLeft--; + if (pileSize > minSelection) { + int objectsToRemove = calculateComputersTurn(pileSizeLeft); + pileSize -= objectsToRemove; + System.out.println("COMPUTER TAKES " + objectsToRemove + " AND LEAVES " + pileSize); + gameState = GAME_STATE.PLAYERS_TURN; + } else { + System.out.println("COMPUTER TAKES " + pileSize + " AND LOSES."); + winner = WINNER.PLAYER; + gameState = GAME_STATE.ANNOUNCE_WINNER; + } + } + break; + + case ANNOUNCE_WINNER: + switch (winner) { + case PLAYER: + System.out.println("CONGRATULATIONS, YOU WIN."); + break; + case COMPUTER: + System.out.println("TOUGH LUCK, YOU LOSE."); + break; + } + gameState = GAME_STATE.START_GAME; + break; + } + } while (gameState != GAME_STATE.GAME_OVER); + } + + /** + * Figure out the computers turn - i.e. how many objects to remove + * + * @param pileSizeLeft current size + * @return the number of objects to remove. + */ + private int calculateComputersTurn(int pileSizeLeft) { + int computersNumberToRemove = pileSizeLeft - rangeOfRemovals * (pileSizeLeft / rangeOfRemovals); + if (computersNumberToRemove < minSelection) { + computersNumberToRemove = minSelection; + } + if (computersNumberToRemove > maxSelection) { + computersNumberToRemove = maxSelection; + } + + return computersNumberToRemove; + } + + private void intro() { + System.out.println(simulateTabs(33) + "BATNUM"); + System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println(); + System.out.println("THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE"); + System.out.println("COMPUTER IS YOUR OPPONENT."); + System.out.println(); + System.out.println("THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU"); + System.out.println("AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE."); + System.out.println("WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR"); + System.out.println("NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS."); + System.out.println("DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME."); + System.out.println("ENTER A NEGATIVE NUMBER FOR NEW PILE SIZE TO STOP PLAYING."); + } + + /* + * Print a message on the screen, then accept input from Keyboard. + * Converts input to 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); + } + + /** + * Accepts a string delimited by comma's and returns the nth delimited + * value (starting at count 0). + * + * @param text - text with values separated by comma's + * @param pos - which position to return a value for + * @return the int representation of the value + */ + private int getDelimitedValue(String text, int pos) { + String[] tokens = text.split(","); + return Integer.parseInt(tokens[pos]); + } +} \ No newline at end of file diff --git a/08 Batnum/java/src/BatNumGame.java b/08 Batnum/java/src/BatNumGame.java new file mode 100644 index 00000000..b84b61c1 --- /dev/null +++ b/08 Batnum/java/src/BatNumGame.java @@ -0,0 +1,8 @@ +public class BatNumGame { + + public static void main(String[] args) { + + BatNum batNum = new BatNum(); + batNum.play(); + } +} diff --git a/08 Batnum/javascript/batnum.html b/08 Batnum/javascript/batnum.html new file mode 100644 index 00000000..51d8dd11 --- /dev/null +++ b/08 Batnum/javascript/batnum.html @@ -0,0 +1,9 @@ + +
++ * Based on the Basic game of Change here + * https://github.com/coding-horror/basic-computer-games/blob/main/22%20Change/change.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 Change { + + // Used for keyboard input + private final Scanner kbScanner; + + private enum GAME_STATE { + START_GAME, + INPUT, + CALCULATE, + END_GAME, + GAME_OVER + } + + // Current game state + private GAME_STATE gameState; + + // Amount of change needed to be given + private double change; + + public Change() { + kbScanner = new Scanner(System.in); + + gameState = GAME_STATE.START_GAME; + } + + /** + * Main game loop + */ + public void play() { + + do { + switch (gameState) { + case START_GAME: + intro(); + gameState = GAME_STATE.INPUT; + break; + + case INPUT: + + double costOfItem = displayTextAndGetNumber("COST OF ITEM "); + double amountPaid = displayTextAndGetNumber("AMOUNT OF PAYMENT "); + change = amountPaid - costOfItem; + if (change == 0) { + // No change needed + System.out.println("CORRECT AMOUNT, THANK YOU."); + gameState = GAME_STATE.END_GAME; + } else if (change < 0) { + System.out.println("YOU HAVE SHORT-CHANGES ME $" + (costOfItem - amountPaid)); + // Don't change game state so it will loop back and try again + } else { + // Change needed. + gameState = GAME_STATE.CALCULATE; + } + break; + + case CALCULATE: + System.out.println("YOUR CHANGE, $" + change); + calculateChange(); + gameState = GAME_STATE.END_GAME; + break; + + case END_GAME: + System.out.println("THANK YOU, COME AGAIN"); + System.out.println(); + gameState = GAME_STATE.INPUT; + } + } while (gameState != GAME_STATE.GAME_OVER); + } + + /** + * Calculate and output the change required for the purchase based on + * what money was paid. + */ + private void calculateChange() { + + double originalChange = change; + + int tenDollarBills = (int) change / 10; + if (tenDollarBills > 0) { + System.out.println(tenDollarBills + " TEN DOLLAR BILL(S)"); + } + change = originalChange - (tenDollarBills * 10); + + int fiveDollarBills = (int) change / 5; + if (fiveDollarBills > 0) { + System.out.println(fiveDollarBills + " FIVE DOLLAR BILL(S)"); + } + change = originalChange - (tenDollarBills * 10 + fiveDollarBills * 5); + + int oneDollarBills = (int) change; + if (oneDollarBills > 0) { + System.out.println(oneDollarBills + " ONE DOLLAR BILL(S)"); + } + change = originalChange - (tenDollarBills * 10 + fiveDollarBills * 5 + oneDollarBills); + + change = change * 100; + double cents = change; + + int halfDollars = (int) change / 50; + if (halfDollars > 0) { + System.out.println(halfDollars + " ONE HALF DOLLAR(S)"); + } + change = cents - (halfDollars * 50); + + int quarters = (int) change / 25; + if (quarters > 0) { + System.out.println(quarters + " QUARTER(S)"); + } + + change = cents - (halfDollars * 50 + quarters * 25); + + int dimes = (int) change / 10; + if (dimes > 0) { + System.out.println(dimes + " DIME(S)"); + } + + change = cents - (halfDollars * 50 + quarters * 25 + dimes * 10); + + int nickels = (int) change / 5; + if (nickels > 0) { + System.out.println(nickels + " NICKEL(S)"); + } + + change = cents - (halfDollars * 50 + quarters * 25 + dimes * 10 + nickels * 5); + + int pennies = (int) (change + .5); + if (pennies > 0) { + System.out.println(pennies + " PENNY(S)"); + } + + } + + private void intro() { + System.out.println(simulateTabs(33) + "CHANGE"); + System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println(); + System.out.println("I, YOUR FRIENDLY MICROCOMPUTER, WILL DETERMINE"); + System.out.println("THE CORRECT CHANGE FOR ITEMS COSTING UP TO $100."); + System.out.println(); + } + + /* + * Print a message on the screen, then accept input from Keyboard. + * Converts input to a Double + * + * @param text message to be displayed on screen. + * @return what was typed by the player. + */ + private double displayTextAndGetNumber(String text) { + return Double.parseDouble(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); + } +} diff --git a/22 Change/java/src/ChangeGame.java b/22 Change/java/src/ChangeGame.java new file mode 100644 index 00000000..c2863914 --- /dev/null +++ b/22 Change/java/src/ChangeGame.java @@ -0,0 +1,6 @@ +public class ChangeGame { + public static void main(String[] args) { + Change change = new Change(); + change.play(); + } +} diff --git a/24 Chemist/java/src/Chemist.java b/24 Chemist/java/src/Chemist.java new file mode 100644 index 00000000..137b3ce5 --- /dev/null +++ b/24 Chemist/java/src/Chemist.java @@ -0,0 +1,143 @@ +import java.util.Arrays; +import java.util.Scanner; + +/** + * Game of Chemist + *
+ * Based on the Basic game of Chemist here + * https://github.com/coding-horror/basic-computer-games/blob/main/24%20Chemist/chemist.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 Chemist { + + public static final int MAX_LIVES = 9; + + // Used for keyboard input + private final Scanner kbScanner; + + private enum GAME_STATE { + START_GAME, + INPUT, + BLOWN_UP, + SURVIVED, + GAME_OVER + } + + // Current game state + private GAME_STATE gameState; + + private int timesBlownUp; + + public Chemist() { + kbScanner = new Scanner(System.in); + + gameState = GAME_STATE.START_GAME; + } + + /** + * Main game loop + */ + public void play() { + + do { + switch (gameState) { + + case START_GAME: + intro(); + timesBlownUp = 0; + gameState = GAME_STATE.INPUT; + break; + + case INPUT: + + int amountOfAcid = (int) (Math.random() * 50); + int correctAmountOfWater = (7 * amountOfAcid) / 3; + int water = displayTextAndGetNumber(amountOfAcid + " LITERS OF KRYPTOCYANIC ACID. HOW MUCH WATER? "); + + // Calculate if the player mixed enough water + int result = Math.abs(correctAmountOfWater - water); + + // Ratio of water wrong? + if (result > (correctAmountOfWater / 20)) { + gameState = GAME_STATE.BLOWN_UP; + } else { + // Got the ratio correct + gameState = GAME_STATE.SURVIVED; + } + break; + + case BLOWN_UP: + System.out.println(" SIZZLE! YOU HAVE JUST BEEN DESALINATED INTO A BLOB"); + System.out.println(" OF QUIVERING PROTOPLASM!"); + + timesBlownUp++; + + if (timesBlownUp < MAX_LIVES) { + System.out.println(" HOWEVER, YOU MAY TRY AGAIN WITH ANOTHER LIFE."); + gameState = GAME_STATE.INPUT; + } else { + System.out.println(" YOUR " + MAX_LIVES + " LIVES ARE USED, BUT YOU WILL BE LONG REMEMBERED FOR"); + System.out.println(" YOUR CONTRIBUTIONS TO THE FIELD OF COMIC BOOK CHEMISTRY."); + gameState = GAME_STATE.GAME_OVER; + } + + break; + + case SURVIVED: + System.out.println(" GOOD JOB! YOU MAY BREATHE NOW, BUT DON'T INHALE THE FUMES!"); + System.out.println(); + gameState = GAME_STATE.INPUT; + break; + + } + } while (gameState != GAME_STATE.GAME_OVER); + } + + private void intro() { + System.out.println(simulateTabs(33) + "CHEMIST"); + System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println(); + System.out.println("THE FICTITIOUS CHEMICAL KRYPTOCYANIC ACID CAN ONLY BE"); + System.out.println("DILUTED BY THE RATIO OF 7 PARTS WATER TO 3 PARTS ACID."); + System.out.println("IF ANY OTHER RATIO IS ATTEMPTED, THE ACID BECOMES UNSTABLE"); + System.out.println("AND SOON EXPLODES. GIVEN THE AMOUNT OF ACID, YOU MUST"); + System.out.println("DECIDE WHO MUCH WATER TO ADD FOR DILUTION. IF YOU MISS"); + System.out.println("YOU FACE THE CONSEQUENCES."); + } + + /* + * 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); + } +} diff --git a/24 Chemist/java/src/ChemistGame.java b/24 Chemist/java/src/ChemistGame.java new file mode 100644 index 00000000..494959a3 --- /dev/null +++ b/24 Chemist/java/src/ChemistGame.java @@ -0,0 +1,6 @@ +public class ChemistGame { + public static void main(String[] args) { + Chemist chemist = new Chemist(); + chemist.play(); + } +} diff --git a/26 Chomp/chomp.bas b/26 Chomp/chomp.bas index 26d0296b..50e5e232 100644 --- a/26 Chomp/chomp.bas +++ b/26 Chomp/chomp.bas @@ -99,6 +99,6 @@ 1010 PRINT "YOU LOSE, PLAYER";P1 1020 PRINT 1030 PRINT "AGAIN (1=YES, 0=NO!)"; -1040 INPUT R$ +1040 INPUT R 1050 IF R=1 THEN 340 1060 END diff --git a/26 Chomp/javascript/chomp.html b/26 Chomp/javascript/chomp.html new file mode 100644 index 00000000..b749afe3 --- /dev/null +++ b/26 Chomp/javascript/chomp.html @@ -0,0 +1,9 @@ + +
++ * Based on the Basic game of Dice here + * https://github.com/coding-horror/basic-computer-games/blob/main/33%20Dice/dice.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 Dice { + + // Used for keyboard input + private final Scanner kbScanner; + + private enum GAME_STATE { + START_GAME, + INPUT_AND_CALCULATE, + RESULTS, + GAME_OVER + } + + // Current game state + private GAME_STATE gameState; + + private int[] spots; + + public Dice() { + kbScanner = new Scanner(System.in); + + gameState = GAME_STATE.START_GAME; + } + + /** + * Main game loop + */ + public void play() { + + do { + switch (gameState) { + + case START_GAME: + intro(); + spots = new int[12]; + gameState = GAME_STATE.INPUT_AND_CALCULATE; + break; + + case INPUT_AND_CALCULATE: + + int howManyRolls = displayTextAndGetNumber("HOW MANY ROLLS? "); + for (int i = 0; i < howManyRolls; i++) { + int diceRoll = (int) (Math.random() * 6 + 1) + (int) (Math.random() * 6 + 1); + // save dice roll in zero based array + spots[diceRoll - 1]++; + } + gameState = GAME_STATE.RESULTS; + break; + + case RESULTS: + System.out.println("TOTAL SPOTS" + simulateTabs(8) + "NUMBER OF TIMES"); + for (int i = 1; i < 12; i++) { + // show output using zero based array + System.out.println(simulateTabs(5) + (i + 1) + simulateTabs(20) + spots[i]); + } + System.out.println(); + if (yesEntered(displayTextAndGetInput("TRY AGAIN? "))) { + gameState = GAME_STATE.START_GAME; + } else { + gameState = GAME_STATE.GAME_OVER; + } + break; + } + } while (gameState != GAME_STATE.GAME_OVER); + } + + private void intro() { + System.out.println(simulateTabs(34) + "DICE"); + System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println(); + System.out.println("THIS PROGRAM SIMULATES THE ROLLING OF A"); + System.out.println("PAIR OF DICE."); + System.out.println("YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO"); + System.out.println("'ROLL' THE DICE. WATCH OUT, VERY LARGE NUMBERS TAKE"); + System.out.println("A LONG TIME. IN PARTICULAR, NUMBERS OVER 5000."); + } + + /* + * 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(); + } + + /** + * 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)); + } + + /** + * 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); + } +} diff --git a/33 Dice/java/src/DiceGame.java b/33 Dice/java/src/DiceGame.java new file mode 100644 index 00000000..97f24e61 --- /dev/null +++ b/33 Dice/java/src/DiceGame.java @@ -0,0 +1,6 @@ +public class DiceGame { + public static void main(String[] args) { + Dice dice = new Dice(); + dice.play(); + } +} diff --git a/41 Guess/java/src/Guess.java b/41 Guess/java/src/Guess.java new file mode 100644 index 00000000..667411ab --- /dev/null +++ b/41 Guess/java/src/Guess.java @@ -0,0 +1,161 @@ +import java.util.Arrays; +import java.util.Scanner; + +/** + * Game of Guess + *
+ * Based on the Basic game of Guess here + * https://github.com/coding-horror/basic-computer-games/blob/main/41%20Guess/guess.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 Guess { + + // Used for keyboard input + private final Scanner kbScanner; + + private enum GAME_STATE { + STARTUP, + INPUT_RANGE, + DEFINE_COMPUTERS_NUMBER, + GUESS, + GAME_OVER + } + + // Current game state + private GAME_STATE gameState; + + // User supplied maximum number to guess + private int limit; + + // Computers calculated number for the player to guess + + private int computersNumber; + + // Number of turns the player has had guessing + private int tries; + + // Optimal number of turns it should take to guess + private int calculatedTurns; + + public Guess() { + kbScanner = new Scanner(System.in); + + gameState = GAME_STATE.STARTUP; + } + + /** + * Main game loop + */ + public void play() { + + do { + switch (gameState) { + + case STARTUP: + intro(); + gameState = GAME_STATE.INPUT_RANGE; + break; + + case INPUT_RANGE: + + limit = displayTextAndGetNumber("WHAT LIMIT DO YOU WANT? "); + calculatedTurns = (int) (Math.log(limit) / Math.log(2)) + 1; + gameState = GAME_STATE.DEFINE_COMPUTERS_NUMBER; + break; + + case DEFINE_COMPUTERS_NUMBER: + + tries = 1; + System.out.println("I'M THINKING OF A NUMBER BETWEEN 1 AND " + limit); + computersNumber = (int) (Math.random() * limit + 1); + + gameState = GAME_STATE.GUESS; + break; + + case GUESS: + int playersGuess = displayTextAndGetNumber("NOW YOU TRY TO GUESS WHAT IT IS "); + + // Allow player to restart game with entry of 0 + if (playersGuess == 0) { + linePadding(); + gameState = GAME_STATE.STARTUP; + break; + } + + if (playersGuess == computersNumber) { + System.out.println("THAT'S IT! YOU GOT IT IN " + tries + " TRIES."); + if (tries < calculatedTurns) { + System.out.println("VERY "); + } + System.out.println("GOOD."); + System.out.println("YOU SHOULD HAVE BEEN ABLE TO GET IT IN ONLY " + calculatedTurns); + linePadding(); + gameState = GAME_STATE.DEFINE_COMPUTERS_NUMBER; + break; + } else if (playersGuess < computersNumber) { + System.out.println("TOO LOW. TRY A BIGGER ANSWER."); + } else { + System.out.println("TOO HIGH. TRY A SMALLER ANSWER."); + } + tries++; + break; + } + } while (gameState != GAME_STATE.GAME_OVER); + } + + private void intro() { + System.out.println(simulateTabs(33) + "GUESS"); + System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println(); + System.out.println("THIS IS A NUMBER GUESSING GAME. I'LL THINK"); + System.out.println("OF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT."); + System.out.println("THEN YOU HAVE TO GUESS WHAT IT IS."); + } + + /** + * Print a predefined number of blank lines + * + */ + private void linePadding() { + for (int i = 1; i <= 5; i++) { + System.out.println(); + } + } + + /* + * 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); + } + +} diff --git a/41 Guess/java/src/GuessGame.java b/41 Guess/java/src/GuessGame.java new file mode 100644 index 00000000..603cdbfb --- /dev/null +++ b/41 Guess/java/src/GuessGame.java @@ -0,0 +1,6 @@ +public class GuessGame { + public static void main(String[] args) { + Guess guess = new Guess(); + guess.play(); + } +} diff --git a/52 Kinema/java/src/Kinema.java b/52 Kinema/java/src/Kinema.java new file mode 100644 index 00000000..afbacbe8 --- /dev/null +++ b/52 Kinema/java/src/Kinema.java @@ -0,0 +1,176 @@ +import java.util.Arrays; +import java.util.Scanner; + +/** + * Game of Kinema + *
+ * Based on the Basic game of Kinema here + * https://github.com/coding-horror/basic-computer-games/blob/main/52%20Kinema/kinema.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 Kinema { + + // Used for keyboard input + private final Scanner kbScanner; + + private enum GAME_STATE { + STARTUP, + INIT, + HOW_HIGH, + SECONDS_TILL_IT_RETURNS, + ITS_VELOCITY, + RESULTS, + GAME_OVER + } + + // Current game state + private GAME_STATE gameState; + + private int numberAnswersCorrect; + + // How many meters per second a ball is thrown + private int velocity; + + public Kinema() { + kbScanner = new Scanner(System.in); + + gameState = GAME_STATE.STARTUP; + } + + /** + * Main game loop + */ + public void play() { + + double playerAnswer; + double correctAnswer; + do { + switch (gameState) { + + case STARTUP: + intro(); + gameState = GAME_STATE.INIT; + break; + + case INIT: + numberAnswersCorrect = 0; + + // calculate a random velocity for the player to use in the calculations + velocity = 5 + (int) (35 * Math.random()); + System.out.println("A BALL IS THROWN UPWARDS AT " + velocity + " METERS PER SECOND."); + gameState = GAME_STATE.HOW_HIGH; + break; + + case HOW_HIGH: + + playerAnswer = displayTextAndGetNumber("HOW HIGH WILL IT GO (IN METERS)? "); + + // Calculate the correct answer to how high it will go + correctAnswer = 0.05 * Math.pow(velocity, 2); + if (calculate(playerAnswer, correctAnswer)) { + numberAnswersCorrect++; + } + gameState = GAME_STATE.ITS_VELOCITY; + break; + + case ITS_VELOCITY: + + playerAnswer = displayTextAndGetNumber("HOW LONG UNTIL IT RETURNS (IN SECONDS)? "); + + // Calculate current Answer for how long until it returns to the ground in seconds + correctAnswer = (double) velocity / 5; + if (calculate(playerAnswer, correctAnswer)) { + numberAnswersCorrect++; + } + gameState = GAME_STATE.SECONDS_TILL_IT_RETURNS; + break; + + case SECONDS_TILL_IT_RETURNS: + + // Calculate random number of seconds for 3rd question + double seconds = 1 + (Math.random() * (2 * velocity)) / 10; + + // Round to one decimal place. + double scale = Math.pow(10, 1); + seconds = Math.round(seconds * scale) / scale; + + playerAnswer = displayTextAndGetNumber("WHAT WILL ITS VELOCITY BE AFTER " + seconds + " SECONDS? "); + + // Calculate the velocity after the given number of seconds + correctAnswer = velocity - (10 * seconds); + if (calculate(playerAnswer, correctAnswer)) { + numberAnswersCorrect++; + } + gameState = GAME_STATE.RESULTS; + break; + + case RESULTS: + System.out.println(numberAnswersCorrect + " RIGHT OUT OF 3"); + if (numberAnswersCorrect > 1) { + System.out.println(" NOT BAD."); + } + gameState = GAME_STATE.STARTUP; + break; + } + } while (gameState != GAME_STATE.GAME_OVER); + } + + private void intro() { + System.out.println(simulateTabs(33) + "KINEMA"); + System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println(); + } + + private boolean calculate(double playerAnswer, double correctAnswer) { + + boolean gotItRight = false; + + if (Math.abs((playerAnswer - correctAnswer) / correctAnswer) < 0.15) { + System.out.println("CLOSE ENOUGH"); + gotItRight = true; + } else { + System.out.println("NOT EVEN CLOSE"); + } + System.out.println("CORRECT ANSWER IS " + correctAnswer); + System.out.println(); + + return gotItRight; + } + + /* + * Print a message on the screen, then accept input from Keyboard. + * Converts input to a Double + * + * @param text message to be displayed on screen. + * @return what was typed by the player. + */ + private double displayTextAndGetNumber(String text) { + return Double.parseDouble(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); + } + +} diff --git a/52 Kinema/java/src/KinemaGame.java b/52 Kinema/java/src/KinemaGame.java new file mode 100644 index 00000000..b84d0019 --- /dev/null +++ b/52 Kinema/java/src/KinemaGame.java @@ -0,0 +1,7 @@ +public class KinemaGame { + public static void main(String[] args) { + + Kinema kinema = new Kinema(); + kinema.play(); + } +} diff --git a/54 Letter/java/src/Letter.java b/54 Letter/java/src/Letter.java new file mode 100644 index 00000000..36582894 --- /dev/null +++ b/54 Letter/java/src/Letter.java @@ -0,0 +1,142 @@ +import java.awt.*; +import java.util.Arrays; +import java.util.Scanner; + +/** + * Game of Letter + *
+ * Based on the Basic game of Letter here + * https://github.com/coding-horror/basic-computer-games/blob/main/54%20Letter/letter.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 Letter { + + public static final int OPTIMAL_GUESSES = 5; + public static final int ASCII_A = 65; + public static final int ALL_LETTERS = 26; + + private enum GAME_STATE { + STARTUP, + INIT, + GUESSING, + RESULTS, + GAME_OVER + } + + // Used for keyboard input + private final Scanner kbScanner; + + // Current game state + private GAME_STATE gameState; + + // Players guess count; + private int playerGuesses; + + // Computers ascii code for a random letter between A..Z + private int computersLetter; + + public Letter() { + + gameState = GAME_STATE.STARTUP; + + // Initialise kb scanner + kbScanner = new Scanner(System.in); + } + + /** + * Main game loop + */ + public void play() { + + do { + switch (gameState) { + + // Show an introduction the first time the game is played. + case STARTUP: + intro(); + gameState = GAME_STATE.INIT; + break; + + case INIT: + playerGuesses = 0; + computersLetter = ASCII_A + (int) (Math.random() * ALL_LETTERS); + System.out.println("O.K., I HAVE A LETTER. START GUESSING."); + gameState = GAME_STATE.GUESSING; + break; + + // Player guesses the number until they get it or run out of guesses + case GUESSING: + String playerGuess = displayTextAndGetInput("WHAT IS YOUR GUESS? ").toUpperCase(); + + // Convert first character of input string to ascii + int toAscii = playerGuess.charAt(0); + playerGuesses++; + if (toAscii == computersLetter) { + gameState = GAME_STATE.RESULTS; + break; + } + + if (toAscii > computersLetter) { + System.out.println("TOO HIGH. TRY A LOWER LETTER."); + } else { + System.out.println("TOO LOW. TRY A HIGHER LETTER."); + } + break; + + // Play again, or exit game? + case RESULTS: + System.out.println(); + System.out.println("YOU GOT IT IN " + playerGuesses + " GUESSES!!"); + if (playerGuesses <= OPTIMAL_GUESSES) { + System.out.println("GOOD JOB !!!!!"); + // Original game beeped 15 tims if you guessed in the optimal guesses or less + // Changed this to do a single beep only + Toolkit.getDefaultToolkit().beep(); + } else { + // Took more than optimal number of guesses + System.out.println("BUT IT SHOULDN'T TAKE MORE THAN " + OPTIMAL_GUESSES + " GUESSES!"); + } + System.out.println(); + System.out.println("LET'S PLAN AGAIN....."); + gameState = GAME_STATE.INIT; + break; + } + } while (gameState != GAME_STATE.GAME_OVER); + } + + public void intro() { + System.out.println(simulateTabs(33) + "LETTER"); + System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println(); + System.out.println("LETTER GUESSING GAME"); + System.out.println(); + System.out.println("I'LL THINK OF A LETTER OF THE ALPHABET, A TO Z."); + System.out.println("TRY TO GUESS MY LETTER AND I'LL GIVE YOU CLUES"); + System.out.println("AS TO HOW CLOSE YOU'RE GETTING TO MY LETTER."); + } + + /** + * 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); + } + + /* + * 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(); + } +} \ No newline at end of file diff --git a/54 Letter/java/src/LetterGame.java b/54 Letter/java/src/LetterGame.java new file mode 100644 index 00000000..fa023329 --- /dev/null +++ b/54 Letter/java/src/LetterGame.java @@ -0,0 +1,8 @@ +public class LetterGame { + + public static void main(String[] args) { + + Letter letter = new Letter(); + letter.play(); + } +} diff --git a/57 Literature Quiz/java/src/LiteratureQuiz.java b/57 Literature Quiz/java/src/LiteratureQuiz.java new file mode 100644 index 00000000..d98d58a8 --- /dev/null +++ b/57 Literature Quiz/java/src/LiteratureQuiz.java @@ -0,0 +1,176 @@ +import java.util.Arrays; +import java.util.Scanner; + +/** + * Game of Literature Quiz + *
+ * Based on the Basic game of Literature Quiz here + * https://github.com/coding-horror/basic-computer-games/blob/main/57%20Literature%20Quiz/litquiz.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 LiteratureQuiz {
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ private enum GAME_STATE {
+ STARTUP,
+ QUESTIONS,
+ RESULTS,
+ GAME_OVER
+ }
+
+ // Current game state
+ private GAME_STATE gameState;
+ // Players correct answers
+ private int correctAnswers;
+
+ public LiteratureQuiz() {
+
+ gameState = GAME_STATE.STARTUP;
+
+ // Initialise kb scanner
+ kbScanner = new Scanner(System.in);
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+
+ // Show an introduction the first time the game is played.
+ case STARTUP:
+ intro();
+ correctAnswers = 0;
+ gameState = GAME_STATE.QUESTIONS;
+ break;
+
+ // Ask the player four questions
+ case QUESTIONS:
+
+ // Question 1
+ System.out.println("IN PINOCCHIO, WHAT WAS THE NAME OF THE CAT");
+ int question1Answer = displayTextAndGetNumber("1)TIGGER, 2)CICERO, 3)FIGARO, 4)GUIPETTO ? ");
+ if (question1Answer == 3) {
+ System.out.println("VERY GOOD! HERE'S ANOTHER.");
+ correctAnswers++;
+ } else {
+ System.out.println("SORRY...FIGARO WAS HIS NAME.");
+ }
+
+ System.out.println();
+
+ // Question 2
+ System.out.println("FROM WHOSE GARDEN DID BUGS BUNNY STEAL THE CARROTS?");
+ int question2Answer = displayTextAndGetNumber("1)MR. NIXON'S, 2)ELMER FUDD'S, 3)CLEM JUDD'S, 4)STROMBOLI'S ? ");
+ if (question2Answer == 2) {
+ System.out.println("PRETTY GOOD!");
+ correctAnswers++;
+ } else {
+ System.out.println("TOO BAD...IT WAS ELMER FUDD'S GARDEN.");
+ }
+
+ System.out.println();
+
+ // Question 3
+ System.out.println("IN THE WIZARD OF OS, DOROTHY'S DOG WAS NAMED");
+ int question3Answer = displayTextAndGetNumber("1)CICERO, 2)TRIXIA, 3)KING, 4)TOTO ? ");
+ if (question3Answer == 4) {
+ System.out.println("YEA! YOU'RE A REAL LITERATURE GIANT.");
+ correctAnswers++;
+ } else {
+ System.out.println("BACK TO THE BOOKS,...TOTO WAS HIS NAME.");
+ }
+
+ System.out.println();
+
+ // Question 4
+ System.out.println("WHO WAS THE FAIR MAIDEN WHO ATE THE POISON APPLE");
+ int question4Answer = displayTextAndGetNumber("1)SLEEPING BEAUTY, 2)CINDERELLA, 3)SNOW WHITE, 4)WENDY ? ");
+ if (question4Answer == 3) {
+ System.out.println("GOOD MEMORY!");
+ correctAnswers++;
+ } else {
+ System.out.println("OH, COME ON NOW...IT WAS SNOW WHITE.");
+ }
+
+ System.out.println();
+ gameState = GAME_STATE.RESULTS;
+ break;
+
+ // How did the player do?
+ case RESULTS:
+ if (correctAnswers == 4) {
+ // All correct
+ System.out.println("WOW! THAT'S SUPER! YOU REALLY KNOW YOUR NURSERY");
+ System.out.println("YOUR NEXT QUIZ WILL BE ON 2ND CENTURY CHINESE");
+ System.out.println("LITERATURE (HA, HA, HA)");
+ // one or none correct
+ } else if (correctAnswers < 2) {
+ System.out.println("UGH. THAT WAS DEFINITELY NOT TOO SWIFT. BACK TO");
+ System.out.println("NURSERY SCHOOL FOR YOU, MY FRIEND.");
+ // two or three correct
+ } else {
+ System.out.println("NOT BAD, BUT YOU MIGHT SPEND A LITTLE MORE TIME");
+ System.out.println("READING THE NURSERY GREATS.");
+ }
+ gameState = GAME_STATE.GAME_OVER;
+ break;
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ public void intro() {
+ System.out.println(simulateTabs(25) + "LITERATURE QUIZ");
+ System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("LITERATURE QUIZ");
+ System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("TEST YOUR KNOWLEDGE OF CHILDREN'S LITERATURE.");
+ System.out.println("THIS IS A MULTIPLE-CHOICE QUIZ.");
+ System.out.println("TYPE A 1, 2, 3, OR 4 AFTER THE QUESTION MARK.");
+ System.out.println();
+ System.out.println("GOOD LUCK!");
+ System.out.println();
+ }
+
+ /**
+ * 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);
+ }
+
+ /*
+ * 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();
+ }
+}
\ No newline at end of file
diff --git a/57 Literature Quiz/java/src/LiteratureQuizGame.java b/57 Literature Quiz/java/src/LiteratureQuizGame.java
new file mode 100644
index 00000000..3f7d9fd4
--- /dev/null
+++ b/57 Literature Quiz/java/src/LiteratureQuizGame.java
@@ -0,0 +1,8 @@
+public class LiteratureQuizGame {
+
+ public static void main(String[] args) {
+
+ LiteratureQuiz literatureQuiz = new LiteratureQuiz();
+ literatureQuiz.play();
+ }
+}
diff --git a/60 Mastermind/python/mastermind.py b/60 Mastermind/python/mastermind.py
new file mode 100644
index 00000000..ccc2ae9c
--- /dev/null
+++ b/60 Mastermind/python/mastermind.py
@@ -0,0 +1,230 @@
+import random, sys
+
+
+
+def main():
+
+ global colors, color_letters, num_positions, num_colors, human_score, computer_score
+ colors = ["BLACK", "WHITE", "RED", "GREEN", "ORANGE", "YELLOW", "PURPLE", "TAN"]
+ color_letters = "BWRGOYPT"
+
+ num_colors = 100
+ human_score = 0
+ computer_score = 0
+
+ # get user inputs for game conditions
+ print("Mastermind")
+ print('Creative Computing Morristown, New Jersey')
+ while num_colors > 8:
+ num_colors = int(input("Number of colors (max 8): ")) # C9 in BASIC
+ num_positions = int(input("Number of positions: ")) # P9 in BASIC
+ num_rounds = int(input("Number of rounds: ")) # R9 in BASIC
+ possibilities = num_colors**num_positions
+ all_possibilities = [1] * possibilities
+
+ print("Number of possibilities {}".format(possibilities))
+ print('Color\tLetter')
+ print('=====\t======')
+ for element in range(0, num_colors):
+ print("{}\t{}".format(colors[element], colors[element][0]))
+
+ current_round = 1
+
+ while current_round <= num_rounds:
+ print('Round number {}'.format(current_round))
+ num_moves = 1
+ guesses = []
+ turn_over = False
+ print('Guess my combination ...')
+ answer = int(possibilities * random.random())
+ numeric_answer = [-1] * num_positions
+ for i in range(0, answer):
+ numeric_answer = get_possibility(numeric_answer)
+ #human_readable_answer = make_human_readable(numeric_answer)
+ while (num_moves < 10 and not turn_over ):
+ print('Move # {} Guess : '.format(num_moves))
+ user_command = input('Guess ')
+ if user_command == "BOARD":
+ print_board(guesses) #2000
+ elif user_command == "QUIT": #2500
+ human_readable_answer = make_human_readable(numeric_answer)
+ print('QUITTER! MY COMBINATION WAS: {}'.format(human_readable_answer))
+ print('GOOD BYE')
+ quit()
+ elif len(user_command) != num_positions: #410
+ print("BAD NUMBER OF POSITIONS")
+ else:
+ invalid_letters = get_invalid_letters(user_command)
+ if invalid_letters > "":
+ print("INVALID GUESS: {}".format(invalid_letters))
+ else:
+ guess_results = compare_two_positions(user_command, make_human_readable(numeric_answer))
+ print("Results: {}".format(guess_results))
+ if guess_results[1] == num_positions: # correct guess
+ turn_over = True
+ print("You guessed it in {} moves!".format(num_moves))
+ human_score = human_score + num_moves
+ print_score()
+ else:
+ print("You have {} blacks and {} whites".format(guess_results[1], guess_results[2]))
+ num_moves = num_moves + 1
+ guesses.append(guess_results)
+ if not turn_over: # RAN OUT OF MOVES
+ print ("YOU RAN OUT OF MOVES! THAT'S ALL YOU GET!")
+ print("THE ACTUAL COMBINATION WAS: {}".format(make_human_readable(numeric_answer)))
+ human_score = human_score + num_moves
+ print_score()
+
+ # COMPUTER TURN
+ guesses = []
+ turn_over = False
+ inconsistent_information = False
+ while(not turn_over and not inconsistent_information ):
+ all_possibilities = [1] * possibilities
+ num_moves = 1
+ inconsistent_information = False
+ print ("NOW I GUESS. THINK OF A COMBINATION.")
+ player_ready = input("HIT RETURN WHEN READY: ")
+ while (num_moves < 10 and not turn_over and not inconsistent_information):
+ found_guess = False
+ computer_guess = int(possibilities * random.random())
+ if all_possibilities[computer_guess] == 1: # random guess is possible, use it
+ found_guess = True
+ guess = computer_guess
+ else:
+ for i in range (computer_guess, possibilities):
+ if all_possibilities[i] == 1:
+ found_guess = True
+ guess = i
+ break
+ if not found_guess:
+ for i in range (0, computer_guess):
+ if all_possibilities[i] == 1:
+ found_guess = True
+ guess = i
+ break
+ if not found_guess: # inconsistent info from user
+ print('YOU HAVE GIVEN ME INCONSISTENT INFORMATION.')
+ print('TRY AGAIN, AND THIS TIME PLEASE BE MORE CAREFUL.')
+ turn_over = True
+ inconsistent_information = True
+ else:
+ numeric_guess = [-1] * num_positions
+ for i in range(0, guess):
+ numeric_guess = get_possibility(numeric_guess)
+ human_readable_guess = make_human_readable(numeric_guess)
+ print('My guess is: {}'.format(human_readable_guess))
+ blacks, whites = input("ENTER BLACKS, WHITES (e.g. 1,2): ").split(",")
+ blacks = int(blacks)
+ whites = int(whites)
+ if blacks == num_positions: #Correct guess
+ print('I GOT IT IN {} MOVES'.format(num_moves))
+ turn_over = True
+ computer_score = computer_score + num_moves
+ print_score()
+ else:
+ num_moves += 1
+ for i in range (0, possibilities):
+ if all_possibilities[i] == 0: #already ruled out
+ continue
+ numeric_possibility = [-1] * num_positions
+ for j in range (0, i):
+ numeric_possibility = get_possibility(numeric_possibility)
+ human_readable_possibility = make_human_readable(numeric_possibility) #4000
+ comparison = compare_two_positions(human_readable_possibility, human_readable_guess)
+ print(comparison)
+ if ((blacks != comparison[1]) or (whites != comparison[2])):
+ all_possibilities[i] = 0
+ if not turn_over: # COMPUTER DID NOT GUESS
+ print("I USED UP ALL MY MOVES!")
+ print("I GUESS MY CPU IS JUST HAVING AN OFF DAY.")
+ computer_score = computer_score + num_moves
+ print_score()
+ current_round += 1
+ print_score(is_final_score=True)
+ sys.exit()
+
+#470
+def get_invalid_letters(user_command):
+ """Makes sure player input consists of valid colors for selected game configuration."""
+ valid_colors = color_letters[:num_colors]
+ invalid_letters = ""
+ for letter in user_command:
+ if letter not in valid_colors:
+ invalid_letters = invalid_letters + letter
+ return invalid_letters
+
+#2000
+def print_board(guesses):
+ """Prints previous guesses within the round."""
+ print("Board")
+ print("Move\tGuess\tBlack White")
+ for idx, guess in enumerate(guesses):
+ print('{}\t{}\t{} {}'.format(idx+1, guess[0], guess[1], guess[2]))
+
+#3500
+# Easily the place for most optimization, since they generate every possibility
+# every time when checking for potential solutions
+# From the original article:
+# "We did try a version that kept an actual list of all possible combinations
+# (as a string array), which was significantly faster than this versionn but
+# which ate tremendous amounts of memory."
+def get_possibility(possibility):
+ #print(possibility)
+ if possibility[0] > -1: #3530
+ current_position = 0 # Python arrays are zero-indexed
+ while True:
+ if possibility[current_position] < num_colors-1: # zero-index again
+ possibility[current_position] += 1
+ return possibility
+ else:
+ possibility[current_position] = 0
+ current_position += 1
+ else: #3524
+ possibility = [0] * num_positions
+ return possibility
+
+#4500
+def compare_two_positions(guess, answer):
+ """Returns blacks (correct color and position) and whites (correct color only) for candidate position (guess) versus reference position (answer)."""
+ increment = 0
+ blacks = 0
+ whites = 0
+ initial_guess = guess
+ for pos in range(0, num_positions):
+ if guess[pos] != answer[pos]:
+ for pos2 in range(0, num_positions):
+ if not(guess[pos] != answer[pos2] or guess[pos2] == answer[pos2]): # correct color but not correct place
+ whites = whites + 1
+ answer = answer[:pos2] + chr(increment) + answer[pos2+1:]
+ guess = guess[:pos] + chr(increment+1) + guess[pos+1:]
+ increment = increment + 2
+ else: #correct color and placement
+ blacks = blacks + 1
+ # THIS IS DEVIOUSLY CLEVER
+ guess = guess[:pos] + chr(increment+1) + guess[pos+1:]
+ answer = answer[:pos] + chr(increment) + answer[pos+1:]
+ increment = increment + 2
+ return [initial_guess, blacks, whites]
+
+#5000 + logic from 1160
+def print_score(is_final_score=False):
+ """Prints score after each turn ends, including final score at end of game."""
+ if is_final_score:
+ print("GAME OVER")
+ print("FINAL SCORE:")
+ else:
+ print("SCORE:")
+ print(" COMPUTER {}".format(computer_score))
+ print(" HUMAN {}".format(human_score))
+
+#4000, 5500, 6000 subroutines are all identical
+def make_human_readable(num):
+ """Make the numeric representation of a position human readable."""
+ retval = ''
+ for i in range(0, len(num)):
+ retval = retval + color_letters[int(num[i])]
+ return retval
+
+if __name__ == "__main__":
+ main()
diff --git a/76 Russian Roulette/csharp/RussianRoulette/Program.cs b/76 Russian Roulette/csharp/RussianRoulette/Program.cs
new file mode 100644
index 00000000..43a8d4bc
--- /dev/null
+++ b/76 Russian Roulette/csharp/RussianRoulette/Program.cs
@@ -0,0 +1,106 @@
+using System;
+
+namespace RussianRoulette
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ PrintTitle();
+
+ var includeRevolver = true;
+ while (true)
+ {
+ PrintInstructions(includeRevolver);
+ switch (PlayGame())
+ {
+ case GameResult.Win:
+ includeRevolver = true;
+ break;
+ case GameResult.Chicken:
+ case GameResult.Dead:
+ includeRevolver = false;
+ break;
+ }
+ }
+ }
+
+ private static void PrintTitle()
+ {
+ Console.WriteLine(" Russian Roulette");
+ Console.WriteLine("Creative Computing Morristown, New Jersey");
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine("This is a game of >>>>>>>>>>Russian Roulette.");
+ }
+
+ private static void PrintInstructions(bool includeRevolver)
+ {
+ Console.WriteLine();
+ if (includeRevolver)
+ {
+ Console.WriteLine("Here is a revolver.");
+ }
+ else
+ {
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine("...Next Victim...");
+ }
+ Console.WriteLine("Type '1' to spin chamber and pull trigger.");
+ Console.WriteLine("Type '2' to give up.");
+ }
+
+ private static GameResult PlayGame()
+ {
+ var rnd = new Random();
+ var round = 0;
+ while (true)
+ {
+ round++;
+ Console.Write("Go: ");
+ var input = Console.ReadKey().KeyChar;
+ Console.WriteLine();
+ if (input != '2')
+ {
+ // Random.Next will retun a value that is the same or greater than the minimum and
+ // less than the maximum.
+ // A revolver has 6 rounds.
+ if (rnd.Next(1, 7) == 6)
+ {
+ Console.WriteLine(" Bang!!!!! You're dead!");
+ Console.WriteLine("Condolences will be sent to your relatives.");
+ return GameResult.Dead;
+ }
+ else
+ {
+ if (round > 10)
+ {
+ Console.WriteLine("You win!!!!!");
+ Console.WriteLine("Let someone else blow their brains out.");
+ return GameResult.Win;
+ }
+ else
+ {
+ Console.WriteLine("- CLICK -");
+ Console.WriteLine();
+ }
+ }
+ }
+ else
+ {
+ Console.WriteLine(" CHICKEN!!!!!");
+ return GameResult.Chicken;
+ }
+ }
+ }
+
+ private enum GameResult
+ {
+ Win,
+ Chicken,
+ Dead
+ }
+ }
+}
diff --git a/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.csproj b/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.csproj
new file mode 100644
index 00000000..20827042
--- /dev/null
+++ b/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.csproj
@@ -0,0 +1,8 @@
+
+ * Based on the Basic program Train here + * https://github.com/coding-horror/basic-computer-games/blob/main/91%20Train/train.bas + *
+ * Note: The idea was to create a version of the 1970's Basic program in Java, without introducing + * new features - no additional text, error checking, etc has been added. + */ +public class Train { + + private final Scanner kbScanner; + + public Train() { + kbScanner = new Scanner(System.in); + } + + public void process() { + + intro(); + + boolean gameOver = false; + + do { + double carMph = (int) (25 * Math.random() + 40); + double hours = (int) (15 * Math.random() + 5); + double train = (int) (19 * Math.random() + 20); + + System.out.println(" A CAR TRAVELING " + (int) carMph + " MPH CAN MAKE A CERTAIN TRIP IN"); + System.out.println((int) hours + " HOURS LESS THAN A TRAIN TRAVELING AT " + (int) train + " MPH."); + + double howLong = Double.parseDouble(displayTextAndGetInput("HOW LONG DOES THE TRIP TAKE BY CAR? ")); + + double hoursAnswer = hours * train / (carMph - train); + int percentage = (int) (Math.abs((hoursAnswer - howLong) * 100 / howLong) + .5); + if (percentage > 5) { + System.out.println("SORRY. YOU WERE OFF BY " + percentage + " PERCENT."); + } else { + System.out.println("GOOD! ANSWER WITHIN " + percentage + " PERCENT."); + } + System.out.println("CORRECT ANSWER IS " + hoursAnswer + " HOURS."); + + System.out.println(); + if (!yesEntered(displayTextAndGetInput("ANOTHER PROBLEM (YES OR NO)? "))) { + gameOver = true; + } + + } while (!gameOver); + + + } + + private void intro() { + System.out.println("TRAIN"); + System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println(); + System.out.println("TIME - SPEED DISTANCE EXERCISE"); + System.out.println(); + } + + /* + * 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(); + } + + /** + * 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)); + + } + + /** + * Program startup. + * + * @param args not used (from command line). + */ + public static void main(String[] args) { + Train train = new Train(); + train.process(); + } +}