diff --git a/.gitignore b/.gitignore index 42752d61..aa42e787 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,3 @@ -################################################################################ -# This .gitignore file was automatically created by Microsoft(R) Visual Studio. -################################################################################ - /01 Acey Ducey/csharp/obj /47 Hi-Lo/csharp/obj /.vs @@ -13,3 +9,4 @@ */csharp/bin */csharp/obj + diff --git a/01 Acey Ducey/java/src/aceyducey/AceyDucey.java b/01 Acey Ducey/java/src/AceyDucey.java similarity index 74% rename from 01 Acey Ducey/java/src/aceyducey/AceyDucey.java rename to 01 Acey Ducey/java/src/AceyDucey.java index 37dcc57c..43fc9950 100644 --- a/01 Acey Ducey/java/src/aceyducey/AceyDucey.java +++ b/01 Acey Ducey/java/src/AceyDucey.java @@ -1,15 +1,12 @@ -package aceyducey; - import java.util.Scanner; /** * Game of AceyDucey - * + *

* Based on the Basic game of AceyDucey here * https://github.com/coding-horror/basic-computer-games/blob/main/01%20Acey%20Ducey/aceyducey.bas - * Note: The idea was to create a version of this 1970's Basic game in Java, without introducing - * new features - no additional text, error checking, etc has been added. - * + * 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 AceyDucey { @@ -32,10 +29,10 @@ public class AceyDucey { private boolean gameOver = false; // Used for keyboard input - private Scanner kbScanner; + private final Scanner kbScanner; // Constant value for cards from a deck - 2 lowest, 14 (Ace) highest - public static final int LOW_CARD_RANGE =2; + public static final int LOW_CARD_RANGE = 2; public static final int HIGH_CARD_RANGE = 14; public AceyDucey() { @@ -58,7 +55,7 @@ public class AceyDucey { String playAgain = kbScanner.next().toUpperCase(); System.out.println(); System.out.println(); - if(playAgain.equals("YES")) { + if (playAgain.equals("YES")) { return true; } else { System.out.println("O.K., HOPE YOU HAD FUN!"); @@ -71,9 +68,8 @@ public class AceyDucey { public void play() { // Keep playing hands until player runs out of cash - // which sets gameover to true do { - if(firstTimePlaying) { + if (firstTimePlaying) { intro(); firstTimePlaying = false; } @@ -81,17 +77,17 @@ public class AceyDucey { drawCards(); displayCards(); int betAmount = getBet(); - this.playersCard = randomCard(); + playersCard = randomCard(); displayPlayerCard(); - if(playerWon()) { + if (playerWon()) { System.out.println("YOU WIN!!"); - this.playerAmount += betAmount; + playerAmount += betAmount; } else { System.out.println("SORRY, YOU LOSE"); - this.playerAmount -= betAmount; + playerAmount -= betAmount; // Player run out of money? - if(this.playerAmount <=0) { - this.gameOver = true; + if (playerAmount <= 0) { + gameOver = true; } } @@ -102,18 +98,14 @@ public class AceyDucey { // to win a players card has to be in the range of the first and second dealer // drawn cards inclusive of first and second cards. private boolean playerWon() { - if((this.playersCard.getValue() >= this.firstCard.getValue()) - && this.playersCard.getValue() <= this.secondCard.getValue()) { - // winner - return true; - } - - return false; + // winner + return (playersCard.getValue() >= firstCard.getValue()) + && playersCard.getValue() <= secondCard.getValue(); } private void displayPlayerCard() { - System.out.println(this.playersCard.getName()); + System.out.println(playersCard.getName()); } // Get the players bet, and return the amount @@ -121,16 +113,16 @@ public class AceyDucey { // method will loop until a valid bet is entered. private int getBet() { boolean validBet = false; - int amount = 0; + int amount; do { System.out.print("WHAT IS YOUR BET "); amount = kbScanner.nextInt(); - if(amount == 0) { + if (amount == 0) { System.out.println("CHICKEN!!"); validBet = true; - } else if(amount > this.playerAmount) { + } else if (amount > playerAmount) { System.out.println("SORRY, MY FRIEND, BUT YOU BET TOO MUCH."); - System.out.println("YOU HAVE ONLY " + this.playerAmount + " DOLLARS TO BET."); + System.out.println("YOU HAVE ONLY " + playerAmount + " DOLLARS TO BET."); } else { validBet = true; } @@ -140,13 +132,13 @@ public class AceyDucey { } private void displayBalance() { - System.out.println("YOU NOW HAVE " + this.playerAmount + " DOLLARS."); + System.out.println("YOU NOW HAVE " + playerAmount + " DOLLARS."); } private void displayCards() { System.out.println("HERE ARE YOUR NEXT TWO CARDS: "); - System.out.println(this.firstCard.getName()); - System.out.println(this.secondCard.getName()); + System.out.println(firstCard.getName()); + System.out.println(secondCard.getName()); } // Draw two dealer cards, and save them for later use. @@ -154,9 +146,9 @@ public class AceyDucey { private void drawCards() { do { - this.firstCard = randomCard(); - this.secondCard = randomCard(); - } while(this.firstCard.getValue() >= this.secondCard.getValue()); + firstCard = randomCard(); + secondCard = randomCard(); + } while (firstCard.getValue() >= secondCard.getValue()); } // Creates a random card diff --git a/01 Acey Ducey/java/src/aceyducey/Game.java b/01 Acey Ducey/java/src/AceyDuceyGame.java similarity index 72% rename from 01 Acey Ducey/java/src/aceyducey/Game.java rename to 01 Acey Ducey/java/src/AceyDuceyGame.java index 54582f5f..1ce08c28 100644 --- a/01 Acey Ducey/java/src/aceyducey/Game.java +++ b/01 Acey Ducey/java/src/AceyDuceyGame.java @@ -1,20 +1,16 @@ -package aceyducey; - /** * This class is used to invoke the game. * */ -public class Game { - - private static AceyDucey game; +public class AceyDuceyGame { public static void main(String[] args) { - boolean keepPlaying = true; + boolean keepPlaying; + AceyDucey game = new AceyDucey(); // Keep playing game until infinity or the player loses do { - game = new AceyDucey(); game.play(); System.out.println(); System.out.println(); diff --git a/01 Acey Ducey/java/src/aceyducey/Card.java b/01 Acey Ducey/java/src/Card.java similarity index 95% rename from 01 Acey Ducey/java/src/aceyducey/Card.java rename to 01 Acey Ducey/java/src/Card.java index ad15cced..88211002 100644 --- a/01 Acey Ducey/java/src/aceyducey/Card.java +++ b/01 Acey Ducey/java/src/Card.java @@ -1,5 +1,3 @@ -package aceyducey; - /** * A card from a deck - the value is between 2-14 to cover * cards with a face value of 2-9 and then a Jack, Queen, King, and Ace @@ -14,7 +12,7 @@ public class Card { private void init(int value) { this.value = value; - if(value <11) { + if (value < 11) { this.name = String.valueOf(value); } else { switch (value) { diff --git a/02 Amazing/python/amazing.py b/02 Amazing/python/amazing.py new file mode 100644 index 00000000..dc9da380 --- /dev/null +++ b/02 Amazing/python/amazing.py @@ -0,0 +1,121 @@ +import random + +# Python translation by Frank Palazzolo - 2/2021 + +print(' '*28+'AMAZING PROGRAM') +print(' '*15+'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY') +print() +print() +print() + +while True: + width, length = input('What are your width and length?').split(',') + width = int(width) + length = int(length) + if width != 1 and length != 1: + break + print('Meaningless dimensions. Try again.') + +# Build two 2D arrays +# +# used: +# Initially set to zero, unprocessed cells +# Filled in with consecutive non-zero numbers as cells are processed +# +# walls: +# Initially set to zero, (all paths blocked) +# Remains 0 if there is no exit down or right +# Set to 1 if there is an exit down +# Set to 2 if there is an exit right +# Set to 3 if there are exits down and right + +used = [] +walls = [] +for i in range(length): + used.append([0]*width) + walls.append([0]*width) + +# Use direction variables with nice names +GO_LEFT,GO_UP,GO_RIGHT,GO_DOWN=[0,1,2,3] +# Give Exit directions nice names +EXIT_DOWN = 1 +EXIT_RIGHT = 2 + +# Pick a random entrance, mark as used +enter_col=random.randint(0,width-1) +row,col=0,enter_col +count=1 +used[row][col]=count +count=count+1 + +while count!=width*length+1: + # remove possible directions that are blocked or + # hit cells that we have already processed + possible_dirs = [GO_LEFT,GO_UP,GO_RIGHT,GO_DOWN] + if col==0 or used[row][col-1]!=0: + possible_dirs.remove(GO_LEFT) + if row==0 or used[row-1][col]!=0: + possible_dirs.remove(GO_UP) + if col==width-1 or used[row][col+1]!=0: + possible_dirs.remove(GO_RIGHT) + if row==length-1 or used[row+1][col]!=0: + possible_dirs.remove(GO_DOWN) + + # If we can move in a direction, move and make opening + if len(possible_dirs)!=0: + direction=random.choice(possible_dirs) + if direction==GO_LEFT: + col=col-1 + walls[row][col]=EXIT_RIGHT + elif direction==GO_UP: + row=row-1 + walls[row][col]=EXIT_DOWN + elif direction==GO_RIGHT: + walls[row][col]=walls[row][col]+EXIT_RIGHT + col=col+1 + elif direction==GO_DOWN: + walls[row][col]=walls[row][col]+EXIT_DOWN + row=row+1 + used[row][col]=count + count=count+1 + # otherwise, move to the next used cell, and try again + else: + while True: + if col!=width-1: + col=col+1 + elif row!=length-1: + row,col=row+1,0 + else: + row,col=0,0 + if used[row][col]!=0: + break + +# Add a random exit +col=random.randint(0,width-1) +row=length-1 +walls[row][col]=walls[row][col]+1 + +# Print the maze +for col in range(width): + if col==enter_col: + print('. ',end='') + else: + print('.--',end='') +print('.') +for row in range(length): + print('I',end='') + for col in range(width): + if walls[row][col]<2: + print(' I',end='') + else: + print(' ',end='') + print() + for col in range(width): + if walls[row][col]==0 or walls[row][col]==2: + print(':--',end='') + else: + print(': ',end='') + print('.') + + + \ No newline at end of file diff --git a/03 Animal/ruby/animal.rb b/03 Animal/ruby/animal.rb new file mode 100644 index 00000000..5100b2aa --- /dev/null +++ b/03 Animal/ruby/animal.rb @@ -0,0 +1,95 @@ +require 'set' + +def intro + puts " ANIMAL + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + + +PLAY 'GUESS THE ANIMAL' + +THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT. + +" +end + +def ask(question) + print "#{question} " + (gets || '').chomp.upcase +end + +Feature = Struct.new(:question, :yes_guess, :no_guess) + +def add_guess(animals, guess) + guess.is_a?(Struct) ? get_all_animals(guess, animals) : animals.add(guess) +end + +def get_all_animals(feature, animals = Set.new) + add_guess(animals, feature.yes_guess) + add_guess(animals, feature.no_guess) + animals +end + +def create_feature(current_animal) + new_animal = ask('THE ANIMAL YOU WERE THINKING OF WAS A ?') + puts "PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A #{new_animal} FROM A #{current_animal}" + question = ask('?') + loop do + yes_no = ask("FOR A #{new_animal} THE ANSWER WOULD BE ?") + next unless ['Y', 'N'].include?(yes_no[0]) + guesses = yes_no[0] == 'Y' ? [new_animal, current_animal] : [current_animal, new_animal] + return Feature.new(question, *guesses) + end +end + +def guess_loop(feature) + loop do + answer = ask(feature.question) + next unless ['Y', 'N'].include?(answer[0]) + answer_is_yes = answer[0] == 'Y' + + name = answer_is_yes ? feature.yes_guess : feature.no_guess + if name.is_a?(Struct) + feature = name + next + end + + guess = ask("IS IT A #{name}?") + correct_guess = guess[0] == 'Y' + + if correct_guess + puts "WHY NOT TRY ANOTHER ANIMAL?" + break + end + + if answer_is_yes + feature.yes_guess = create_feature(name) + else + feature.no_guess = create_feature(name) + end + break + end +end + +def main + intro + feature = Feature.new('DOES IT SWIM?', 'FISH', 'BIRD') + + while true do + option = ask("ARE YOU THINKING OF AN ANIMAL?") + if option == 'LIST' + puts + puts "ANIMALS I ALREADY KNOW ARE:" + puts get_all_animals(feature).to_a.join(" " * 15) + puts + elsif option[0] == 'Y' + guess_loop(feature) + elsif option == '' + puts + end + end +end + +trap "SIGINT" do puts; exit 130 end + +main \ No newline at end of file diff --git a/05 Bagels/csharp/BagelNumber.cs b/05 Bagels/csharp/BagelNumber.cs new file mode 100644 index 00000000..2fd660e9 --- /dev/null +++ b/05 Bagels/csharp/BagelNumber.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace BasicComputerGames.Bagels +{ + public enum BagelValidation + { + Valid, + WrongLength, + NotUnique, + NonDigit + }; + public class BagelNumber + { + private static readonly Random Rnd = new Random(); + + private readonly int[] _digits; + public override string ToString() + { + return String.Join('-', _digits); + } + + public static BagelNumber CreateSecretNumber(int numDigits) + { + if (numDigits < 3 || numDigits > 9) + throw new ArgumentOutOfRangeException(nameof(numDigits), + "Number of digits must be between 3 and 9, inclusive"); + + var digits = GetDigits(numDigits); + return new BagelNumber(digits); + } + + + + public static BagelValidation IsValid(string number, int length) + { + if (number.Length != length) + return BagelValidation.WrongLength; + + if (!number.All(Char.IsDigit)) + return BagelValidation.NonDigit; + + if (new HashSet(number).Count != length) + return BagelValidation.NotUnique; + + return BagelValidation.Valid; + } + + public BagelNumber(string number) + { + if (number.Any(d => !Char.IsDigit(d))) + throw new ArgumentException("Number must be all unique digits", nameof(number)); + + _digits = number.Select(d => d - '0').ToArray(); + } + + //public BagelNumber(long number) + //{ + // var digits = new List(); + // if (number >= 1E10) + // throw new ArgumentOutOfRangeException(nameof(number), "Number can be no more than 9 digits"); + + // while (number > 0) + // { + // long num = number / 10; + // int digit = (int)(number - (num * 10)); + // number = num; + // digits.Add(digit); + // } + + // _digits = digits.ToArray(); + //} + + public BagelNumber(int[] digits) + { + _digits = digits; + } + + private static int[] GetDigits(int numDigits) + { + int[] digits = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + Shuffle(digits); + return digits.Take(numDigits).ToArray(); + + } + + private static void Shuffle(int[] digits) + { + for (int i = digits.Length - 1; i > 0; --i) + { + int pos = Rnd.Next(i); + var t = digits[i]; + digits[i] = digits[pos]; + digits[pos] = t; + } + + } + + public (int pico, int fermi) CompareTo(BagelNumber other) + { + int pico = 0; + int fermi = 0; + for (int i = 0; i < _digits.Length; i++) + { + for (int j = 0; j < other._digits.Length; j++) + { + if (_digits[i] == other._digits[j]) + { + if (i == j) + ++fermi; + else + ++pico; + } + } + } + + return (pico, fermi); + } + } +} \ No newline at end of file diff --git a/05 Bagels/csharp/Bagels.csproj b/05 Bagels/csharp/Bagels.csproj new file mode 100644 index 00000000..68fa11ec --- /dev/null +++ b/05 Bagels/csharp/Bagels.csproj @@ -0,0 +1,13 @@ + + + + Exe + net5.0 + BasicComputerGames.Bagels + + + + + + + diff --git a/05 Bagels/csharp/Game.cs b/05 Bagels/csharp/Game.cs new file mode 100644 index 00000000..f6885464 --- /dev/null +++ b/05 Bagels/csharp/Game.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace BasicComputerGames.Bagels +{ + public class Game : GameBase + { + public void GameLoop() + { + DisplayIntroText(); + int points = 0; + do + { + var result =PlayRound(); + if (result) + ++points; + } while (TryAgain()); + + Console.WriteLine(); + Console.WriteLine($"A {points} point Bagels buff!!"); + Console.WriteLine("Hope you had fun. Bye."); + } + + private const int Length = 3; + private const int MaxGuesses = 20; + + private bool PlayRound() + { + var secret = BagelNumber.CreateSecretNumber(Length); + Console.WriteLine("O.K. I have a number in mind."); + for (int guessNo = 1; guessNo <= MaxGuesses; ++guessNo) + { + string strGuess; + BagelValidation isValid; + do + { + Console.WriteLine($"Guess #{guessNo}"); + strGuess = Console.ReadLine(); + isValid = BagelNumber.IsValid(strGuess, Length); + PrintError(isValid); + } while (isValid != BagelValidation.Valid); + + var guess = new BagelNumber(strGuess); + var fermi = 0; + var pico = 0; + (pico, fermi) = secret.CompareTo(guess); + if(pico + fermi == 0) + Console.Write("BAGELS!"); + else if (fermi == Length) + { + Console.WriteLine("You got it!"); + return true; + } + else + { + PrintList("Pico ", pico); + PrintList("Fermi ", fermi); + } + Console.WriteLine(); + } + + Console.WriteLine("Oh, well."); + Console.WriteLine($"That's {MaxGuesses} guesses. My Number was {secret}"); + + return false; + + } + + private void PrintError(BagelValidation isValid) + { + switch (isValid) + { + case BagelValidation.NonDigit: + Console.WriteLine("What?"); + break; + + case BagelValidation.NotUnique: + Console.WriteLine("Oh, I forgot to tell you that the number I have in mind has no two digits the same."); + break; + + case BagelValidation.WrongLength: + Console.WriteLine($"Try guessing a {Length}-digit number."); + break; + + case BagelValidation.Valid: + break; + } + } + + private void PrintList(string msg, int repeat) + { + for(int i=0; i + /// Prompt the player to try again, and wait for them to press Y or N. + /// + /// Returns true if the player wants to try again, false if they have finished playing. + protected bool TryAgain() + { + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine("Would you like to try again? (Press 'Y' for yes or 'N' for no)"); + + Console.ForegroundColor = ConsoleColor.Yellow; + Console.Write("> "); + + char pressedKey; + // Keep looping until we get a recognised input + do + { + // Read a key, don't display it on screen + ConsoleKeyInfo key = Console.ReadKey(true); + // Convert to upper-case so we don't need to care about capitalisation + pressedKey = Char.ToUpper(key.KeyChar); + // Is this a key we recognise? If not, keep looping + } while (pressedKey != 'Y' && pressedKey != 'N'); + // Display the result on the screen + Console.WriteLine(pressedKey); + + // Return true if the player pressed 'Y', false for anything else. + return (pressedKey == 'Y'); + } + + } +} \ No newline at end of file diff --git a/05 Bagels/csharp/Program.cs b/05 Bagels/csharp/Program.cs new file mode 100644 index 00000000..5dd0949a --- /dev/null +++ b/05 Bagels/csharp/Program.cs @@ -0,0 +1,14 @@ +namespace BasicComputerGames.Bagels +{ + public class Program + { + public static void Main(string[] args) + { + // Create an instance of our main Game class + var game = new Game(); + + // Call its GameLoop function. This will play the game endlessly in a loop until the player chooses to quit. + game.GameLoop(); + } + } +} 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 @@ + + +BASKETBALL + + +


+
+
+
diff --git a/07 Basketball/javascript/basketball.js b/07 Basketball/javascript/basketball.js
new file mode 100644
index 00000000..5b0b73e7
--- /dev/null
+++ b/07 Basketball/javascript/basketball.js	
@@ -0,0 +1,384 @@
+// BASKETBALL
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+var s = [0, 0];
+var z;
+var d;
+var p;
+var your_turn;
+var game_restart;
+
+function two_minutes()
+{
+    print("\n");
+    print("   *** TWO MINUTES LEFT IN THE GAME ***\n");
+    print("\n");
+}
+
+function show_scores()
+{
+    print("SCORE: " + s[1] + " TO " + s[0] + "\n");
+}
+
+function score_computer()
+{
+    s[0] = s[0] + 2;
+    show_scores();
+}
+
+function score_player()
+{
+    s[1] = s[1] + 2;
+    show_scores();
+}
+
+function half_time()
+{
+    print("\n");
+    print("   ***** END OF FIRST HALF *****\n");
+    print("SCORE: DARMOUTH: " + s[1] + "  " + os + ": " + s[0] + "\n");
+    print("\n");
+    print("\n");
+}
+
+function foul()
+{
+    if (Math.random() <= 0.49) {
+        print("SHOOTER MAKES BOTH SHOTS.\n");
+        s[1 - p] = s[1 - p] + 2;
+        show_scores();
+    } else if (Math.random() <= 0.75) {
+        print("SHOOTER MAKES ONE SHOT AND MISSES ONE.\n");
+        s[1 - p] = s[1 - p] + 1;
+        show_scores();
+    } else {
+        print("BOTH SHOTS MISSED.\n");
+        show_scores();
+    }
+}
+
+function player_play()
+{
+    if (z == 1 || z == 2) {
+        t++;
+        if (t == 50) {
+            half_time();
+            game_restart = 1;
+            return;
+        }
+        if (t == 92)
+            two_minutes();
+        print("JUMP SHOT\n");
+        if (Math.random() <= 0.341 * d / 8) {
+            print("SHOT IS GOOD.\n");
+            score_player();
+            return;
+        }
+        if (Math.random() <= 0.682 * d / 8) {
+            print("SHOT IS OFF TARGET.\n");
+            if (d / 6 * Math.random() >= 0.45) {
+                print("REBOUND TO " + os + "\n");
+                return;
+            }
+            print("DARTMOUTH CONTROLS THE REBOUND.\n");
+            if (Math.random() > 0.4) {
+                if (d == 6) {
+                    if (Math.random() > 0.6) {
+                        print("PASS STOLEN BY " + os + " EASY LAYUP.\n");
+                        score_computer();
+                        return;
+                    }
+                }
+                print("BALL PASSED BACK TO YOU. ");
+                your_turn = 1;
+                return;
+            }
+        } else if (Math.random() <= 0.782 * d / 8) {
+            print("SHOT IS BLOCKED.  BALL CONTROLLED BY ");
+            if (Math.random() <= 0.5) {
+                print("DARTMOUTH.\n");
+                your_turn = 1;
+                return;
+            }
+            print(os + ".\n");
+            return;
+        } else if (Math.random() <= 0.843 * d / 8) {
+            print("SHOOTER IS FOULED.  TWO SHOTS.\n");
+            foul();
+            return;
+            // In original code but lines 1180-1195 aren't used (maybe replicate from computer's play)
+            //        } else if (Math.random() <= 0.9 * d / 8) {
+            //            print("PLAYER FOULED, TWO SHOTS.\n");
+            //            foul();
+            //            return;
+        } else {
+            print("CHARGING FOUL.  DARTMOUTH LOSES BALL.\n");
+            return;
+        }
+    }
+    while (1) {
+        if (++t == 50) {
+            half_time();
+            game_restart = 1;
+            return;
+        }
+        if (t == 92)
+            two_minutes();
+        if (z == 0) {
+            your_turn = 2;
+            return;
+        }
+        if (z <= 3)
+            print("LAY UP.\n");
+        else
+            print("SET SHOT.\n");
+        if (7 / d * Math.random() <= 0.4) {
+            print("SHOT IS GOOD.  TWO POINTS.\n");
+            score_player();
+            return;
+        }
+        if (7 / d * Math.random() <= 0.7) {
+            print("SHOT IS OFF THE RIM.\n");
+            if (Math.random() <= 2.0 / 3.0) {
+                print(os + " CONTROLS THE REBOUND.\n");
+                return;
+            }
+            print("DARMOUTH CONTROLS THE REBOUND.\n");
+            if (Math.random() <= 0.4)
+                continue;
+            print("BALL PASSED BACK TO YOU.\n");
+            your_turn = 1;
+            return;
+        }
+        if (7 /d * Math.random() <= 0.875) {
+            print("SHOOTER FOULED.  TWO SHOTS.\n");
+            foul();
+            return;
+        }
+        if (7 /d * Math.random() <= 0.925) {
+            print("SHOT BLOCKED. " + os + "'S BALL.\n");
+            return;
+        }
+        print("CHARGING FOUL.  DARTHMOUTH LOSES THE BALL.\n");
+        return;
+    }
+}
+
+function computer_play()
+{
+    rebound = 0;
+    while (1) {
+        p = 1;
+        if (++t == 50) {
+            half_time();
+            game_restart = 1;
+            return;
+        }
+        print("\n");
+        z1 = 10 / 4 * Math.random() + 1;
+        if (z1 <= 2) {
+            print("JUMP SHOT.\n");
+            if (8 / d * Math.random() <= 0.35) {
+                print("SHOT IS GOOD.\n");
+                score_computer();
+                return;
+            }
+            if (8 / d * Math.random() <= 0.75) {
+                print("SHOT IS OFF RIM.\n");
+                if (d / 6 * Math.random() <= 0.5) {
+                    print("DARMOUTH CONTROLS THE REBOUND.\n");
+                    return;
+                }
+                print(os + " CONTROLS THE REBOUND.\n");
+                if (d == 6) {
+                    if (Math.random() <= 0.75) {
+                        print("BALL STOLEN.  EASY LAP UP FOR DARTMOUTH.\n");
+                        score_player();
+                        continue;
+                    }
+                    if (Math.random() > 0.6) {
+                        print("PASS STOLEN BY " + os + " EASY LAYUP.\n");
+                        score_computer();
+                        return;
+                    }
+                    print("BALL PASSED BACK TO YOU. ");
+                    return;
+                }
+                if (Math.random() <= 0.5) {
+                    print("PASS BACK TO " + os + " GUARD.\n");
+                    continue;
+                }
+            } else if (8 / d * Math.random() <= 0.90) {
+                print("PLAYER FOULED.  TWO SHOTS.\n");
+                foul();
+                return;
+            } else {
+                print("OFFENSIVE FOUL.  DARTMOUTH'S BALL.\n");
+                return;
+            }
+        }
+        while (1) {
+            if (z1 > 3) {
+                print("SET SHOT.\n");
+            } else {
+                print("LAY UP.\n");
+            }
+            if (7 / d * Math.random() <= 0.413) {
+                print("SHOT IS GOOD.\n");
+                score_computer();
+                return;
+            }
+            print("SHOT IS MISSED.\n");
+            // Spaguetti jump, better to replicate code
+            if (d / 6 * Math.random() <= 0.5) {
+                print("DARMOUTH CONTROLS THE REBOUND.\n");
+                return;
+            }
+            print(os + " CONTROLS THE REBOUND.\n");
+            if (d == 6) {
+                if (Math.random() <= 0.75) {
+                    print("BALL STOLEN.  EASY LAP UP FOR DARTMOUTH.\n");
+                    score_player();
+                    break;
+                }
+                if (Math.random() > 0.6) {
+                    print("PASS STOLEN BY " + os + " EASY LAYUP.\n");
+                    score_computer();
+                    return;
+                }
+                print("BALL PASSED BACK TO YOU. ");
+                return;
+            }
+            if (Math.random() <= 0.5) {
+                print("PASS BACK TO " + os + " GUARD.\n");
+                break;
+            }
+        }
+    }
+}
+
+// Main program
+async function main()
+{
+    print(tab(31) + "BASKETBALL\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("THIS IS DARTMOUTH COLLEGE BASKETBALL.  YOU WILL BE DARTMOUTH\n");
+    print(" CAPTAIN AND PLAYMAKER.  CALL SHOTS AS FOLLOWS:  1. LONG\n");
+    print(" (30 FT.) JUMP SHOT; 2. SHORT (15 FT.) JUMP SHOT; 3. LAY\n");
+    print(" UP; 4. SET SHOT.\n");
+    print("BOTH TEAMS WILL USE THE SAME DEFENSE.  CALL DEFENSE AS\n");
+    print("FOLLOWS:  6. PRESS; 6.5 MAN-TO MAN; 7. ZONE; 7.5 NONE.\n");
+    print("TO CHANGE DEFENSE, JUST TYPE 0 AS YOUR NEXT SHOT.\n");
+    print("YOUR STARTING DEFENSE WILL BE");
+    t = 0;
+    p = 0;
+    d = parseFloat(await input());
+    if (d < 6) {
+        your_turn = 2;
+    } else {
+        print("\n");
+        print("CHOOSE YOUR OPPONENT");
+        os = await input();
+        game_restart = 1;
+    }
+    while (1) {
+        if (game_restart) {
+            game_restart = 0;
+            print("CENTER JUMP\n");
+            if (Math.random() > 3.0 / 5.0) {
+                print("DARMOUTH CONTROLS THE TAP.\n");
+            } else {
+                print(os + " CONTROLS THE TAP.\n");
+                computer_play();
+            }
+        }
+        if (your_turn == 2) {
+            print("YOUR NEW DEFENSIVE ALLIGNMENT IS");
+            d = parseFloat(await input());
+        }
+        print("\n");
+        while (1) {
+            print("YOUR SHOT");
+            z = parseInt(await input());
+            p = 0;
+            if (z != Math.floor(z) || z < 0 || z > 4)
+                print("INCORRECT ANSWER.  RETYPE IT. ");
+            else
+                break;
+        }
+        if (Math.random() < 0.5 || t < 100) {
+            game_restart = 0;
+            your_turn = 0;
+            player_play();
+            if (game_restart == 0 && your_turn == 0)
+                computer_play();
+        } else {
+            print("\n");
+            if (s[1] == s[0]) {
+                print("\n");
+                print("   ***** END OF SECOND HALF *****\n");
+                print("\n");
+                print("SCORE AT END OF REGULATION TIME:\n");
+                print("        DARTMOUTH: " + s[1] + "  " + os + ": " + s[0] + "\n");
+                print("\n");
+                print("BEGIN TWO MINUTE OVERTIME PERIOD\n");
+                t = 93;
+                print("CENTER JUMP\n");
+                if (Math.random() > 3.0 / 5.0)
+                    print("DARMOUTH CONTROLS THE TAP.\n");
+                else
+                    print(os + " CONTROLS THE TAP.\n");
+            } else {
+                print("   ***** END OF GAME *****\n");
+                print("FINAL SCORE: DARMOUTH: " + s[1] + "  " + os + ": " + s[0] + "\n");
+                break;
+            }
+        }
+    }
+}
+
+main();
diff --git a/08 Batnum/java/src/BatNum.java b/08 Batnum/java/src/BatNum.java
new file mode 100644
index 00000000..4211d74d
--- /dev/null
+++ b/08 Batnum/java/src/BatNum.java	
@@ -0,0 +1,292 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of BatNum
+ * 

+ * 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 @@ + + +BATNUM + + +


+
+
+
diff --git a/08 Batnum/javascript/batnum.js b/08 Batnum/javascript/batnum.js
new file mode 100644
index 00000000..c7d25b78
--- /dev/null
+++ b/08 Batnum/javascript/batnum.js	
@@ -0,0 +1,161 @@
+// BATNUM
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+// Main program
+async function main()
+{
+    print(tab(33) + "BATNUM\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE\n");
+    print("COMPUTER IS YOUR OPPONENT.\n");
+    print("\n");
+    print("THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU\n");
+    print("AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE.\n");
+    print("WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR\n");
+    print("NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS.\n");
+    print("DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME.\n");
+    print("ENTER A NEGATIVE NUMBER FOR NEW PILE SIZE TO STOP PLAYING.\n");
+    print("\n");
+    first_time = 1;
+    while (1) {
+        while (1) {
+            if (first_time == 1) {
+                first_time = 0;
+            } else {
+                for (i = 1; i <= 10; i++)
+                    print("\n");
+            }
+            print("ENTER PILE SIZE");
+            n = parseInt(await input());
+            if (n >= 1)
+                break;
+        }
+        while (1) {
+            print("ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: ");
+            m = parseInt(await input());
+            if (m == 1 || m == 2)
+                break;
+        }
+        while (1) {
+            print("ENTER MIN AND MAX ");
+            str = await input();
+            a = parseInt(str);
+            b = parseInt(str.substr(str.indexOf(",") + 1));
+            if (a <= b && a >= 1)
+                break;
+        }
+        while (1) {
+            print("ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST ");
+            s = parseInt(await input());
+            print("\n");
+            print("\n");
+            if (s == 1 || s == 2)
+                break;
+        }
+        w = 0;
+        c = a + b;
+        while (1) {
+            if (s == 1) {
+                // Computer's turn
+                q = n;
+                if (m != 1)
+                    q--;
+                if (m != 1 && n <= a) {
+                    w = 1;
+                    print("COMPUTER TAKES " + n + " AND LOSES.\n");
+                } else if (m == 1 && n <= b) {
+                    w = 1;
+                    print("COMPUTER TAKES " + n + " AND WINS.\n");
+                } else {
+                    p = q - c * Math.floor(q / c);
+                    if (p < a)
+                        p = a;
+                    if (p > b)
+                        p = b;
+                    n -= p;
+                    print("COMPUTER TAKES " + p + " AND LEAVES " + n + "\n");
+                    w = 0;
+                }
+                s = 2;
+            }
+            if (w)
+                break;
+            if (s == 2) {
+                while (1) {
+                    print("\n");
+                    print("YOUR MOVE ");
+                    p = parseInt(await input());
+                    if (p == 0) {
+                        print("I TOLD YOU NOT TO USE ZERO! COMPUTER WINS BY FORFEIT.\n");
+                        w = 1;
+                        break;
+                    } else if (p >= a && p <= b && n - p >= 0) {
+                        break;
+                    }
+                }
+                if (p != 0) {
+                    n -= p;
+                    if (n == 0) {
+                        if (m != 1) {
+                            print("TOUGH LUCK, YOU LOSE.\n");
+                        } else {
+                            print("CONGRATULATIONS, YOU WIN.\n");
+                        }
+                        w = 1;
+                    } else {
+                        w = 0;
+                    }
+                }
+                s = 1;
+            }
+            if (w)
+                break;
+        }
+    }
+}
+
+main();
diff --git a/10 Blackjack/csharp/Blackjack.csproj b/10 Blackjack/csharp/Blackjack.csproj
new file mode 100644
index 00000000..796a6731
--- /dev/null
+++ b/10 Blackjack/csharp/Blackjack.csproj	
@@ -0,0 +1,9 @@
+
+
+  
+    Exe
+    Blackjack
+    net5.0
+  
+
+
diff --git a/10 Blackjack/csharp/Card.cs b/10 Blackjack/csharp/Card.cs
new file mode 100644
index 00000000..a2b6b6bd
--- /dev/null
+++ b/10 Blackjack/csharp/Card.cs	
@@ -0,0 +1,32 @@
+namespace Blackjack
+{
+    public class Card
+    {
+        private static readonly string[] _names = new[] {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
+
+        public Card(int index)
+        {
+            Index = index;
+        }
+
+        public int Index { get; private set; }
+
+        public string Name => _names[Index];
+
+        public string IndefiniteArticle => (Index == 0 || Index == 7) ? "an" : "a";
+
+        public bool IsAce => Index == 0;
+
+        public int Value
+        {
+            get
+            {
+                if (IsAce)
+                    return 11;
+                if (Index > 8)
+                    return 10;
+                return Index + 1;
+            }
+        }
+    }
+}
diff --git a/10 Blackjack/csharp/Deck.cs b/10 Blackjack/csharp/Deck.cs
new file mode 100644
index 00000000..21b1e9ef
--- /dev/null
+++ b/10 Blackjack/csharp/Deck.cs	
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+
+namespace Blackjack
+{
+    public class Deck
+    {
+        private static readonly Random _random = new Random();
+
+        private readonly List _cards = new List(52);
+        private readonly List _discards = new List(52);
+
+        public Deck()
+        {
+            for (var index = 0; index < 12; index++)
+            {
+                for (var suit = 0; suit < 4; suit++)
+                {
+                    _discards.Add(new Card(index));
+                }
+            }
+            Reshuffle();
+        }
+
+        private void Reshuffle()
+        {
+            Console.WriteLine("Reshuffling");
+
+            _cards.AddRange(_discards);
+            _discards.Clear();
+
+            for (var index1 = _cards.Count - 1; index1 > 0; index1--)
+            {
+                var index2 = _random.Next(0, index1);
+                var swapCard = _cards[index1];
+                _cards[index1] = _cards[index2];
+                _cards[index2] = swapCard;
+            }
+        }
+
+        public Card DrawCard()
+        {
+            if (_cards.Count < 2)
+                Reshuffle();
+
+            var card = _cards[_cards.Count - 1];
+            _cards.RemoveAt(_cards.Count - 1);
+            return card;
+        }
+
+        public void Discard(IEnumerable cards)
+        {
+            _discards.AddRange(cards);
+        }
+    }
+}
diff --git a/10 Blackjack/csharp/Game.cs b/10 Blackjack/csharp/Game.cs
new file mode 100644
index 00000000..7bb16350
--- /dev/null
+++ b/10 Blackjack/csharp/Game.cs	
@@ -0,0 +1,232 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Blackjack
+{
+    public class Game
+    {
+        private readonly Deck _deck = new Deck();
+        private readonly int _numberOfPlayers;
+        private readonly Player[] _players;
+        private readonly Hand _dealerHand;
+
+        public Game(int numberOfPlayers)
+        {
+            _numberOfPlayers = numberOfPlayers;
+            _players = new Player[_numberOfPlayers];
+            for (var playerIndex = 0; playerIndex < _numberOfPlayers; playerIndex++)
+                _players[playerIndex] = new Player(playerIndex);
+            _dealerHand = new Hand();
+        }
+
+        public void PlayGame()
+        {
+            while (true)
+            {
+                PlayRound();
+                TallyResults();
+                ResetRoundState();
+                Console.WriteLine();
+            }
+        }
+
+        public void PlayRound()
+        {
+            GetPlayerBets();
+
+            DealHands();
+
+            // Test for insurance
+            var dealerIsShowingAce = _dealerHand.Cards[0].IsAce;
+            if (dealerIsShowingAce && Prompt.ForYesNo("Any insurance?"))
+            {
+                Console.WriteLine("Insurance bets");
+                var insuranceBets = new int[_numberOfPlayers];
+                foreach (var player in _players)
+                    insuranceBets[player.Index] = Prompt.ForInteger($"# {player.Index + 1} ?", 0, player.RoundBet / 2);
+
+                var insuranceEffectMultiplier = _dealerHand.IsBlackjack ? 2 : -1;
+                foreach (var player in _players)
+                    player.RoundWinnings += insuranceBets[player.Index] * insuranceEffectMultiplier;
+            }
+
+            // Test for dealer blackjack
+            var concealedCard = _dealerHand.Cards[0];
+            if (_dealerHand.IsBlackjack)
+            {
+                Console.WriteLine();
+                Console.WriteLine("Dealer has {0} {1} in the hole for blackjack.", concealedCard.IndefiniteArticle, concealedCard.Name);
+                return;
+            }
+            else if (dealerIsShowingAce)
+            {
+                Console.WriteLine();
+                Console.WriteLine("No dealer blackjack.");
+            }
+
+            foreach (var player in _players)
+                PlayHand(player);
+
+            // Dealer hand
+            var allPlayersBusted = _players.All(p => p.Hand.IsBusted && (!p.SecondHand.Exists || p.SecondHand.IsBusted));
+            if (allPlayersBusted)
+                Console.WriteLine("Dealer had {0} {1} concealed.", concealedCard.IndefiniteArticle, concealedCard.Name);
+            else
+            {
+                Console.WriteLine("Dealer has {0} {1} concealed for a total of {2}", concealedCard.IndefiniteArticle, concealedCard.Name, _dealerHand.Total);
+                if (_dealerHand.Total < 17)
+                {
+                    Console.Write("Draws");
+                    while (_dealerHand.Total < 17)
+                    {
+                        var card = _dealerHand.AddCard(_deck.DrawCard());
+                        Console.Write("  {0}", card.Name);
+                    }
+                    if (_dealerHand.IsBusted)
+                        Console.WriteLine("  ...Busted");
+                    else
+                        Console.WriteLine("  ---Total is {0}", _dealerHand.Total);
+                }
+            }
+        }
+
+        private void GetPlayerBets()
+        {
+            Console.WriteLine("Bets:");
+            foreach (var player in _players)
+                player.RoundBet = Prompt.ForInteger($"# {player.Name} ?", 1, 500);
+        }
+
+        private void DealHands()
+        {
+            Console.Write("Player ");
+            foreach (var player in _players)
+                Console.Write("{0}     ", player.Name);
+            Console.WriteLine("Dealer");
+
+            for (var cardIndex = 0; cardIndex < 2; cardIndex++)
+            {
+                Console.Write("      ");
+                foreach (var player in _players)
+                    Console.Write("  {0,-4}", player.Hand.AddCard(_deck.DrawCard()).Name);
+                var dealerCard = _dealerHand.AddCard(_deck.DrawCard());
+                Console.Write("  {0,-4}", (cardIndex == 0) ? "XX" : dealerCard.Name);
+
+                Console.WriteLine();
+            }
+        }
+
+        private void PlayHand(Player player)
+        {
+            var hand = player.Hand;
+
+            Console.Write("Player {0} ", player.Name);
+
+            var playerCanSplit = hand.Cards[0].Value == hand.Cards[1].Value;
+            var command = Prompt.ForCommandCharacter("?", playerCanSplit ? "HSD/" : "HSD");
+            switch (command)
+            {
+                case "D":
+                    player.RoundBet *= 2;
+                    goto case "H";
+
+                case "H":
+                    while (TakeHit(hand) && PromptForAnotherHit())
+                    { }
+                    if (!hand.IsBusted)
+                        Console.WriteLine("Total is {0}", hand.Total);
+                    break;
+
+                case "S":
+                    if (hand.IsBlackjack)
+                    {
+                        Console.WriteLine("Blackjack!");
+                        player.RoundWinnings = (int)(1.5 * player.RoundBet + 0.5);
+                        player.RoundBet = 0;
+                    }
+                    else
+                        Console.WriteLine("Total is {0}", hand.Total);
+                    break;
+
+                case "/":
+                    hand.SplitHand(player.SecondHand);
+                    var card = hand.AddCard(_deck.DrawCard());
+                    Console.WriteLine("First hand receives {0} {1}", card.IndefiniteArticle, card.Name);
+                    card = player.SecondHand.AddCard(_deck.DrawCard());
+                    Console.WriteLine("Second hand receives {0} {1}", card.IndefiniteArticle, card.Name);
+
+                    for (int handNumber = 1; handNumber <= 2; handNumber++)
+                    {
+                        hand = (handNumber == 1) ? player.Hand : player.SecondHand;
+
+                        Console.Write("Hand {0}", handNumber);
+                        while (PromptForAnotherHit() && TakeHit(hand))
+                        { }
+                        if (!hand.IsBusted)
+                            Console.WriteLine("Total is {0}", hand.Total);
+                    }
+                    break;
+            }
+        }
+
+        private bool TakeHit(Hand hand)
+        {
+            var card = hand.AddCard(_deck.DrawCard());
+            Console.Write("Received {0,-6}", $"{card.IndefiniteArticle} {card.Name}");
+            if (hand.IsBusted)
+            {
+                Console.WriteLine("...Busted");
+                return false;
+            }
+            return true;
+        }
+
+        private bool PromptForAnotherHit()
+        {
+            return String.Equals(Prompt.ForCommandCharacter(" Hit?", "HS"), "H");
+        }
+
+        private void TallyResults()
+        {
+            Console.WriteLine();
+            foreach (var player in _players)
+            {
+                player.RoundWinnings += CalculateWinnings(player, player.Hand);
+                if (player.SecondHand.Exists)
+                    player.RoundWinnings += CalculateWinnings(player, player.SecondHand);
+                player.TotalWinnings += player.RoundWinnings;
+
+                Console.WriteLine("Player {0} {1,-6} {2,3}   Total= {3,5}",
+                        player.Name,
+                        (player.RoundWinnings > 0) ? "wins" : (player.RoundWinnings) < 0 ? "loses" : "pushes",
+                        (player.RoundWinnings != 0) ? Math.Abs(player.RoundWinnings).ToString() : "",
+                        player.TotalWinnings);
+            }
+            Console.WriteLine("Dealer's total= {0}", -_players.Sum(p => p.TotalWinnings));
+        }
+
+        private int CalculateWinnings(Player player, Hand hand)
+        {
+            if (hand.IsBusted)
+                return -player.RoundBet;
+            if (hand.Total == _dealerHand.Total)
+                return 0;
+            if (_dealerHand.IsBusted || hand.Total > _dealerHand.Total)
+                return player.RoundBet;
+            return -player.RoundBet;
+        }
+
+        private void ResetRoundState()
+        {
+            foreach (var player in _players)
+            {
+                player.RoundWinnings = 0;
+                player.RoundBet = 0;
+                player.Hand.Discard(_deck);
+                player.SecondHand.Discard(_deck);
+            }
+            _dealerHand.Discard(_deck);
+        }
+    }
+}
diff --git a/10 Blackjack/csharp/Hand.cs b/10 Blackjack/csharp/Hand.cs
new file mode 100644
index 00000000..49b945bb
--- /dev/null
+++ b/10 Blackjack/csharp/Hand.cs	
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+
+namespace Blackjack
+{
+    public class Hand
+    {
+        private readonly List _cards = new List(12);
+        private int _cachedTotal = 0;
+
+        public Card AddCard(Card card)
+        {
+            _cards.Add(card);
+            _cachedTotal = 0;
+            return card;
+        }
+
+        public void Discard(Deck deck)
+        {
+            deck.Discard(_cards);
+            _cards.Clear();
+            _cachedTotal = 0;
+        }
+
+        public void SplitHand(Hand secondHand)
+        {
+            if (Count != 2 || secondHand.Count != 0)
+                throw new InvalidOperationException();
+            secondHand.AddCard(_cards[1]);
+            _cards.RemoveAt(1);
+            _cachedTotal = 0;
+        }
+
+        public IReadOnlyList Cards => _cards;
+
+        public int Count => _cards.Count;
+
+        public bool Exists => _cards.Count > 0;
+
+        public int Total
+        {
+            get
+            {
+                if (_cachedTotal == 0)
+                {
+                    var aceCount = 0;
+                    foreach (var card in _cards)
+                    {
+                        _cachedTotal += card.Value;
+                        if (card.IsAce)
+                            aceCount++;
+                    }
+                    while (_cachedTotal > 21 && aceCount > 0)
+                    {
+                        _cachedTotal -= 10;
+                        aceCount--;
+                    }
+                }
+                return _cachedTotal;
+            }
+        }
+
+        public bool IsBlackjack => Total == 21 && Count == 2;
+
+        public bool IsBusted => Total > 21;
+    }
+}
diff --git a/10 Blackjack/csharp/Player.cs b/10 Blackjack/csharp/Player.cs
new file mode 100644
index 00000000..58664f1d
--- /dev/null
+++ b/10 Blackjack/csharp/Player.cs	
@@ -0,0 +1,27 @@
+namespace Blackjack
+{
+    public class Player
+    {
+        public Player(int index)
+        {
+            Index = index;
+            Name = (index + 1).ToString();
+            Hand = new Hand();
+            SecondHand = new Hand();
+        }
+
+        public int Index { get; private set; }
+
+        public string Name { get; private set; }
+
+        public Hand Hand { get; private set; }
+
+        public Hand SecondHand { get; private set;}
+
+        public int RoundBet { get; set; }
+
+        public int RoundWinnings { get; set; }
+
+        public int TotalWinnings { get; set; }
+    }
+}
diff --git a/10 Blackjack/csharp/Program.cs b/10 Blackjack/csharp/Program.cs
new file mode 100644
index 00000000..dac7da86
--- /dev/null
+++ b/10 Blackjack/csharp/Program.cs	
@@ -0,0 +1,41 @@
+using System;
+
+namespace Blackjack
+{
+    static class Program
+    {
+        static void Main(string[] args)
+        {
+            Console.WriteLine("{0}BLACK JACK", new string(' ', 31));
+            Console.WriteLine("{0}CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY", new string(' ', 15));
+            Console.WriteLine();
+            Console.WriteLine();
+            Console.WriteLine();
+
+            OfferInstructions();
+
+            var numberOfPlayers = Prompt.ForInteger("Number of players?", 1, 6);
+            var game = new Game(numberOfPlayers);
+            game.PlayGame();
+        }
+
+        private static void OfferInstructions()
+        {
+            if (!Prompt.ForYesNo("Do you want instructions?"))
+                return;
+
+            Console.WriteLine("This is the game of 21. As many as 7 players may play the");
+            Console.WriteLine("game. On each deal, bets will be asked for, and the");
+            Console.WriteLine("players' bets should be typed in. The cards will then be");
+            Console.WriteLine("dealt, and each player in turn plays his hand. The");
+            Console.WriteLine("first response should be either 'D', indicating that the");
+            Console.WriteLine("player is doubling down, 'S', indicating that he is");
+            Console.WriteLine("standing, 'H', indicating he wants another card, or '/',");
+            Console.WriteLine("indicating that he wants to split his cards. After the");
+            Console.WriteLine("initial response, all further responses should be 's' or");
+            Console.WriteLine("'H', unless the cards were split, in which case doubling");
+            Console.WriteLine("down is again permitted. In order to collect for");
+            Console.WriteLine("Blackjack, the initial response should be 'S'.");
+        }
+    }
+}
diff --git a/10 Blackjack/csharp/Prompt.cs b/10 Blackjack/csharp/Prompt.cs
new file mode 100644
index 00000000..9f798965
--- /dev/null
+++ b/10 Blackjack/csharp/Prompt.cs	
@@ -0,0 +1,58 @@
+using System;
+
+namespace Blackjack
+{
+    public static class Prompt
+    {
+        public static bool ForYesNo(string prompt)
+        {
+            while(true)
+            {
+                Console.Write("{0} ", prompt);
+                var input = Console.ReadLine();
+                if (input.StartsWith("y", StringComparison.InvariantCultureIgnoreCase))
+                    return true;
+                if (input.StartsWith("n", StringComparison.InvariantCultureIgnoreCase))
+                    return false;
+                WriteNotUnderstood();
+            }
+        }
+
+        public static int ForInteger(string prompt, int minimum = 1, int maximum = int.MaxValue)
+        {
+            while (true)
+            {
+                Console.Write("{0} ", prompt);
+                if (!int.TryParse(Console.ReadLine(), out var number))
+                    WriteNotUnderstood();
+                else if (number < minimum || number > maximum)
+                    Console.WriteLine("Sorry, I need a number between {0} and {1}.", minimum, maximum);
+                else
+                    return number;
+            }
+        }
+
+        public static string ForCommandCharacter(string prompt, string allowedCharacters)
+        {
+            while (true)
+            {
+                Console.Write("{0} ", prompt);
+                var input = Console.ReadLine();
+                if (input.Length > 0)
+                {
+                    var character = input.Substring(0, 1);
+                    var characterIndex = allowedCharacters.IndexOf(character, StringComparison.InvariantCultureIgnoreCase);
+                    if (characterIndex != -1)
+                        return allowedCharacters.Substring(characterIndex, 1);
+                }
+
+                Console.WriteLine("Type one of {0} please", String.Join(", ", allowedCharacters.ToCharArray()));
+            }
+        }
+
+        private static void WriteNotUnderstood()
+        {
+            Console.WriteLine("Sorry, I didn't understand.");
+        }
+    }
+}
diff --git a/11 Bombardment/java/src/Bombardment.java b/11 Bombardment/java/src/Bombardment.java
index 06a3043c..1dede841 100644
--- a/11 Bombardment/java/src/Bombardment.java	
+++ b/11 Bombardment/java/src/Bombardment.java	
@@ -3,12 +3,12 @@ import java.util.Scanner;
 
 /**
  * Game of Bombardment
- *
+ * 

* Based on the Basic game of Bombardment here * https://github.com/coding-horror/basic-computer-games/blob/main/11%20Bombardment/bombardment.bas - * - * Note: The idea was to create a version of this 1970's Basic game in Java, without introducing - * new features - no additional text, error checking, etc has been added. + *

+ * 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 Bombardment { @@ -28,11 +28,11 @@ public class Bombardment { private GAME_STATE gameState; - public static final String[] PLAYER_HIT_MESSAGES = { "ONE DOWN, THREE TO GO.", - "TWO DOWN, TWO TO GO.", "THREE DOWN, ONE TO GO." }; + public static final String[] PLAYER_HIT_MESSAGES = {"ONE DOWN, THREE TO GO.", + "TWO DOWN, TWO TO GO.", "THREE DOWN, ONE TO GO."}; public static final String[] COMPUTER_HIT_MESSAGES = {"YOU HAVE ONLY THREE OUTPOSTS LEFT.", - "YOU HAVE ONLY TWO OUTPOSTS LEFT.", "YOU HAVE ONLY ONE OUTPOST LEFT." }; + "YOU HAVE ONLY TWO OUTPOSTS LEFT.", "YOU HAVE ONLY ONE OUTPOST LEFT."}; private HashSet computersPlatoons; private HashSet playersPlatoons; @@ -44,7 +44,7 @@ public class Bombardment { public Bombardment() { - this.gameState = GAME_STATE.STARTING; + gameState = GAME_STATE.STARTING; // Initialise kb scanner kbScanner = new Scanner(System.in); @@ -56,19 +56,19 @@ public class Bombardment { public void play() { do { - switch (this.gameState) { + switch (gameState) { // Show an introduction the first time the game is played. case STARTING: init(); intro(); - this.gameState = GAME_STATE.DRAW_BATTLEFIELD; + gameState = GAME_STATE.DRAW_BATTLEFIELD; break; // Enter the players name case DRAW_BATTLEFIELD: drawBattlefield(); - this.gameState = GAME_STATE.GET_PLAYER_CHOICES; + gameState = GAME_STATE.GET_PLAYER_CHOICES; break; // Get the players 4 locations for their platoons @@ -76,35 +76,35 @@ public class Bombardment { String playerChoices = displayTextAndGetInput("WHAT ARE YOUR FOUR POSITIONS? "); // Store the 4 player choices that were entered separated with commas - for(int i=0; i computersChosenPlatoons() { @@ -198,19 +196,20 @@ public class Bombardment { tempPlatoons.add(randomNumber()); // All four created? - if(tempPlatoons.size() == PLATOONS) { + if (tempPlatoons.size() == PLATOONS) { // Exit when we have created four allPlatoonsAdded = true; } - } while(!allPlatoonsAdded); + } while (!allPlatoonsAdded); return tempPlatoons; } + /** * Shows a different message for each number of hits * - * @param hits total number of hits by player on computer + * @param hits total number of hits by player on computer */ private void showPlayerProgress(int hits) { @@ -221,7 +220,7 @@ public class Bombardment { /** * Shows a different message for each number of hits * - * @param hits total number of hits by computer on player + * @param hits total number of hits by computer on player */ private void showComputerProgress(int hits, int lastGuess) { @@ -231,42 +230,42 @@ public class Bombardment { /** * Prints a message from the passed array based on the value of hits - - * @param hits - number of hits the player or computer has made + * + * @param hits - number of hits the player or computer has made * @param messages - an array of string with messages */ private void showProgress(int hits, String[] messages) { - System.out.println(messages[hits-1]); + System.out.println(messages[hits - 1]); } /** - * * Update a player hit - adds a hit the player made on the computers platoon. + * * @param fireLocation - computer location that got hit * @return number of hits the player has inflicted on the computer in total */ private int updatePlayerHits(int fireLocation) { // N.B. only removes if present, so its redundant to check if it exists first - this.computersPlatoons.remove(fireLocation); + computersPlatoons.remove(fireLocation); // return number of hits in total - return PLATOONS - this.computersPlatoons.size(); + return PLATOONS - computersPlatoons.size(); } /** - * * Update a computer hit - adds a hit the computer made on the players platoon. + * * @param fireLocation - player location that got hit * @return number of hits the player has inflicted on the computer in total */ private int updateComputerHits(int fireLocation) { // N.B. only removes if present, so its redundant to check if it exists first - this.playersPlatoons.remove(fireLocation); + playersPlatoons.remove(fireLocation); // return number of hits in total - return PLATOONS - this.playersPlatoons.size(); + return PLATOONS - playersPlatoons.size(); } /** @@ -276,7 +275,7 @@ public class Bombardment { * @return true if a computer platoon was at that position */ private boolean didPlayerHitComputerPlatoon(int fireLocation) { - return this.computersPlatoons.contains(fireLocation); + return computersPlatoons.contains(fireLocation); } /** @@ -286,22 +285,20 @@ public class Bombardment { * @return true if a players platoon was at that position */ private boolean didComputerHitPlayerPlatoon(int fireLocation) { - return this.playersPlatoons.contains(fireLocation); + return playersPlatoons.contains(fireLocation); } /** * Draw the battlefield grid - * */ private void drawBattlefield() { - for(int i=1; i(); + playersPlatoons = new HashSet<>(); - this.computersGuesses = new HashSet<>(); + computersGuesses = new HashSet<>(); } /** diff --git a/11 Bombardment/javascript/bombardment.html b/11 Bombardment/javascript/bombardment.html new file mode 100644 index 00000000..5255cdd9 --- /dev/null +++ b/11 Bombardment/javascript/bombardment.html @@ -0,0 +1,9 @@ + + +BOMBARDMENT + + +


+
+
+
diff --git a/11 Bombardment/javascript/bombardment.js b/11 Bombardment/javascript/bombardment.js
new file mode 100644
index 00000000..3cd0a5d7
--- /dev/null
+++ b/11 Bombardment/javascript/bombardment.js	
@@ -0,0 +1,167 @@
+// BOMBARDMENT
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+// Main program
+async function main()
+{
+    print(tab(33) + "BOMBARDMENT\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU\n");
+    print("HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.\n");
+    print("YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST.\n");
+    print("THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS.\n");
+    print("\n");
+    print("THE OBJECT OF THE GAME IS TO FIRE MISSILES AT THE\n");
+    print("OUTPOSTS OF THE COMPUTER.  IT WILL DO THE SAME TO YOU.\n");
+    print("THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS\n");
+    print("FIRST IS THE WINNER.\n");
+    print("\n");
+    print("GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!\n");
+    print("\n");
+    // "TEAR OFF" because it supposed this to be printed on a teletype
+    print("TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS.\n");
+    for (r = 1; r <= 5; r++)
+        print("\n");
+    ma = [];
+    for (r = 1; r <= 100; r++)
+        ma[r] = 0;
+    p = 0;
+    q = 0;
+    z = 0;
+    for (r = 1; r <= 5; r++) {
+        i = (r - 1) * 5 + 1;
+        print(i + "\t" + (i + 1) + "\t" + (i + 2) + "\t" + (i + 3) + "\t" + (i + 4) + "\n");
+    }
+    for (r = 1; r <= 10; r++)
+        print("\n");
+    c = Math.floor(Math.random() * 25) + 1;
+    do {
+        d = Math.floor(Math.random() * 25) + 1;
+        e = Math.floor(Math.random() * 25) + 1;
+        f = Math.floor(Math.random() * 25) + 1;
+    } while (c == d || c == e || c == f || d == e || d == f || e == f) ;
+    print("WHAT ARE YOUR FOUR POSITIONS");
+    str = await input();
+    g = parseInt(str);
+    str = str.substr(str.indexOf(",") + 1);
+    h = parseInt(str);
+    str = str.substr(str.indexOf(",") + 1);
+    k = parseInt(str);
+    str = str.substr(str.indexOf(",") + 1);
+    l = parseInt(str);
+    print("\n");
+    // Another "bug" your outpost can be in the same position as a computer outpost
+    // Let us suppose both live in a different matrix.
+    while (1) {
+        // The original game didn't limited the input to 1-25
+        do {
+            print("WHERE DO YOU WISH TO FIRE YOUR MISSLE");
+            y = parseInt(await input());
+        } while (y < 0 || y > 25) ;
+        if (y == c || y == d || y == e || y == f) {
+            
+            // The original game has a bug. You can shoot the same outpost
+            // several times. This solves it.
+            if (y == c)
+                c = 0;
+            if (y == d)
+                d = 0;
+            if (y == e)
+                e = 0;
+            if (y == f)
+                f = 0;
+            q++;
+            if (q == 1) {
+                print("ONE DOWN. THREE TO GO.\n");
+            } else if (q == 2) {
+                print("TWO DOWN. TWO TO GO.\n");
+            } else if (q == 3) {
+                print("THREE DOWN. ONE TO GO.\n");
+            } else {
+                print("YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN\n");
+                print("MY TRANSISTO&S RECUP%RA*E!\n");
+                break;
+            }
+        } else {
+            print("HA, HA YOU MISSED. MY TURN NOW:\n");
+        }
+        print("\n");
+        print("\n");
+        do {
+            m = Math.floor(Math.random() * 25 + 1);
+            p++;
+            n = p - 1;
+            for (t = 1; t <= n; t++) {
+                if (m == ma[t])
+                    break;
+            }
+        } while (t <= n) ;
+        x = m;
+        ma[p] = m;
+        if (x == g || x == h || x == l || x == k) {
+            z++;
+            if (z < 4)
+                print("I GOT YOU. IT WON'T BE LONG NOW. POST " + x + " WAS HIT.\n");
+            if (z == 1) {
+                print("YOU HAVE ONLY THREE OUTPOSTS LEFT.\n");
+            } else if (z == 2) {
+                print("YOU HAVE ONLY TWO OUTPOSTS LEFT.\n");
+            } else if (z == 3) {
+                print("YOU HAVE ONLY ONE OUTPOST LEFT.\n");
+            } else {
+                print("YOU'RE DEAD. YOUR LAST OUTPOST WAS AT " + x + ". HA, HA, HA.\n");
+                print("BETTER LUCK NEXT TIME.\n");
+            }
+        } else {
+            print("I MISSED YOU, YOU DIRTY RAT. I PICKED " + m + ". YOUR TURN:\n");
+        }
+        print("\n");
+        print("\n");
+    }
+}
+
+main();
diff --git a/11 Bombardment/python/bombardment.py b/11 Bombardment/python/bombardment.py
new file mode 100755
index 00000000..a16113e7
--- /dev/null
+++ b/11 Bombardment/python/bombardment.py	
@@ -0,0 +1,151 @@
+#!/usr/bin/env python3
+import random
+from functools import partial
+
+def display_intro():
+    print("" * 33 + "BOMBARDMENT")
+    print("" * 15 + " CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
+    print("\n\n")
+    print("YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU")
+    print("HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.")
+    print("YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST.")
+    print("THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS.")
+    print()
+    print("THE OBJECT OF THE GAME IS TO FIRE MISSLES AT THE")
+    print("OUTPOSTS OF THE COMPUTER.  IT WILL DO THE SAME TO YOU.")
+    print("THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS")
+    print("FIRST IS THE WINNER.")
+    print()
+    print("GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!")
+    print()
+    print("TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS.")
+    print("\n" * 4)
+
+
+def display_field():
+    for row in range(5):
+        initial = row * 5 + 1
+        print('\t'.join([str(initial + column) for column in range(5)]))
+
+    print("\n" * 9)
+
+
+def positions_list():
+    return list(range(1, 26, 1))
+
+
+def generate_enemy_positions():
+    """ Randomly choose 4 'positions' out of a range of 1 to 25 """
+    positions = positions_list()
+    random.shuffle(positions)
+    return set(positions[:4])
+
+
+def is_valid_position(pos):
+    return pos in positions_list()
+
+
+def prompt_for_player_positions():
+
+    while True:
+        raw_positions = input("WHAT ARE YOUR FOUR POSITIONS? ")
+        positions = set(int(pos) for pos in raw_positions.split())
+        # Verify user inputs (for example, if the player gives a
+        # a position for 26, the enemy can never hit it)
+        if (len(positions) != 4):
+            print("PLEASE ENTER 4 UNIQUE POSITIONS\n")
+            continue
+        elif (any(not is_valid_position(pos) for pos in positions)):
+            print("ALL POSITIONS MUST RANGE (1-25)\n")
+            continue
+        else:
+            return positions
+
+
+def prompt_player_for_target():
+
+    while True:
+        target = int(input("WHERE DO YOU WISH TO FIRE YOUR MISSLE? "))
+        if not is_valid_position(target):
+            print("POSITIONS MUST RANGE (1-25)\n")
+            continue
+
+        return target
+
+
+def attack(target, positions, hit_message, miss_message, progress_messages):
+    """ Performs attack procedure returning True if we are to continue. """
+
+    if target in positions:
+        print(hit_message.format(target))
+        positions.remove(target)
+        print(progress_messages[len(positions)].format(target))
+    else:
+        print(miss_message.format(target))
+
+    return len(positions) > 0
+
+
+def init_enemy():
+    """ Returns a closure analogous to prompt_player_for_target. Will
+        choose from a unique sequence of positions to avoid picking the
+        same position twice. """
+
+    position_sequence = positions_list()
+    random.shuffle(position_sequence)
+    position = iter(position_sequence)
+
+    def choose():
+        return next(position)
+
+    return choose
+
+
+# Messages correspond to outposts remaining (3, 2, 1, 0)
+PLAYER_PROGRESS_MESSAGES = (
+    "YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN\n"
+    "MY TRANSISTO&S RECUP%RA*E!",
+    "THREE DOWN, ONE TO GO.\n\n",
+    "TWO DOWN, TWO TO GO.\n\n",
+    "ONE DOWN, THREE TO GO.\n\n"
+    )
+
+
+ENEMY_PROGRESS_MESSAGES = (
+    "YOU'RE DEAD. YOUR LAST OUTPOST WAS AT {}. HA, HA, HA.\n"
+    "BETTER LUCK NEXT TIME.",
+    "YOU HAVE ONLY ONE OUTPOST LEFT.\n\n",
+    "YOU HAVE ONLY TWO OUTPOSTS LEFT.\n\n",
+    "YOU HAVE ONLY THREE OUTPOSTS LEFT.\n\n",
+    )
+
+
+def play():
+    display_intro()
+    display_field()
+
+    enemy_positions = generate_enemy_positions()
+    player_positions = prompt_for_player_positions()
+
+    # Build partial functions only requiring the target as input
+    player_attacks = partial(attack,
+                             positions=enemy_positions,
+                             hit_message="YOU GOT ONE OF MY OUTPOSTS!",
+                             miss_message="HA, HA YOU MISSED. MY TURN NOW:\n\n",
+                             progress_messages=PLAYER_PROGRESS_MESSAGES)
+
+    enemy_attacks = partial(attack,
+                            positions=player_positions,
+                            hit_message="I GOT YOU. IT WON'T BE LONG NOW. POST {} WAS HIT.",
+                            miss_message="I MISSED YOU, YOU DIRTY RAT. I PICKED {}. YOUR TURN:\n\n",
+                            progress_messages=ENEMY_PROGRESS_MESSAGES)
+
+    enemy_position_choice = init_enemy()
+
+    # Play as long as both player_attacks and enemy_attacks allow to continue
+    while player_attacks(prompt_player_for_target()) and enemy_attacks(enemy_position_choice()):
+        pass
+
+
+if __name__ == "__main__":
+    play()
diff --git a/12 Bombs Away/java/src/BombsAway.java b/12 Bombs Away/java/src/BombsAway.java
new file mode 100644
index 00000000..e156ea73
--- /dev/null
+++ b/12 Bombs Away/java/src/BombsAway.java	
@@ -0,0 +1,505 @@
+import java.util.Scanner;
+
+/**
+ * Game of Bombs Away
+ *
+ * Based on the Basic game of Bombs Away here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/12%20Bombs%20Away/bombsaway.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 BombsAway {
+
+    public static final int MAX_PILOT_MISSIONS = 160;
+    public static final int MAX_CASUALTIES = 100;
+    public static final int MISSED_TARGET_CONST_1 = 2;
+    public static final int MISSED_TARGET_CONST_2 = 30;
+    public static final int CHANCE_OF_BEING_SHOT_DOWN_BASE = 100;
+    public static final double SIXTY_FIVE_PERCENT = .65;
+
+    private enum GAME_STATE {
+        START,
+        CHOOSE_SIDE,
+        CHOOSE_PLANE,
+        CHOOSE_TARGET,
+        CHOOSE_MISSIONS,
+        CHOOSE_ENEMY_DEFENCES,
+        FLY_MISSION,
+        DIRECT_HIT,
+        MISSED_TARGET,
+        PROCESS_FLAK,
+        SHOT_DOWN,
+        MADE_IT_THROUGH_FLAK,
+        PLAY_AGAIN,
+        GAME_OVER
+    }
+
+    public enum SIDE {
+        ITALY(1),
+        ALLIES(2),
+        JAPAN(3),
+        GERMANY(4);
+
+        private final int value;
+
+        SIDE(int value) {
+            this.value = value;
+        }
+
+        public int getValue() {
+            return value;
+        }
+
+
+    }
+
+    public enum TARGET {
+        ALBANIA(1),
+        GREECE(2),
+        NORTH_AFRICA(3),
+        RUSSIA(4),
+        ENGLAND(5),
+        FRANCE(6);
+
+        private final int value;
+
+        TARGET(int value) {
+            this.value = value;
+        }
+
+        public int getValue() {
+            return value;
+        }
+    }
+
+    public enum ENEMY_DEFENCES {
+        GUNS(1),
+        MISSILES(2),
+        BOTH(3);
+
+        private final int value;
+
+        ENEMY_DEFENCES(int value) {
+            this.value = value;
+        }
+
+        public int getValue() {
+            return value;
+        }
+    }
+
+    public enum AIRCRAFT {
+        LIBERATOR(1),
+        B29(2),
+        B17(3),
+        LANCASTER(4);
+
+        private final int value;
+
+        AIRCRAFT(int value) {
+            this.value = value;
+        }
+
+        public int getValue() {
+            return value;
+        }
+    }
+
+    // Used for keyboard input
+    private final Scanner kbScanner;
+
+    // Current game state
+    private GAME_STATE gameState;
+
+    private SIDE side;
+
+    private int missions;
+
+    private int chanceToHit;
+    private int percentageHitRateOfGunners;
+
+    public BombsAway() {
+
+        gameState = GAME_STATE.START;
+
+        // 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 START:
+                    intro();
+                    chanceToHit = 0;
+                    percentageHitRateOfGunners = 0;
+
+                    gameState = GAME_STATE.CHOOSE_SIDE;
+                    break;
+
+                case CHOOSE_SIDE:
+                    side = getSide("WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4) ? ");
+                    if (side == null) {
+                        System.out.println("TRY AGAIN...");
+                    } else {
+                        // Different game paths depending on which side was chosen
+                        switch (side) {
+                            case ITALY:
+                            case GERMANY:
+                                gameState = GAME_STATE.CHOOSE_TARGET;
+                                break;
+                            case ALLIES:
+                            case JAPAN:
+                                gameState = GAME_STATE.CHOOSE_PLANE;
+                                break;
+                        }
+                    }
+                    break;
+
+                case CHOOSE_TARGET:
+                    String prompt;
+                    if (side == SIDE.ITALY) {
+                        prompt = "YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3) ? ";
+                    } else {
+                        // Germany
+                        System.out.println("A NAZI, EH?  OH WELL.  ARE YOU GOING FOR RUSSIA(1),");
+                        prompt = "ENGLAND(2), OR FRANCE(3) ? ";
+                    }
+                    TARGET target = getTarget(prompt);
+                    if (target == null) {
+                        System.out.println("TRY AGAIN...");
+                    } else {
+                        displayTargetMessage(target);
+                        gameState = GAME_STATE.CHOOSE_MISSIONS;
+                    }
+
+                case CHOOSE_MISSIONS:
+                    missions = getNumberFromKeyboard("HOW MANY MISSIONS HAVE YOU FLOWN? ");
+
+                    if(missions <25) {
+                        System.out.println("FRESH OUT OF TRAINING, EH?");
+                        gameState = GAME_STATE.FLY_MISSION;
+                    } else if(missions < 100) {
+                        System.out.println("THAT'S PUSHING THE ODDS!");
+                        gameState = GAME_STATE.FLY_MISSION;
+                    } else if(missions >=160) {
+                        System.out.println("MISSIONS, NOT MILES...");
+                        System.out.println("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS.");
+                        System.out.println("NOW THEN, ");
+                    } else {
+                        // No specific message if missions is 100-159, but still valid
+                        gameState = GAME_STATE.FLY_MISSION;
+                    }
+                    break;
+
+                case CHOOSE_PLANE:
+                    switch(side) {
+                        case ALLIES:
+                            AIRCRAFT plane = getPlane("AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4)? ");
+                            if(plane == null) {
+                                System.out.println("TRY AGAIN...");
+                            } else {
+                                switch(plane) {
+
+                                    case LIBERATOR:
+                                        System.out.println("YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI.");
+                                        break;
+                                    case B29:
+                                        System.out.println("YOU'RE DUMPING THE A-BOMB ON HIROSHIMA.");
+                                        break;
+                                    case B17:
+                                        System.out.println("YOU'RE CHASING THE BISMARK IN THE NORTH SEA.");
+                                        break;
+                                    case LANCASTER:
+                                        System.out.println("YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR.");
+                                        break;
+                                }
+
+                                gameState = GAME_STATE.CHOOSE_MISSIONS;
+                            }
+                            break;
+
+                        case JAPAN:
+                            System.out.println("YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.");
+                            if(yesEntered(displayTextAndGetInput("YOUR FIRST KAMIKAZE MISSION(Y OR N) ? "))) {
+                                if(randomNumber(1) > SIXTY_FIVE_PERCENT) {
+                                    gameState = GAME_STATE.DIRECT_HIT;
+                                } else {
+                                    // It's a miss
+                                    gameState = GAME_STATE.MISSED_TARGET;
+                                }
+                            } else {
+                                gameState = GAME_STATE.PROCESS_FLAK;
+                            }
+                            break;
+                    }
+                    break;
+
+                case FLY_MISSION:
+                    double missionResult = (MAX_PILOT_MISSIONS * randomNumber(1));
+                    if(missions > missionResult) {
+                        gameState = GAME_STATE.DIRECT_HIT;
+                    } else {
+                        gameState = GAME_STATE.MISSED_TARGET;
+                    }
+
+                    break;
+
+                case DIRECT_HIT:
+                    System.out.println("DIRECT HIT!!!! " + (int) Math.round(randomNumber(MAX_CASUALTIES)) + " KILLED.");
+                    System.out.println("MISSION SUCCESSFUL.");
+                    gameState = GAME_STATE.PLAY_AGAIN;
+                    break;
+
+                case MISSED_TARGET:
+                    System.out.println("MISSED TARGET BY " + (int) Math.round(MISSED_TARGET_CONST_1 + MISSED_TARGET_CONST_2 * (randomNumber(1))) + " MILES!");
+                    System.out.println("NOW YOU'RE REALLY IN FOR IT !!");
+                    System.out.println();
+                    gameState = GAME_STATE.CHOOSE_ENEMY_DEFENCES;
+                    break;
+
+                case CHOOSE_ENEMY_DEFENCES:
+                    boolean bothWeapons = true;
+
+                    ENEMY_DEFENCES enemyDefences = getEnemyDefences("DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3) ? ");
+                    if(enemyDefences == null) {
+                        System.out.println("TRY AGAIN...");
+                    } else {
+                        switch(enemyDefences) {
+                            case MISSILES:
+                            case GUNS:
+                                bothWeapons = false;
+
+                                // fall through on purpose to BOTH since its pretty much identical code other than the chance to hit
+                                // increasing if both weapons are part of the defence.
+
+                            case BOTH:
+                                percentageHitRateOfGunners = getNumberFromKeyboard("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? ");
+                                if(percentageHitRateOfGunners < 10) {
+                                    System.out.println("YOU LIE, BUT YOU'LL PAY...");
+                                }
+                                if(bothWeapons) {
+                                    chanceToHit = 35;
+
+                                }
+                                break;
+                        }
+                    }
+                    gameState = GAME_STATE.PROCESS_FLAK;
+
+                // Determine if the players airplan makes it through the Flak.
+                case PROCESS_FLAK:
+                    double calc = (CHANCE_OF_BEING_SHOT_DOWN_BASE * randomNumber(1));
+
+                    if ((chanceToHit + percentageHitRateOfGunners) > calc) {
+                        gameState = GAME_STATE.SHOT_DOWN;
+                    } else {
+                        gameState = GAME_STATE.MADE_IT_THROUGH_FLAK;
+                    }
+                    break;
+
+                case SHOT_DOWN:
+                    System.out.println("* * * * BOOM * * * *");
+                    System.out.println("YOU HAVE BEEN SHOT DOWN.....");
+                    System.out.println("DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR");
+                    System.out.println("LAST TRIBUTE...");
+                    gameState = GAME_STATE.PLAY_AGAIN;
+                    break;
+
+                case MADE_IT_THROUGH_FLAK:
+                    System.out.println("YOU MADE IT THROUGH TREMENDOUS FLAK!!");
+                    gameState = GAME_STATE.PLAY_AGAIN;
+                    break;
+
+                case PLAY_AGAIN:
+                    if(yesEntered(displayTextAndGetInput("ANOTHER MISSION (Y OR N) ? "))) {
+                        gameState = GAME_STATE.START;
+                    } else {
+                        System.out.println("CHICKEN !!!");
+                        gameState = GAME_STATE.GAME_OVER;
+                    }
+                    break;
+            }
+        } while (gameState != GAME_STATE.GAME_OVER) ;
+    }
+
+    /**
+     * Display a (brief) intro
+     */
+    public void intro() {
+        System.out.println("YOU ARE A PILOT IN A WORLD WAR II BOMBER.");
+    }
+
+    /**
+     * Determine the side the player is going to play on.
+     * @param message displayed before the kb input
+     * @return the SIDE enum selected by the player
+     */
+    private SIDE getSide(String message) {
+        int valueEntered = getNumberFromKeyboard(message);
+        for(SIDE side : SIDE.values()) {
+            if(side.getValue() == valueEntered) {
+                return side;
+            }
+        }
+
+        // Input out of range
+        return null;
+    }
+
+    /**
+     * Determine the target the player is going for.
+     * @param message displayed before the kb input
+     * @return the TARGET enum selected by the player
+     */
+    private TARGET getTarget(String message) {
+        int valueEntered = getNumberFromKeyboard(message);
+
+        for(TARGET target : TARGET.values()) {
+            if(target.getValue() == valueEntered) {
+                return target;
+            }
+        }
+
+        // Input out of range
+        return null;
+    }
+
+    /**
+     * Determine the airplane the player is going to fly.
+     * @param message displayed before the kb input
+     * @return the AIRCRAFT enum selected by the player
+     */
+    private AIRCRAFT getPlane(String message) {
+        int valueEntered = getNumberFromKeyboard(message);
+
+        for(AIRCRAFT plane : AIRCRAFT.values()) {
+            if(plane.getValue() == valueEntered) {
+                return plane;
+            }
+        }
+
+        // Input out of range
+        return null;
+
+    }
+
+    /**
+     * Select the type of enemy defences.
+     *
+     * @param message displayed before kb input
+     * @return the ENEMY_DEFENCES enum as selected by player
+     */
+    private ENEMY_DEFENCES getEnemyDefences(String message) {
+        int valueEntered = getNumberFromKeyboard(message);
+        for (ENEMY_DEFENCES enemyDefences : ENEMY_DEFENCES.values()) {
+            if(enemyDefences.getValue() == valueEntered) {
+                return enemyDefences;
+            }
+        }
+
+        // Input out of range
+        return null;
+    }
+
+    // output a specific message based on the target selected
+    private void displayTargetMessage(TARGET target) {
+
+        switch (target) {
+
+            case ALBANIA:
+                System.out.println("SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE.");
+                break;
+            case GREECE:
+                System.out.println("BE CAREFUL!!!");
+                break;
+            case NORTH_AFRICA:
+                System.out.println("YOU'RE GOING FOR THE OIL, EH?");
+                break;
+            case RUSSIA:
+                System.out.println("YOU'RE NEARING STALINGRAD.");
+                break;
+            case ENGLAND:
+                System.out.println("NEARING LONDON.  BE CAREFUL, THEY'VE GOT RADAR.");
+                break;
+            case FRANCE:
+                System.out.println("NEARING VERSAILLES.  DUCK SOUP.  THEY'RE NEARLY DEFENSELESS.");
+                break;
+        }
+    }
+
+    /**
+     * Accepts a string from the keyboard, and converts to an int
+     *
+     * @param message displayed text on screen before keyboard input
+     *
+     * @return the number entered by the player
+     */
+    private int getNumberFromKeyboard(String message) {
+
+        String answer = displayTextAndGetInput(message);
+        return Integer.parseInt(answer);
+    }
+
+    /**
+     * 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) {
+
+        // Cycle through the variable number of values and test each
+        for(String val:values) {
+            if(text.equalsIgnoreCase(val)) {
+                return true;
+            }
+        }
+
+        // no matches
+        return false;
+    }
+
+    /*
+     * 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();
+    }
+
+    /**
+     * Generate random number
+     * Used as a single digit of the computer player
+     *
+     * @return random number
+     */
+    private double randomNumber(int range) {
+        return (Math.random()
+                * (range));
+    }
+}
\ No newline at end of file
diff --git a/12 Bombs Away/java/src/BombsAwayGame.java b/12 Bombs Away/java/src/BombsAwayGame.java
new file mode 100644
index 00000000..cfa05cd7
--- /dev/null
+++ b/12 Bombs Away/java/src/BombsAwayGame.java	
@@ -0,0 +1,8 @@
+public class BombsAwayGame {
+
+    public static void main(String[] args) {
+
+        BombsAway bombsAway = new BombsAway();
+        bombsAway.play();
+    }
+}
diff --git a/12 Bombs Away/javascript/bombsaway.html b/12 Bombs Away/javascript/bombsaway.html
new file mode 100644
index 00000000..c58c753f
--- /dev/null
+++ b/12 Bombs Away/javascript/bombsaway.html	
@@ -0,0 +1,9 @@
+
+
+BOMBARDMENT
+
+
+

+
+
+
diff --git a/12 Bombs Away/javascript/bombsaway.js b/12 Bombs Away/javascript/bombsaway.js
new file mode 100644
index 00000000..835a2608
--- /dev/null
+++ b/12 Bombs Away/javascript/bombsaway.js	
@@ -0,0 +1,205 @@
+// BOMBS AWAY
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+// Main program
+async function main()
+{
+    while (1) {
+        print("YOU ARE A PILOT IN A WORLD WAR II BOMBER.\n");
+        while (1) {
+            print("WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4)");
+            a = parseInt(await input());
+            if (a < 1 || a > 4)
+                print("TRY AGAIN...\n");
+            else
+                break;
+        }
+        if (a == 1) {
+            while (1) {
+                print("YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3)");
+                b = parseInt(await input());
+                if (b < 1 || b > 3)
+                    print("TRY AGAIN...\n");
+                else
+                    break;
+            }
+            print("\n");
+            if (b == 1) {
+                print("SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE.\n");
+            } else if (b == 2) {
+                print("BE CAREFUL!!!\n");
+            } else {
+                print("YOU'RE GOING FOR THE OIL, EH?\n");
+            }
+        } else if (a == 2) {
+            while (1) {
+                print("AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4)");
+                g = parseInt(await input());
+                if (g < 1 || g > 4)
+                    print("TRY AGAIN...\n");
+                else
+                    break;
+            }
+            print("\n");
+            if (g == 1) {
+                print("YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI.\n");
+            } else if (g == 2) {
+                print("YOU'RE DUMPING THE A-BOMB ON HIROSHIMA.\n");
+            } else if (g == 3) {
+                print("YOU'RE CHASING THE BISMARK IN THE NORTH SEA.\n");
+            } else {
+                print("YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR.\n");
+            }
+        } else if (a == 3) {
+            print("YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.\n");
+            print("YOUR FIRST KAMIKAZE MISSION(Y OR N)");
+            str = await input();
+            if (str == "N") {
+                s = 0;
+            } else {
+                s = 1;
+                print("\n");
+            }
+        } else {
+            while (1) {
+                print("A NAZI, EH?  OH WELL.  ARE YOU GOING FOR RUSSIA(1),\n");
+                print("ENGLAND(2), OR FRANCE(3)");
+                m = parseInt(await input());
+                if (m < 1 || m > 3)
+                    print("TRY AGAIN...\n");
+                else
+                    break;
+            }
+            print("\n");
+            if (m == 1) {
+                print("YOU'RE NEARING STALINGRAD.\n");
+            } else if (m == 2) {
+                print("NEARING LONDON.  BE CAREFUL, THEY'VE GOT RADAR.\n");
+            } else if (m == 3) {
+                print("NEARING VERSAILLES.  DUCK SOUP.  THEY'RE NEARLY DEFENSELESS.\n");
+            }
+        }
+        if (a != 3) {
+            print("\n");
+            while (1) {
+                print("HOW MANY MISSIONS HAVE YOU FLOWN");
+                d = parseInt(await input());
+                if (d < 160)
+                    break;
+                print("MISSIONS, NOT MILES...\n");
+                print("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS.\n");
+                print("NOW THEN, ");
+            }
+            print("\n");
+            if (d >= 100) {
+                print("THAT'S PUSHING THE ODDS!\n");
+            } else if (d < 25) {
+                print("FRESH OUT OF TRAINING, EH?\n");
+            }
+            print("\n");
+            if (d >= 160 * Math.random())
+                hit = true;
+            else
+                hit = false;
+        } else {
+            if (s == 0) {
+                hit = false;
+            } else if (Math.random() > 0.65) {
+                hit = true;
+            } else {
+                hit = false;
+                s = 100;
+            }
+        }
+        if (hit) {
+            print("DIRECT HIT!!!! " + Math.floor(100 * Math.random()) + " KILLED.\n");
+            print("MISSION SUCCESSFUL.\n");
+        } else {
+            t = 0;
+            if (a != 3) {
+                print("MISSED TARGET BY " + Math.floor(2 + 30 * Math.random()) + " MILES!\n");
+                print("NOW YOU'RE REALLY IN FOR IT !!\n");
+                print("\n");
+                while (1) {
+                    print("DOES THE ENEMY HAVE GUNS(1), MISSILE(2), OR BOTH(3)");
+                    r = parseInt(await input());
+                    if (r < 1 || r > 3)
+                        print("TRY AGAIN...\n");
+                    else
+                        break;
+                }
+                print("\n");
+                if (r != 2) {
+                    print("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)");
+                    s = parseInt(await input());
+                    if (s < 10)
+                        print("YOU LIE, BUT YOU'LL PAY...\n");
+                    print("\n");
+                }
+                print("\n");
+                if (r > 1)
+                    t = 35;
+            }
+            if (s + t <= 100 * Math.random()) {
+                print("YOU MADE IT THROUGH TREMENDOUS FLAK!!\n");
+            } else {
+                print("* * * * BOOM * * * *\n");
+                print("YOU HAVE BEEN SHOT DOWN.....\n");
+                print("DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR\n");
+                print("LAST TRIBUTE...\n");
+            }
+        }
+        print("\n");
+        print("\n");
+        print("\n");
+        print("ANOTHER MISSION (Y OR N)");
+        str = await input();
+        if (str != "Y")
+            break;
+    }
+    print("CHICKEN !!!\n");
+    print("\n");
+}
+
+main();
diff --git a/13 Bounce/javascript/bounce.html b/13 Bounce/javascript/bounce.html
new file mode 100644
index 00000000..b1e8c529
--- /dev/null
+++ b/13 Bounce/javascript/bounce.html	
@@ -0,0 +1,9 @@
+
+
+BOUNCE
+
+
+

+
+
+
diff --git a/13 Bounce/javascript/bounce.js b/13 Bounce/javascript/bounce.js
new file mode 100644
index 00000000..d9cac590
--- /dev/null
+++ b/13 Bounce/javascript/bounce.js	
@@ -0,0 +1,112 @@
+// BOUNCE
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+// Main program
+async function main()
+{
+    print(tab(33) + "BOUNCE\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    ta = [];
+    print("THIS SIMULATION LETS YOU SPECIFY THE INITIAL VELOCITY\n");
+    print("OF A BALL THROWN STRAIGHT UP, AND THE COEFFICIENT OF\n");
+    print("ELASTICITY OF THE BALL.  PLEASE USE A DECIMAL FRACTION\n");
+    print("COEFFICIENCY (LESS THAN 1).\n");
+    print("\n");
+    print("YOU ALSO SPECIFY THE TIME INCREMENT TO BE USED IN\n");
+    print("'STROBING' THE BALL'S FLIGHT (TRY .1 INITIALLY).\n");
+    print("\n");
+    while (1) {
+        print("TIME INCREMENT (SEC)");
+        s2 = parseFloat(await input());
+        print("\n");
+        print("VELOCITY (FPS)");
+        v = parseFloat(await input());
+        print("\n");
+        print("COEFFICIENT");
+        c = parseFloat(await input());
+        print("\n");
+        print("FEET\n");
+        print("\n");
+        s1 = Math.floor(70 / (v / (16 * s2)));
+        for (i = 1; i <= s1; i++)
+            ta[i] = v * Math.pow(c, i - 1) / 16;
+        for (h = Math.floor(-16 * Math.pow(v / 32, 2) + Math.pow(v, 2) / 32 + 0.5); h >= 0; h -= 0.5) {
+            str = "";
+            if (Math.floor(h) == h)
+                str += " " + h + " ";
+            l = 0;
+            for (i = 1; i <= s1; i++) {
+                for (t = 0; t <= ta[i]; t += s2) {
+                    l += s2;
+                    if (Math.abs(h - (0.5 * (-32) * Math.pow(t, 2) + v * Math.pow(c, i - 1) * t)) <= 0.25) {
+                        while (str.length < l / s2)
+                            str += " ";
+                        str += "0";
+                    }
+                }
+                t = ta[i + 1] / 2;
+                if (-16 * Math.pow(t, 2) + v * Math.pow(c, i - 1) * t < h)
+                    break;
+            }
+            print(str + "\n");
+        }
+        str = " ";
+        for (i = 1; i < Math.floor(l + 1) / s2 + 1; i++)
+            str += ".";
+        print(str + "\n");
+        str = " 0";
+        for (i = 1; i < Math.floor(l + 0.9995); i++) {
+            while (str.length < Math.floor(i / s2))
+                str += " ";
+            str += i;
+        }
+        print(str + "\n");
+        print(tab(Math.floor(l + 1) / (2 * s2) - 2) + "SECONDS\n");
+    }
+}
+
+main();
diff --git a/16 Bug/java/src/Bug.java b/16 Bug/java/src/Bug.java
new file mode 100644
index 00000000..861afc5a
--- /dev/null
+++ b/16 Bug/java/src/Bug.java	
@@ -0,0 +1,253 @@
+import java.util.ArrayList;
+import java.util.Scanner;
+
+/**
+ * Game of Bug
+ * 

+ * Based on the Basic game of Bug here + * https://github.com/coding-horror/basic-computer-games/blob/main/16%20Bug/bug.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 Bug { + + // Dice roll + public static final int SIX = 6; + + private enum GAME_STATE { + START, + PLAYER_TURN, + COMPUTER_TURN, + CHECK_FOR_WINNER, + GAME_OVER + } + + // Used for keyboard input + private final Scanner kbScanner; + + // Current game state + private GAME_STATE gameState; + + + private final Insect playersBug; + + private final Insect computersBug; + + // Used to show the result of dice roll. + private final String[] ROLLS = new String[]{"BODY", "NECK", "HEAD", "FEELERS", "TAIL", "LEGS"}; + + public Bug() { + + playersBug = new PlayerBug(); + computersBug = new ComputerBug(); + + gameState = GAME_STATE.START; + + // 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. + // And optionally instructions. + case START: + intro(); + if (!noEntered(displayTextAndGetInput("DO YOU WANT INSTRUCTIONS? "))) { + instructions(); + } + + gameState = GAME_STATE.PLAYER_TURN; + break; + + case PLAYER_TURN: + int playersRoll = randomNumber(); + System.out.println("YOU ROLLED A " + playersRoll + "=" + ROLLS[playersRoll - 1]); + switch (playersRoll) { + case 1: + System.out.println(playersBug.addBody()); + break; + case 2: + System.out.println(playersBug.addNeck()); + break; + case 3: + System.out.println(playersBug.addHead()); + break; + case 4: + System.out.println(playersBug.addFeelers()); + break; + case 5: + System.out.println(playersBug.addTail()); + break; + case 6: + System.out.println(playersBug.addLeg()); + break; + } + + gameState = GAME_STATE.COMPUTER_TURN; + break; + + case COMPUTER_TURN: + int computersRoll = randomNumber(); + System.out.println("I ROLLED A " + computersRoll + "=" + ROLLS[computersRoll - 1]); + switch (computersRoll) { + case 1: + System.out.println(computersBug.addBody()); + break; + case 2: + System.out.println(computersBug.addNeck()); + break; + case 3: + System.out.println(computersBug.addHead()); + break; + case 4: + System.out.println(computersBug.addFeelers()); + break; + case 5: + System.out.println(computersBug.addTail()); + break; + case 6: + System.out.println(computersBug.addLeg()); + break; + } + + gameState = GAME_STATE.CHECK_FOR_WINNER; + break; + + case CHECK_FOR_WINNER: + boolean gameOver = false; + + if (playersBug.complete()) { + System.out.println("YOUR BUG IS FINISHED."); + gameOver = true; + } else if (computersBug.complete()) { + System.out.println("MY BUG IS FINISHED."); + gameOver = true; + } + + if (noEntered(displayTextAndGetInput("DO YOU WANT THE PICTURES? "))) { + gameState = GAME_STATE.PLAYER_TURN; + } else { + System.out.println("*****YOUR BUG*****"); + System.out.println(); + draw(playersBug); + + System.out.println(); + System.out.println("*****MY BUG*****"); + System.out.println(); + draw(computersBug); + gameState = GAME_STATE.PLAYER_TURN; + } + if (gameOver) { + System.out.println("I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!"); + gameState = GAME_STATE.GAME_OVER; + } + } + } while (gameState != GAME_STATE.GAME_OVER); + } + + /** + * Draw the bug (player or computer) based on what has + * already been added to it. + * + * @param bug The bug to be drawn. + */ + private void draw(Insect bug) { + ArrayList insectOutput = bug.draw(); + for (String s : insectOutput) { + System.out.println(s); + } + } + + /** + * Display an intro + */ + private void intro() { + System.out.println("BUG"); + System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println(); + System.out.println("THE GAME BUG"); + System.out.println("I HOPE YOU ENJOY THIS GAME."); + } + + private void instructions() { + System.out.println("THE OBJECT OF BUG IS TO FINISH YOUR BUG BEFORE I FINISH"); + System.out.println("MINE. EACH NUMBER STANDS FOR A PART OF THE BUG BODY."); + System.out.println("I WILL ROLL THE DIE FOR YOU, TELL YOU WHAT I ROLLED FOR YOU"); + System.out.println("WHAT THE NUMBER STANDS FOR, AND IF YOU CAN GET THE PART."); + System.out.println("IF YOU CAN GET THE PART I WILL GIVE IT TO YOU."); + System.out.println("THE SAME WILL HAPPEN ON MY TURN."); + System.out.println("IF THERE IS A CHANGE IN EITHER BUG I WILL GIVE YOU THE"); + System.out.println("OPTION OF SEEING THE PICTURES OF THE BUGS."); + System.out.println("THE NUMBERS STAND FOR PARTS AS FOLLOWS:"); + System.out.println("NUMBER\tPART\tNUMBER OF PART NEEDED"); + System.out.println("1\tBODY\t1"); + System.out.println("2\tNECK\t1"); + System.out.println("3\tHEAD\t1"); + System.out.println("4\tFEELERS\t2"); + System.out.println("5\tTAIL\t1"); + System.out.println("6\tLEGS\t6"); + System.out.println(); + + } + + /** + * Checks whether player entered N or NO to a question. + * + * @param text player string from kb + * @return true if N or NO was entered, otherwise false + */ + private boolean noEntered(String text) { + return stringIsAnyValue(text, "N", "NO"); + } + + /** + * 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) { + + // Cycle through the variable number of values and test each + for (String val : values) { + if (text.equalsIgnoreCase(val)) { + return true; + } + } + + // no matches + return false; + } + + /* + * 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(); + } + + /** + * Generate random number + * + * @return random number + */ + private int randomNumber() { + return (int) (Math.random() + * (SIX) + 1); + } +} \ No newline at end of file diff --git a/16 Bug/java/src/BugGame.java b/16 Bug/java/src/BugGame.java new file mode 100644 index 00000000..074ff45e --- /dev/null +++ b/16 Bug/java/src/BugGame.java @@ -0,0 +1,10 @@ + + +public class BugGame { + + public static void main(String[] args) { + + Bug bug = new Bug(); + bug.play(); + } +} diff --git a/16 Bug/java/src/ComputerBug.java b/16 Bug/java/src/ComputerBug.java new file mode 100644 index 00000000..fe232364 --- /dev/null +++ b/16 Bug/java/src/ComputerBug.java @@ -0,0 +1,15 @@ +public class ComputerBug extends Insect { + + // Create messages specific to the computer player. + + public ComputerBug() { + // Call superclass constructor for initialization. + super(); + addMessages(new String[]{"I GET A FEELER.", "I HAVE " + MAX_FEELERS + " FEELERS ALREADY.", "I DO NOT HAVE A HEAD."}, PARTS.FEELERS); + addMessages(new String[]{"I NEEDED A HEAD.", "I DO NOT NEED A HEAD.", "I DO NOT HAVE A NECK."}, PARTS.HEAD); + addMessages(new String[]{"I NOW HAVE A NECK.", "I DO NOT NEED A NECK.", "I DO NOT HAVE A BODY."}, PARTS.NECK); + addMessages(new String[]{"I NOW HAVE A BODY.", "I DO NOT NEED A BODY."}, PARTS.BODY); + addMessages(new String[]{"I NOW HAVE A TAIL.", "I DO NOT NEED A TAIL.", "I DO NOT HAVE A BODY."}, PARTS.TAIL); + addMessages(new String[]{"I NOW HAVE ^^^" + " LEG", "I HAVE " + MAX_LEGS + " FEET.", "I DO NOT HAVE A BODY."}, PARTS.LEGS); + } +} diff --git a/16 Bug/java/src/Insect.java b/16 Bug/java/src/Insect.java new file mode 100644 index 00000000..08e9414f --- /dev/null +++ b/16 Bug/java/src/Insect.java @@ -0,0 +1,363 @@ +import java.util.ArrayList; +import java.util.Arrays; + +/** + * This tracks the insect (bug) and has methods to + * add body parts, create an array of output so it + * can be drawn and to determine if a bug is complete. + * N.B. This is a super class for ComputerBug and PlayerBug + */ +public class Insect { + + public static final int MAX_FEELERS = 2; + public static final int MAX_LEGS = 6; + + public static final int ADDED = 0; + public static final int NOT_ADDED = 1; + public static final int MISSING = 2; + + // Various parts of the bug + public enum PARTS { + FEELERS, + HEAD, + NECK, + BODY, + TAIL, + LEGS + } + + // Tracks what parts of the bug have been added + private boolean body; + private boolean neck; + private boolean head; + private int feelers; + private boolean tail; + private int legs; + + // Messages about for various body parts + // These are set in the subclass ComputerBug or PlayerBug + private String[] bodyMessages; + private String[] neckMessages; + private String[] headMessages; + private String[] feelerMessages; + private String[] tailMessages; + private String[] legMessages; + + public Insect() { + init(); + } + + /** + * Add a body to the bug if there is not one already added. + * + * @return return an appropriate message about the status of the operation. + */ + public String addBody() { + + boolean currentState = false; + + if (!body) { + body = true; + currentState = true; + } + + return addBodyMessage(currentState); + } + + /** + * Create output based on adding the body or it being already added previously + * + * @return contains the output message + */ + + private String addBodyMessage(boolean wasAdded) { + + // Return the appropriate message depending on whether the + // body was added or not. + if (wasAdded) { + return bodyMessages[ADDED]; + } else { + return bodyMessages[NOT_ADDED]; + } + } + + /** + * Add a neck if a) a body has previously been added and + * b) a neck has not previously been added. + * + * @return text containing the status of the operation + */ + public String addNeck() { + + int status = NOT_ADDED; // Default is not added + + if (!body) { + // No body, cannot add a neck + status = MISSING; + } else if (!neck) { + neck = true; + status = ADDED; + } + + return neckMessages[status]; + } + + /** + * Add a head to the bug if a) there already exists a neck and + * b) a head has not previously been added + * + * @return text outlining the success of the operation + */ + public String addHead() { + + int status = NOT_ADDED; // Default is not added + + if (!neck) { + // No neck, cannot add a head + status = MISSING; + } else if (!head) { + head = true; + status = ADDED; + } + + return headMessages[status]; + } + + /** + * Add a feeler to the head if a) there has been a head added to + * the bug previously, and b) there are not already 2 (MAX_FEELERS) + * feelers previously added to the bug. + * + * @return text outlining the status of the operation + */ + public String addFeelers() { + + int status = NOT_ADDED; // Default is not added + + if (!head) { + // No head, cannot add a feeler + status = MISSING; + } else if (feelers < MAX_FEELERS) { + feelers++; + status = ADDED; + } + + return feelerMessages[status]; + } + + /** + * Add a tail to the bug if a) there is already a body previously added + * to the bug and b) there is not already a tail added. + * + * @return text outlining the status of the operation. + */ + public String addTail() { + + int status = NOT_ADDED; // Default is not added + + if (!body) { + // No body, cannot add a tail + status = MISSING; + } else if (!tail) { + tail = true; + status = ADDED; + } + + return tailMessages[status]; + } + + /** + * Add a leg to the bug if a) there is already a body previously added + * b) there are less than 6 (MAX_LEGS) previously added. + * + * @return text outlining status of the operation. + */ + public String addLeg() { + + int status = NOT_ADDED; // Default is not added + + if (!body) { + // No body, cannot add a leg + status = MISSING; + } else if (legs < MAX_LEGS) { + legs++; + status = ADDED; + } + + String message = ""; + + // Create a string showing the result of the operation + + switch(status) { + case ADDED: + // Replace # with number of legs + message = legMessages[status].replace("^^^", String.valueOf(legs)); + // Add text S. if >1 leg, or just . if one leg. + if (legs > 1) { + message += "S."; + } else { + message += "."; + } + break; + + case NOT_ADDED: + + // Deliberate fall through to next case as its the + // same code to be executed + case MISSING: + message = legMessages[status]; + break; + } + + return message; + } + + /** + * Initialise + */ + public void init() { + body = false; + neck = false; + head = false; + feelers = 0; + tail = false; + legs = 0; + } + + /** + * Add unique messages depending on type of player + * A subclass of this class calls this method + * e.g. See ComputerBug or PlayerBug classes + * + * @param messages an array of messages + * @param bodyPart the bodypart the messages relate to. + */ + public void addMessages(String[] messages, PARTS bodyPart) { + + switch (bodyPart) { + case FEELERS: + feelerMessages = messages; + break; + + case HEAD: + headMessages = messages; + break; + + case NECK: + neckMessages = messages; + break; + + case BODY: + bodyMessages = messages; + break; + + case TAIL: + tailMessages = messages; + break; + + case LEGS: + legMessages = messages; + break; + } + } + + /** + * Returns a string array containing + * the "bug" that can be output to console + * + * @return the bug ready to draw + */ + public ArrayList draw() { + ArrayList bug = new ArrayList<>(); + StringBuilder lineOutput; + + // Feelers + if (feelers > 0) { + for (int i = 0; i < 4; i++) { + lineOutput = new StringBuilder(addSpaces(10)); + for (int j = 0; j < feelers; j++) { + lineOutput.append("A "); + } + bug.add(lineOutput.toString()); + } + } + + if (head) { + lineOutput = new StringBuilder(addSpaces(8) + "HHHHHHH"); + bug.add(lineOutput.toString()); + lineOutput = new StringBuilder(addSpaces(8) + "H" + addSpaces(5) + "H"); + bug.add(lineOutput.toString()); + lineOutput = new StringBuilder(addSpaces(8) + "H O O H"); + bug.add(lineOutput.toString()); + lineOutput = new StringBuilder(addSpaces(8) + "H" + addSpaces(5) + "H"); + bug.add(lineOutput.toString()); + lineOutput = new StringBuilder(addSpaces(8) + "H" + addSpaces(2) + "V" + addSpaces(2) + "H"); + bug.add(lineOutput.toString()); + lineOutput = new StringBuilder(addSpaces(8) + "HHHHHHH"); + bug.add(lineOutput.toString()); + } + + if (neck) { + for (int i = 0; i < 2; i++) { + lineOutput = new StringBuilder(addSpaces(10) + "N N"); + bug.add(lineOutput.toString()); + } + } + + if (body) { + lineOutput = new StringBuilder(addSpaces(5) + "BBBBBBBBBBBB"); + bug.add(lineOutput.toString()); + for (int i = 0; i < 2; i++) { + lineOutput = new StringBuilder(addSpaces(5) + "B" + addSpaces(10) + "B"); + bug.add(lineOutput.toString()); + } + if (tail) { + lineOutput = new StringBuilder("TTTTTB" + addSpaces(10) + "B"); + bug.add(lineOutput.toString()); + } + lineOutput = new StringBuilder(addSpaces(5) + "BBBBBBBBBBBB"); + bug.add(lineOutput.toString()); + } + + if (legs > 0) { + for (int i = 0; i < 2; i++) { + lineOutput = new StringBuilder(addSpaces(5)); + for (int j = 0; j < legs; j++) { + lineOutput.append(" L"); + } + bug.add(lineOutput.toString()); + } + } + + return bug; + } + + /** + * Check if the bug is complete i.e. it has + * 2 (MAX_FEELERS) feelers, a head, a neck, a body + * a tail and 6 (MAX_FEET) feet. + * + * @return true if complete. + */ + public boolean complete() { + return (feelers == MAX_FEELERS) + && head + && neck + && body + && tail + && (legs == MAX_LEGS); + } + + /** + * Simulate tabs be creating a string of X spaces. + * + * @param number contains number of spaces needed. + * @return a String containing the spaces + */ + private String addSpaces(int number) { + char[] spaces = new char[number]; + Arrays.fill(spaces, ' '); + return new String(spaces); + + } +} \ No newline at end of file diff --git a/16 Bug/java/src/PlayerBug.java b/16 Bug/java/src/PlayerBug.java new file mode 100644 index 00000000..1a82e8b3 --- /dev/null +++ b/16 Bug/java/src/PlayerBug.java @@ -0,0 +1,18 @@ +public class PlayerBug extends Insect { + + // Create messages specific to the player. + + public PlayerBug() { + // Call superclass constructor for initialization. + super(); + addMessages(new String[]{"I NOW GIVE YOU A FEELER.", "YOU HAVE " + MAX_FEELERS + " FEELERS ALREADY.", "YOU DO NOT HAVE A HEAD."}, PARTS.FEELERS); + addMessages(new String[]{"YOU NEEDED A HEAD.", "YOU HAVE A HEAD.", "YOU DO NOT HAVE A NECK."}, PARTS.HEAD); + addMessages(new String[]{"YOU NOW HAVE A NECK.", "YOU DO NOT NEED A NECK.", "YOU DO NOT HAVE A BODY."}, PARTS.NECK); + addMessages(new String[]{"YOU NOW HAVE A BODY.", "YOU DO NOT NEED A BODY."}, PARTS.BODY); + addMessages(new String[]{"I NOW GIVE YOU A TAIL.", "YOU ALREADY HAVE A TAIL.", "YOU DO NOT HAVE A BODY."}, PARTS.TAIL); + addMessages(new String[]{"YOU NOW HAVE ^^^ LEG", "YOU HAVE " + MAX_LEGS + " FEET ALREADY.", "YOU DO NOT HAVE A BODY."}, PARTS.LEGS); + } + + +} + diff --git a/18 Bullseye/java/src/Bullseye.java b/18 Bullseye/java/src/Bullseye.java index 06090351..fda321ae 100644 --- a/18 Bullseye/java/src/Bullseye.java +++ b/18 Bullseye/java/src/Bullseye.java @@ -1,15 +1,26 @@ import java.util.ArrayList; import java.util.Scanner; +/** + * Game of Bullseye + *

+ * Based on the Basic game of Bullseye here + * https://github.com/coding-horror/basic-computer-games/blob/main/18%20Bullseye/bullseye.bas + *

+ * Note: The idea was to create a version of 1970's Basic game in Java, without introducing + * new features - no additional text, error checking, etc has been added. + */ public class Bullseye { + // Used for formatting output public static final int FIRST_IDENT = 10; public static final int SECOND_IDENT = 30; public static final int THIRD_INDENT = 30; - public static final double[] SHOT_ONE = new double[] { .65, .55, .5, .5}; - public static final double[] SHOT_TWO = new double[] { .99, .77, .43,.01}; - public static final double[] SHOT_THREE = new double[] { .95, .75, .45, .05 }; + // Used to decide throw result + public static final double[] SHOT_ONE = new double[]{.65, .55, .5, .5}; + public static final double[] SHOT_TWO = new double[]{.99, .77, .43, .01}; + public static final double[] SHOT_THREE = new double[]{.95, .75, .45, .05}; private enum GAME_STATE { STARTING, @@ -20,14 +31,12 @@ public class Bullseye { private GAME_STATE gameState; - private ArrayList players; + private final ArrayList players; - private Shot[] shots; + private final Shot[] shots; // Used for keyboard input - private Scanner kbScanner; - - private int numberOfPlayers; + private final Scanner kbScanner; private int round; @@ -49,7 +58,6 @@ public class Bullseye { /** * Main game loop - * */ public void play() { @@ -65,10 +73,10 @@ public class Bullseye { // Start the game, set the number of players, names and round case START_GAME: - this.numberOfPlayers = chooseNumberOfPlayers(); + int numberOfPlayers = chooseNumberOfPlayers(); - for(int i=0; i=200) { - if(!foundWinner) { + if (score >= 200) { + if (!foundWinner) { System.out.println("WE HAVE A WINNER!!"); System.out.println(); foundWinner = true; @@ -110,7 +116,7 @@ public class Bullseye { } } - if(foundWinner) { + if (foundWinner) { System.out.println("THANKS FOR THE GAME."); gameState = GAME_STATE.GAME_OVER; } else { @@ -120,12 +126,11 @@ public class Bullseye { break; } - } while(gameState != GAME_STATE.GAME_OVER); + } while (gameState != GAME_STATE.GAME_OVER); } /** * Display info about the game - * */ private void intro() { System.out.println("BULLSEYE"); @@ -136,7 +141,7 @@ public class Bullseye { System.out.println("TO GET 200 POINTS."); System.out.println(); System.out.println(paddedString("THROW", "DESCRIPTION", "PROBABLE SCORE")); - System.out.println(paddedString("1", "FAST OVERARM","BULLSEYE OR COMPLETE MISS")); + System.out.println(paddedString("1", "FAST OVERARM", "BULLSEYE OR COMPLETE MISS")); System.out.println(paddedString("2", "CONTROLLED OVERARM", "10, 20 OR 30 POINTS")); System.out.println(paddedString("3", "UNDERARM", "ANYTHING")); } @@ -151,16 +156,16 @@ public class Bullseye { private int calculatePlayerPoints(int playerThrow) { // -1 is because of 0 base Java array - double p1 = this.shots[playerThrow-1].getShot(0); - double p2 = this.shots[playerThrow-1].getShot(1); - double p3 = this.shots[playerThrow-1].getShot(2); - double p4 = this.shots[playerThrow-1].getShot(3); + double p1 = this.shots[playerThrow - 1].getShot(0); + double p2 = this.shots[playerThrow - 1].getShot(1); + double p3 = this.shots[playerThrow - 1].getShot(2); + double p4 = this.shots[playerThrow - 1].getShot(3); double random = Math.random(); int points; - if(random >= p1) { + if (random >= p1) { System.out.println("BULLSEYE!! 40 POINTS!"); points = 40; // If the throw was 1 (bullseye or missed, then make it missed @@ -170,13 +175,13 @@ public class Bullseye { } else if (playerThrow == 1) { System.out.println("MISSED THE TARGET! TOO BAD."); points = 0; - } else if(random >= p2) { + } else if (random >= p2) { System.out.println("30-POINT ZONE!"); points = 30; - } else if(random >= p3) { + } else if (random >= p3) { System.out.println("20-POINT ZONE"); points = 20; - } else if(random >= p4) { + } else if (random >= p4) { System.out.println("WHEW! 10 POINTS."); points = 10; } else { @@ -190,23 +195,23 @@ public class Bullseye { /** * Get players shot 1,2, or 3 - ask again if invalid input * - * @param player - * @return 1,2, or 3 indicating the players shot + * @param player the player we are calculating the throw on + * @return 1, 2, or 3 indicating the players shot */ private int getPlayersThrow(Player player) { boolean inputCorrect = false; String theThrow; do { theThrow = displayTextAndGetInput(player.getName() + "'S THROW "); - if(theThrow.equals("1") || theThrow.equals("2") || theThrow.equals("3")) { + if (theThrow.equals("1") || theThrow.equals("2") || theThrow.equals("3")) { inputCorrect = true; } else { System.out.println("INPUT 1, 2, OR 3!"); } - } while(!inputCorrect); + } while (!inputCorrect); - return Integer.valueOf(theThrow); + return Integer.parseInt(theThrow); } @@ -217,8 +222,9 @@ public class Bullseye { */ private int chooseNumberOfPlayers() { - return Integer.valueOf((displayTextAndGetInput("HOW MANY PLAYERS? "))); + return Integer.parseInt((displayTextAndGetInput("HOW MANY PLAYERS? "))); } + /* * Print a message on the screen, then accept input from Keyboard. * @@ -234,9 +240,9 @@ public class Bullseye { * Format three strings to a given number of spaces * Replacing the original basic code which used tabs * - * @param first String to print in pos 1 + * @param first String to print in pos 1 * @param second String to print in pos 2 - * @param third String to print in pos 3 + * @param third String to print in pos 3 * @return formatted string */ private String paddedString(String first, String second, String third) { diff --git a/18 Bullseye/java/src/Player.java b/18 Bullseye/java/src/Player.java index b67b9309..1a30935a 100644 --- a/18 Bullseye/java/src/Player.java +++ b/18 Bullseye/java/src/Player.java @@ -4,7 +4,8 @@ */ public class Player { - private String name; + private final String name; + private int score; Player(String name) { diff --git a/18 Bullseye/java/src/Shot.java b/18 Bullseye/java/src/Shot.java index 01d8b283..43fa84e4 100644 --- a/18 Bullseye/java/src/Shot.java +++ b/18 Bullseye/java/src/Shot.java @@ -10,9 +10,7 @@ public class Shot { // Array of doubles are passed for a specific type of shot Shot(double[] shots) { chances = new double[shots.length]; - for(int i=0; i 128: + break + + # If we've reached this portion of the code, 'command' indicates the 'start' + # position of a line segment. + start = command + # Position cursor at start + print(tab(start), end="") + + # The following number, indicates the end of the segment. + end = next(data) + # Unlike FOR I=X TO Y, the 'stop' argument of 'range' is non-inclusive, so we must add 1 + for i in range(start, end+1, 1): + # Cycle through the letters in "BUNNY" as we draw line + j = i - 5 * int(i / 5) + print(chr(L + bunny[j]), end="") + + +if __name__ == "__main__": + play() diff --git a/20 Buzzword/java/src/Buzzword.java b/20 Buzzword/java/src/Buzzword.java new file mode 100755 index 00000000..82ed9100 --- /dev/null +++ b/20 Buzzword/java/src/Buzzword.java @@ -0,0 +1,41 @@ +import java.util.Scanner; +import static java.lang.System.out; + +// This is very close to the original BASIC. Changes: +// 1) the array indexing is adjusted by 1 +// 2) the user can enter a lower case "y" +// 3) moved the word list to the top 8~) +public class Buzzword { + private static final String[] A = { + "ABILITY","BASAL","BEHAVIORAL","CHILD-CENTERED", + "DIFFERENTIATED","DISCOVERY","FLEXIBLE","HETEROGENEOUS", + "HOMOGENEOUS","MANIPULATIVE","MODULAR","TAVISTOCK", + "INDIVIDUALIZED","LEARNING","EVALUATIVE","OBJECTIVE", + "COGNITIVE","ENRICHMENT","SCHEDULING","HUMANISTIC", + "INTEGRATED","NON-GRADED","TRAINING","VERTICAL AGE", + "MOTIVATIONAL","CREATIVE","GROUPING","MODIFICATION", + "ACCOUNTABILITY","PROCESS","CORE CURRICULUM","ALGORITHM", + "PERFORMANCE","REINFORCEMENT","OPEN CLASSROOM","RESOURCE", + "STRUCTURE","FACILITY","ENVIRONMENT" + }; + private static Scanner scanner = new Scanner( System.in ); + + public static void main( final String [] args ) { + out.println( " BUZZWORD GENERATOR" ); + out.println( " CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" ); + out.println();out.println();out.println(); + out.println( "THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN" ); + out.println( "'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS" ); + out.println( "AND SPEECHES. WHENEVER A QUESTION MARK IS PRINTED," ); + out.println( "TYPE A 'Y' FOR ANOTHER PHRASE OR 'N' TO QUIT." ); + out.println();out.println();out.println( "HERE'S THE FIRST PHRASE:" ); + do { + out.print( A[ (int)( 13 * Math.random() ) ] + " " ); + out.print( A[ (int)( 13 * Math.random() + 13 ) ] + " " ); + out.print( A[ (int)( 13 * Math.random() + 26 ) ] ); out.println(); + out.print( "?" ); + } + while ( "Y".equals( scanner.nextLine().toUpperCase() ) ); + out.println( "COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!" ); + } +} diff --git a/22 Change/java/src/Change.java b/22 Change/java/src/Change.java new file mode 100644 index 00000000..38177245 --- /dev/null +++ b/22 Change/java/src/Change.java @@ -0,0 +1,187 @@ +import java.util.Arrays; +import java.util.Scanner; + +/** + * Game of Change + *

+ * 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/25 Chief/java/src/Chief.java b/25 Chief/java/src/Chief.java index d7fbbc08..1db2eb6c 100644 --- a/25 Chief/java/src/Chief.java +++ b/25 Chief/java/src/Chief.java @@ -1,6 +1,15 @@ import java.util.Arrays; import java.util.Scanner; +/** + * Game of Chief + *

+ * Based on the Basic game of Hurkle here + * https://github.com/coding-horror/basic-computer-games/blob/main/25%20Chief/chief.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 Chief { private enum GAME_STATE { @@ -14,6 +23,7 @@ public class Chief { private GAME_STATE gameState; + // The number the computer determines to be the players starting number private double calculatedNumber; // Used for keyboard input @@ -43,7 +53,7 @@ public class Chief { // show an message to start case READY_TO_START: - if(!yesEntered(displayTextAndGetInput("ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR? "))) { + if (!yesEntered(displayTextAndGetInput("ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR? "))) { System.out.println("SHUT UP, PALE FACE WITH WISE TONGUE."); } @@ -57,17 +67,17 @@ public class Chief { displayTextAndGetInput(" WHAT DO YOU HAVE? ")); // Exact same formula used in the original game to calculate the players original number - this.calculatedNumber = (playerNumber +1-5)*5/8*5-3; + calculatedNumber = (playerNumber + 1 - 5) * 5 / 8 * 5 - 3; - this.gameState = GAME_STATE.CALCULATE_AND_SHOW; + gameState = GAME_STATE.CALCULATE_AND_SHOW; break; // Enter the number to be used to calculate case CALCULATE_AND_SHOW: - if(yesEntered( - displayTextAndGetInput("I BET YOUR NUMBER WAS " + this.calculatedNumber - + ". AM I RIGHT? "))) { - this.gameState = GAME_STATE.END_GAME; + if (yesEntered( + displayTextAndGetInput("I BET YOUR NUMBER WAS " + calculatedNumber + + ". AM I RIGHT? "))) { + gameState = GAME_STATE.END_GAME; } else { // Player did not agree, so show the breakdown @@ -76,27 +86,27 @@ public class Chief { double f = number + 3; double g = f / 5; double h = g * 8; - double i = h/5 + 5; - double j = i -1; + double i = h / 5 + 5; + double j = i - 1; System.out.println("SO YOU THINK YOU'RE SO SMART, EH?"); System.out.println("NOW WATCH."); - System.out.println(number +" PLUS 3 EQUALS " + f + ". THIS DIVIDED BY 5 EQUALS " + g); - System.out.println("THIS TIMES 8 EQUALS " + h + ". IF WE DIVIDE BY 5 AND ADD 5,"); + System.out.println(number + " PLUS 3 EQUALS " + f + ". DIVIDED BY 5 EQUALS " + g); + System.out.println("TIMES 8 EQUALS " + h + ". IF WE DIVIDE BY 5 AND ADD 5,"); System.out.println("WE GET " + i + ", WHICH, MINUS 1, EQUALS " + j + "."); - if(yesEntered(displayTextAndGetInput("NOW DO YOU BELIEVE ME? "))) { - this.gameState = GAME_STATE.END_GAME; + if (yesEntered(displayTextAndGetInput("NOW DO YOU BELIEVE ME? "))) { + gameState = GAME_STATE.END_GAME; } else { // Time for a lightning bolt. System.out.println("YOU HAVE MADE ME MAD!!!"); System.out.println("THERE MUST BE A GREAT LIGHTNING BOLT!"); System.out.println(); - for(int x=30; x>=22; x--) { + for (int x = 30; x >= 22; x--) { System.out.println(tabbedSpaces(x) + "X X"); } System.out.println(tabbedSpaces(21) + "X XXX"); System.out.println(tabbedSpaces(20) + "X X"); System.out.println(tabbedSpaces(19) + "XX X"); - for(int y=20; y>=13; y--) { + for (int y = 20; y >= 13; y--) { System.out.println(tabbedSpaces(y) + "X X"); } System.out.println(tabbedSpaces(12) + "XX"); @@ -106,7 +116,7 @@ public class Chief { System.out.println("#########################"); System.out.println(); System.out.println("I HOPE YOU BELIEVE ME NOW, FOR YOUR SAKE!!"); - this.gameState = GAME_STATE.GAME_OVER; + gameState = GAME_STATE.GAME_OVER; } } @@ -115,7 +125,7 @@ public class Chief { // Sign off message for cases where the Chief is not upset case END_GAME: System.out.println("BYE!!!"); - this.gameState = GAME_STATE.GAME_OVER; + gameState = GAME_STATE.GAME_OVER; break; // GAME_OVER State does not specifically have a case @@ -134,14 +144,14 @@ public class Chief { Arrays.fill(repeat, ' '); return new String(repeat); } + private void instructions() { - System.out.println(" TAKE A NUMBER AND ADD 3. DIVIDE THIS NUMBER BY 5 AND"); + System.out.println(" TAKE A NUMBER AND ADD 3. DIVIDE NUMBER BY 5 AND"); System.out.println("MULTIPLY BY 8. DIVIDE BY 5 AND ADD THE SAME. SUBTRACT 1."); } /** * Basic information about the game - * */ private void intro() { System.out.println("CHIEF"); @@ -165,15 +175,15 @@ public class Chief { * Returns true if a given string contains at least one of the varargs (2nd parameter). * Note: Case insensitive comparison. * - * @param text string to search + * @param text string to search * @param values varargs of type string containing values to compare * @return true if one of the varargs arguments was found in text */ private boolean stringIsAnyValue(String text, String... values) { // Cycle through the variable number of values and test each - for(String val:values) { - if(text.equalsIgnoreCase(val)) { + for (String val : values) { + if (text.equalsIgnoreCase(val)) { return true; } } 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 @@ + + +CHOMP + + +


+
+
+
diff --git a/26 Chomp/javascript/chomp.js b/26 Chomp/javascript/chomp.js
new file mode 100644
index 00000000..652023e6
--- /dev/null
+++ b/26 Chomp/javascript/chomp.js	
@@ -0,0 +1,175 @@
+// CHOMP
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+var a = [];
+var r;
+var c;
+
+function init_board()
+{
+    for (i = 1; i <= r; i++)
+        for (j = 1; j <= c; j++)
+            a[i][j] = 1;
+    a[1][1] = -1;
+}
+
+function show_board()
+{
+    print("\n");
+    print(tab(7) + "1 2 3 4 5 6 7 8 9\n");
+    for (i = 1; i <= r; i++) {
+        str = i + tab(6);
+        for (j = 1; j <= c; j++) {
+            if (a[i][j] == -1)
+                str += "P ";
+            else if (a[i][j] == 0)
+                break;
+            else
+                str += "* ";
+        }
+        print(str + "\n");
+    }
+    print("\n");
+}
+
+// Main program
+async function main()
+{
+    print(tab(33) + "CHOMP\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    for (i = 1; i <= 10; i++)
+        a[i] = [];
+    // *** THE GAME OF CHOMP *** COPYRIGHT PCC 1973 ***
+    print("\n");
+    print("THIS IS THE GAME OF CHOMP (SCIENTIFIC AMERICAN, JAN 1973)\n");
+    print("DO YOU WANT THE RULES (1=YES, 0=NO!)");
+    r = parseInt(await input());
+    if (r != 0) {
+        f = 1;
+        r = 5;
+        c = 7;
+        print("CHOMP IS FOR 1 OR MORE PLAYERS (HUMANS ONLY).\n");
+        print("\n");
+        print("HERE'S HOW A BOARD LOOKS (THIS ONE IS 5 BY 7):\n");
+        init_board();
+        show_board();
+        print("\n");
+        print("THE BOARD IS A BIG COOKIE - R ROWS HIGH AND C COLUMNS\n");
+        print("WIDE. YOU INPUT R AND C AT THE START. IN THE UPPER LEFT\n");
+        print("CORNER OF THE COOKIE IS A POISON SQUARE (P). THE ONE WHO\n");
+        print("CHOMPS THE POISON SQUARE LOSES. TO TAKE A CHOMP, TYPE THE\n");
+        print("ROW AND COLUMN OF ONE OF THE SQUARES ON THE COOKIE.\n");
+        print("ALL OF THE SQUARES BELOW AND TO THE RIGHT OF THAT SQUARE\n");
+        print("INCLUDING THAT SQUARE, TOO) DISAPPEAR -- CHOMP!!\n");
+        print("NO FAIR CHOMPING SQUARES THAT HAVE ALREADY BEEN CHOMPED,\n");
+        print("OR THAT ARE OUTSIDE THE ORIGINAL DIMENSIONS OF THE COOKIE.\n");
+        print("\n");
+    }
+    while (1) {
+        print("HERE WE GO...\n");
+        f = 0;
+        for (i = 1; i <= 10; i++) {
+            a[i] = [];
+            for (j = 1; j <= 10; j++) {
+                a[i][j] = 0;
+            }
+        }
+        print("\n");
+        print("HOW MANY PLAYERS");
+        p = parseInt(await input());
+        i1 = 0;
+        while (1) {
+            print("HOW MANY ROWS");
+            r = parseInt(await input());
+            if (r <= 9)
+                break;
+            print("TOO MANY ROWS (9 IS MAXIMUM). NOW ");
+        }
+        while (1) {
+            print("HOW MANY COLUMNS");
+            c = parseInt(await input());
+            if (c <= 9)
+                break;
+            print("TOO MANY COLUMNS (9 IS MAXIMUM). NOW ");
+        }
+        print("\n");
+        init_board();
+        while (1) {
+            // Print the board
+            show_board();
+            // Get chomps for each player in turn
+            i1++;
+            p1 = i1 - Math.floor(i1 / p) * p;
+            if (p1 == 0)
+                p1 = p;
+            while (1) {
+                print("PLAYER " + p1 + "\n");
+                print("COORDINATES OF CHOMP (ROW,COLUMN)");
+                str = await input();
+                r1 = parseInt(str);
+                c1 = parseInt(str.substr(str.indexOf(",") + 1));
+                if (r1 >= 1 && r1 <= r && c1 >= 1 && c1 <= c && a[r1][c1] != 0)
+                    break;
+                print("NO FAIR. YOU'RE TRYING TO CHOMP ON EMPTY SPACE!\n");
+            }
+            if (a[r1][c1] == -1)
+                break;
+            for (i = r1; i <= r; i++)
+                for (j = c1; j <= c; j++)
+                    a[i][j] = 0;
+        }
+        // End of game detected
+        print("YOU LOSE, PLAYER " + p1 + "\n");
+        print("\n");
+        print("AGAIN (1=YES, 0=NO!)");
+        r = parseInt(await input());
+        if (r != 1)
+            break;
+    }
+}
+
+main();
diff --git a/26 Chomp/python/chomp.py b/26 Chomp/python/chomp.py
new file mode 100755
index 00000000..56190a9e
--- /dev/null
+++ b/26 Chomp/python/chomp.py	
@@ -0,0 +1,132 @@
+#!/usr/bin/env python3
+# CHOMP
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+
+class Canvas:
+    """ For drawing the cookie """
+
+    def __init__(self, width=9, height=9, fill="*"):
+        self._buffer = []
+        for _ in range(height):
+            line = []
+            for _ in range(width):
+                line.append(fill)
+            self._buffer.append(line)
+        self._buffer[0][0] = "P"
+
+    def render(self):
+        lines = ["       1 2 3 4 5 6 7 8 9"]
+        row = 0
+        for line in self._buffer:
+            row += 1
+            lines.append(" " + str(row) + " " * 5 + " ".join(line))
+        return "\n".join(lines)
+
+    def chomp(self, r, c):
+        if not 1 <= r <= len(self._buffer) or not 1 <= c <= len(self._buffer[0]):
+            return "Empty"
+        elif self._buffer[r - 1][c - 1] == " ":
+            return "Empty"
+        elif self._buffer[r - 1][c - 1] == "P":
+            return "Poison"
+        else:
+            for row in range(r - 1, len(self._buffer)):
+                for column in range(c - 1, len(self._buffer[row])):
+                    self._buffer[row][column] = " "
+            return "Chomp"
+
+
+def play_game():
+    """Play one round of the game"""
+    players = 0
+    while players == 0:
+        try:
+            players = int(input("How many players "))
+
+        except ValueError:
+            print("Please enter a number.")
+    rows = 0
+    while rows == 0:
+        try:
+            rows = int(input("How many rows "))
+            if rows > 9 or rows < 1:
+                rows = 0
+                print("Too many rows (9 is maximum).")
+
+        except ValueError:
+            print("Please enter a number.")
+    columns = 0
+    while columns == 0:
+        try:
+            columns = int(input("How many columns "))
+            if columns > 9 or columns < 1:
+                columns = 0
+                print("Too many columns (9 is maximum).")
+
+        except ValueError:
+            print("Please enter a number.")
+    cookie = Canvas(width=columns, height=rows)
+    player = 0
+    alive = True
+    while alive:
+        print("")
+        print(cookie.render())
+        print("")
+        player += 1
+        if player > players:
+            player = 1
+        while True:
+            print("Player", player)
+            player_row = -1
+            player_column = -1
+            while player_row == -1 or player_column == -1:
+                try:
+                    coordinates = [int(item) for item in input(
+                        "Coordinates of chomp (Row, Column) ").split(",")]
+                    player_row = coordinates[0]
+                    player_column = coordinates[1]
+
+                except (ValueError, IndexError):
+                    print("Please enter valid coordinates.")
+            result = cookie.chomp(player_row, player_column)
+            if result == "Empty":
+                print("No fair. You're trying to chomp on empty space!")
+            elif result == "Poison":
+                print("\nYou lose player", player)
+                alive = False
+                break
+            else:
+                break
+
+
+def main():
+    print(" " * 33 + "CHOMP")
+    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
+    print("THIS IS THE GAME OF CHOMP (SCIENTIFIC AMERICAN, JAN 1973)")
+    if input("Do you want the rules (1=Yes, 0=No!) ") != "0":
+        print("Chomp is for 1 or more players (Humans only).\n")
+        print("Here's how a board looks (This one is 5 by 7):")
+        example = Canvas(width=7, height=5)
+        print(example.render())
+        print("\nThe board is a big cookie - R rows high and C columns")
+        print("wide. You input R and C at the start. In the upper left")
+        print("corner of the cookie is a poison square (P). The one who")
+        print("chomps the poison square loses. To take a chomp, type the")
+        print("row and column of one of the squares on the cookie.")
+        print("All of the squares below and to the right of that square")
+        print("(Including that square, too) disappear -- CHOMP!!")
+        print("No fair chomping squares that have already been chomped,")
+        print("or that are outside the original dimensions of the cookie.\n")
+        print("Here we go...")
+
+    keep_playing = True
+    while keep_playing:
+
+        play_game()
+        keep_playing = input("\nAgain (1=Yes, 0=No!) ") == "1"
+
+
+if __name__ == "__main__":
+    main()
diff --git a/30 Cube/python/cube.py b/30 Cube/python/cube.py
new file mode 100755
index 00000000..8bb540e0
--- /dev/null
+++ b/30 Cube/python/cube.py	
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+# CUBE
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+
+def mine_position():
+    mine = []
+    for _ in range(3):
+        mine.append(random.randint(1, 3))
+    return mine
+
+
+def play_game():
+    """Play one round of the game"""
+
+    money = 500
+    print("\nYou have", money, "dollars.")
+    while True:
+        mines = []
+        for _ in range(5):
+            mine = []
+            while True:
+                mine = mine_position()
+                if not(mine in mines or mine == [1, 1, 1] or mine == [3, 3, 3]):
+                    break
+            mines.append(mine)
+        wager = -1
+        while wager == -1:
+            try:
+                wager = int(input("\nHow much do you want to wager? "))
+                if not 0 <= wager <= money:
+                    wager = -1
+                    print("Tried to fool me; bet again")
+            except ValueError:
+                print("Please enter a number.")
+        prompt = "\nIt's your move: "
+        position = [1, 1, 1]
+        while True:
+            move = [-1, -1, -1]
+            while move == [-1, -1, -1]:
+                try:
+                    coordinates = [int(item)
+                                   for item in input(prompt).split(",")]
+                    if len(coordinates) == 3:
+                        move = coordinates
+                    else:
+                        raise ValueError
+                except (ValueError, IndexError):
+                    print("Please enter valid coordinates.")
+            if (abs(move[0]-position[0]) + abs(move[1]-position[1]) + abs(move[2]-position[2])) > 1:
+                print("\nIllegal move. You lose")
+                money = money - wager
+                break
+            elif not move[0] in [1, 2, 3] or not move[1] in [1, 2, 3] or not move[2] in [1, 2, 3]:
+                print("\nIllegal move. You lose")
+                money = money - wager
+                break
+            elif move == [3, 3, 3]:
+                print("\nCongratulations!")
+                money = money + wager
+                break
+            elif move in mines:
+                print("\n******BANG******")
+                print("You lose!")
+                money = money - wager
+                break
+            else:
+                position = move
+                prompt = "\nNext move: "
+        if money > 0:
+            print("\nYou now have", money, "dollars.")
+            if not input("Do you want to try again ").lower().startswith("y"):
+                break
+        else:
+            print("\nYou bust.")
+    print("\nTough luck")
+    print("\nGoodbye.")
+
+
+def main():
+    print(" " * 34 + "CUBE")
+    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
+    if input("Do you want to see the instructions ").lower().startswith("y"):
+        print("\nThis is a game in which you will be playing against the")
+        print("random decisions of the computer. The field of play is a")
+        print("cube of side 3. Any of the 27 locations can be designated")
+        print("by inputing three numbers such as 2,3,1. At the start,")
+        print("you are automatically at location 1,1,1. The object of")
+        print("the game is to get to location 3,3,3. One minor detail:")
+        print("the computer will pick, at random, 5 locations at which")
+        print("it will plant land mines. If you hit one of these locations")
+        print("you lose. One other detail: You may move only one space")
+        print("in one direction each move. For example: From 1,1,2 you")
+        print("may move to 2,1,2 or 1,1,3. You may not change")
+        print("two of the numbers on the same move. If you make an illegal")
+        print("move, you lose and the computer takes the money you may")
+        print("have bet on that round.\n")
+        print("When stating the amount of a wager, print only the number")
+        print("of dollars (example: 250) you are automatically started with")
+        print("500 dollars in your account.\n")
+        print("Good luck!")
+
+    keep_playing = True
+    while keep_playing:
+        play_game()
+        keep_playing = input(
+            "\nPlay again? (yes or no) ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/31 Depth Charge/javascript/depthcharge.html b/31 Depth Charge/javascript/depthcharge.html
new file mode 100644
index 00000000..7a1e3add
--- /dev/null
+++ b/31 Depth Charge/javascript/depthcharge.html	
@@ -0,0 +1,9 @@
+
+
+DEPTH CHARGE
+
+
+

+
+
+
diff --git a/31 Depth Charge/javascript/depthcharge.js b/31 Depth Charge/javascript/depthcharge.js
new file mode 100644
index 00000000..6b0a7813
--- /dev/null
+++ b/31 Depth Charge/javascript/depthcharge.js	
@@ -0,0 +1,112 @@
+// DEPTH CHARGE
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+// Main program
+async function main()
+{
+    print(tab(30) + "DEPTH CHARGE\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("DIMENSION OF THE SEARCH AREA");
+    g = Math.floor(await input());
+    n = Math.floor(Math.log(g) / Math.log(2)) + 1;
+    print("YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER\n");
+    print("AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE.  YOUR\n");
+    print("MISSION IS TO DESTROY IT.  YOU HAVE " + n + " SHOTS.\n");
+    print("SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A\n");
+    print("TRIO OF NUMBERS -- THE FIRST TWO ARE THE\n");
+    print("SURFACE COORDINATES; THE THIRD IS THE DEPTH.\n");
+    do {
+        print("\n");
+        print("GOOD LUCK !\n");
+        print("\n");
+        a = Math.floor(Math.random() * g);
+        b = Math.floor(Math.random() * g);
+        c = Math.floor(Math.random() * g);
+        for (d = 1; d <= n; d++) {
+            print("\n");
+            print("TRIAL #" + d + " ");
+            str = await input();
+            x = parseInt(str);
+            y = parseInt(str.substr(str.indexOf(",") + 1));
+            z = parseInt(str.substr(str.lastIndexOf(",") + 1));
+            if (Math.abs(x - a) + Math.abs(y - b) + Math.abs(z - c) == 0)
+                break;
+            if (y > b)
+                print("NORTH");
+            if (y < b)
+                print("SOUTH");
+            if (x > a)
+                print("EAST");
+            if (x < a)
+                print("WEST");
+            if (y != b || x != a)
+                print(" AND");
+            if (z > c)
+                print(" TOO LOW.\n");
+            if (z < c)
+                print(" TOO HIGH.\n");
+            if (z == c)
+                print(" DEPTH OK.\n");
+            print("\n");
+        }
+        if (d <= n) {
+            print("\n");
+            print("B O O M ! ! YOU FOUND IT IN " + d + " TRIES!\n");
+        } else {
+            print("\n");
+            print("YOU HAVE BEEN TORPEDOED!  ABANDON SHIP!\n");
+            print("THE SUBMARINE WAS AT " + a + "," + b + "," + c + "\n");
+        }
+        print("\n");
+        print("\n");
+        print("ANOTHER GAME (Y OR N)");
+        str = await input();
+    } while (str.substr(0, 1) == "Y") ;
+    print("OK.  HOPE YOU ENJOYED YOURSELF.\n");
+}
+
+main();
diff --git a/32 Diamond/javascript/diamond.html b/32 Diamond/javascript/diamond.html
new file mode 100644
index 00000000..9756b2ab
--- /dev/null
+++ b/32 Diamond/javascript/diamond.html	
@@ -0,0 +1,9 @@
+
+
+DIAMOND
+
+
+

+
+
+
diff --git a/32 Diamond/javascript/diamond.js b/32 Diamond/javascript/diamond.js
new file mode 100644
index 00000000..bb6f0fe9
--- /dev/null
+++ b/32 Diamond/javascript/diamond.js	
@@ -0,0 +1,94 @@
+// DIAMOND
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+// Main program
+async function main()
+{
+    print(tab(33) + "DIAMOND\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("FOR A PRETTY DIAMOND PATTERN,\n");
+    print("TYPE IN AN ODD NUMBER BETWEEN 5 AND 21");
+    r = parseInt(await input());
+    q = Math.floor(60 / r);
+    as = "CC"
+    x = 1;
+    y = r;
+    z = 2;
+    for (l = 1; l <= q; l++) {
+        for (n = x; z < 0 ? n >= y : n <= y; n += z) {
+            str = "";
+            while (str.length < (r - n) / 2)
+                str += " ";
+            for (m = 1; m <= q; m++) {
+                c = 1;
+                for (a = 1; a <= n; a++) {
+                    if (c > as.length)
+                        str += "!";
+                    else
+                        str += as[c++ - 1];
+                }
+                if (m == q)
+                    break;
+                while (str.length < r * m + (r - n) / 2)
+                    str += " ";
+            }
+            print(str + "\n");
+        }
+        if (x != 1) {
+            x = 1;
+            y = r;
+            z = 2;
+        } else {
+            x = r - 2;
+            y = 1;
+            z = -2;
+            l--;
+        }
+    }
+}
+
+main();
diff --git a/32 Diamond/ruby/diamond.rb b/32 Diamond/ruby/diamond.rb
new file mode 100644
index 00000000..251cee25
--- /dev/null
+++ b/32 Diamond/ruby/diamond.rb	
@@ -0,0 +1,45 @@
+def intro
+  print "                                 DIAMOND
+               CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
+
+
+
+FOR A PRETTY DIAMOND PATTERN,
+TYPE IN AN ODD NUMBER BETWEEN 5 AND 21? "
+end
+
+def get_facets
+  while true
+    number = gets.chomp
+    return number.to_i if /^\d+$/.match(number)
+    puts "!NUMBER EXPECTED - RETRY INPUT LINE"
+    print "? "
+  end
+end
+
+def get_diamond_lines(facets)
+  spacers = (facets - 1) / 2
+  lines = [' ' * spacers + 'C' + ' ' * spacers]
+  lines += (1...facets).step(2).to_a.map { |v|
+    spacers -= 1
+    ' ' * spacers + 'CC' + '!' * v + ' ' * spacers
+  }
+  lines + lines[0..-2].reverse
+end
+
+def draw_diamonds(lines)
+  repeat = 60 / lines[0].length
+  (0...repeat).each { lines.map { |l| l * repeat }.each { |l| puts l } }
+end
+
+def main
+  intro
+  facets = get_facets
+  puts
+  lines = get_diamond_lines(facets)
+  draw_diamonds(lines)
+end
+
+trap "SIGINT" do puts; exit 130 end
+
+main
\ No newline at end of file
diff --git a/33 Dice/java/src/Dice.java b/33 Dice/java/src/Dice.java
new file mode 100644
index 00000000..739b2084
--- /dev/null
+++ b/33 Dice/java/src/Dice.java	
@@ -0,0 +1,146 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of Dice
+ * 

+ * 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/33 Dice/javascript/dice.html b/33 Dice/javascript/dice.html new file mode 100644 index 00000000..420dbc5d --- /dev/null +++ b/33 Dice/javascript/dice.html @@ -0,0 +1,9 @@ + + +DICE + + +


+
+
+
diff --git a/33 Dice/javascript/dice.js b/33 Dice/javascript/dice.js
new file mode 100644
index 00000000..e33e538a
--- /dev/null
+++ b/33 Dice/javascript/dice.js	
@@ -0,0 +1,84 @@
+// DICE
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+// Main program
+async function main()
+{
+    print(tab(34) + "DICE\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    f = [];
+    // Danny Freidus
+    print("THIS PROGRAM SIMULATES THE ROLLING OF A\n");
+    print("PAIR OF DICE.\n");
+    print("YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO\n");
+    print("'ROLL' THE DICE.  WATCH OUT, VERY LARGE NUMBERS TAKE\n");
+    print("A LONG TIME.  IN PARTICULAR, NUMBERS OVER 5000.\n");
+    do {
+        for (q = 1; q <= 12; q++)
+            f[q] = 0;
+        print("\n");
+        print("HOW MANY ROLLS");
+        x = parseInt(await input());
+        for (s = 1; s <= x; s++) {
+            a = Math.floor(Math.random() * 6 + 1);
+            b = Math.floor(Math.random() * 6 + 1);
+            r = a + b;
+            f[r]++;
+        }
+        print("\n");
+        print("TOTAL SPOTS\tNUMBER OF TIMES\n");
+        for (v = 2; v <= 12; v++) {
+            print("\t" + v + "\t" + f[v] + "\n");
+        }
+        print("\n");
+        print("\n");
+        print("TRY AGAIN");
+        str = await input();
+    } while (str.substr(0, 1) == "Y") ;
+}
+
+main();
diff --git a/33 Dice/ruby/dice.rb b/33 Dice/ruby/dice.rb
new file mode 100644
index 00000000..58380928
--- /dev/null
+++ b/33 Dice/ruby/dice.rb	
@@ -0,0 +1,51 @@
+def intro
+  puts "                                  DICE
+               CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
+
+
+
+THIS PROGRAM SIMULATES THE ROLLING OF A
+PAIR OF DICE.
+YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO
+'ROLL' THE DICE.  WATCH OUT, VERY LARGE NUMBERS TAKE
+A LONG TIME.  IN PARTICULAR, NUMBERS OVER 5000.
+
+"
+end
+
+def get_rolls
+  while true
+    number = gets.chomp
+    return number.to_i if /^\d+$/.match(number)
+    puts "!NUMBER EXPECTED - RETRY INPUT LINE"
+    print "? "
+  end
+end
+
+def dice_roll = rand(6) + 1 # ruby 3, woot!
+
+def print_rolls(rolls)
+  values = Array.new(11, 0)
+  (1..rolls).each { values[dice_roll + dice_roll - 2] += 1 }
+  puts "\nTOTAL SPOTS   NUMBER OF TIMES"
+  (0..10).each { |k| puts " %-2d            %-2d" % [k + 2, values[k]] }
+end
+
+def main
+  intro
+  loop do
+    print "HOW MANY ROLLS? "
+    rolls = get_rolls
+
+    print_rolls(rolls)
+
+    print "\n\nTRY AGAIN? "
+    option = (gets || '').chomp.upcase
+    break unless option == 'YES'
+    puts
+  end
+end
+
+trap "SIGINT" do puts; exit 130 end
+
+main
\ No newline at end of file
diff --git a/38 Fur Trader/csharp/FurTrader.csproj b/38 Fur Trader/csharp/FurTrader.csproj
new file mode 100644
index 00000000..c73e0d16
--- /dev/null
+++ b/38 Fur Trader/csharp/FurTrader.csproj	
@@ -0,0 +1,8 @@
+
+
+  
+    Exe
+    netcoreapp3.1
+  
+
+
diff --git a/38 Fur Trader/csharp/FurTrader.sln b/38 Fur Trader/csharp/FurTrader.sln
new file mode 100644
index 00000000..54a1760c
--- /dev/null
+++ b/38 Fur Trader/csharp/FurTrader.sln	
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30804.86
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FurTrader", "FurTrader.csproj", "{1FB826B9-8794-4DB7-B676-B51F177B7B87}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{1FB826B9-8794-4DB7-B676-B51F177B7B87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1FB826B9-8794-4DB7-B676-B51F177B7B87}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1FB826B9-8794-4DB7-B676-B51F177B7B87}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1FB826B9-8794-4DB7-B676-B51F177B7B87}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {DDB24448-50EB-47C6-BDB9-465896A81779}
+	EndGlobalSection
+EndGlobal
diff --git a/38 Fur Trader/csharp/Game.cs b/38 Fur Trader/csharp/Game.cs
new file mode 100644
index 00000000..fc1aae25
--- /dev/null
+++ b/38 Fur Trader/csharp/Game.cs	
@@ -0,0 +1,506 @@
+using System;
+
+namespace FurTrader
+{
+    public class Game
+    {
+        /// 
+        /// random number generator; no seed to be faithful to original implementation
+        /// 
+        private Random Rnd { get; } = new Random();
+
+        /// 
+        /// Generate a price for pelts based off a factor and baseline value
+        /// 
+        /// Multiplier for the price
+        /// The baseline price
+        /// A randomised price for pelts
+        internal double RandomPriceGenerator(double factor, double baseline)
+        {
+            var price = (Convert.ToInt32((factor * Rnd.NextDouble() + baseline) * 100d) + 5) / 100d;
+            return price;
+        }
+
+        /// 
+        /// Main game loop function. This will play the game endlessly until the player chooses to quit or a GameOver event occurs
+        /// 
+        /// 
+        /// General structure followed from Adam Dawes (@AdamDawes575) implementation of Acey Ducey.");
+        /// 
+        internal void GameLoop()
+        {
+            // display instructions to the player
+            DisplayIntroText();
+
+            var state = new GameState();
+
+            // loop for each turn until the player decides not to continue (or has a Game Over event)
+            while ((!state.GameOver) && ContinueGame())
+            {
+                // clear display at start of each turn
+                Console.Clear();
+
+                // play the next turn; pass game state for details and updates from the turn
+                PlayTurn(state);
+            }
+
+            // end screen; show some statistics to the player
+            Console.Clear();
+            Console.WriteLine("Thanks for playing!");
+            Console.WriteLine("");
+            Console.WriteLine($"Total Expeditions: {state.ExpeditionCount}");
+            Console.WriteLine($"Final Amount:      {state.Savings.ToString("c")}");
+        }
+
+        /// 
+        /// Display instructions on how to play the game and wait for the player to press a key.
+        /// 
+        private void DisplayIntroText()
+        {
+            Console.ForegroundColor = ConsoleColor.Yellow;
+            Console.WriteLine("Fur Trader.");
+            Console.WriteLine("Creating Computing, Morristown, New Jersey.");
+            Console.WriteLine("");
+
+            Console.ForegroundColor = ConsoleColor.DarkGreen;
+            Console.WriteLine("Originally published in 1978 in the book 'Basic Computer Games' by David Ahl.");
+            Console.WriteLine("");
+
+            Console.ForegroundColor = ConsoleColor.Gray;
+            Console.WriteLine("You are the leader of a French fur trading expedition in 1776 leaving the Lake Ontario area to sell furs and get supplies for the next year.");
+            Console.WriteLine("");
+            Console.WriteLine("You have a choice of three forts at which you may trade. The cost of supplies and the amount you receive for your furs will depend on the fort that you choose.");
+            Console.WriteLine("");
+
+            Console.ForegroundColor = ConsoleColor.Yellow;
+            Console.WriteLine("Press any key start the game.");
+            Console.ReadKey(true);
+
+        }
+
+        /// 
+        /// Prompt the player to try again, and wait for them to press Y or N.
+        /// 
+        /// Returns true if the player wants to try again, false if they have finished playing.
+        private bool ContinueGame()
+        {
+            Console.WriteLine("");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.WriteLine("Do you wish to trade furs? ");
+            Console.Write("Answer (Y)es or (N)o ");
+            Console.ForegroundColor = ConsoleColor.Yellow;
+            Console.Write("> ");
+
+            char pressedKey;
+            // Keep looping until we get a recognised input
+            do
+            {
+                // Read a key, don't display it on screen
+                ConsoleKeyInfo key = Console.ReadKey(true);
+                // Convert to upper-case so we don't need to care about capitalisation
+                pressedKey = Char.ToUpper(key.KeyChar);
+                // Is this a key we recognise? If not, keep looping
+            } while (pressedKey != 'Y' && pressedKey != 'N');
+
+            // Display the result on the screen
+            Console.WriteLine(pressedKey);
+
+            // Return true if the player pressed 'Y', false for anything else.
+            return (pressedKey == 'Y');
+        }
+
+        /// 
+        /// Play a turn
+        /// 
+        /// The current game state
+        private void PlayTurn(GameState state)
+        {
+            state.UnasignedFurCount = 190;      /// start with 190 furs each turn
+            
+            // provide current status to user
+            Console.WriteLine(new string('_', 70));
+            Console.WriteLine("");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.WriteLine("");
+            Console.WriteLine($"You have {state.Savings.ToString("c")} savings and {state.UnasignedFurCount} furs to begin the expedition.");
+            Console.WriteLine("");
+            Console.WriteLine($"Your {state.UnasignedFurCount} furs are distributed among the following kinds of pelts: Mink, Beaver, Ermine, and Fox");
+            Console.WriteLine("");
+
+            // get input on number of pelts
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.Write("How many Mink pelts do you have? ");
+            state.MinkPelts = GetPelts(state.UnasignedFurCount);
+            state.UnasignedFurCount -= state.MinkPelts;
+            Console.WriteLine("");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");            
+            Console.Write("How many Beaver pelts do you have? ");
+            state.BeaverPelts = GetPelts(state.UnasignedFurCount);
+            state.UnasignedFurCount -= state.BeaverPelts;
+            Console.WriteLine("");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");
+            Console.Write("How many Ermine pelts do you have? ");
+            state.ErminePelts = GetPelts(state.UnasignedFurCount);
+            state.UnasignedFurCount -= state.ErminePelts;
+            Console.WriteLine("");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");
+            Console.Write("How many Fox pelts do you have? ");
+            state.FoxPelts = GetPelts(state.UnasignedFurCount);
+            state.UnasignedFurCount -= state.FoxPelts;            
+
+            // get input on which fort to trade with; user gets an opportunity to evaluate and re-select fort after selection until user confirms selection
+            do
+            {
+                Console.ForegroundColor = ConsoleColor.White;
+                Console.WriteLine("");
+                Console.WriteLine("Do you want to trade your furs at Fort 1, Fort 2, or Fort 3");
+                Console.WriteLine("Fort 1 is Fort Hochelaga (Montreal) and is under the protection of the French army.");
+                Console.WriteLine("Fort 2 is Fort Stadacona (Quebec) and is under the protection of the French army. However, you must make a portage and cross the Lachine rapids.");
+                Console.WriteLine("Fort 3 is Fort New York and is under Dutch control. You must cross through Iroquois land.");
+                Console.WriteLine("");
+                state.SelectedFort = GetSelectedFort();
+
+                DisplaySelectedFortInformation(state.SelectedFort);
+
+            } while (TradeAtAnotherFort());
+
+            // process the travel to the fort
+            ProcessExpeditionOutcome(state);
+
+            // display results of expedition (savings change) to the user
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.Write("You now have ");
+            Console.ForegroundColor = ConsoleColor.Yellow;
+            Console.Write($"{state.Savings.ToString("c")}");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.WriteLine(" including your previous savings.");
+
+            // update the turn count now that another turn has been played
+            state.ExpeditionCount += 1;
+        }
+
+        /// 
+        /// Method to show the expedition costs to the player with some standard formatting
+        /// 
+        /// The name of the fort traded with
+        /// The cost of the supplies at the fort
+        /// The travel expenses for the expedition
+        internal void DisplayCosts(string fortname, double supplies, double expenses)
+        {
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.Write($"Supplies at {fortname} cost".PadLeft(55));
+            Console.ForegroundColor = ConsoleColor.Red;
+            Console.WriteLine($"{supplies.ToString("c").PadLeft(10)}");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.Write($"Your travel expenses to {fortname} were".PadLeft(55));
+            Console.ForegroundColor = ConsoleColor.Red;
+            Console.WriteLine($"{expenses.ToString("c").PadLeft(10)}");
+            Console.ForegroundColor = ConsoleColor.White;
+        }
+
+        /// 
+        /// Process the results of the expedition
+        /// 
+        /// the game state
+        private void ProcessExpeditionOutcome(GameState state)
+        {
+            var beaverPrice = RandomPriceGenerator(0.25d, 1.00d);
+            var foxPrice =    RandomPriceGenerator(0.2d , 0.80d);
+            var erminePrice = RandomPriceGenerator(0.15d, 0.95d);
+            var minkPrice =   RandomPriceGenerator(0.2d , 0.70d);
+
+            var fortname = String.Empty;
+            var suppliesCost = 0.0d;
+            var travelExpenses = 0.0d;
+
+            // create a random value 1 to 10 for the different outcomes at each fort
+            var p = ((int)(10 * Rnd.NextDouble())) + 1;
+            Console.WriteLine("");
+
+            switch (state.SelectedFort)
+            {
+                case 1:     // outcome for expedition to Fort Hochelaga
+                    beaverPrice = RandomPriceGenerator(0.2d, 0.75d);
+                    foxPrice =    RandomPriceGenerator(0.2d, 0.80d);
+                    erminePrice = RandomPriceGenerator(0.2d, 0.65d);
+                    minkPrice =   RandomPriceGenerator(0.2d, 0.70d);
+                    fortname = "Fort Hochelaga";
+                    suppliesCost = 150.0d;
+                    travelExpenses = 10.0d;
+                    break;
+                case 2:     // outcome for expedition to Fort Stadacona
+                    beaverPrice = RandomPriceGenerator(0.2d , 0.90d);
+                    foxPrice =    RandomPriceGenerator(0.2d , 0.80d);
+                    erminePrice = RandomPriceGenerator(0.15d, 0.80d);
+                    minkPrice =   RandomPriceGenerator(0.3d , 0.85d);
+                    fortname = "Fort Stadacona";
+                    suppliesCost = 125.0d;
+                    travelExpenses = 15.0d;
+                    if (p <= 2)
+                    {
+                        state.BeaverPelts = 0;
+                        Console.WriteLine("Your beaver were to heavy to carry across the portage.");
+                        Console.WriteLine("You had to leave the pelts but found them stolen when you returned");
+                    }
+                    else if (p <= 6)
+                    {
+                        Console.WriteLine("You arrived safely at Fort Stadacona");
+                    }
+                    else if (p <= 8)
+                    {
+                        state.BeaverPelts = 0;
+                        state.FoxPelts = 0;
+                        state.ErminePelts = 0;
+                        state.MinkPelts = 0;
+                        Console.WriteLine("Your canoe upset in the Lachine Rapids.");
+                        Console.WriteLine("Your lost all your furs");
+                    }
+                    else if (p <= 10)
+                    {
+                        state.FoxPelts = 0;
+                        Console.WriteLine("Your fox pelts were not cured properly.");
+                        Console.WriteLine("No one will buy them.");
+                    }
+                    else
+                    {
+                        throw new Exception($"Unexpected Outcome p = {p}");
+                    }
+                    break;
+                case 3:     // outcome for expedition to Fort New York
+                    beaverPrice = RandomPriceGenerator(0.2d , 1.00d);
+                    foxPrice =    RandomPriceGenerator(0.25d, 1.10d);
+                    erminePrice = RandomPriceGenerator(0.2d , 0.95d);
+                    minkPrice =   RandomPriceGenerator(0.15d, 1.05d); 
+                    fortname = "Fort New York";
+                    suppliesCost = 80.0d;
+                    travelExpenses = 25.0d;
+                    if (p <= 2)
+                    {
+                        state.BeaverPelts = 0;
+                        state.FoxPelts = 0;
+                        state.ErminePelts = 0;
+                        state.MinkPelts = 0;
+                        suppliesCost = 0.0d;
+                        travelExpenses = 0.0d;
+                        Console.WriteLine("You were attacked by a party of Iroquois.");
+                        Console.WriteLine("All people in your trading group were killed.");
+                        Console.WriteLine("This ends the game (press any key).");
+                        Console.ReadKey(true);
+                        state.GameOver = true;
+                    }
+                    else if (p <= 6)
+                    {
+                        Console.WriteLine("You were lucky. You arrived safely at Fort New York.");
+                    }
+                    else if (p <= 8)
+                    {
+                        state.BeaverPelts = 0;
+                        state.FoxPelts = 0;
+                        state.ErminePelts = 0;
+                        state.MinkPelts = 0;
+                        Console.WriteLine("You narrowly escaped an Iroquois raiding party.");
+                        Console.WriteLine("However, you had to leave all your furs behind.");
+                    }
+                    else if (p <= 10)
+                    {
+                        beaverPrice = beaverPrice / 2;
+                        minkPrice = minkPrice / 2;
+                        Console.WriteLine("Your mink and beaver were damaged on your trip.");
+                        Console.WriteLine("You receive only half the current price for these furs.");
+                    }
+                    else
+                    {
+                        throw new Exception($"Unexpected Outcome p = {p}");
+                    }
+                    break;
+                default:
+                    break;
+            }
+
+            var beaverSale = state.BeaverPelts * beaverPrice;
+            var foxSale = state.FoxPelts * foxPrice;
+            var ermineSale = state.ErminePelts * erminePrice;
+            var minkSale = state.MinkPelts * minkPrice;
+            var profit = beaverSale + foxSale + ermineSale + minkSale - suppliesCost - travelExpenses;
+            state.Savings += profit;
+
+            Console.WriteLine("");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.Write($"Your {state.BeaverPelts.ToString().PadLeft(3, ' ')} beaver pelts sold @ {beaverPrice.ToString("c")} per pelt for a total");
+            Console.ForegroundColor = ConsoleColor.Green;
+            Console.WriteLine($"{beaverSale.ToString("c").PadLeft(10)}");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.Write($"Your {state.FoxPelts.ToString().PadLeft(3, ' ')} fox    pelts sold @ {foxPrice.ToString("c")} per pelt for a total");
+            Console.ForegroundColor = ConsoleColor.Green;
+            Console.WriteLine($"{foxSale.ToString("c").PadLeft(10)}");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.Write($"Your {state.ErminePelts.ToString().PadLeft(3, ' ')} ermine pelts sold @ {erminePrice.ToString("c")} per pelt for a total");
+            Console.ForegroundColor = ConsoleColor.Green;
+            Console.WriteLine($"{ermineSale.ToString("c").PadLeft(10)}");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.Write($"Your {state.MinkPelts.ToString().PadLeft(3, ' ')} mink   pelts sold @ {minkPrice.ToString("c")} per pelt for a total");
+            Console.ForegroundColor = ConsoleColor.Green;
+            Console.WriteLine($"{minkSale.ToString("c").PadLeft(10)}");
+            Console.WriteLine("");
+            DisplayCosts(fortname, suppliesCost, travelExpenses);
+            Console.WriteLine("");
+            Console.Write($"Profit / Loss".PadLeft(55));
+            Console.ForegroundColor = profit >= 0.0d ? ConsoleColor.Green : ConsoleColor.Red;
+            Console.WriteLine($"{profit.ToString("c").PadLeft(10)}");
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.WriteLine("");
+        }
+
+        private void DisplaySelectedFortInformation(int selectedFort)
+        {
+            Console.WriteLine("");
+            Console.ForegroundColor = ConsoleColor.White;
+
+            switch (selectedFort)
+            {
+                case 1:    // selected fort details for Fort Hochelaga
+                    Console.WriteLine("You have chosen the easiest route.");
+                    Console.WriteLine("However, the fort is far from any seaport.");
+                    Console.WriteLine("The value you receive for your furs will be low.");
+                    Console.WriteLine("The cost of supplies will be higher than at Forts Stadacona or New York");
+                    break;
+                case 2:    // selected fort details for Fort Stadacona
+                    Console.WriteLine("You have chosen a hard route.");
+                    Console.WriteLine("It is, in comparsion, harder than the route to Hochelaga but easier than the route to New York.");
+                    Console.WriteLine("You will receive an average value for your furs.");
+                    Console.WriteLine("The cost of your supplies will be average.");
+                    break;
+                case 3:    // selected fort details for Fort New York
+                    Console.WriteLine("You have chosen the most difficult route.");
+                    Console.WriteLine("At Fort New York you will receive the higest value for your furs.");
+                    Console.WriteLine("The cost of your supplies will be lower than at all the other forts.");
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        private bool TradeAtAnotherFort()
+        {
+            Console.ForegroundColor = ConsoleColor.White;
+            Console.WriteLine("");
+            Console.WriteLine("Do you want to trade at another fort?");
+            Console.Write("Answer (Y)es or (N)o ");
+            Console.ForegroundColor = ConsoleColor.Yellow;
+            Console.Write("> ");
+
+            char pressedKey;
+            // Keep looping until we get a recognised input
+            do
+            {
+                // Read a key, don't display it on screen
+                ConsoleKeyInfo key = Console.ReadKey(true);
+                // Convert to upper-case so we don't need to care about capitalisation
+                pressedKey = Char.ToUpper(key.KeyChar);
+                // Is this a key we recognise? If not, keep looping
+            } while (pressedKey != 'Y' && pressedKey != 'N');
+
+            // Display the result on the screen
+            Console.WriteLine(pressedKey);
+
+            // Return true if the player pressed 'Y', false for anything else.
+            return (pressedKey == 'Y');
+        }
+
+        /// 
+        /// Get an amount of pelts from the user
+        /// 
+        /// The total pelts available
+        /// Returns the amount the player selects
+        private int GetPelts(int furCount)
+        {
+            int peltCount;
+            
+            // loop until the user enters a valid value
+            do
+            {
+                Console.ForegroundColor = ConsoleColor.Yellow;
+                Console.Write("> ");
+                string input = Console.ReadLine();
+
+                // parse user information to check if it is a valid entry
+                if (!int.TryParse(input, out peltCount))
+                {
+                    // invalid entry; message back to user
+                    Console.ForegroundColor = ConsoleColor.Red;
+                    Console.WriteLine("Sorry, I didn't understand. Please enter the number of pelts.");
+                    
+                    // continue looping
+                    continue;
+                }
+
+                // check if plet amount is more than the available pelts
+                if (peltCount > furCount)
+                {
+                    // too many pelts selected
+                    Console.ForegroundColor = ConsoleColor.Red;
+                    Console.WriteLine($"You may not have that many furs. Do not try to cheat. I can add.");
+                    
+                    // continue looping
+                    continue;
+                }
+
+                // valid pelt amount entered
+                break;
+            } while (true);
+
+            // return pelt count to the user
+            return peltCount;
+        }
+
+        /// 
+        /// Prompt the user for their selected fort
+        /// 
+        /// returns the fort the user has selected
+        private int GetSelectedFort()
+        {
+            int selectedFort;
+
+            // loop until the user enters a valid value
+            do
+            {
+                Console.ForegroundColor = ConsoleColor.White;
+                Console.Write("Answer 1, 2, or 3 ");
+                Console.ForegroundColor = ConsoleColor.Yellow;
+                Console.Write("> ");
+                string input = Console.ReadLine();
+
+                // is the user entry valid
+                if (!int.TryParse(input, out selectedFort))
+                {
+                    // no, invalid data
+                    Console.ForegroundColor = ConsoleColor.Red;
+                    Console.WriteLine("Sorry, I didn't understand. Please answer 1, 2, or 3.");
+                    
+                    // continue looping
+                    continue;
+                }
+
+                // is the selected fort an option (one, two or three only)
+                if (selectedFort != 1 && selectedFort != 2 && selectedFort != 3)
+                {
+                    // no, invalid for selected
+                    Console.ForegroundColor = ConsoleColor.Red;
+                    Console.WriteLine($"Please answer 1, 2, or 3.");
+                    
+                    // continue looping
+                    continue;
+                }
+
+                // valid fort selected, stop looping
+                break;
+            } while (true);
+
+            // return the players selected fort
+            return selectedFort;
+        }
+    }
+}
diff --git a/38 Fur Trader/csharp/GameState.cs b/38 Fur Trader/csharp/GameState.cs
new file mode 100644
index 00000000..4e174040
--- /dev/null
+++ b/38 Fur Trader/csharp/GameState.cs	
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FurTrader
+{
+    internal class GameState
+    {
+        internal bool GameOver { get; set; }
+
+        internal double Savings { get; set; }        
+
+        internal int ExpeditionCount { get; set; }        
+
+        internal int UnasignedFurCount { get; set; }        
+
+        internal int[] Pelts { get; private set; }
+
+        internal int MinkPelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
+        internal int BeaverPelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
+        internal int ErminePelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
+        internal int FoxPelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
+
+        internal int SelectedFort { get; set; }
+
+        internal GameState()
+        {
+            this.Savings = 600;
+            this.ExpeditionCount = 0;
+            this.UnasignedFurCount = 190;
+            this.Pelts = new int[4];
+            this.SelectedFort = 0;
+        }
+
+        internal void StartTurn()
+        {
+            this.SelectedFort = 0;              // reset to a default value
+            this.UnasignedFurCount = 190;       // each turn starts with 190 furs
+            this.Pelts = new int[4];            // reset pelts on each turn
+        }
+    }
+}
diff --git a/38 Fur Trader/csharp/Program.cs b/38 Fur Trader/csharp/Program.cs
new file mode 100644
index 00000000..438d5c4c
--- /dev/null
+++ b/38 Fur Trader/csharp/Program.cs	
@@ -0,0 +1,20 @@
+using System;
+
+namespace FurTrader
+{
+    public class Program
+    {
+        /// 
+        /// This function will be called automatically when the application begins
+        /// 
+        /// 
+        public static void Main(string[] args)
+        {
+            // Create an instance of our main Game class
+            var game = new Game();
+
+            // Call its GameLoop function. This will play the game endlessly in a loop until the player chooses to quit.
+            game.GameLoop();
+        }
+    }
+}
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/41 Guess/javascript/guess.html b/41 Guess/javascript/guess.html new file mode 100644 index 00000000..22a1bee0 --- /dev/null +++ b/41 Guess/javascript/guess.html @@ -0,0 +1,9 @@ + + +GUESS + + +


+
+
+
diff --git a/41 Guess/javascript/guess.js b/41 Guess/javascript/guess.js
new file mode 100644
index 00000000..e313169c
--- /dev/null
+++ b/41 Guess/javascript/guess.js	
@@ -0,0 +1,104 @@
+// GUESS
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+function make_space()
+{
+    for (h = 1; h <= 5; h++)
+        print("\n");
+}
+
+// Main control section
+async function main()
+{
+    while (1) {
+        print(tab(33) + "GUESS\n");
+        print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+        print("\n");
+        print("\n");
+        print("\n");
+        print("THIS IS A NUMBER GUESSING GAME. I'LL THINK\n");
+        print("OF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT.\n");
+        print("THEN YOU HAVE TO GUESS WHAT IT IS.\n");
+        print("\n");
+        
+        print("WHAT LIMIT DO YOU WANT");
+        l = parseInt(await input());
+        print("\n");
+        l1 = Math.floor(Math.log(l) / Math.log(2)) + 1;
+        while (1) {
+            print("I'M THINKING OF A NUMBER BETWEEN 1 AND " + l + "\n");
+            g = 1;
+            print("NOW YOU TRY TO GUESS WHAT IT IS.\n");
+            m = Math.floor(l * Math.random() + 1);
+            while (1) {
+                n = parseInt(await input());
+                if (n <= 0) {
+                    make_space();
+                    break;
+                }
+                if (n == m) {
+                    print("THAT'S IT! YOU GOT IT IN " + g + " TRIES.\n");
+                    if (g == l1) {
+                        print("GOOD.\n");
+                    } else if (g < l1) {
+                        print("VERY GOOD.\n");
+                    } else {
+                        print("YOU SHOULD HAVE BEEN TO GET IT IN ONLY " + l1 + "\n");
+                    }
+                    make_space();
+                    break;
+                }
+                g++;
+                if (n > m)
+                    print("TOO HIGH. TRY A SMALLER ANSWER.\n");
+                else
+                    print("TOO LOW. TRY A BIGGER ANSWER.\n");
+            }
+            if (n <= 0)
+                break;
+        }
+    }
+}
+
+main();
diff --git a/42 Gunner/javascript/gunner.html b/42 Gunner/javascript/gunner.html
new file mode 100644
index 00000000..431c9064
--- /dev/null
+++ b/42 Gunner/javascript/gunner.html	
@@ -0,0 +1,9 @@
+
+
+GUNNER
+
+
+

+
+
+
diff --git a/42 Gunner/javascript/gunner.js b/42 Gunner/javascript/gunner.js
new file mode 100644
index 00000000..64a427a1
--- /dev/null
+++ b/42 Gunner/javascript/gunner.js	
@@ -0,0 +1,139 @@
+// GUNNER
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+print(tab(30) + "GUNNER\n");
+print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+print("\n");
+print("\n");
+print("\n");
+print("YOU ARE THE OFFICER-IN-CHARGE, GIVING ORDERS TO A GUN\n");
+print("CREW, TELLING THEM THE DEGREES OF ELEVATION YOU ESTIMATE\n");
+print("WILL PLACE A PROJECTILE ON TARGET.  A HIT WITHIN 100 YARDS\n");
+print("OF THE TARGET WILL DESTROY IT.\n");
+print("\n");
+
+// Main control section
+async function main()
+{
+    while (1) {
+        r = Math.floor(40000 * Math.random() + 20000);
+        print("MAXIMUM RANGE OF YOUR GUN IS " + r + " YARDS.\n");
+        z = 0;
+        print("\n");
+        s1 = 0;
+        while (1) {
+            t = Math.floor(r * (0.1 + 0.8 * Math.random()));
+            s = 0;
+            print("DISTANCE TO THE TARGET IS " + t + " YARDS.\n");
+            print("\n");
+            
+            while (1) {
+                print("\n");
+                print("ELEVATION");
+                b = parseFloat(await input());
+                if (b > 89) {
+                    print("MAXIMUM ELEVATION IS 89 DEGREES.\n");
+                    continue;
+                }
+                if (b < 1) {
+                    print("MINIMUM ELEVATION IS ONE DEGREE.\n");
+                    continue;
+                }
+                if (++s >= 6) {
+                    print("\n");
+                    print("BOOM !!!!   YOU HAVE JUST BEEN DESTROYED BY THE ENEMY.\n");
+                    print("\n");
+                    print("\n");
+                    print("\n");
+                    e = 0;
+                    break;
+                }
+                b2 = 2 * b / 57.3;
+                i = r * Math.sin(b2);
+                x = t - i;
+                e = Math.floor(x);
+                if (true) { //Math.abs(e) < 100) {
+                    e = 1;
+                    break;
+                }
+                if (e > 100) {
+                    print("SHORT OF TARGET BY " + Math.abs(e) + " YARDS.\n");
+                } else {
+                    print("OVER TARGET BY " + Math.abs(e) + " YARDS.\n");
+                }
+            }
+            if (e == 1) {
+                print("*** TARGET DESTROYED *** " + s + " ROUNDS OF AMMUNITION EXPENDED.\n");
+                s1 += s;
+                if (z == 4) {
+                    print("\n");
+                    print("\n");
+                    print("TOTAL ROUND EXPENDED WERE: " + s1 + "\n");
+                    break;
+                } else {
+                    z++;
+                    print("\n");
+                    print("THE FORWARD OBSERVER HAS SIGHTED MORE ENEMY ACTIVITY...\n");
+                }
+            } else {
+                s1 = 19;
+                break;
+            }
+        }
+        if (s1 > 18) {
+            print("BETTER GO BACK TO FORT SILL FOR REFRESHER TRAINING!\n");
+        } else {
+            print("NICE SHOOTING !!");
+        }
+        print("\n");
+        print("TRY AGAIN (Y OR N)");
+        str = await input();
+        if (str.substr(0, 1) != "Y")
+            break;
+    }
+    print("\n");
+    print("OK.  RETURN TO BASE CAMP.\n");
+}
+
+main();
diff --git a/43 Hammurabi/javascript/hammurabi.html b/43 Hammurabi/javascript/hammurabi.html
new file mode 100644
index 00000000..2facdcb4
--- /dev/null
+++ b/43 Hammurabi/javascript/hammurabi.html	
@@ -0,0 +1,9 @@
+
+
+HAMMURABI
+
+
+

+
+
+
diff --git a/43 Hammurabi/javascript/hammurabi.js b/43 Hammurabi/javascript/hammurabi.js
new file mode 100644
index 00000000..285753c7
--- /dev/null
+++ b/43 Hammurabi/javascript/hammurabi.js	
@@ -0,0 +1,253 @@
+// HAMMURABI
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+var a;
+var s;
+
+function exceeded_grain()
+{
+    print("HAMURABI: THINK AGAIN.  YOU HAVE ONLY\n");
+    print(s + " BUSHELS OF GRAIN.  NOW THEN,\n");
+    
+}
+
+function exceeded_acres()
+{
+    print("HAMURABI: THINK AGAIN.  YOU OWN ONLY " + a + " ACRES.  NOW THEN,\n");
+}
+
+// Main control section
+async function main()
+{
+    print(tab(32) + "HAMURABI\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA\n");
+    print("FOR A TEN-YEAR TERM OF OFFICE.\n");
+    print("\n");
+    
+    d1 = 0;
+    p1 = 0;
+    z = 0;
+    p = 95;
+    s = 2800;
+    h = 3000;
+    e = h - s;
+    y = 3;
+    a = h / y;
+    i = 5;
+    q = 1;
+    d = 0;
+    while (1) {
+        print("\n");
+        print("\n");
+        print("\n");
+        print("HAMURABI:  I BEG TO REPORT TO YOU,\n");
+        z++;
+        print("IN YEAR " + z + ", " + d + " PEOPLE STARVED, " + i + " CAME TO THE CITY,\n");
+        p += i;
+        if (q <= 0) {
+            p = Math.floor(p / 2);
+            print("A HORRIBLE PLAGUE STRUCK!  HALF THE PEOPLE DIED.\n");
+        }
+        print("POPULATION IS NOW " + p + "\n");
+        print("THE CITY NOW OWNS " + a + " ACRES.\n");
+        print("YOU HARVESTED " + y + " BUSHELS PER ACRE.\n");
+        print("THE RATS ATE " + e + " BUSHELS.\n");
+        print("YOU NOW HAVE " + s + " BUSHELS IN STORE.\n");
+        print("\n");
+        if (z == 11) {
+            q = 0;
+            break;
+        }
+        c = Math.floor(10 * Math.random());
+        y = c + 17;
+        print("LAND IS TRADING AT " + y + " BUSHELS PER ACRE.\n");
+        while (1) {
+            print("HOW MANY ACRES DO YOU WISH TO BUY");
+            q = parseInt(await input());
+            if (q < 0)
+                break;
+            if (y * q > s) {
+                exceeded_grain();
+            } else
+                break;
+        }
+        if (q < 0)
+            break;
+        if (q != 0) {
+            a += q;
+            s -= y * q;
+            c = 0;
+        } else {
+            while (1) {
+                print("HOW MANY ACRES DO YOU WISH TO SELL");
+                q = parseInt(await input());
+                if (q < 0)
+                    break;
+                if (q >= a) {
+                    exceeded_acres();
+                } else {
+                    break;
+                }
+            }
+            if (q < 0)
+                break;
+            a -= q;
+            s += y * q;
+            c = 0;
+        }
+        print("\n");
+        while (1) {
+            print("HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE");
+            q = parseInt(await input());
+            if (q < 0)
+                break;
+            if (q > s)  // Trying to use more grain than is in silos?
+                exceeded_grain();
+            else
+                break;
+        }
+        if (q < 0)
+            break;
+        s -= q;
+        c = 1;
+        print("\n");
+        while (1) {
+            print("HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED");
+            d = parseInt(await input());
+            if (d != 0) {
+                if (d < 0)
+                    break;
+                if (d > a) {    // Trying to plant more acres than you own?
+                    exceeded_acres();
+                } else {
+                    if (Math.floor(d / 2) > s)  // Enough grain for seed?
+                        exceeded_grain();
+                    else {
+                        if (d >= 10 * p) {
+                            print("BUT YOU HAVE ONLY " + p + " PEOPLE TO TEND THE FIELDS!  NOW THEN,\n");
+                        } else {
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        if (d < 0) {
+            q = -1;
+            break;
+        }
+        s -= Math.floor(d / 2);
+        c = Math.floor(Math.random() * 5) + 1;
+        // A bountiful harvest!
+        if (c % 2 == 0) {
+            // Rats are running wild!!
+            e = Math.floor(s / c);
+        }
+        s = s - e + h;
+        c = Math.floor(Math.random() * 5) + 1;
+        // Let's have some babies
+        i = Math.floor(c * (20 * a + s) / p / 100 + 1);
+        // How many people had full tummies?
+        c = Math.floor(q / 20);
+        // Horros, a 15% chance of plague
+        q = Math.floor(10 * (2 * Math.random() - 0.3));
+        if (p < c) {
+            d = 0;
+            continue;
+        }
+        // Starve enough for impeachment?
+        d = p - c;
+        if (d <= 0.45 * p) {
+            p1 = ((z - 1) * p1 + d * 100 / p) / z;
+            p = c;
+            d1 += d;
+            continue;
+        }
+        print("\n");
+        print("YOU STARVED " + d + " PEOPLE IN ONE YEAR!!!\n");
+        q = 0;
+        p1 = 34;
+        p = 1;
+        break;
+    }
+    if (q < 0) {
+        print("\n");
+        print("HAMURABI:  I CANNOT DO WHAT YOU WISH.\n");
+        print("GET YOURSELF ANOTHER STEWARD!!!!!\n");
+    } else {
+        print("IN YOUR 10-YEAR TERM OF OFFICE, " + p1 + " PERCENT OF THE\n");
+        print("POPULATION STARVED PER YEAR ON THE AVERAGE, I.E. A TOTAL OF\n");
+        print(d1 + " PEOPLE DIED!!\n");
+        l = a / p;
+        print("YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH\n");
+        print(l + " ACRES PER PERSON.\n");
+        print("\n");
+        if (p1 > 33 || l < 7) {
+            print("DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY\n");
+            print("BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE\n");
+            print("ALSO BEEN DECLARED NATIONAL FINK!!!!\n");
+        } else if (p1 > 10 || l < 9) {
+            print("YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.\n");
+            print("THE PEOPLE (REMIANING) FIND YOU AN UNPLEASANT RULER, AND,\n");
+            print("FRANKLY, HATE YOUR GUTS!!\n");
+        } else if (p1 > 3 || l < 10) {
+            print("YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT\n");
+            print("REALLY WASN'T TOO BAD AT ALL. " + Math.floor(p * 0.8 * Math.random()) + " PEOPLE\n");
+            print("WOULD DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR\n");
+            print("TRIVIAL PROBLEMS.\n");
+        } else {
+            print("A FANTASTIC PERFORMANCE!!!  CHARLEMANGE, DISRAELI, AND\n");
+            print("JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!\n");
+        }
+    }
+    print("\n");
+    print("SO LONG FOR NOW.\n");
+    print("\n");
+}
+
+main();
diff --git a/44 Hangman/csharp/Hangman/Graphic.cs b/44 Hangman/csharp/Hangman/Graphic.cs
new file mode 100644
index 00000000..ba01fcac
--- /dev/null
+++ b/44 Hangman/csharp/Hangman/Graphic.cs	
@@ -0,0 +1,129 @@
+using System;
+
+namespace Hangman
+{
+    /// 
+    /// Represents the main "Hangman" graphic.
+    /// 
+    public class Graphic
+    {
+        private readonly char[,] _graphic;
+        private const int Width = 12;
+        private const int Height = 12;
+
+        public Graphic()
+        {
+            // 12 x 12 array to represent the graphics.
+            _graphic = new char[Height, Width];
+
+            // Fill it with empty spaces.
+            for (var i = 0; i < Height; i++)
+            {
+                for (var j = 0; j < Width; j++)
+                {
+                    _graphic[i, j] = ' ';
+                }
+            }
+
+            // Draw the vertical line.
+            for (var i = 0; i < Height; i++)
+            {
+                _graphic[i, 0] = 'X';
+            }
+
+            // Draw the horizontal line.
+            for (var i = 0; i < 7; i++)
+            {
+                _graphic[0, i] = 'X';
+            }
+
+            // Draw the rope.
+            _graphic[1, 6] = 'X';
+        }
+
+        public void Print()
+        {
+            for (var i = 0; i < Height; i++)
+            {
+                for (var j = 0; j < Width; j++)
+                {
+                    Console.Write(_graphic[i, j]);
+                }
+
+                Console.Write("\n"); // New line.
+            }
+        }
+
+        public void AddHead()
+        {
+            _graphic[2, 5] = '-';
+            _graphic[2, 6] = '-';
+            _graphic[2, 7] = '-';
+            _graphic[3, 4] = '(';
+            _graphic[3, 5] = '.';
+            _graphic[3, 7] = '.';
+            _graphic[3, 8] = ')';
+            _graphic[4, 5] = '-';
+            _graphic[4, 6] = '-';
+            _graphic[4, 7] = '-';
+        }
+
+        public void AddBody()
+        {
+            for (var i = 5; i < 9; i++)
+            {
+                _graphic[i, 6] = 'X';
+            }
+        }
+
+        public void AddRightArm()
+        {
+            for (var i = 3; i < 7; i++)
+            {
+                _graphic[i, i - 1] = '\\'; // This is the escape character for the back slash.
+            }
+        }
+
+        public void AddLeftArm()
+        {
+            _graphic[3, 10] = '/';
+            _graphic[4, 9] = '/';
+            _graphic[5, 8] = '/';
+            _graphic[6, 7] = '/';
+        }
+
+        public void AddRightLeg()
+        {
+            _graphic[9, 5] = '/';
+            _graphic[10, 4] = '/';
+        }
+
+        public void AddLeftLeg()
+        {
+            _graphic[9, 7] = '\\';
+            _graphic[10, 8] = '\\';
+        }
+
+        public void AddRightHand()
+        {
+            _graphic[2, 2] = '/';
+        }
+        
+        public void AddLeftHand()
+        {
+            _graphic[2, 10] = '\\';
+        }
+        
+        public void AddRightFoot()
+        {
+            _graphic[11, 9] = '\\';
+            _graphic[11, 10] = '-';
+        }
+        
+        public void AddLeftFoot()
+        {
+            _graphic[11, 3] = '/';
+            _graphic[11, 2] = '-';
+        }
+    }
+}
\ No newline at end of file
diff --git a/44 Hangman/csharp/Hangman/Hangman.csproj b/44 Hangman/csharp/Hangman/Hangman.csproj
new file mode 100644
index 00000000..9590466a
--- /dev/null
+++ b/44 Hangman/csharp/Hangman/Hangman.csproj	
@@ -0,0 +1,8 @@
+
+
+    
+        Exe
+        net5.0
+    
+
+
diff --git a/44 Hangman/csharp/Hangman/Hangman.sln b/44 Hangman/csharp/Hangman/Hangman.sln
new file mode 100644
index 00000000..ef93fef7
--- /dev/null
+++ b/44 Hangman/csharp/Hangman/Hangman.sln	
@@ -0,0 +1,16 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hangman", "Hangman.csproj", "{1C516A9E-F4F2-4C79-8C37-0162C403B1F7}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+EndGlobal
diff --git a/44 Hangman/csharp/Hangman/Program.cs b/44 Hangman/csharp/Hangman/Program.cs
new file mode 100644
index 00000000..7ecb09df
--- /dev/null
+++ b/44 Hangman/csharp/Hangman/Program.cs	
@@ -0,0 +1,313 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json.Serialization;
+
+namespace Hangman
+{
+    /// 
+    /// C# version of the game "Hangman" from the book BASIC Computer Games.
+    /// 
+    static class Program
+    {
+        static void Main()
+        {
+            Console.WriteLine(Tab(32) + "HANGMAN");
+            Console.WriteLine(Tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
+            Console.WriteLine();
+            Console.WriteLine();
+            Console.WriteLine();
+            MainLoop();
+            Console.WriteLine();
+            Console.WriteLine("IT'S BEEN FUN!  BYE FOR NOW.");
+        }
+
+        static void MainLoop()
+        {
+            var words = GetWords();
+            var stillPlaying = true;
+
+            while (stillPlaying)
+            {
+                if (words.Count == 0)
+                {
+                    Console.WriteLine("YOU DID ALL THE WORDS!!");
+                    break;
+                }
+
+                // Get a random number from 0 to the number of words we have minus one (C# arrays are zero-based).
+                var rnd = new Random();
+                var randomNumber = rnd.Next(words.Count - 1);
+
+                // Pick a random word and remove it from the list.
+                var word = words[randomNumber];
+                words.Remove(word);
+
+                GameLoop(word);
+                
+                // Game finished. Ask if player wants another one.
+                Console.WriteLine("WANT ANOTHER WORD? ");
+                var response = Console.ReadLine();
+                if (response == null || response.ToUpper() != "YES")
+                {
+                    stillPlaying = false;   // Exit the loop if the player didn't answer "yes".
+                }
+            }
+        }
+
+        static void GameLoop(string word)
+        {
+            var graphic = new Graphic();
+            var wrongGuesses = 0;
+            var numberOfGuesses = 0;
+            var usedLetters = new List();
+
+            // The word that the user sees. Since we just started, it's just dashes.
+            var displayedWord = new char[word.Length];
+            for (var i = 0; i < word.Length; i++)
+            {
+                displayedWord[i] = '-';
+            }
+
+            var stillPlaying = true;
+            while (stillPlaying)
+            {
+                var guess = GetLetterFromPlayer(displayedWord, usedLetters);
+                usedLetters.Add(guess);
+                numberOfGuesses++;
+                var correctLetterCount = 0;
+                // Now we check every letter in the word to see if the player guessed any of them correctly.
+                for(var i = 0; i < word.Length; i++)
+                {
+                    if (word[i] == guess)
+                    {
+                        correctLetterCount++;
+                        displayedWord[i] = guess;
+                    }
+                }
+
+                if (correctLetterCount == 0)
+                {
+                    // Wrong guess.
+                    Console.WriteLine("SORRY, THAT LETTER ISN'T IN THE WORD.");
+                    wrongGuesses++;
+                    DrawBody(graphic, wrongGuesses);
+                    if (wrongGuesses == 10)
+                    {
+                        // Player exhausted all their guesses. Finish the game loop.
+                        Console.WriteLine($"SORRY, YOU LOSE.  THE WORD WAS {word}");
+                        Console.Write("YOU MISSED THAT ONE.  DO YOU ");
+                        stillPlaying = false;
+                    }
+                }
+                else
+                {
+                    // Player guessed a correct letter. Let's see if there are any unguessed letters left in the word.
+                    if (displayedWord.Contains('-'))
+                    {
+                        Console.WriteLine(displayedWord);
+                        
+                        // Give the player a chance to guess the whole word.
+                        var wordGuess = GetWordFromPlayer();
+                        if (word == wordGuess)
+                        {
+                            // Player found the word. Mark it found.
+                            Console.WriteLine("YOU FOUND THE WORD!");
+                            stillPlaying = false;   // Exit game loop.
+                        }
+                        else
+                        {
+                            // Player didn't guess the word. Continue the game loop.
+                            Console.WriteLine("WRONG.  TRY ANOTHER LETTER.");
+                        }
+                    }
+                    else
+                    {
+                        // Player guessed all the letters.
+                        Console.WriteLine("YOU FOUND THE WORD!");
+                        stillPlaying = false;   // Exit game loop.
+                    }
+                }
+            } // End of game loop.
+        }
+
+        /// 
+        /// Display the current state of the word and all the already guessed letters, and get a new guess from the player
+        /// 
+        /// A char array that represents the current state of the guessed word
+        /// A list of chars that represents all the letters guessed so far
+        /// The letter that the player has just entered as a guess
+        private static char GetLetterFromPlayer(char[] displayedWord, List usedLetters)
+        {
+            while (true)    // Infinite loop, unless the player enters an unused letter.
+            {
+                Console.WriteLine();
+                Console.WriteLine(displayedWord);
+                Console.WriteLine();
+                Console.WriteLine();
+                Console.WriteLine("HERE ARE THE LETTERS YOU USED:");
+                for (var i = 0; i < usedLetters.Count; i++)
+                {
+                    Console.Write(usedLetters[i]);
+
+                    // If it's not the last letter, print a comma.
+                    if (i != usedLetters.Count - 1)
+                    {
+                        Console.Write(",");
+                    }
+                }
+
+                Console.WriteLine();
+                Console.WriteLine("WHAT IS YOUR GUESS?");
+                var guess = char.ToUpper(Console.ReadKey().KeyChar);
+                Console.WriteLine();
+                
+                if (usedLetters.Contains(guess))
+                {
+                    // After this the loop will continue.
+                    Console.WriteLine("YOU GUESSED THAT LETTER BEFORE!");
+                }
+                else
+                {
+                    // Break out of the loop by returning guessed letter.
+                    return guess;
+                }
+            }
+        }
+
+        /// 
+        /// Gets a word guess from the player.
+        /// 
+        /// The guessed word.
+        private static string GetWordFromPlayer()
+        {
+            while (true)    // Infinite loop, unless the player enters something.
+            {
+                Console.WriteLine("WHAT IS YOUR GUESS FOR THE WORD? ");
+                var guess = Console.ReadLine();
+                if (guess != null)
+                {
+                    return guess.ToUpper();
+                }
+            }
+        }
+
+        /// 
+        /// Draw body after wrong guess.
+        /// 
+        /// The instance of the Graphic class being used.
+        /// Number of wrong guesses.
+        private static void DrawBody(Graphic graphic, int wrongGuesses)
+        {
+            switch (wrongGuesses)
+                    {
+                        case 1:
+                            Console.WriteLine("FIRST, WE DRAW A HEAD.");
+                            graphic.AddHead();
+                            break;
+                        case 2:
+                            Console.WriteLine("NOW WE DRAW A BODY.");
+                            graphic.AddBody();
+                            break;
+                        case 3:
+                            Console.WriteLine("NEXT WE DRAW AN ARM.");
+                            graphic.AddRightArm();
+                            break;
+                        case 4:
+                            Console.WriteLine("THIS TIME IT'S THE OTHER ARM.");
+                            graphic.AddLeftArm();
+                            break;
+                        case 5:
+                            Console.WriteLine("NOW, LET'S DRAW THE RIGHT LEG.");
+                            graphic.AddRightLeg();
+                            break;
+                        case 6:
+                            Console.WriteLine("THIS TIME WE DRAW THE LEFT LEG.");
+                            graphic.AddLeftLeg();
+                            break;
+                        case 7:
+                            Console.WriteLine("NOW WE PUT UP A HAND.");
+                            graphic.AddRightHand();
+                            break;
+                        case 8:
+                            Console.WriteLine("NEXT THE OTHER HAND.");
+                            graphic.AddLeftHand();
+                            break;
+                        case 9:
+                            Console.WriteLine("NOW WE DRAW ONE FOOT.");
+                            graphic.AddRightFoot();
+                            break;
+                        case 10:
+                            Console.WriteLine("HERE'S THE OTHER FOOT -- YOU'RE HUNG!!");
+                            graphic.AddLeftFoot();
+                            break;
+                    }
+                    graphic.Print();
+        }
+        
+        /// 
+        /// Get a list of words to use in the game.
+        /// 
+        /// List of strings.
+        private static List GetWords() => new()
+        {
+            "GUM",
+            "SIN",
+            "FOR",
+            "CRY",
+            "LUG",
+            "BYE",
+            "FLY",
+            "UGLY",
+            "EACH",
+            "FROM",
+            "WORK",
+            "TALK",
+            "WITH",
+            "SELF",
+            "PIZZA",
+            "THING",
+            "FEIGN",
+            "FIEND",
+            "ELBOW",
+            "FAULT",
+            "DIRTY",
+            "BUDGET",
+            "SPIRIT",
+            "QUAINT",
+            "MAIDEN",
+            "ESCORT",
+            "PICKAX",
+            "EXAMPLE",
+            "TENSION",
+            "QUININE",
+            "KIDNEY",
+            "REPLICA",
+            "SLEEPER",
+            "TRIANGLE",
+            "KANGAROO",
+            "MAHOGANY",
+            "SERGEANT",
+            "SEQUENCE",
+            "MOUSTACHE",
+            "DANGEROUS",
+            "SCIENTIST",
+            "DIFFERENT",
+            "QUIESCENT",
+            "MAGISTRATE",
+            "ERRONEOUSLY",
+            "LOUDSPEAKER",
+            "PHYTOTOXIC",
+            "MATRIMONIAL",
+            "PARASYMPATHOMIMETIC",
+            "THIGMOTROPISM"
+        };
+
+        /// 
+        /// Leave a number of spaces empty.
+        /// 
+        /// Number of spaces.
+        /// The result string.
+        private static string Tab(int length) => new string(' ', length);
+    }
+}
\ No newline at end of file
diff --git a/47 Hi-Lo/java/src/HiLo.java b/47 Hi-Lo/java/src/HiLo.java
index 36f44ee5..2d0263e9 100644
--- a/47 Hi-Lo/java/src/HiLo.java	
+++ b/47 Hi-Lo/java/src/HiLo.java	
@@ -6,7 +6,7 @@ import java.util.Scanner;
  * Based on the Basic game of Hi-Lo here
  * https://github.com/coding-horror/basic-computer-games/blob/main/47%20Hi-Lo/hi-lo.bas
  *
- * Note:  The idea was to create a version of this 1970's Basic game in Java, without introducing
+ * 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 HiLo {
@@ -24,7 +24,7 @@ public class HiLo {
     }
 
     // Used for keyboard input
-    private Scanner kbScanner;
+    private final Scanner kbScanner;
 
     // Current game state
     private GAME_STATE gameState;
@@ -40,8 +40,8 @@ public class HiLo {
 
     public HiLo() {
 
-        this.gameState = GAME_STATE.STARTING;
-        this.playerAmountWon = 0;
+        gameState = GAME_STATE.STARTING;
+        playerAmountWon = 0;
 
         // Initialise kb scanner
         kbScanner = new Scanner(System.in);
@@ -66,7 +66,7 @@ public class HiLo {
                 case START_GAME:
                     init();
                     System.out.println("O.K.  I HAVE A NUMBER IN MIND.");
-                    this.gameState = GAME_STATE.GUESSING;
+                    gameState = GAME_STATE.GUESSING;
                     break;
 
                 // Player guesses the number until they get it or run out of guesses
@@ -75,21 +75,21 @@ public class HiLo {
 
                     // Check if the player guessed the number
                     if(validateGuess(guess)) {
-                        System.out.println("GOT IT!!!!!!!!!!   YOU WIN " + this.computersNumber
+                        System.out.println("GOT IT!!!!!!!!!!   YOU WIN " + computersNumber
                                 + " DOLLARS.");
-                        this.playerAmountWon += this.computersNumber;
+                        playerAmountWon += computersNumber;
                         System.out.println("YOUR TOTAL WINNINGS ARE NOW "
-                                + this.playerAmountWon + " DOLLARS.");
-                        this.gameState = GAME_STATE.PLAY_AGAIN;
+                                + playerAmountWon + " DOLLARS.");
+                        gameState = GAME_STATE.PLAY_AGAIN;
                     } else {
                         // incorrect guess
-                        this.playersGuesses++;
+                        playersGuesses++;
                         // Ran out of guesses?
-                        if (this.playersGuesses == MAX_GUESSES) {
+                        if (playersGuesses == MAX_GUESSES) {
                             System.out.println("YOU BLEW IT...TOO BAD...THE NUMBER WAS "
-                                    + this.computersNumber);
-                            this.playerAmountWon = 0;
-                            this.gameState = GAME_STATE.PLAY_AGAIN;
+                                    + computersNumber);
+                            playerAmountWon = 0;
+                            gameState = GAME_STATE.PLAY_AGAIN;
                         }
                     }
                     break;
@@ -98,11 +98,11 @@ public class HiLo {
                 case PLAY_AGAIN:
                     System.out.println();
                     if(yesEntered(displayTextAndGetInput("PLAY AGAIN (YES OR NO) "))) {
-                        this.gameState = GAME_STATE.START_GAME;
+                        gameState = GAME_STATE.START_GAME;
                     } else {
                         // Chose not to play again
                         System.out.println("SO LONG.  HOPE YOU ENJOYED YOURSELF!!!");
-                        this.gameState = GAME_STATE.GAME_OVER;
+                        gameState = GAME_STATE.GAME_OVER;
                     }
             }
         } while (gameState != GAME_STATE.GAME_OVER);
@@ -111,17 +111,17 @@ public class HiLo {
     /**
      * Checks the players guess against the computers randomly generated number
      *
-     * @param theGuess
+     * @param theGuess the players guess
      * @return true if the player guessed correctly, false otherwise
      */
     private boolean validateGuess(int theGuess) {
 
         // Correct guess?
-        if(theGuess == this.computersNumber) {
+        if(theGuess == computersNumber) {
             return true;
         }
 
-        if(theGuess > this.computersNumber) {
+        if(theGuess > computersNumber) {
             System.out.println("YOUR GUESS IS TOO HIGH.");
         } else {
             System.out.println("YOUR GUESS IS TOO LOW.");
@@ -131,8 +131,8 @@ public class HiLo {
     }
 
     private void init() {
-        this.playersGuesses = 0;
-        this.computersNumber = randomNumber();
+        playersGuesses = 0;
+        computersNumber = randomNumber();
     }
 
     public void intro() {
@@ -140,7 +140,7 @@ public class HiLo {
         System.out.println("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
         System.out.println();
         System.out.println();
-        System.out.println("THIS IS THE GAME OF HI LO.");
+        System.out.println("IS THE GAME OF HI LO.");
         System.out.println();
         System.out.println("YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE");
         System.out.println("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS.  IF YOU");
@@ -155,7 +155,7 @@ public class HiLo {
      * @return players guess as an int
      */
     private int playerGuess() {
-        return Integer.valueOf((displayTextAndGetInput("YOUR GUESS? ")));
+        return Integer.parseInt((displayTextAndGetInput("YOUR GUESS? ")));
     }
 
     /**
@@ -165,7 +165,7 @@ public class HiLo {
      * @return true of Y or YES was entered, otherwise false
      */
     private boolean yesEntered(String text) {
-        return stringIsAnyValue(text, new String[] {"Y", "YES"});
+        return stringIsAnyValue(text, "Y", "YES");
     }
 
     /**
diff --git a/51 Hurkle/java/src/Hurkle.java b/51 Hurkle/java/src/Hurkle.java
index 8af8732f..7fc2ed1e 100644
--- a/51 Hurkle/java/src/Hurkle.java	
+++ b/51 Hurkle/java/src/Hurkle.java	
@@ -1,6 +1,14 @@
-import java.util.ArrayList;
 import java.util.Scanner;
 
+/**
+ * Game of Hurkle
+ * 

+ * Based on the Basic game of Hurkle here + * https://github.com/coding-horror/basic-computer-games/blob/main/51%20Hurkle/hurkle.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 Hurkle { public static final int GRID_SIZE = 10; @@ -17,7 +25,7 @@ public class Hurkle { private GAME_STATE gameState; // Used for keyboard input - private Scanner kbScanner; + private final Scanner kbScanner; private int guesses; @@ -54,32 +62,31 @@ public class Hurkle { // Start the game, set the number of players, names and round case START_GAME: - this.hurkleXPos = randomNumber(); - this.hurkleYPos = randomNumber(); - System.out.println("HURKLE AT : " + this.hurkleXPos + "," + this.hurkleYPos); + hurkleXPos = randomNumber(); + hurkleYPos = randomNumber(); - this.guesses = 1; + guesses = 1; gameState = GAME_STATE.GUESSING; break; // Guess an x,y position of the hurkle case GUESSING: - String guess = displayTextAndGetInput("GUESS #" + this.guesses + "? "); - this.playerGuessXPos = getDelimitedValue(guess, 0); - this.playerGuessYPos = getDelimitedValue(guess, 1); + String guess = displayTextAndGetInput("GUESS #" + guesses + "? "); + playerGuessXPos = getDelimitedValue(guess, 0); + playerGuessYPos = getDelimitedValue(guess, 1); if (foundHurkle()) { - this.gameState = GAME_STATE.PLAY_AGAIN; + gameState = GAME_STATE.PLAY_AGAIN; } else { showDirectionOfHurkle(); - this.guesses++; - if(this.guesses > MAX_GUESSES) { + guesses++; + if (guesses > MAX_GUESSES) { System.out.println("SORRY, THAT'S " + MAX_GUESSES + " GUESSES."); System.out.println("THE HURKLE IS AT " - + this.hurkleXPos + "," + this.hurkleYPos); + + hurkleXPos + "," + hurkleYPos); System.out.println(); - this.gameState = GAME_STATE.PLAY_AGAIN; + gameState = GAME_STATE.PLAY_AGAIN; } } @@ -88,7 +95,7 @@ public class Hurkle { case PLAY_AGAIN: System.out.println("LET'S PLAY AGAIN, HURKLE IS HIDING."); System.out.println(); - this.gameState = GAME_STATE.START_GAME; + gameState = GAME_STATE.START_GAME; break; } // Effectively an endless loop because the game never quits as per @@ -98,31 +105,30 @@ public class Hurkle { private void showDirectionOfHurkle() { System.out.print("GO "); - if(this.playerGuessYPos == this.hurkleYPos) { + if (playerGuessYPos == hurkleYPos) { // don't print North or South because the player has chosen the // same y grid pos as the hurkle - } else if (this.playerGuessYPos < this.hurkleYPos) { + } else if (playerGuessYPos < hurkleYPos) { System.out.print("NORTH"); - } else if(this.playerGuessYPos > this.hurkleYPos) { + } else if (playerGuessYPos > hurkleYPos) { System.out.print("SOUTH"); } - if(this.playerGuessXPos == this.hurkleXPos) { + if (playerGuessXPos == hurkleXPos) { // don't print East or West because the player has chosen the // same x grid pos as the hurkle - } else if(this.playerGuessXPos < this.hurkleXPos) { + } else if (playerGuessXPos < hurkleXPos) { System.out.print("EAST"); - } else if(this.playerGuessXPos > this.hurkleXPos) { + } else if (playerGuessXPos > hurkleXPos) { System.out.print("WEST"); } System.out.println(); - return; } private boolean foundHurkle() { - if ((this.playerGuessXPos - this.hurkleXPos) - - (this.playerGuessYPos - this.hurkleYPos) == 0) { - System.out.println("YOU FOUND HIM IN " + this.guesses + " GUESSES."); + if ((playerGuessXPos - hurkleXPos) + - (playerGuessYPos - hurkleYPos) == 0) { + System.out.println("YOU FOUND HIM IN " + guesses + " GUESSES."); return true; } diff --git a/51 Hurkle/java/src/HurkleGame.java b/51 Hurkle/java/src/HurkleGame.java index c582885e..1b527398 100644 --- a/51 Hurkle/java/src/HurkleGame.java +++ b/51 Hurkle/java/src/HurkleGame.java @@ -1,7 +1,7 @@ public class HurkleGame { public static void main(String[] args) { - Hurkle hurkle = new Hurkle(); - hurkle.play(); + Hurkle hurkle = new Hurkle(); + hurkle.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/69 Pizza/java/src/Pizza.java b/69 Pizza/java/src/Pizza.java index f7e68f0e..55bf8ceb 100644 --- a/69 Pizza/java/src/Pizza.java +++ b/69 Pizza/java/src/Pizza.java @@ -1,5 +1,14 @@ import java.util.Scanner; +/** + * Game of Pizza + *

+ * Based on the Basic game of Hurkle here + * https://github.com/coding-horror/basic-computer-games/blob/main/69%20Pizza/pizza.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 Pizza { private final int MAX_DELIVERIES = 5; @@ -17,11 +26,11 @@ public class Pizza { } // houses that can order pizza - private final char[] houses = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + private final char[] houses = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'}; // size of grid - private final int[] gridPos = new int[] { 1, 2, 3, 4}; + private final int[] gridPos = new int[]{1, 2, 3, 4}; private GAME_STATE gameState; @@ -38,7 +47,7 @@ public class Pizza { public Pizza() { - this.gameState = GAME_STATE.STARTING; + gameState = GAME_STATE.STARTING; // Initialise kb scanner kbScanner = new Scanner(System.in); @@ -50,40 +59,40 @@ public class Pizza { public void play() { do { - switch (this.gameState) { + switch (gameState) { // Show an introduction the first time the game is played. case STARTING: init(); intro(); - this.gameState = GAME_STATE.ENTER_NAME; + gameState = GAME_STATE.ENTER_NAME; break; // Enter the players name case ENTER_NAME: - this.playerName = displayTextAndGetInput("WHAT IS YOUR FIRST NAME? "); - System.out.println("HI " + this.playerName + ". IN THIS GAME YOU ARE TO TAKE ORDERS"); + playerName = displayTextAndGetInput("WHAT IS YOUR FIRST NAME? "); + System.out.println("HI " + playerName + ". IN GAME YOU ARE TO TAKE ORDERS"); System.out.println("FOR PIZZAS. THEN YOU ARE TO TELL A DELIVERY BOY"); System.out.println("WHERE TO DELIVER THE ORDERED PIZZAS."); System.out.println(); - this.gameState = GAME_STATE.DRAW_MAP; + gameState = GAME_STATE.DRAW_MAP; break; // Draw the map case DRAW_MAP: drawMap(); - this.gameState = GAME_STATE.MORE_DIRECTIONS; + gameState = GAME_STATE.MORE_DIRECTIONS; break; // need more directions (how to play) ? case MORE_DIRECTIONS: extendedIntro(); String moreInfo = displayTextAndGetInput("DO YOU NEED MORE DIRECTIONS? "); - if(!yesOrNoEntered(moreInfo)) { + if (!yesOrNoEntered(moreInfo)) { System.out.println("'YES' OR 'NO' PLEASE, NOW THEN,"); } else { // More instructions selected - if(yesEntered(moreInfo)) { + if (yesEntered(moreInfo)) { displayMoreDirections(); // Player understand now? if (yesEntered(displayTextAndGetInput("UNDERSTAND? "))) { @@ -91,86 +100,86 @@ public class Pizza { System.out.println(); System.out.println("GOOD LUCK!!"); System.out.println(); - this.gameState = GAME_STATE.START_DELIVER; + gameState = GAME_STATE.START_DELIVER; } else { // Not understood, essentially game over - this.gameState = GAME_STATE.TOO_DIFFICULT; + gameState = GAME_STATE.TOO_DIFFICULT; } } else { // no more directions were needed, start delivering pizza - this.gameState = GAME_STATE.START_DELIVER; + gameState = GAME_STATE.START_DELIVER; } } - break; + break; // Too difficult to understand, game over! case TOO_DIFFICULT: - System.out.println("THIS JOB IS DEFINITELY TOO DIFFICULT FOR YOU. THANKS ANYWAY"); - this.gameState = GAME_STATE.GAME_OVER; + System.out.println("JOB IS DEFINITELY TOO DIFFICULT FOR YOU. THANKS ANYWAY"); + gameState = GAME_STATE.GAME_OVER; break; // Delivering pizza case START_DELIVER: // select a random house and "order" a pizza for them. - this.currentHouseDelivery = (int) (Math.random() - * (this.houses.length) + 1) -1; // Deduct 1 for 0-based array + currentHouseDelivery = (int) (Math.random() + * (houses.length) + 1) - 1; // Deduct 1 for 0-based array - System.out.println("HELLO " + this.playerName + "'S PIZZA. THIS IS " - + this.houses[this.currentHouseDelivery] + "."); + System.out.println("HELLO " + playerName + "'S PIZZA. IS " + + houses[currentHouseDelivery] + "."); System.out.println(" PLEASE SEND A PIZZA."); - this.gameState = GAME_STATE.DELIVER_PIZZA; + gameState = GAME_STATE.DELIVER_PIZZA; break; // Try and deliver the pizza case DELIVER_PIZZA: - String question = " DRIVER TO " + this.playerName + ": WHERE DOES " - + this.houses[this.currentHouseDelivery] + " LIVE ? "; + String question = " DRIVER TO " + playerName + ": WHERE DOES " + + houses[currentHouseDelivery] + " LIVE ? "; String answer = displayTextAndGetInput(question); // Convert x,y entered by player to grid position of a house int x = getDelimitedValue(answer, 0); int y = getDelimitedValue(answer, 1); - int calculatedPos = (x + (y -1) * 4) -1; + int calculatedPos = (x + (y - 1) * 4) - 1; // Did the player select the right house to deliver? - if(calculatedPos == this.currentHouseDelivery) { - System.out.println("HELLO " + this.playerName + ". THIS IS " + this.houses[this.currentHouseDelivery] + if (calculatedPos == currentHouseDelivery) { + System.out.println("HELLO " + playerName + ". IS " + houses[currentHouseDelivery] + ", THANKS FOR THE PIZZA."); - this.pizzaDeliveryCount++; + pizzaDeliveryCount++; // Delivered enough pizza? - if(this.pizzaDeliveryCount > MAX_DELIVERIES) { - this.gameState = GAME_STATE.END_GAME; + if (pizzaDeliveryCount > MAX_DELIVERIES) { + gameState = GAME_STATE.END_GAME; } else { - this.gameState = GAME_STATE.START_DELIVER; + gameState = GAME_STATE.START_DELIVER; } } else { - System.out.println("THIS IS " + houses[calculatedPos] + ". I DID NOT ORDER A PIZZA."); + System.out.println("IS " + houses[calculatedPos] + ". I DID NOT ORDER A PIZZA."); System.out.println("I LIVE AT " + x + "," + y); - // Don't change gameState so this state is executed again + // Don't change gameState so state is executed again } break; // Sign off message for cases where the Chief is not upset case END_GAME: - if(yesEntered(displayTextAndGetInput("DO YOU WANT TO DELIVER MORE PIZZAS? "))) { + if (yesEntered(displayTextAndGetInput("DO YOU WANT TO DELIVER MORE PIZZAS? "))) { init(); - this.gameState = GAME_STATE.START_DELIVER; + gameState = GAME_STATE.START_DELIVER; } else { System.out.println(); - System.out.println("O.K. " + this.playerName + ", SEE YOU LATER!"); + System.out.println("O.K. " + playerName + ", SEE YOU LATER!"); System.out.println(); - this.gameState = GAME_STATE.GAME_OVER; + gameState = GAME_STATE.GAME_OVER; } break; // GAME_OVER State does not specifically have a case } - } while (this.gameState != GAME_STATE.GAME_OVER); + } while (gameState != GAME_STATE.GAME_OVER); } private void drawMap() { @@ -179,19 +188,19 @@ public class Pizza { System.out.println(); System.out.println(" -----1-----2-----3-----4-----"); int k = 3; - for(int i=1; i<5; i++) { + for (int i = 1; i < 5; i++) { System.out.println("-"); System.out.println("-"); System.out.println("-"); System.out.println("-"); - System.out.print(this.gridPos[k]); + System.out.print(gridPos[k]); int pos = 16 - 4 * i; - System.out.print(" " + this.houses[pos]); - System.out.print(" " + this.houses[pos + 1]); - System.out.print(" " + this.houses[pos + 2]); - System.out.print(" " + this.houses[pos + 3]); - System.out.println(" " + this.gridPos[k]); + System.out.print(" " + houses[pos]); + System.out.print(" " + houses[pos + 1]); + System.out.print(" " + houses[pos + 2]); + System.out.print(" " + houses[pos + 3]); + System.out.println(" " + gridPos[k]); k = k - 1; } System.out.println("-"); @@ -199,10 +208,10 @@ public class Pizza { System.out.println("-"); System.out.println("-"); System.out.println(" -----1-----2-----3-----4-----"); -} + } + /** * Basic information about the game - * */ private void intro() { System.out.println("PIZZA"); @@ -229,14 +238,14 @@ public class Pizza { System.out.println("DELIVERED. THEN A DELIVERY BOY WILL"); System.out.println("ASK YOU FOR THE LOCATION."); System.out.println(" EXAMPLE:"); - System.out.println("THIS IS J. PLEASE SEND A PIZZA."); - System.out.println("DRIVER TO " + this.playerName + ". WHERE DOES J LIVE?"); + System.out.println("IS J. PLEASE SEND A PIZZA."); + System.out.println("DRIVER TO " + playerName + ". WHERE DOES J LIVE?"); System.out.println("YOUR ANSWER WOULD BE 2,3"); System.out.println(); } private void init() { - this.pizzaDeliveryCount = 1; + pizzaDeliveryCount = 1; } /** @@ -273,19 +282,20 @@ public class Pizza { private boolean yesOrNoEntered(String text) { return stringIsAnyValue(text, "Y", "YES", "N", "NO"); } + /** * Returns true if a given string contains at least one of the varargs (2nd parameter). * Note: Case insensitive comparison. * - * @param text string to search + * @param text string to search * @param values varargs of type string containing values to compare * @return true if one of the varargs arguments was found in text */ private boolean stringIsAnyValue(String text, String... values) { // Cycle through the variable number of values and test each - for(String val:values) { - if(text.equalsIgnoreCase(val)) { + for (String val : values) { + if (text.equalsIgnoreCase(val)) { return true; } } diff --git a/69 Pizza/java/src/PizzaGame.java b/69 Pizza/java/src/PizzaGame.java index 2a94afc9..b7074fa4 100644 --- a/69 Pizza/java/src/PizzaGame.java +++ b/69 Pizza/java/src/PizzaGame.java @@ -2,7 +2,7 @@ public class PizzaGame { public static void main(String[] args) { - Pizza pizza = new Pizza(); - pizza.play(); + Pizza pizza = new Pizza(); + pizza.play(); } } diff --git a/73 Reverse/python/reverse.py b/73 Reverse/python/reverse.py new file mode 100755 index 00000000..b73c779d --- /dev/null +++ b/73 Reverse/python/reverse.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +import random +import textwrap + + +NUMCNT = 9 # How many numbers are we playing with? + + +def play(): + print('REVERSE'.center(72)) + print('CREATIVE COMPUTING MORRISTOWN, NEW JERSEY'.center(72)) + print() + print() + print('REVERSE -- A GAME OF SKILL') + print() + + if not input('DO YOU WANT THE RULES? (yes/no) ').lower().startswith('n'): + rules() + + while True: + game_loop() + + if not input('TRY AGAIN? (yes/no) ').lower().startswith('y'): + return + + +def game_loop(): + """Play the main game.""" + # Make a random list from 1 to NUMCNT + numbers = list(range(1, NUMCNT + 1)) + random.shuffle(numbers) + + # Print original list and start the game + print() + print('HERE WE GO ... THE LIST IS:') + print_list(numbers) + + turns = 0 + while True: + try: + howmany = int(input('HOW MANY SHALL I REVERSE? ')) + assert howmany >= 0 + except (ValueError, AssertionError): + continue + + if howmany == 0: + return + + if howmany > NUMCNT: + print('OOPS! WRONG! I CAN REVERSE AT MOST', NUMCNT) + continue + + turns += 1 + + # Reverse as many items as requested. + newnums = numbers[0:howmany] + newnums.reverse() + newnums.extend(numbers[howmany:]) + numbers = newnums + + print_list(numbers) + + # Check for a win + if all(numbers[i] == i + 1 for i in range(NUMCNT)): + print('YOU WON IT IN {} MOVES!'.format(turns)) + print() + return + + +def print_list(numbers): + """Print out the list""" + print(' '.join(map(str, numbers))) + + +def rules(): + """Print out the rules""" + help = textwrap.dedent(""" + THIS IS THE GAME OF "REVERSE". TO WIN, ALL YOU HAVE + TO DO IS ARRANGE A LIST OF NUMBERS (1 THROUGH {}) + IN NUMERICAL ORDER FROM LEFT TO RIGHT. TO MOVE, YOU + TELL ME HOW MANY NUMBERS (COUNTING FROM THE LEFT) TO + REVERSE. FOR EXAMPLE, IF THE CURRENT LIST IS: + + 2 3 4 5 1 6 7 8 9 + + AND YOU REVERSE 4, THE RESULT WILL BE: + + 5 4 3 2 1 6 7 8 9 + + NOW IF YOU REVERSE 5, YOU WIN! + + 1 2 3 4 5 6 7 8 9 + + NO DOUBT YOU WILL LIKE THIS GAME, BUT + IF YOU WANT TO QUIT, REVERSE 0 (ZERO). + """.format(NUMCNT)) + print(help) + print() + + +if __name__ == '__main__': + try: + play() + except KeyboardInterrupt: + pass diff --git a/74 Rock Scissors Paper/csharp/Choice.cs b/74 Rock Scissors Paper/csharp/Choice.cs new file mode 100644 index 00000000..c981a45a --- /dev/null +++ b/74 Rock Scissors Paper/csharp/Choice.cs @@ -0,0 +1,19 @@ +namespace RockScissorsPaper +{ + public class Choice + { + public string Selector {get; private set; } + public string Name { get; private set; } + internal Choice CanBeat { get; set; } + + public Choice(string selector, string name) { + Selector = selector; + Name = name; + } + + public bool Beats(Choice choice) + { + return choice == CanBeat; + } + } +} diff --git a/74 Rock Scissors Paper/csharp/Choices.cs b/74 Rock Scissors Paper/csharp/Choices.cs new file mode 100644 index 00000000..3026d7cc --- /dev/null +++ b/74 Rock Scissors Paper/csharp/Choices.cs @@ -0,0 +1,42 @@ +using System; + +namespace RockScissorsPaper +{ + public class Choices + { + public static readonly Choice Rock = new Choice("3", "Rock"); + public static readonly Choice Scissors = new Choice("2", "Scissors"); + public static readonly Choice Paper = new Choice("1", "Paper"); + + private static readonly Choice[] _allChoices; + private static readonly Random _random = new Random(); + + static Choices() + { + Rock.CanBeat = Scissors; + Scissors.CanBeat = Paper; + Paper.CanBeat = Rock; + + _allChoices = new[] { Rock, Scissors, Paper }; + } + + public static Choice GetRandom() + { + return _allChoices[_random.Next(_allChoices.GetLength(0))]; + } + + public static bool TryGetBySelector(string selector, out Choice choice) + { + foreach (var possibleChoice in _allChoices) + { + if (string.Equals(possibleChoice.Selector, selector)) + { + choice = possibleChoice; + return true; + } + } + choice = null; + return false; + } + } +} diff --git a/74 Rock Scissors Paper/csharp/Game.cs b/74 Rock Scissors Paper/csharp/Game.cs new file mode 100644 index 00000000..8916a217 --- /dev/null +++ b/74 Rock Scissors Paper/csharp/Game.cs @@ -0,0 +1,58 @@ +using System; +using System.Linq; + +namespace RockScissorsPaper +{ + public class Game + { + public int ComputerWins { get; private set; } + public int HumanWins { get; private set; } + public int TieGames { get; private set; } + + public void PlayGame() + { + var computerChoice = Choices.GetRandom(); + var humanChoice = GetHumanChoice(); + + Console.WriteLine("This is my choice..."); + Console.WriteLine("...{0}", computerChoice.Name); + + if (humanChoice.Beats(computerChoice)) + { + Console.WriteLine("You win!!!"); + HumanWins++; + } + else if (computerChoice.Beats(humanChoice)) + { + Console.WriteLine("Wow! I win!!!"); + ComputerWins++; + } + else + { + Console.WriteLine("Tie game. No winner."); + TieGames++; + } + } + + public void WriteFinalScore() + { + Console.WriteLine(); + Console.WriteLine("Here is the final game score:"); + Console.WriteLine("I have won {0} game(s).", ComputerWins); + Console.WriteLine("You have one {0} game(s).", HumanWins); + Console.WriteLine("And {0} game(s) ended in a tie.", TieGames); + } + + public Choice GetHumanChoice() + { + while (true) + { + Console.WriteLine("3=Rock...2=Scissors...1=Paper"); + Console.WriteLine("1...2...3...What's your choice"); + if (Choices.TryGetBySelector(Console.ReadLine(), out var choice)) + return choice; + Console.WriteLine("Invalid."); + } + } + } +} diff --git a/74 Rock Scissors Paper/csharp/Program.cs b/74 Rock Scissors Paper/csharp/Program.cs new file mode 100644 index 00000000..acd49e4b --- /dev/null +++ b/74 Rock Scissors Paper/csharp/Program.cs @@ -0,0 +1,48 @@ +using System; + +namespace RockScissorsPaper +{ + static class Program + { + static void Main(string[] args) + { + Console.WriteLine("GAME OF ROCK, SCISSORS, PAPER"); + Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine(); + + var numberOfGames = GetNumberOfGames(); + + var game = new Game(); + for (var gameNumber = 1; gameNumber <= numberOfGames; gameNumber++) { + Console.WriteLine(); + Console.WriteLine("Game number {0}", gameNumber); + + game.PlayGame(); + } + + game.WriteFinalScore(); + + Console.WriteLine(); + Console.WriteLine("Thanks for playing!!"); + } + + static int GetNumberOfGames() + { + while (true) { + Console.WriteLine("How many games"); + if (int.TryParse(Console.ReadLine(), out var number)) + { + if (number < 11 && number > 0) + return number; + Console.WriteLine("Sorry, but we aren't allowed to play that many."); + } + else + { + Console.WriteLine("Sorry, I didn't understand."); + } + } + } + } +} diff --git a/74 Rock Scissors Paper/csharp/RockScissorsPaper.csproj b/74 Rock Scissors Paper/csharp/RockScissorsPaper.csproj new file mode 100644 index 00000000..6e6a5510 --- /dev/null +++ b/74 Rock Scissors Paper/csharp/RockScissorsPaper.csproj @@ -0,0 +1,9 @@ + + + + Exe + net5.0 + RockScissorsPaper + + + diff --git a/74 Rock Scissors Paper/javascript/rockscissors.html b/74 Rock Scissors Paper/javascript/rockscissors.html new file mode 100644 index 00000000..2b938a5f --- /dev/null +++ b/74 Rock Scissors Paper/javascript/rockscissors.html @@ -0,0 +1,9 @@ + + +ROCK, SCISSORS, PAPER + + +


+
+
+
diff --git a/74 Rock Scissors Paper/javascript/rockscissors.js b/74 Rock Scissors Paper/javascript/rockscissors.js
new file mode 100644
index 00000000..a5d86862
--- /dev/null
+++ b/74 Rock Scissors Paper/javascript/rockscissors.js	
@@ -0,0 +1,107 @@
+// ROCK, SCISSORS, PAPER
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+// Main control section
+async function main()
+{
+    print(tab(21) + "GAME OF ROCK, SCISSORS, PAPER\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    while (1) {
+        print("HOW MANY GAMES");
+        q = parseInt(await input());
+        if (q >= 11)
+            print("SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY.\n");
+        else
+            break;
+    }
+    h = 0;  // Human
+    c = 0;  // Computer
+    for (g = 1; g <= q; g++ ) {
+        print("\n");
+        print("GAME NUMBER " + g + "\n");
+        x = Math.floor(Math.random() * 3 + 1);
+        while (1) {
+            print("3=ROCK...2=SCISSORS...1=PAPER\n");
+            print("1...2...3...WHAT'S YOUR CHOICE");
+            k = parseInt(await input());
+            if (k != 1 && k != 2 && k != 3)
+                print("INVALID.\n");
+            else
+                break;
+        }
+        print("THIS IS MY CHOICE...");
+        switch (x) {
+            case 1:
+                print("...PAPER\n");
+                break;
+            case 2:
+                print("...SCISSORS\n");
+                break;
+            case 3:
+                print("...ROCK\n");
+                break;
+        }
+        if (x == k) {
+            print("TIE GAME.  NO WINNER.\n");
+        } else if ((x > k && (k != 1 || x != 3)) || (x == 1 && k == 3)) {
+            print("WOW!  I WIN!!!\n");
+            c++;
+        } else {
+            print("YOU WIN!!!\n");
+            h++;
+        }
+    }
+    print("\n");
+    print("HERE IS THE FINAL GAME SCORE:\n");
+    print("I HAVE WON " + c + " GAME(S).\n");
+    print("YOU HAVE WON " + h + " GAME(S).\n");
+    print("AND " + (q - (c + h)) + " GAME(S) ENDED IN A TIE.\n");
+    print("\n");
+    print("THANKS FOR PLAYING!!\n");
+}
+
+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 @@
+
+
+  
+    Exe
+    net5.0
+  
+
+
diff --git a/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.sln b/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.sln
new file mode 100644
index 00000000..1e4b621e
--- /dev/null
+++ b/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.sln	
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31019.35
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RussianRoulette", "RussianRoulette.csproj", "{9F052B4A-FA33-4BBE-9D9D-3CF8152569F1}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{9F052B4A-FA33-4BBE-9D9D-3CF8152569F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9F052B4A-FA33-4BBE-9D9D-3CF8152569F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9F052B4A-FA33-4BBE-9D9D-3CF8152569F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9F052B4A-FA33-4BBE-9D9D-3CF8152569F1}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {97F5B1B0-A80A-4C1F-9F76-8D68B4A49E82}
+	EndGlobalSection
+EndGlobal
diff --git a/78 Sine Wave/java/SineWave.java b/78 Sine Wave/java/src/SineWave.java
similarity index 90%
rename from 78 Sine Wave/java/SineWave.java
rename to 78 Sine Wave/java/src/SineWave.java
index 7d917a75..f3b3c7eb 100644
--- a/78 Sine Wave/java/SineWave.java	
+++ b/78 Sine Wave/java/src/SineWave.java	
@@ -6,7 +6,7 @@ import java.util.Arrays;
  * Based on the Sine Wave program here
  * https://github.com/coding-horror/basic-computer-games/blob/main/78%20Sine%20Wave/sinewave.bas
  *
- * Note:  The idea was to create a version of this 1970's Basic program in Java, without introducing
+ * 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 SineWave {
diff --git a/78 Sine Wave/perl/sinewave.pl b/78 Sine Wave/perl/sinewave.pl
new file mode 100644
index 00000000..a28d3865
--- /dev/null
+++ b/78 Sine Wave/perl/sinewave.pl	
@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+print ' ' x 30 ."SINE WAVE\n";
+print ' ' x 15 ."CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n";
+print "\n\n\n\n\n";
+
+my $B=0;
+
+for (my $T=0; $T<40; $T+=.25) {
+	my $A=int(26+25*sin($T));
+	print ' ' x $A;
+	if ($B==0) { print "CREATIVE\n"; }
+	if ($B==1) { print "COMPUTING\n"; }
+	$B= !$B; #Toggle
+	}
diff --git a/78 Sine Wave/ruby/sinewave.rb b/78 Sine Wave/ruby/sinewave.rb
new file mode 100644
index 00000000..001e2cd8
--- /dev/null
+++ b/78 Sine Wave/ruby/sinewave.rb	
@@ -0,0 +1,15 @@
+def intro
+  puts "                              SINE WAVE
+               CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n\n\n\n"
+end
+
+def main
+  intro
+  (0..40).step(0.25).each do |t|
+    a = (26 + 25 * Math.sin(t)).to_i
+    text = (t % 0.5) == 0 ? "CREATIVE" : "COMPUTING"
+    puts " " * a + text
+  end
+end
+
+main
\ No newline at end of file
diff --git a/80 Slots/python/slots.py b/80 Slots/python/slots.py
new file mode 100644
index 00000000..fbae665b
--- /dev/null
+++ b/80 Slots/python/slots.py	
@@ -0,0 +1,159 @@
+########################################################
+#
+# Slots
+#
+# From Basic Computer Games (1978)
+#
+#    "The slot machine or one-arm bandit is a mechanical
+#   device that will absorb coins just about as fast as
+#   you can feed it. After inserting a coin, you pull a
+#   handle that sets three indepent reels spining. If the
+#   reels stop with certain symbols appearing in the pay
+#   line, you get a certain payoff. The original slot
+#   machine, called the Liberty bell, was invented in 1895
+#   by Charles Fey in San Francisco. Fey refused to sell
+#   or lease the manufacturing rights, so H.S. Mills in
+#   Chicago built a similar, but much improved, machine
+#   called the Operators Bell. This has survived nearly
+#   unchanged to today.
+#     On the operators Bell and other standard slot
+#   machines, there are 20 symbols on each wheel but they
+#   are not distributed evenly among the objects(cherries,
+#   bar, apples, etc). Of the 8000 possible combinations,
+#   the expected payoff(to the player) is 7049 or $89.11
+#   for every $100.00 put in, one of the lowest expected
+#   payoffs of all casino games.
+#     In the program here, the payoff is considerably more
+#   liberal; indeed it appears to favor the player by 11%
+#   -- i.e., an expected payoff of $111 for each $100 bet."
+#     The program was originally written by Fred Mirabelle
+#   and Bob Harper
+#
+########################################################
+
+from random import choices
+from collections import Counter
+import sys
+
+
+def initial_message():
+    print(" "*30 + "Slots")
+    print(" "*15 + "Creative Computing Morrison, New Jersey")
+    print("\n"*3)
+    print("You are in the H&M Casino, in front of one of our")
+    print("one-arm Bandits. Bet from $1 to $100.")
+    print("To pull the arm, punch the return key after making your bet.")
+
+
+def input_betting():
+    print("\n")
+    b = -1
+    while b < 1 or b > 100:
+        try:
+            b = int(input("Your bet:"))
+        except ValueError:
+            b = -1
+        if b > 100:
+            print("House limits are $100")
+        elif b < 1:
+            print("Minium bet is $1")
+    beeping()
+    return int(b)
+
+
+def beeping():
+    # Function to produce a beep sound.
+    # In the original program is the subroutine at line 1270
+    for _ in range(5):
+        sys.stdout.write('\a')
+        sys.stdout.flush()
+
+
+def spin_wheels():
+    possible_fruits = ["Bar", "Bell", "Orange", "Lemon", "Plum", "Cherry"]
+    wheel = choices(possible_fruits, k=3)
+
+    print(*wheel)
+    beeping()
+
+    return wheel
+
+
+def adjust_profits(wheel, m, profits):
+    # we remove the duplicates
+    s = set(wheel)
+
+    if len(s) == 1:
+        # the three fruits are the same
+        fruit = s.pop()
+
+        if fruit == "Bar":
+            print("\n***Jackpot***")
+            profits = (((100*m)+m)+profits)
+        else:
+            print("\n**Top Dollar**")
+            profits = (((10*m)+m)+profits)
+
+        print("You Won!")
+    elif len(s) == 2:
+        # two fruits are equal
+        c = Counter(wheel)
+        # we get the fruit that appears two times
+        fruit = sorted(c.items(), key=lambda x: x[1], reverse=True)[0][0]
+
+        if fruit == "Bar":
+            print("\n*Double Bar*")
+            profits = (((5*m)+m)+profits)
+        else:
+            print("\nDouble!!")
+            profits = (((2*m)+m)+profits)
+
+        print("You Won!")
+    else:
+        # three different fruits
+        print("\nYou Lost.")
+        profits = profits - m
+
+    return profits
+
+
+def final_message(profits):
+    if profits < 0:
+        print("Pay up!  Please leave your money on the terminal")
+    elif profits == 0:
+        print("Hey, You broke even.")
+    else:
+        print("Collect your winings from the H&M cashier.")
+
+
+profits = 0
+keep_betting = True
+
+initial_message()
+while keep_betting:
+    m = input_betting()
+    w = spin_wheels()
+    profits = adjust_profits(w, m, profits)
+
+    print("Your standings are ${}".format(profits))
+    answer = input("Again?")
+
+    try:
+        if not answer[0].lower() == "y":
+            keep_betting = False
+    except IndexError:
+        keep_betting = False
+
+final_message(profits)
+
+
+######################################################################
+#
+# Porting notes
+#
+#   The selections of the fruits(Bar, apples, lemon, etc.) are made
+#   with equal probability, accordingly to random.choices documentation.
+#   It could be added a weights list to the function and therefore
+#   adjust the expected payoff
+#
+######################################################################
diff --git a/82 Stars/java/src/Stars.java b/82 Stars/java/src/Stars.java
index f28a0510..75e7cdd6 100644
--- a/82 Stars/java/src/Stars.java	
+++ b/82 Stars/java/src/Stars.java	
@@ -7,7 +7,7 @@ import java.util.Scanner;
  * Based on the Basic game of Stars here
  * https://github.com/coding-horror/basic-computer-games/blob/main/82%20Stars/stars.bas
  *
- * Note:  The idea was to create a version of this 1970's Basic game in Java, without introducing
+ * 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 Stars {
@@ -42,7 +42,7 @@ public class Stars {
 
     public Stars() {
 
-        this.gameState = GAME_STATE.STARTING;
+        gameState = GAME_STATE.STARTING;
 
         // Initialise kb scanner
         kbScanner = new Scanner(System.in);
@@ -68,30 +68,30 @@ public class Stars {
                     if(yesEntered(displayTextAndGetInput("DO YOU WANT INSTRUCTIONS? "))) {
                         instructions();
                     }
-                    this.gameState = GAME_STATE.START_GAME;
+                    gameState = GAME_STATE.START_GAME;
                     break;
 
                 // Generate computers number for player to guess, etc.
                 case START_GAME:
                     init();
                     System.out.println("OK, I AM THINKING OF A NUMBER, START GUESSING.");
-                    this.gameState = GAME_STATE.GUESSING;
+                    gameState = GAME_STATE.GUESSING;
                     break;
 
                 // Player guesses the number until they get it or run out of guesses
                 case GUESSING:
-                    this.playerCurrentGuess = playerGuess();
+                    playerCurrentGuess = playerGuess();
 
                     // Check if the player guessed the number
-                    if(this.playerCurrentGuess == this.computersNumber) {
-                        this.gameState = GAME_STATE.WON;
+                    if(playerCurrentGuess == computersNumber) {
+                        gameState = GAME_STATE.WON;
                     } else {
                         // incorrect guess
                         showStars();
-                        this.playerTotalGuesses++;
+                        playerTotalGuesses++;
                         // Ran out of guesses?
-                        if (this.playerTotalGuesses > MAX_GUESSES) {
-                            this.gameState = GAME_STATE.LOST;
+                        if (playerTotalGuesses > MAX_GUESSES) {
+                            gameState = GAME_STATE.LOST;
                         }
                     }
                     break;
@@ -100,16 +100,16 @@ public class Stars {
                 case WON:
 
                     System.out.println(stars(79));
-                    System.out.println("YOU GOT IT IN " + this.playerTotalGuesses
+                    System.out.println("YOU GOT IT IN " + playerTotalGuesses
                             + " GUESSES!!!  LET'S PLAY AGAIN...");
-                    this.gameState = GAME_STATE.START_GAME;
+                    gameState = GAME_STATE.START_GAME;
                     break;
 
                 // Lost game by running out of guesses
                 case LOST:
                     System.out.println("SORRY, THAT'S " + MAX_GUESSES
-                            + " GUESSES. THE NUMBER WAS " + this.computersNumber);
-                    this.gameState = GAME_STATE.START_GAME;
+                            + " GUESSES. THE NUMBER WAS " + computersNumber);
+                    gameState = GAME_STATE.START_GAME;
                     break;
             }
             // Endless loop since the original code did not allow the player to exit
@@ -123,7 +123,7 @@ public class Stars {
      *
      */
     private void showStars() {
-        int d = Math.abs(this.playerCurrentGuess - this.computersNumber);
+        int d = Math.abs(playerCurrentGuess - computersNumber);
         int starsToShow;
         if(d >=64) {
             starsToShow = 1;
@@ -159,8 +159,8 @@ public class Stars {
      *
      */
     private void init() {
-        this.playerTotalGuesses = 1;
-        this.computersNumber = randomNumber();
+        playerTotalGuesses = 1;
+        computersNumber = randomNumber();
     }
 
     public void instructions() {
diff --git a/87 3-D Plot/perl/3dplot.pl b/87 3-D Plot/perl/3dplot.pl
new file mode 100644
index 00000000..a7cfb1c6
--- /dev/null
+++ b/87 3-D Plot/perl/3dplot.pl	
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+print ' 'x32 ."3D PLOT\n";
+print ' 'x15 ."CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n";
+print "\n\n\n";
+
+sub FNA {
+	my ($Z)= @_;
+	return 30*exp(-$Z*$Z/100);
+	}
+
+print "\n";
+
+for (my $X=-30; $X<=30; $X+=1.5) {
+	my $L=0;
+	my $Line=" "x80; #Empty buffer string;
+	my $Y1=5*int(sqrt(900-$X*$X)/5);
+	for (my $Y=$Y1; $Y>=-$Y1; $Y-=5) {
+		my $Z=int(25+&FNA(sqrt($X*$X+$Y*$Y))-.7*$Y);
+		if ($Z<=$L) { next; }
+		$L= $Z;
+		substr $Line, $Z, 1, "*"; #Plot on the line by sustitution.
+		}
+	print "$Line\n"; #Now print the line.
+	}
diff --git a/87 3-D Plot/python/3dplot.py b/87 3-D Plot/python/3dplot.py
index 99e8c438..2dda44ff 100644
--- a/87 3-D Plot/python/3dplot.py	
+++ b/87 3-D Plot/python/3dplot.py	
@@ -9,8 +9,8 @@ import math
 def equation(input):
 	return 30 * math.exp(-input * input / 100)
 
-print(" " * 32 + "3D PLOT\n")
-print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
+print(" " * 32 + "3D PLOT")
+print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n\n")
 
 for x in range (-300, 315, 15):
 	x1 = x / 10
@@ -23,4 +23,4 @@ for x in range (-300, 315, 15):
 		if z > l:
 			l = z
 			yPlot[z] = "*"
-	print("".join(yPlot) + "\n")
\ No newline at end of file
+	print("".join(yPlot))
\ No newline at end of file
diff --git a/87 3-D Plot/ruby/3dplot.rb b/87 3-D Plot/ruby/3dplot.rb
new file mode 100644
index 00000000..9c4e8394
--- /dev/null
+++ b/87 3-D Plot/ruby/3dplot.rb	
@@ -0,0 +1,28 @@
+def intro
+  puts "                                3D PLOT
+               CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n\n\n"
+end
+
+def fna(z) = 30 * Math.exp(-z * z / 100)
+
+def render
+  (-30..30).step(1.5).each do |x|
+    l = 0
+    y1 = 5 * (Math.sqrt(900 - x * x) / 5).to_i
+    y_plot = " " * 80
+    (y1..-y1).step(-5).each do |y|
+      z = (25 + fna(Math.sqrt(x * x + y * y)) - 0.7 * y).to_i
+      next if z <= l
+      l = z
+      y_plot[z] = '*'
+    end
+    puts y_plot
+  end
+end
+
+def main
+  intro
+  render
+end
+
+main
\ No newline at end of file
diff --git a/91 Train/java/src/Train.java b/91 Train/java/src/Train.java
new file mode 100644
index 00000000..0fc5ff12
--- /dev/null
+++ b/91 Train/java/src/Train.java	
@@ -0,0 +1,109 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Train
+ * 

+ * 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(); + } +} diff --git a/91 Train/javascript/train.html b/91 Train/javascript/train.html new file mode 100644 index 00000000..3aee95e2 --- /dev/null +++ b/91 Train/javascript/train.html @@ -0,0 +1,9 @@ + + +TRAIN + + +


+
+
+
diff --git a/91 Train/javascript/train.js b/91 Train/javascript/train.js
new file mode 100644
index 00000000..e49d00bc
--- /dev/null
+++ b/91 Train/javascript/train.js	
@@ -0,0 +1,80 @@
+// TRAIN
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+// Main control section
+async function main()
+{
+    print(tab(33) + "TRAIN\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("TIME - SPEED DISTANCE EXERCISE\n");
+    print("\n ");
+    while (1) {
+        c = Math.floor(25 * Math.random()) + 40;
+        d = Math.floor(15 * Math.random()) + 5;
+        t = Math.floor(19 * Math.random()) + 20;
+        print(" A CAR TRAVELING " + c + " MPH CAN MAKE A CERTAIN TRIP IN\n");
+        print(d + " HOURS LESS THAN A TRAIN TRAVELING AT " + t + " MPH.\n");
+        print("HOW LONG DOES THE TRIP TAKE BY CAR");
+        a = parseFloat(await input());
+        v = d * t / (c - t);
+        e = Math.floor(Math.abs((v - a) * 100 / a) + 0.5);
+        if (e > 5) {
+            print("SORRY.  YOU WERE OFF BY " + e + " PERCENT.\n");
+        } else {
+            print("GOOD! ANSWER WITHIN " + e + " PERCENT.\n");
+        }
+        print("CORRECT ANSWER IS " + v + " HOURS.\n");
+        print("\n");
+        print("ANOTHER PROBLEM (YES OR NO)\n");
+        str = await input();
+        print("\n");
+        if (str.substr(0, 1) != "Y")
+            break;
+    }
+}
+
+main();
diff --git a/91 Train/perl/train.pl b/91 Train/perl/train.pl
new file mode 100644
index 00000000..d628b12c
--- /dev/null
+++ b/91 Train/perl/train.pl	
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+print ' 'x33 ."TRAIN\n";
+print ' 'x15 ."CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n";
+print "\n\n\n";
+print "TIME - SPEED DISTANCE EXERCISE\n"; print "\n";
+
+
+my $A= ""; #We must declare this before...
+do {
+	my $C= int(25*rand(1))+40;
+	my $D= int(15*rand(1))+5;
+	my $T= int(19*rand(1))+20;
+
+	print " A CAR TRAVELING $C MPH CAN MAKE A CERTAIN TRIP IN\n";
+	print "$D HOURS LESS THAN A TRAIN TRAVELING AT $T MPH.\n";
+	print "HOW LONG DOES THE TRIP TAKE BY CAR\n";
+	chomp ($A = );
+
+	my $V= $D*$T/($C-$T);
+	my $E= int(abs(($V-$A)*100/$A)+.5);
+	if ($E>5) { 
+		print "SORRY.  YOU WERE OFF BY $E PERCENT.\n";
+		} else {
+		print "GOOD! ANSWER WITHIN $E PERCENT.\n";
+		}
+
+	print "CORRECT ANSWER IS $V HOURS.\n";
+	print "\n";
+	print "ANOTHER PROBLEM (YES OR NO)\n";
+	chomp ($A = uc()); #Uppercased
+	} until ($A ne "YES");
diff --git a/91 Train/python/train.py b/91 Train/python/train.py
new file mode 100644
index 00000000..0fd68b3c
--- /dev/null
+++ b/91 Train/python/train.py	
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+# TRAIN
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+
+def play_game():
+    """Play one round of the game"""
+    car_speed = random.randint(40, 65)
+    time_difference = random.randint(5, 20)
+    train_speed = random.randint(20, 39)
+    print("\nA car travelling", car_speed, "MPH can make a certain trip in")
+    print(time_difference, "hours less than a train travelling at", train_speed, "MPH")
+    time_answer = 0
+    while time_answer == 0:
+        try:
+            time_answer = float(input("How long does the trip take by car "))
+        except ValueError:
+            print("Please enter a number.")
+    car_time = time_difference*train_speed/(car_speed-train_speed)
+    error_percent = int(abs((car_time-time_answer)*100/time_answer)+.5)
+    if error_percent > 5:
+        print("Sorry. You were off by", error_percent, "percent.")
+        print("Correct answer is", round(car_time, 6), "hours")
+    else:
+        print("Good! Answer within", error_percent, "percent.")
+
+
+def main():
+    print(" " * 33 + "TRAIN")
+    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
+    print("Time - speed distance exercise")
+
+    keep_playing = True
+    while keep_playing:
+        play_game()
+        keep_playing = input(
+            "\nAnother problem (yes or no) ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/91 Train/ruby/train.rb b/91 Train/ruby/train.rb
new file mode 100644
index 00000000..c6850035
--- /dev/null
+++ b/91 Train/ruby/train.rb	
@@ -0,0 +1,58 @@
+def intro
+  puts "                                 TRAIN
+               CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
+
+
+
+TIME - SPEED DISTANCE EXERCISE
+
+"
+end
+
+def get_user_guess
+  while true
+    begin
+      number = Float(gets.chomp)
+      return number
+    rescue ArgumentError
+      # Ignored
+    end
+
+    puts "!NUMBER EXPECTED - RETRY INPUT LINE"
+    print "? "
+  end
+end
+
+def main
+  intro
+
+  loop do
+    car_speed = rand(25) + 40
+    car_time = rand(15) + 5
+    train_speed = rand(19) + 20
+
+    print " A CAR TRAVELING #{car_speed} MPH CAN MAKE A CERTAIN TRIP IN
+ #{car_time} HOURS LESS THAN A TRAIN TRAVELING AT #{train_speed} MPH.
+HOW LONG DOES THE TRIP TAKE BY CAR? "
+    guess = get_user_guess
+
+    answer = ((car_time * train_speed) / (car_speed - train_speed).to_f).round(5)
+    delta = (((answer - guess) * 100 / guess) + 0.5).abs.to_i
+
+    if delta > 5
+      puts "SORRY.  YOU WERE OFF BY #{delta} PERCENT."
+    else
+      puts "GOOD! ANSWER WITHIN #{delta} PERCENT."
+    end
+
+    print "CORRECT ANSWER IS #{answer == answer.to_i ? answer.to_i : answer} HOURS.
+
+ANOTHER PROBLEM (YES OR NO)? "
+    option = (gets || '').chomp.upcase
+    break unless option == 'YES'
+  end
+end
+
+trap "SIGINT" do puts; exit 130 end
+
+main
\ No newline at end of file
diff --git a/92 Trap/java/src/Trap.java b/92 Trap/java/src/Trap.java
new file mode 100644
index 00000000..d3dd5824
--- /dev/null
+++ b/92 Trap/java/src/Trap.java	
@@ -0,0 +1,201 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of Trap
+ * 

+ * Based on the Basic game of Trap here + * https://github.com/coding-horror/basic-computer-games/blob/main/92%20Trap/trap.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 Trap { + + public static final int HIGH_NUMBER_RANGE = 100; + public static final int MAX_GUESSES = 6; + + private enum GAME_STATE { + STARTING, + START_GAME, + GUESSING, + PLAY_AGAIN, + GAME_OVER + } + + // Used for keyboard input + private final Scanner kbScanner; + + // Current game state + private GAME_STATE gameState; + + // Players guess count; + private int currentPlayersGuess; + + // Computers random number + private int computersNumber; + + public Trap() { + + 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(); + if (yesEntered(displayTextAndGetInput("INSTRUCTIONS? "))) { + instructions(); + } + gameState = GAME_STATE.START_GAME; + break; + + // Start new game + case START_GAME: + computersNumber = randomNumber(); + currentPlayersGuess = 1; + gameState = GAME_STATE.GUESSING; + break; + + // Player guesses the number until they get it or run out of guesses + case GUESSING: + System.out.println(); + String playerRangeGuess = displayTextAndGetInput("GUESS # " + currentPlayersGuess + "? "); + int startRange = getDelimitedValue(playerRangeGuess, 0); + int endRange = getDelimitedValue(playerRangeGuess, 1); + + // Has the player won? + if (startRange == computersNumber && endRange == computersNumber) { + System.out.println("YOU GOT IT!!!"); + System.out.println(); + gameState = GAME_STATE.PLAY_AGAIN; + } else { + // show where the guess is at + System.out.println(showGuessResult(startRange, endRange)); + currentPlayersGuess++; + if (currentPlayersGuess > MAX_GUESSES) { + System.out.println("SORRY, THAT'S " + MAX_GUESSES + " GUESSES. THE NUMBER WAS " + + computersNumber); + gameState = GAME_STATE.PLAY_AGAIN; + } + } + break; + + // Play again, or exit game? + case PLAY_AGAIN: + System.out.println("TRY AGAIN"); + gameState = GAME_STATE.START_GAME; + } + } while (gameState != GAME_STATE.GAME_OVER); + } + + /** + * Show the players guess result + * + * @param start start range entered by player + * @param end end range + * @return text to indicate their progress. + */ + private String showGuessResult(int start, int end) { + + String status; + if (start <= computersNumber && computersNumber <= end) { + status = "YOU HAVE TRAPPED MY NUMBER."; + } else if (computersNumber < start) { + status = "MY NUMBER IS SMALLER THAN YOUR TRAP NUMBERS."; + } else { + status = "MY NUMBER IS LARGER THAN YOUR TRAP NUMBERS."; + } + + return status; + } + + private void instructions() { + System.out.println("I AM THINKING OF A NUMBER BETWEEN 1 AND " + HIGH_NUMBER_RANGE); + System.out.println("TRY TO GUESS MY NUMBER. ON EACH GUESS,"); + System.out.println("YOU ARE TO ENTER 2 NUMBERS, TRYING TO TRAP"); + System.out.println("MY NUMBER BETWEEN THE TWO NUMBERS. I WILL"); + System.out.println("TELL YOU IF YOU HAVE TRAPPED MY NUMBER, IF MY"); + System.out.println("NUMBER IS LARGER THAN YOUR TWO NUMBERS, OR IF"); + System.out.println("MY NUMBER IS SMALLER THAN YOUR TWO NUMBERS."); + System.out.println("IF YOU WANT TO GUESS ONE SINGLE NUMBER, TYPE"); + System.out.println("YOUR GUESS FOR BOTH YOUR TRAP NUMBERS."); + System.out.println("YOU GET " + MAX_GUESSES + " GUESSES TO GET MY NUMBER."); + } + + private void intro() { + System.out.println("TRAP"); + System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println(); + System.out.println(); + } + + /** + * 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]); + } + + /** + * 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)); + } + + /* + * 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(); + } + + /** + * Generate random number + * Used as a single digit of the computer player + * + * @return random number + */ + private int randomNumber() { + return (int) (Math.random() + * (HIGH_NUMBER_RANGE) + 1); + } +} \ No newline at end of file diff --git a/92 Trap/java/src/TrapGame.java b/92 Trap/java/src/TrapGame.java new file mode 100644 index 00000000..754446e2 --- /dev/null +++ b/92 Trap/java/src/TrapGame.java @@ -0,0 +1,8 @@ +public class TrapGame { + + public static void main(String[] args) { + + Trap trap = new Trap(); + trap.play(); + } +} diff --git a/92 Trap/javascript/trap.html b/92 Trap/javascript/trap.html new file mode 100644 index 00000000..1084e1de --- /dev/null +++ b/92 Trap/javascript/trap.html @@ -0,0 +1,9 @@ + + +TRAP + + +


+
+
+
diff --git a/92 Trap/javascript/trap.js b/92 Trap/javascript/trap.js
new file mode 100644
index 00000000..c2a5a2f3
--- /dev/null
+++ b/92 Trap/javascript/trap.js	
@@ -0,0 +1,102 @@
+// TRAP
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+// Main control section
+async function main()
+{
+    print(tab(34) + "TRAP\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    g = 6;
+    n = 100;
+    // Trap
+    // Steve Ullman, Aug/01/1972
+    print("INSTRUCTIONS");
+    str = await input();
+    if (str.substr(0, 1) == "Y") {
+        print("I AM THINKING OF A NUMBER BETWEEN 1 AND " + n + "\n");
+        print("TRY TO GUESS MY NUMBER. ON EACH GUESS,\n");
+        print("YOU ARE TO ENTER 2 NUMBERS, TRYING TO TRAP\n");
+        print("MY NUMBER BETWEEN THE TWO NUMBERS. I WILL\n");
+        print("TELL YOU IF YOU HAVE TRAPPED MY NUMBER, IF MY\n");
+        print("NUMBER IS LARGER THAN YOUR TWO NUMBERS, OR IF\n");
+        print("MY NUMBER IS SMALLER THAN YOUR TWO NUMBERS.\n");
+        print("IF YOU WANT TO GUESS ONE SINGLE NUMBER, TYPE\n");
+        print("YOUR GUESS FOR BOTH YOUR TRAP NUMBERS.\n");
+        print("YOU GET " + g + " GUESSES TO GET MY NUMBER.\n");
+    }
+    while (1) {
+        x = Math.floor(n * Math.random()) + 1;
+        for (q = 1; q <= g; q++) {
+            print("\n");
+            print("GUESS #" + q + " ");
+            str = await input();
+            a = parseInt(str);
+            b = parseInt(str.substr(str.indexOf(",") + 1));
+            if (a == b && x == a) {
+                print("YOU GOT IT!!!\n");
+                break;
+            }
+            if (a > b) {
+                r = a;
+                a = b;
+                b = r;
+            }
+            if (a <= x && x <= b) {
+                print("YOU HAVE TRAPPED MY NUMBER.\n");
+            } else if (x >= a) {
+                print("MY NUMBER IS LARGER THAN YOUR TRAP NUMBERS.\n");
+            } else {
+                print("MY NUMBER IS SMALLER THAN YOUR TRAP NUMBERS.\n");
+            }
+        }
+        print("\n");
+        print("TRY AGAIN.\n");
+        print("\n");
+    }
+}
+
+main();
diff --git a/92 Trap/python/trap.py b/92 Trap/python/trap.py
new file mode 100644
index 00000000..772bd3c5
--- /dev/null
+++ b/92 Trap/python/trap.py	
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+# TRAP
+#
+# STEVE ULLMAN, 8-1-72
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+number_max = 100
+guess_max = 6
+
+
+def play_game():
+    """Play one round of the game"""
+
+    number_computer = random.randint(1, number_max)
+    turn = 0
+    while True:
+        turn += 1
+        user_guess = [-1, -1]
+        while user_guess == [-1, -1]:
+            try:
+                user_input = [int(item) for item in input(
+                    "\nGuess # " + str(turn) + " ? ").split(",")]
+                if len(user_input) == 2:
+                    if sum(1 < x < number_max for x in user_input) == 2:
+                        user_guess = user_input
+                    else:
+                        raise ValueError
+                else:
+                    raise ValueError
+            except (ValueError, IndexError):
+                print("Please enter a valid guess.")
+        if user_guess[0] > user_guess[1]:
+            user_guess[0], user_guess[1] = user_guess[1], user_guess[0]
+        if user_guess[0] == user_guess[1] == number_computer:
+            print("You got it!!!")
+            break
+        elif user_guess[0] <= number_computer <= user_guess[1]:
+            print("You have trapped my number.")
+        elif number_computer < user_guess[0]:
+            print("My number is smaller than your trap numbers.")
+        else:
+            print("My number is larger than your trap numbers.")
+        if turn == guess_max:
+            print("That's", turn, "guesses. The number was", number_computer)
+            break
+
+
+def main():
+    print(" " * 34 + "TRAP")
+    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
+    if input("Instructions ").lower().startswith("y"):
+        print("\nI am thinking of a number between 1 and", number_max)
+        print("try to guess my number. On each guess,")
+        print("you are to enter 2 numbers, trying to trap")
+        print("my number between the two numbers. I will")
+        print("tell you if you have trapped my number, if my")
+        print("number is larger than your two numbers, or if")
+        print("my number is smaller than your two numbers.")
+        print("If you want to guess one single number, type")
+        print("your guess for both your trap numbers.")
+        print("You get", guess_max, "guesses to get my number.")
+
+    keep_playing = True
+    while keep_playing:
+        play_game()
+        keep_playing = input(
+            "\nTry again. ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/93 23 Matches/javascript/23matches.html b/93 23 Matches/javascript/23matches.html
new file mode 100644
index 00000000..70d67217
--- /dev/null
+++ b/93 23 Matches/javascript/23matches.html	
@@ -0,0 +1,9 @@
+
+
+23 MATCHES
+
+
+

+
+
+
diff --git a/93 23 Matches/javascript/23matches.js b/93 23 Matches/javascript/23matches.js
new file mode 100644
index 00000000..2233cda6
--- /dev/null
+++ b/93 23 Matches/javascript/23matches.js	
@@ -0,0 +1,122 @@
+// 23 MATCHES
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+// Main control section
+async function main()
+{
+    print(tab(31) + "23 MATCHES\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print(" THIS IS A GAME CALLED '23 MATCHES'.\n");
+    print("\n");
+    print("WHEN IT IS YOUR TURN, YOU MAY TAKE ONE, TWO, OR THREE\n");
+    print("MATCHES. THE OBJECT OF THE GAME IS NOT TO HAVE TO TAKE\n");
+    print("THE LAST MATCH.\n");
+    print("\n");
+    print("LET'S FLIP A COIN TO SEE WHO GOES FIRST.\n");
+    print("IF IT COMES UP HEADS, I WILL WIN THE TOSS.\n");
+    print("\n");
+    n = 23;
+    q = Math.floor(2 * Math.random());
+    if (q != 1) {
+        print("TAILS! YOU GO FIRST. \n");
+        print("\n");
+    } else {
+        print("HEADS! I WIN! HA! HA!\n");
+        print("PREPARE TO LOSE, MEATBALL-NOSE!!\n");
+        print("\n");
+        print("I TAKE 2 MATCHES\n");
+        n -= 2;
+    }
+    while (1) {
+        if (q == 1) {
+            print("THE NUMBER OF MATCHES IS NOW " + n + "\n");
+            print("\n");
+            print("YOUR TURN -- YOU MAY TAKE 1, 2 OR 3 MATCHES.\n");
+        }
+        print("HOW MANY DO YOU WISH TO REMOVE ");
+        while (1) {
+            k = parseInt(await input());
+            if (k <= 0 || k > 3) {
+                print("VERY FUNNY! DUMMY!\n");
+                print("DO YOU WANT TO PLAY OR GOOF AROUND?\n");
+                print("NOW, HOW MANY MATCHES DO YOU WANT ");
+            } else {
+                break;
+            }
+        }
+        n -= k;
+        print("THERE ARE NOW " + n + " MATCHES REMAINING.\n");
+        if (n == 4) {
+            z = 3;
+        } else if (n == 3) {
+            z = 2;
+        } else if (n == 2) {
+            z = 1;
+        } else if (n > 1) {
+            z = 4 - k;
+        } else {
+            print("YOU WON, FLOPPY EARS !\n");
+            print("THINK YOU'RE PRETTY SMART !\n");
+            print("LETS PLAY AGAIN AND I'LL BLOW YOUR SHOES OFF !!\n");
+            break;
+        }
+        print("MY TURN ! I REMOVE " + z + " MATCHES\n");
+        n -= z;
+        if (n <= 1) {
+            print("\n");
+            print("YOU POOR BOOB! YOU TOOK THE LAST MATCH! I GOTCHA!!\n");
+            print("HA ! HA ! I BEAT YOU !!!\n");
+            print("\n");
+            print("GOOD BYE LOSER!\n");
+            break;
+        }
+        q = 1;
+    }
+    
+}
+
+main();
diff --git a/93 23 Matches/python/23matches.py b/93 23 Matches/python/23matches.py
new file mode 100755
index 00000000..189f5aa6
--- /dev/null
+++ b/93 23 Matches/python/23matches.py	
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+# 23 Matches
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+
+def play_game():
+    """Play one round of the game"""
+
+    matches = 23
+    humans_turn = random.randint(0, 1) == 1
+    if humans_turn:
+        print("Tails! You go first.\n")
+        prompt_human = "How many do you wish to remove "
+    else:
+        print("Heads! I win! Ha! Ha!")
+        print("Prepare to lose, meatball-nose!!")
+
+    choice_human = 2
+    while matches > 0:
+        if humans_turn:
+            choice_human = 0
+            if matches == 1:
+                choice_human = 1
+            while choice_human == 0:
+                try:
+                    choice_human = int(input(prompt_human))
+                    if choice_human not in [1, 2, 3] or choice_human > matches:
+                        choice_human = 0
+                        print("Very funny! Dummy!")
+                        print("Do you want to play or goof around?")
+                        prompt_human = "Now, how many matches do you want "
+                except ValueError:
+                    print("Please enter a number.")
+                    prompt_human = "How many do you wish to remove "
+            matches = matches - choice_human
+            if matches == 0:
+                print("You poor boob! You took the last match! I gotcha!!")
+                print("Ha ! Ha ! I beat you !!\n")
+                print("Good bye loser!")
+            else:
+                print("There are now", matches, "matches remaining.\n")
+        else:
+            choice_computer = 4 - choice_human
+            if matches == 1:
+                choice_computer = 1
+            elif 1 < matches < 4:
+                choice_computer = matches - 1
+            matches = matches - choice_computer
+            if matches == 0:
+                print("You won, floppy ears !")
+                print("Think you're pretty smart !")
+                print("Let's play again and I'll blow your shoes off !!")
+            else:
+                print("My turn ! I remove", choice_computer, "matches")
+                print("The number of matches is now", matches, "\n")
+        humans_turn = not humans_turn
+        prompt_human = "Your turn -- you may take 1, 2 or 3 matches.\nHow many do you wish to remove "
+
+
+def main():
+    print(" " * 31 + "23 MATCHHES")
+    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
+    print("This is a game called '23 Matches'.\n")
+    print("When it is your turn, you may take one, two, or three")
+    print("matches. The object of the game is not to have to take")
+    print("the last match.\n")
+    print("Let's flip a coin to see who goes first.")
+    print("If it comes up heads, I will win the toss.\n")
+
+    keep_playing = True
+    while keep_playing:
+        play_game()
+        keep_playing = input(
+            "\nPlay again? (yes or no) ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/94 War/javascript/war.html b/94 War/javascript/war.html
new file mode 100644
index 00000000..67cab7d2
--- /dev/null
+++ b/94 War/javascript/war.html	
@@ -0,0 +1,9 @@
+
+
+WAR
+
+
+

+
+
+
diff --git a/94 War/javascript/war.js b/94 War/javascript/war.js
new file mode 100644
index 00000000..eb74fb0c
--- /dev/null
+++ b/94 War/javascript/war.js	
@@ -0,0 +1,136 @@
+// WAR
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+var a = [, "S-2","H-2","C-2","D-2","S-3","H-3","C-3","D-3",
+         "S-4","H-4","C-4","D-4","S-5","H-5","C-5","D-5",
+         "S-6","H-6","C-6","D-6","S-7","H-7","C-7","D-7",
+         "S-8","H-8","C-8","D-8","S-9","H-9","C-9","D-9",
+         "S-10","H-10","C-10","D-10","S-J","H-J","C-J","D-J",
+         "S-Q","H-Q","C-Q","D-Q","S-K","H-K","C-K","D-K",
+         "S-A","H-A","C-A","D-A"];
+
+var l = [];
+
+// Main control section
+async function main()
+{
+    print(tab(33) + "WAR\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("THIS IS THE CARD GAME OF WAR.  EACH CARD IS GIVEN BY SUIT-#\n");
+    print("AS S-7 FOR SPADE 7.  ");
+    while (1) {
+        print("DO YOU WANT DIRECTIONS");
+        str = await input();
+        if (str == "YES") {
+            print("THE COMPUTER GIVES YOU AND IT A 'CARD'.  THE HIGHER CARD\n");
+            print("(NUMERICALLY) WINS.  THE GAME ENDS WHEN YOU CHOOSE NOT TO\n");
+            print("CONTINUE OR WHEN YOU HAVE FINISHED THE PACK.\n");
+            break;
+        }
+        if (str == "NO")
+            break;
+        print("YES OR NO, PLEASE.  ");
+    }
+    print("\n");
+    print("\n");
+    
+    a1 = 0;
+    b1 = 0;
+    p = 0;
+    
+    // Generate a random deck
+    for (j = 1; j <= 52; j++) {
+        do {
+            l[j] = Math.floor(52 * Math.random()) + 1;
+            for (k = 1; k < j; k++) {
+                if (l[k] == l[j])   // Already in deck?
+                    break;
+            }
+        } while (j != 1 && k < j) ;
+    }
+    l[j] = 0;   // Mark the end of the deck
+    
+    while (1) {
+        m1 = l[++p];    // Take a card
+        m2 = l[++p];    // Take a card
+        print("\n");
+        print("YOU: " + a[m1] + "\tCOMPUTER: " + a[m2] + "\n");
+        n1 = Math.floor((m1 - 0.5) / 4);
+        n2 = Math.floor((m2 - 0.5) / 4);
+        if (n1 < n2) {
+            a1++;
+            print("THE COMPUTER WINS!!! YOU HAVE " + b1 + " AND THE COMPUTER HAS " + a1 + "\n");
+        } else if (n1 > n2) {
+            b1++;
+            print("YOU WIN. YOU HAVE " + b1 + " AND THE COMPUTER HAS " + a1 + "\n");
+        } else {
+            print("TIE.  NO SCORE CHANGE.\n");
+        }
+        if (l[p + 1] == 0) {
+            print("\n");
+            print("\n");
+            print("WE HAVE RUN OUT OF CARDS.  FINAL SCORE:  YOU: " + b1 + "  THE COMPUTER: " + a1 + "\n");
+            print("\n");
+            break;
+        }
+        while (1) {
+            print("DO YOU WANT TO CONTINUE");
+            str = await input();
+            if (str == "YES")
+                break;
+            if (str == "NO")
+                break;
+            print("YES OR NO, PLEASE.  ");
+        }
+        if (str == "NO")
+            break;
+    }
+    print("THANKS FOR PLAYING.  IT WAS FUN.\n");
+    print("\n");
+}
+
+main();
diff --git a/94 War/python/war.py b/94 War/python/war.py
new file mode 100755
index 00000000..ebd87036
--- /dev/null
+++ b/94 War/python/war.py	
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+# WAR
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+
+def card_value(input):
+    return ["2", "3", "4", "5", "6", "7", "8",
+            "9", "10", "J", "Q", "K", "A"].index(input.split("-")[1])
+
+
+cards = ["S-2", "H-2", "C-2", "D-2", "S-3", "H-3", "C-3", "D-3",
+         "S-4", "H-4", "C-4", "D-4", "S-5", "H-5", "C-5", "D-5",
+         "S-6", "H-6", "C-6", "D-6", "S-7", "H-7", "C-7", "D-7",
+         "S-8", "H-8", "C-8", "D-8", "S-9", "H-9", "C-9", "D-9",
+         "S-10", "H-10", "C-10", "D-10", "S-J", "H-J", "C-J", "D-J",
+         "S-Q", "H-Q", "C-Q", "D-Q", "S-K", "H-K", "C-K", "D-K",
+         "S-A", "H-A", "C-A", "D-A"]
+
+
+def play_game():
+    """Play one round of the game"""
+
+    random.shuffle(cards)
+    score_you = 0
+    score_computer = 0
+    cards_left = 52
+    for round in range(26):
+        print()
+        card_you = cards[round]
+        card_computer = cards[round * 2]
+        print("You:", card_you, " " * (8 - len(card_you)) +
+              "Computer:", card_computer)
+        value_you = card_value(card_you)
+        value_computer = card_value(card_computer)
+        if value_you > value_computer:
+            score_you += 1
+            print("You win. You have", score_you,
+                  "and the computer has", score_computer)
+        elif value_computer > value_you:
+            score_computer += 1
+            print("The computer wins!!! You have", score_you,
+                  "and the computer has", score_computer)
+        else:
+            print("Tie. No score change.")
+        cards_left -= 2
+        if cards_left > 2:
+            if input("Do you want to continue ").lower().startswith("n"):
+                break
+    if cards_left == 0:
+        print("\nWe have run out of cards. Final score: You:",
+              score_you, "the computer:", score_computer)
+    print("\nThanks for playing. It was fun.")
+
+
+def main():
+    print(" " * 33 + "WAR")
+    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
+    print("This is the card game of war. Each card is given by suit-#")
+    print("as S-7 for Spade 7.")
+    if input("Do you want directions ").lower().startswith("y"):
+        print("The computer gives you and it a 'card'. The higher card")
+        print("(numerically) wins. The game ends when you choose not to")
+        print("contine or when you have finished the pack.")
+
+    keep_playing = True
+    while keep_playing:
+        play_game()
+        keep_playing = input(
+            "\nPlay again? (yes or no) ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/95 Weekday/javascript/weekday.html b/95 Weekday/javascript/weekday.html
new file mode 100644
index 00000000..928df878
--- /dev/null
+++ b/95 Weekday/javascript/weekday.html	
@@ -0,0 +1,9 @@
+
+
+WEEKDAY
+
+
+

+
+
+
diff --git a/95 Weekday/javascript/weekday.js b/95 Weekday/javascript/weekday.js
new file mode 100644
index 00000000..276e1817
--- /dev/null
+++ b/95 Weekday/javascript/weekday.js	
@@ -0,0 +1,208 @@
+// WEEKDAY
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+function fna(arg) {
+    return Math.floor(arg / 4);
+}
+
+function fnb(arg) {
+    return Math.floor(arg / 7);
+}
+
+var t = [, 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5];
+
+var k5;
+var k6;
+var k7;
+
+function time_spent(f, a8)
+{
+    k1 = Math.floor(f * a8);
+    i5 = Math.floor(k1 / 365);
+    k1 -= i5 * 365;
+    i6 = Math.floor(k1 / 30);
+    i7 = k1 - (i6 * 30);
+    k5 -= i5;
+    k6 -= i6;
+    k7 -= i7;
+    if (k7 < 0) {
+        k7 += 30;
+        k6--;
+    }
+    if (k6 <= 0) {
+        k6 += 12;
+        k5--;
+    }
+    print(i5 + "\t" + i6 + "\t" + i7 + "\n");
+}
+
+// Main control section
+async function main()
+{
+    print(tab(32) + "WEEKDAY\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("WEEKDAY IS A COMPUTER DEMONSTRATION THAT\n");
+    print("GIVES FACTS ABOUT A DATE OF INTEREST TO YOU.\n");
+    print("\n");
+    print("ENTER TODAY'S DATE IN THE FORM: 3,24,1979  ");
+    str = await input();
+    m1 = parseInt(str);
+    d1 = parseInt(str.substr(str.indexOf(",") + 1));
+    y1 = parseInt(str.substr(str.lastIndexOf(",") + 1));
+    // This program determines the day of the week
+    //  for a date after 1582
+    print("ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST)");
+    str = await input();
+    m = parseInt(str);
+    d = parseInt(str.substr(str.indexOf(",") + 1));
+    y = parseInt(str.substr(str.lastIndexOf(",") + 1));
+    print("\n");
+    i1 = Math.floor((y - 1500) / 100);
+    // Test for date before current calendar.
+    if (y - 1582 < 0) {
+        print("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII.\n");
+    } else {
+        a = i1 * 5 + (i1 + 3) / 4;
+        i2 = Math.floor(a - fnb(a) * 7);
+        y2 = Math.floor(y / 100);
+        y3 = Math.floor(y - y2 * 100);
+        a = y3 / 4 + y3 + d + t[m] + i2;
+        b = Math.floor(a - fnb(a) * 7) + 1;
+        if (m <= 2) {
+            if (y3 != 0) {
+                t1 = Math.floor(y - fna(y) * 4);
+            } else {
+                a = i1 - 1;
+                t1 = Math.floor(a - fna(a) * 4);
+            }
+            if (t1 == 0) {
+                if (b == 0)
+                    b = 6;
+                b--;
+            }
+        }
+        if (b == 0)
+            b = 7;
+        if ((y1 * 12 + m1) * 31 + d1 < (y * 12 + m) * 31 + d) {
+            print(m + "/" + d + "/" + y + " WILL BE A ");
+        } else if ((y1 * 12 + m1) * 31 + d1 == (y * 12 + m) * 31 + d) {
+            print(m + "/" + d + "/" + y + " IS A ");
+        } else {
+            print(m + "/" + d + "/" + y + " WAS A ");
+        }
+        switch (b) {
+            case 1: print("SUNDAY.\n"); break;
+            case 2: print("MONDAY.\n"); break;
+            case 3: print("TUESDAY.\n"); break;
+            case 4: print("WEDNESDAY.\n"); break;
+            case 5: print("THURSDAY.\n"); break;
+            case 6:
+                if (d == 13) {
+                    print("FRIDAY THE THIRTEENTH---BEWARE!\n");
+                } else {
+                    print("FRIDAY.\n");
+                }
+                break;
+            case 7: print("SATURDAY.\n"); break;
+        }
+        if ((y1 * 12 + m1) * 31 + d1 != (y * 12 + m) * 31 + d) {
+            i5 = y1 - y;
+            print("\n");
+            i6 = m1 - m;
+            i7 = d1 - d;
+            if (i7 < 0) {
+                i6--;
+                i7 += 30;
+            }
+            if (i6 < 0) {
+                i5--;
+                i6 += 12;
+            }
+            if (i5 >= 0) {
+                if (i7 == 0 && i6 == 0)
+                    print("***HAPPY BIRTHDAY***\n");
+                print("                        \tYEARS\tMONTHS\tDAYS\n");
+                print("                        \t-----\t------\t----\n");
+                print("YOUR AGE (IF BIRTHDATE) \t" + i5 + "\t" + i6 + "\t" + i7 + "\n");
+                a8 = (i5 * 365) + (i6 * 30) + i7 + Math.floor(i6 / 2);
+                k5 = i5;
+                k6 = i6;
+                k7 = i7;
+                // Calculate retirement date.
+                e = y + 65;
+                // Calculate time spent in the following functions.
+                print("YOU HAVE SLEPT \t\t\t");
+                time_spent(0.35, a8);
+                print("YOU HAVE EATEN \t\t\t");
+                time_spent(0.17, a8);
+                if (k5 <= 3) {
+                    print("YOU HAVE PLAYED \t\t\t");
+                } else if (k5 <= 9) {
+                    print("YOU HAVE PLAYED/STUDIED \t\t");
+                } else {
+                    print("YOU HAVE WORKED/PLAYED \t\t");
+                }
+                time_spent(0.23, a8);
+                if (k6 == 12) {
+                    k5++;
+                    k6 = 0;
+                }
+                print("YOU HAVE RELAXED \t\t" + k5 + "\t" + k6 + "\t" + k7 + "\n");
+                print("\n");
+                print(tab(16) + "***  YOU MAY RETIRE IN " + e + " ***\n");
+                print("\n");
+            }
+        }
+    }
+    print("\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("\n");
+}
+
+main();
diff --git a/96 Word/javascript/word.html b/96 Word/javascript/word.html
new file mode 100644
index 00000000..ddc88134
--- /dev/null
+++ b/96 Word/javascript/word.html	
@@ -0,0 +1,9 @@
+
+
+WORD
+
+
+

+
+
+
diff --git a/96 Word/javascript/word.js b/96 Word/javascript/word.js
new file mode 100644
index 00000000..6e5acf50
--- /dev/null
+++ b/96 Word/javascript/word.js	
@@ -0,0 +1,150 @@
+// WORD
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+    document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+    var input_element;
+    var input_str;
+    
+    return new Promise(function (resolve) {
+                       input_element = document.createElement("INPUT");
+                       
+                       print("? ");
+                       input_element.setAttribute("type", "text");
+                       input_element.setAttribute("length", "50");
+                       document.getElementById("output").appendChild(input_element);
+                       input_element.focus();
+                       input_str = undefined;
+                       input_element.addEventListener("keydown", function (event) {
+                                                      if (event.keyCode == 13) {
+                                                      input_str = input_element.value;
+                                                      document.getElementById("output").removeChild(input_element);
+                                                      print(input_str);
+                                                      print("\n");
+                                                      resolve(input_str);
+                                                      }
+                                                      });
+                       });
+}
+
+function tab(space)
+{
+    var str = "";
+    while (space-- > 0)
+        str += " ";
+    return str;
+}
+
+var words = ["DINKY", "SMOKE", "WATER", "GLASS", "TRAIN",
+             "MIGHT", "FIRST", "CANDY", "CHAMP", "WOULD",
+             "CLUMP", "DOPEY"];
+
+var s = [];
+var a = [];
+var l = [];
+var d = [];
+var p = [];
+
+// Main control section
+async function main()
+{
+    print(tab(33) + "WORD\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("I AM THINKING OF A WORD -- YOU GUESS IT.  I WILL GIVE YOU\n");
+    print("CLUE TO HELP YO GET IT.  GOOD LUCK!!\n");
+    print("\n");
+    print("\n");
+    while (1) {
+        print("\n");
+        print("\n");
+        print("YOU ARE STARTING A NEW GAME...\n");
+        n = words.length;
+        ss = words[Math.floor(Math.random() * n)];
+        g = 0;
+        s[0] = ss.length;
+        for (i = 1; i <= ss.length; i++)
+            s[i] = ss.charCodeAt(i - 1);
+        for (i = 1; i <= 5; i++)
+            a[i] = 45;
+        for (j = 1; j <= 5; j++)
+            p[j] = 0;
+        while (1) {
+            print("GUESS A FIVE LETTER WORD");
+            ls = await input();
+            g++;
+            if (ss == ls)
+                break;
+            for (i = 1; i <= 7; i++)
+                p[i] = 0;
+            l[0] = ls.length;
+            for (i = 1; i <= ls.length; i++) {
+                l[i] = ls.charCodeAt(i - 1);
+            }
+            if (l[1] == 63) {
+                print("THE SECRET WORD IS " + ss + "\n");
+                print("\n");
+                break;
+            }
+            if (l[0] != 5) {
+                print("YOU MUST GUESS A 5 LETTER WORD.  START AGAIN.\n");
+                print("\n");
+                g--;
+                continue;
+            }
+            m = 0;
+            q = 1;
+            for (i = 1; i <= 5; i++) {
+                for (j = 1; j <= 5; j++) {
+                    if (s[i] == l[j]) {
+                        p[q] = l[j];
+                        q++;
+                        if (i == j)
+                            a[j] = l[j];
+                        m++;
+                    }
+                }
+            }
+            a[0] = 5;
+            p[0] = m;
+            as = "";
+            for (i = 1; i <= a[0]; i++)
+                as += String.fromCharCode(a[i]);
+            ps = "";
+            for (i = 1; i <= p[0]; i++)
+                ps += String.fromCharCode(p[i]);
+            print("THERE WERE " + m + " MATCHES AND THE COMMON LETTERS WERE... " + ps + "\n");
+            print("FROM THE EXACT LETTER MATCHES, YOU KNOW............ " + as + "\n");
+            if (as == ss) {
+                ls = as;
+                break;
+            }
+            if (m <= 1) {
+                print("\n");
+                print("IF YOU GIVE UP, TYPE '?' FOR YOUR NEXT GUESS.\n");
+                print("\n");
+            }
+        }
+        if (ss == ls) {
+            print("YOU HAVE GUESSED THE WORD.  IT TOOK " + g + " GUESSES!\n");
+            print("\n");
+        } else {
+            continue;
+        }
+        print("WANT TO PLAY AGAIN");
+        qs = await input();
+        if (qs != "YES")
+            break;
+    }
+}
+
+main();
diff --git a/96 Word/python/word.py b/96 Word/python/word.py
new file mode 100644
index 00000000..a3689f96
--- /dev/null
+++ b/96 Word/python/word.py	
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+# WORD
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+words = ["DINKY", "SMOKE", "WATER", "GRASS", "TRAIN", "MIGHT", "FIRST",
+         "CANDY", "CHAMP", "WOULD", "CLUMP", "DOPEY"]
+
+
+def play_game():
+    """Play one round of the game"""
+
+    random.shuffle(words)
+    target_word = words[0]
+    guess_count = 0
+    guess_progress = ["-"] * 5
+
+    print("You are starting a new game...")
+    while True:
+        guess_word = ""
+        while guess_word == "":
+            guess_word = input("\nGuess a five letter word. ").upper()
+            if guess_word == "?":
+                break
+            elif not guess_word.isalpha() or len(guess_word) != 5:
+                guess_word = ""
+                print("You must guess a five letter word. Start again.")
+        guess_count += 1
+        if guess_word == "?":
+            print("The secret word is", target_word)
+            break
+        else:
+            common_letters = ""
+            matches = 0
+            for i in range(5):
+                for j in range(5):
+                    if guess_word[i] == target_word[j]:
+                        matches += 1
+                        common_letters = common_letters + guess_word[i]
+                        if i == j:
+                            guess_progress[j] = guess_word[i]
+            print("There were", matches,
+                  "matches and the common letters were... " + common_letters)
+            print(
+                "From the exact letter matches, you know............ " + "".join(guess_progress))
+            if "".join(guess_progress) == guess_word:
+                print("\nYou have guessed the word. It took",
+                      guess_count, "guesses!")
+                break
+            elif matches == 0:
+                print("\nIf you give up, type '?' for you next guess.")
+
+
+def main():
+    print(" " * 33 + "WORD")
+    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
+
+    print("I am thinking of a word -- you guess it. I will give you")
+    print("clues to help you get it. Good luck!!\n")
+
+    keep_playing = True
+    while keep_playing:
+        play_game()
+        keep_playing = input(
+            "\nWant to play again? ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/96 Word/word.bas b/96 Word/word.bas
index 8435310f..46e69061 100644
--- a/96 Word/word.bas	
+++ b/96 Word/word.bas	
@@ -24,7 +24,7 @@
 150 PRINT "GUESS A FIVE LETTER WORD";
 160 INPUT L$
 170 G=G+1
-172 IF S$=G$ THEN 500
+172 IF S$=L$ THEN 500
 173 FOR I=1 TO 7: P(I)=0: NEXT I
 175 L(0)=LEN(L$)
 180 FOR I=1 TO LEN(L$): L(I)=ASC(MID$(L$,I,1)): NEXT I
diff --git a/basic-computer-games-dot-net/basic-computer-games-dot-net.sln b/basic-computer-games-dot-net/basic-computer-games-dot-net.sln
index a5b03908..f32f088d 100644
--- a/basic-computer-games-dot-net/basic-computer-games-dot-net.sln
+++ b/basic-computer-games-dot-net/basic-computer-games-dot-net.sln
@@ -21,6 +21,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp", "csharp", "{04298E
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "hi-lo", "..\47 Hi-Lo\csharp\hi-lo.csproj", "{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "05 Bagels", "05 Bagels", "{946C0E7C-8A83-4C7F-9959-1AF0AEF4A027}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp", "csharp", "{91DA95EE-DD42-4AEC-A886-07F834061BFC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bagels", "..\05 Bagels\csharp\Bagels.csproj", "{DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -39,6 +45,10 @@ Global
 		{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -50,6 +60,8 @@ Global
 		{26D086DE-0BBD-4A18-AC63-2476A7DB52D3} = {AC302ACD-C3B2-460D-BA1A-0A511C36A848}
 		{04298EE8-0EF3-475C-9427-E04C267BBEFB} = {A2BC8E4A-B977-46A6-B897-7E675ACB96F0}
 		{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6} = {04298EE8-0EF3-475C-9427-E04C267BBEFB}
+		{91DA95EE-DD42-4AEC-A886-07F834061BFC} = {946C0E7C-8A83-4C7F-9959-1AF0AEF4A027}
+		{DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A} = {91DA95EE-DD42-4AEC-A886-07F834061BFC}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {703D538E-7F20-4DD0-A3DD-7BBE36AC82AF}