diff --git a/.gitignore b/.gitignore index 9bea4330..e69de29b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +0,0 @@ - -.DS_Store diff --git a/01 Acey Ducey/README.md b/01 Acey Ducey/README.md index ad0bdbad..11c6b1a8 100644 --- a/01 Acey Ducey/README.md +++ b/01 Acey Ducey/README.md @@ -5,3 +5,7 @@ https://www.atariarchives.org/basicgames/showpage.php?page=2 Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html + +#### Other languages: + +- [Pascal/Object Pascal](https://github.com/gcarreno/basic-computer-games-in-pascal/tree/main/01%20Acey%20Ducey) \ No newline at end of file diff --git a/03 Animal/csharp/Animal.csproj b/03 Animal/csharp/Animal.csproj new file mode 100644 index 00000000..20827042 --- /dev/null +++ b/03 Animal/csharp/Animal.csproj @@ -0,0 +1,8 @@ + + + + Exe + net5.0 + + + diff --git a/03 Animal/csharp/Animal.sln b/03 Animal/csharp/Animal.sln new file mode 100644 index 00000000..1d81e643 --- /dev/null +++ b/03 Animal/csharp/Animal.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30907.101 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Animal", "Animal.csproj", "{D9A8DAB5-1B29-44A9-B13F-CED17B5A22B9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9A8DAB5-1B29-44A9-B13F-CED17B5A22B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D9A8DAB5-1B29-44A9-B13F-CED17B5A22B9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D9A8DAB5-1B29-44A9-B13F-CED17B5A22B9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D9A8DAB5-1B29-44A9-B13F-CED17B5A22B9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {064879D3-A288-4980-8DC4-59653D5EE2DD} + EndGlobalSection +EndGlobal diff --git a/03 Animal/csharp/Branch.cs b/03 Animal/csharp/Branch.cs new file mode 100644 index 00000000..52c13037 --- /dev/null +++ b/03 Animal/csharp/Branch.cs @@ -0,0 +1,18 @@ +namespace Animal +{ + public class Branch + { + public string Text { get; set; } + + public bool IsEnd => Yes == null && No == null; + + public Branch Yes { get; set; } + + public Branch No { get; set; } + + public override string ToString() + { + return $"{Text} : IsEnd {IsEnd}"; + } + } +} \ No newline at end of file diff --git a/03 Animal/csharp/Program.cs b/03 Animal/csharp/Program.cs new file mode 100644 index 00000000..0d159724 --- /dev/null +++ b/03 Animal/csharp/Program.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Animal; + +Console.WriteLine(new string(' ', 32) + "ANIMAL"); +Console.WriteLine(new string(' ', 15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); +Console.WriteLine(); +Console.WriteLine(); +Console.WriteLine(); +Console.WriteLine("PLAY 'GUESS THE ANIMAL'"); +Console.WriteLine(); +Console.WriteLine("THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT."); +Console.WriteLine(); + +// Root of the question and answer tree +Branch rootBranch = new Branch +{ + Text = "DOES IT SWIM", + Yes = new Branch { Text = "FISH" }, + No = new Branch { Text = "BIRD" } +}; + +string[] TRUE_INPUTS = { "Y", "YES", "T", "TRUE" }; +string[] FALSE_INPUTS = { "N", "NO", "F", "FALSE" }; + + +while (true) +{ + MainGameLoop(); +} + +void MainGameLoop() +{ + // Wait fora YES or LIST command + string input = null; + while (true) + { + input = GetInput("ARE YOU THINKING OF AN ANIMAL"); + if (IsInputListCommand(input)) + { + ListKnownAnimals(rootBranch); + } + else if (IsInputYes(input)) + { + break; + } + } + + // Walk through the tree following the YES and NO + // branches based on user input. + Branch currentBranch = rootBranch; + while (!currentBranch.IsEnd) + { + while (true) + { + input = GetInput(currentBranch.Text); + if (IsInputYes(input)) + { + currentBranch = currentBranch.Yes; + break; + } + else if (IsInputNo(input)) + { + currentBranch = currentBranch.No; + break; + } + } + } + + // Was the answer correct? + input = GetInput($"IS IT A {currentBranch.Text}"); + if (IsInputYes(input)) + { + Console.WriteLine("WHY NOT TRY ANOTHER ANIMAL?"); + return; + } + + // Interview the user to add a new question and answer + // branch to the tree + string newAnimal = GetInput("THE ANIMAL YOU WERE THINKING OF WAS A"); + string newQuestion = GetInput($"PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A {newAnimal} FROM A {currentBranch.Text}"); + string newAnswer = null; + while (true) + { + newAnswer = GetInput($"FOR A {newAnimal} THE ANSWER WOULD BE"); + if (IsInputNo(newAnswer)) + { + currentBranch.No = new Branch { Text = newAnimal }; + currentBranch.Yes = new Branch { Text = currentBranch.Text }; + currentBranch.Text = newQuestion; + break; + } + else if (IsInputYes(newAnswer)) + { + currentBranch.Yes = new Branch { Text = newAnimal }; + currentBranch.No = new Branch { Text = currentBranch.Text }; + currentBranch.Text = newQuestion; + break; + } + } +} + +string GetInput(string prompt) +{ + Console.Write($"{prompt}? "); + string result = Console.ReadLine(); + if (string.IsNullOrWhiteSpace(result)) + { + return GetInput(prompt); + } + + return result.Trim().ToUpper(); +} + +bool IsInputYes(string input) => TRUE_INPUTS.Contains(input.ToUpperInvariant().Trim()); + +bool IsInputNo(string input) => FALSE_INPUTS.Contains(input.ToUpperInvariant().Trim()); + +bool IsInputListCommand(string input) => input.ToUpperInvariant().Trim() == "LIST"; + +string[] GetKnownAnimals(Branch branch) +{ + List result = new List(); + if (branch.IsEnd) + { + return new[] { branch.Text }; + } + else + { + result.AddRange(GetKnownAnimals(branch.Yes)); + result.AddRange(GetKnownAnimals(branch.No)); + return result.ToArray(); + } +} + +void ListKnownAnimals(Branch branch) +{ + string[] animals = GetKnownAnimals(branch); + for (int x = 0; x < animals.Length; x++) + { + int column = (x % 4); + if (column == 0) + { + Console.WriteLine(); + } + + Console.Write(new string(' ', column == 0 ? 0 : 15) + animals[x]); + } + Console.WriteLine(); +} 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/04 Awari/awari.bas b/04 Awari/awari.bas index f5f66e1b..78c204e3 100644 --- a/04 Awari/awari.bas +++ b/04 Awari/awari.bas @@ -51,7 +51,7 @@ 800 D=-99:H=13 805 FOR I=0 TO 13:G(I)=B(I):NEXT I 810 FOR J=7 TO 12:IF B(J)=0 THEN 885 -815 G=0:M=J:GOSUB 600 +815 Q=0:M=J:GOSUB 600 820 FOR I=0 TO 5:IF B(I)=0 THEN 845 825 L=B(I)+I:R=0 830 IF L>13 THEN L=L-14:R=1:GOTO 830 diff --git a/04 Awari/javascript/awari.html b/04 Awari/javascript/awari.html new file mode 100644 index 00000000..1d3c6208 --- /dev/null +++ b/04 Awari/javascript/awari.html @@ -0,0 +1,9 @@ + + +AWARI + + +

+
+
+
diff --git a/04 Awari/javascript/awari.js b/04 Awari/javascript/awari.js
new file mode 100644
index 00000000..cda27c08
--- /dev/null
+++ b/04 Awari/javascript/awari.js	
@@ -0,0 +1,259 @@
+// AWARI
+//
+// 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(34) + "AWARI\n");
+print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+
+n = 0;
+
+b = [0,0,0,0,0,0,0,0,0,0,0,0,0,0];
+g = [0,0,0,0,0,0,0,0,0,0,0,0,0,0];
+f = [];
+for (i = 0; i <= 50; i++) {
+    f[i] = 0;
+}
+
+function show_number(number)
+{
+    if (number < 10)
+        print("  " + number + " ");
+    else
+        print(" " + number + " ");
+}
+
+function show_board()
+{
+    var i;
+    
+    print("\n");
+    print("   ");
+    for (i = 12; i >= 7; i--)
+        show_number(b[i]);
+    print("\n");
+    i = 13;
+    show_number(b[i]);
+    print("                       " + b[6] + "\n");
+    print("   ");
+    for (i = 0; i <= 5; i++)
+        show_number(b[i]);
+    print("\n");
+    print("\n");
+}
+
+function do_move()
+{
+    k = m;
+    adjust_board();
+    e = 0;
+    if (k > 6)
+        k -= 7;
+    c++;
+    if (c < 9)
+        f[n] = f[n] * 6 + k
+        for (i = 0; i <= 5; i++) {
+            if (b[i] != 0) {
+                for (i = 7; i <= 12; i++) {
+                    if (b[i] != 0) {
+                        e = 1;
+                        return;
+                    }
+                }
+            }
+        }
+}
+
+function adjust_board()
+{
+    p = b[m];
+    b[m] = 0;
+    while (p >= 1) {
+        m++;
+        if (m > 13)
+            m -= 14;
+        b[m]++;
+        p--;
+    }
+    if (b[m] == 1) {
+        if (m != 6 && m != 13) {
+            if (b[12 - m] != 0) {
+                b[h] += b[12 - m] + 1;
+                b[m] = 0;
+                b[12 - m] = 0;
+            }
+        }
+    }
+}
+
+function computer_move()
+{
+    d = -99;
+    h = 13;
+    for (i = 0; i<= 13; i++)	// Backup board
+        g[i] = b[i];
+    for (j = 7; j <= 12; j++) {
+        if (b[j] == 0)
+            continue;
+        q = 0;
+        m = j;
+        adjust_board();
+        for (i = 0; i <= 5; i++) {
+            if (b[i] == 0)
+                continue;
+            l = b[i] + i;
+            r = 0;
+            while (l > 13) {
+                l -= 14;
+                r = 1;
+            }
+            if (b[l] == 0) {
+                if (l != 6 && l != 13)
+                    r = b[12 - l] + r;
+            }
+            if (r > q)
+                q = r;
+        }
+        q = b[13] - b[6] - q;
+        if (c < 8) {
+            k = j;
+            if (k > 6)
+                k -= 7;
+            for (i = 0; i <= n - 1; i++) {
+                if (f[n] * 6 + k == Math.floor(f[i] / Math.pow(7 - c, 6) + 0.1))
+                    q -= 2;
+            }
+        }
+        for (i = 0; i <= 13; i++)	// Restore board
+            b[i] = g[i];
+        if (q >= d) {
+            a = j;
+            d = q;
+        }
+    }
+    m = a;
+    print(m - 6);
+    do_move();
+}
+
+// Main program
+async function main()
+{
+    while (1) {
+        print("\n");
+        print("\n");
+        e = 0;
+        for (i = 0; i <= 12; i++)
+            b[i] = 3;
+        
+        c = 0;
+        f[n] = 0;
+        b[13] = 0;
+        b[6] = 0;
+        
+        while (1) {
+            show_board();
+            print("YOUR MOVE");
+            while (1) {
+                m = parseInt(await input());
+                if (m < 7) {
+                    if (m > 0) {
+                        m--;
+                        if (b[m] != 0)
+                            break;
+                    }
+                }
+                print("ILLEGAL MOVE\n");
+                print("AGAIN");
+            }
+            h = 6;
+            do_move();
+            show_board();
+            if (e == 0)
+                break;
+            if (m == h) {
+                print("AGAIN");
+                while (1) {
+                    m = parseInt(await input());
+                    if (m < 7) {
+                        if (m > 0) {
+                            m--;
+                            if (b[m] != 0)
+                                break;
+                        }
+                    }
+                    print("ILLEGAL MOVE\n");
+                    print("AGAIN");
+                }
+                h = 6;
+                do_move();
+                show_board();
+            }
+            if (e == 0)
+                break;
+            print("MY MOVE IS ");
+            computer_move();
+            if (e == 0)
+                break;
+            if (m == h) {
+                print(",");
+                computer_move();
+            }
+            if (e == 0)
+                break;
+        }
+        print("\n");
+        print("GAME OVER\n");
+        d = b[6] - b[13];
+        if (d < 0)
+            print("I WIN BY " + -d + " POINTS\n");
+        else if (d == 0) {
+            n++;
+            print("DRAWN GAME\n");
+        } else {
+            n++;
+            print("YOU WIN BY " + d + " POINTS\n");
+        }
+    }
+}
+
+main();
diff --git a/05 Bagels/bagels.bas b/05 Bagels/bagels.bas
index 3136955b..d16c20c3 100644
--- a/05 Bagels/bagels.bas	
+++ b/05 Bagels/bagels.bas	
@@ -3,7 +3,7 @@
 15 REM *** BAGLES NUMBER GUESSING GAME
 20 REM *** ORIGINAL SOURCE UNKNOWN BUT SUSPECTED TO BE
 25 REM *** LAWRENCE HALL OF SCIENCE, U.C. BERKELY
-30 DIM A1(6),A(3),B(3)
+30 DIM A1(3),A(3),B(3)
 40 Y=0:T=255
 50 PRINT:PRINT:PRINT
 70 INPUT "WOULD YOU LIKE THE RULES (YES OR NO)";A$
@@ -66,7 +66,7 @@
 600 PRINT
 605 NEXT I
 610 PRINT "OH WELL."
-615 PRINT "THAT'S TWNETY GUESSES.  MY NUMBER WAS";100*A(1)+10*A(2)+A(3)
+615 PRINT "THAT'S TWENTY GUESSES.  MY NUMBER WAS";100*A(1)+10*A(2)+A(3)
 620 GOTO 700
 630 PRINT "TRY GUESSING A THREE-DIGIT NUMBER.":GOTO 230
 650 PRINT "OH, I FORGOT TO TELL YOU THAT THE NUMBER I HAVE IN MIND"
@@ -74,7 +74,7 @@
 680 PRINT "YOU GOT IT!!!":PRINT
 690 Y=Y+1
 700 INPUT "PLAY AGAIN (YES OR NO)";A$
-720 IF LEFT$(A$,1)="YES" THEN 150
+720 IF LEFT$(A$,1)="Y" THEN 150
 730 IF Y=0 THEN 750
 740 PRINT:PRINT "A";Y;"POINT BAGELS BUFF!!"
 750 PRINT "HOPE YOU HAD FUN.  BYE."
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/05 Bagels/javascript/bagels.html b/05 Bagels/javascript/bagels.html
new file mode 100644
index 00000000..714c3c9a
--- /dev/null
+++ b/05 Bagels/javascript/bagels.html	
@@ -0,0 +1,9 @@
+
+
+BAGELS
+
+
+

+
+
+
diff --git a/05 Bagels/javascript/bagels.js b/05 Bagels/javascript/bagels.js
new file mode 100644
index 00000000..37fa3665
--- /dev/null
+++ b/05 Bagels/javascript/bagels.js	
@@ -0,0 +1,160 @@
+// BAGELS
+//
+// 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(33) + "BAGELS\n");
+print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+
+// *** Bagles number guessing game
+// *** Original source unknown but suspected to be
+// *** Lawrence Hall of Science, U.C. Berkeley
+
+a1 = [0,0,0,0];
+a = [0,0,0,0];
+b = [0,0,0,0];
+
+y = 0;
+t = 255;
+
+print("\n");
+print("\n");
+print("\n");
+
+// Main program
+async function main()
+{
+    while (1) {
+        print("WOULD YOU LIKE THE RULES (YES OR NO)");
+        str = await input();
+        if (str.substr(0, 1) != "N") {
+            print("\n");
+            print("I AM THINKING OF A THREE-DIGIT NUMBER.  TRY TO GUESS\n");
+            print("MY NUMBER AND I WILL GIVE YOU CLUES AS FOLLOWS:\n");
+            print("   PICO   - ONE DIGIT CORRECT BUT IN THE WRONG POSITION\n");
+            print("   FERMI  - ONE DIGIT CORRECT AND IN THE RIGHT POSITION\n");
+            print("   BAGELS - NO DIGITS CORRECT\n");
+        }
+        for (i = 1; i <= 3; i++) {
+            do {
+                a[i] = Math.floor(Math.random() * 10);
+                for (j = i - 1; j >= 1; j--) {
+                    if (a[i] == a[j])
+                        break;
+                }
+            } while (j >= 1) ;
+        }
+        print("\n");
+        print("O.K.  I HAVE A NUMBER IN MIND.\n");
+        for (i = 1; i <= 20; i++) {
+            while (1) {
+                print("GUESS #" + i);
+                str = await input();
+                if (str.length != 3) {
+                    print("TRY GUESSING A THREE-DIGIT NUMBER.\n");
+                    continue;
+                }
+                for (z = 1; z <= 3; z++)
+                    a1[z] = str.charCodeAt(z - 1);
+                for (j = 1; j <= 3; j++) {
+                    if (a1[j] < 48 || a1[j] > 57)
+                        break;
+                    b[j] = a1[j] - 48;
+                }
+                if (j <= 3) {
+                    print("WHAT?");
+                    continue;
+                }
+                if (b[1] == b[2] || b[2] == b[3] || b[3] == b[1]) {
+                    print("OH, I FORGOT TO TELL YOU THAT THE NUMBER I HAVE IN MIND\n");
+                    print("HAS NO TWO DIGITS THE SAME.\n");
+                    continue;
+                }
+                break;
+            }
+            c = 0;
+            d = 0;
+            for (j = 1; j <= 2; j++) {
+                if (a[j] == b[j + 1])
+                    c++;
+                if (a[j + 1] == b[j])
+                    c++;
+            }
+            if (a[1] == b[3])
+                c++;
+            if (a[3] == b[1])
+                c++;
+            for (j = 1; j <= 3; j++) {
+                if (a[j] == b[j])
+                    d++;
+            }
+            if (d == 3)
+                break;
+            for (j = 0; j < c; j++)
+                print("PICO ");
+            for (j = 0; j < d; j++)
+                print("FERMI ");
+            if (c + d == 0)
+                print("BAGELS");
+            print("\n");
+        }
+        if (i <= 20) {
+            print("YOU GOT IT!!!\n");
+            print("\n");
+        } else {
+            print("OH WELL.\n");
+            print("THAT'S A TWENTY GUESS.  MY NUMBER WAS " + a[1] + a[2] + a[3]);
+        }
+        y++;
+        print("PLAY AGAIN (YES OR NO)");
+        str = await input();
+        if (str.substr(0, 1) != "Y")
+            break;
+    }
+    if (y == 0)
+        print("HOPE YOU HAD FUN.  BYE.\n");
+    else
+        print("\nA " + y + " POINT BAGELS BUFF!!\n");
+    
+}
+
+main();
diff --git a/06 Banner/javascript/banner.html b/06 Banner/javascript/banner.html
new file mode 100644
index 00000000..62f1bca8
--- /dev/null
+++ b/06 Banner/javascript/banner.html	
@@ -0,0 +1,9 @@
+
+
+BANNER
+
+
+

+
+
+
diff --git a/06 Banner/javascript/banner.js b/06 Banner/javascript/banner.js
new file mode 100644
index 00000000..ca360487
--- /dev/null
+++ b/06 Banner/javascript/banner.js	
@@ -0,0 +1,168 @@
+// BANNER
+//
+// 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 letters = [" ",0,0,0,0,0,0,0,
+               "A",505,37,35,34,35,37,505,
+               "G",125,131,258,258,290,163,101,
+               "E",512,274,274,274,274,258,258,
+               "T",2,2,2,512,2,2,2,
+               "W",256,257,129,65,129,257,256,
+               "L",512,257,257,257,257,257,257,
+               "S",69,139,274,274,274,163,69,
+               "O",125,131,258,258,258,131,125,
+               "N",512,7,9,17,33,193,512,
+               "F",512,18,18,18,18,2,2,
+               "K",512,17,17,41,69,131,258,
+               "B",512,274,274,274,274,274,239,
+               "D",512,258,258,258,258,131,125,
+               "H",512,17,17,17,17,17,512,
+               "M",512,7,13,25,13,7,512,
+               "?",5,3,2,354,18,11,5,
+               "U",128,129,257,257,257,129,128,
+               "R",512,18,18,50,82,146,271,
+               "P",512,18,18,18,18,18,15,
+               "Q",125,131,258,258,322,131,381,
+               "Y",8,9,17,481,17,9,8,
+               "V",64,65,129,257,129,65,64,
+               "X",388,69,41,17,41,69,388,
+               "Z",386,322,290,274,266,262,260,
+               "I",258,258,258,512,258,258,258,
+               "C",125,131,258,258,258,131,69,
+               "J",65,129,257,257,257,129,128,
+               "1",0,0,261,259,512,257,257,
+               "2",261,387,322,290,274,267,261,
+               "*",69,41,17,512,17,41,69,
+               "3",66,130,258,274,266,150,100,
+               "4",33,49,41,37,35,512,33,
+               "5",160,274,274,274,274,274,226,
+               "6",194,291,293,297,305,289,193,
+               "7",258,130,66,34,18,10,8,
+               "8",69,171,274,274,274,171,69,
+               "9",263,138,74,42,26,10,7,
+               "=",41,41,41,41,41,41,41,
+               "!",1,1,1,384,1,1,1,
+               "0",57,69,131,258,131,69,57,
+               ".",1,1,129,449,129,1,1];
+
+f = [];
+j = [];
+s = [];
+
+// Main program
+async function main()
+{
+    print("HORIZONTAL");
+    x = parseInt(await input());
+    print("VERTICAL");
+    y = parseInt(await input());
+    print("CENTERED");
+    ls = await input();
+    g1 = 0;
+    if (ls > "P")
+        g1 = 1;
+    print("CHARACTER (TYPE 'ALL' IF YOU WANT CHARACTER BEING PRINTED)");
+    ms = await input();
+    print("STATEMENT");
+    as = await input();
+    print("SET PAGE");	// This means to prepare printer, just press Enter
+    os = await input();
+    
+    for (t = 0; t < as.length; t++) {
+        ps = as.substr(t, 1);
+        for (o = 0; o < 50 * 8; o += 8) {
+            if (letters[o] == ps) {
+                for (u = 1; u <= 7; u++)
+                    s[u] = letters[o + u];
+                break;
+            }
+        }
+        if (o == 50 * 8) {
+            ps = " ";
+            o = 0;
+        }
+//      print("Doing " + o + "\n");
+        if (o == 0) {
+            for (h = 1; h <= 7 * x; h++)
+                print("\n");
+        } else {
+            xs = ms;
+            if (ms == "ALL")
+                xs = ps;
+            for (u = 1; u <= 7; u++) {
+                // An inefficient way of extracting bits
+                // but good enough in BASIC because there
+                // aren't bit shifting operators.
+                for (k = 8; k >= 0; k--) {
+                    if (Math.pow(2, k) >= s[u]) {
+                        j[9 - k] = 0;
+                    } else {
+                        j[9 - k] = 1;
+                        s[u] -= Math.pow(2, k);
+                        if (s[u] == 1) {
+                            f[u] = 9 - k;
+                            break;
+                        }
+                    }
+                }
+                for (t1 = 1; t1 <= x; t1++) {
+                    str = tab((63 - 4.5 * y) * g1 / xs.length + 1);
+                    for (b = 1; b <= f[u]; b++) {
+                        if (j[b] == 0) {
+                            for (i = 1; i <= y; i++)
+                                str += tab(xs.length);
+                        } else {
+                            for (i = 1; i <= y; i++)
+                                str += xs;
+                        }
+                    }
+                    print(str + "\n");	
+                }
+            }
+            for (h = 1; h <= 2 * x; h++) 
+                print("\n");
+        }
+    }    
+}
+
+main();
diff --git a/06 Banner/python/banner.py b/06 Banner/python/banner.py
new file mode 100644
index 00000000..11f10766
--- /dev/null
+++ b/06 Banner/python/banner.py	
@@ -0,0 +1,123 @@
+#!/usr/bin/env python3
+
+# BANNER
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+letters = {
+    " ": [0, 0, 0, 0, 0, 0, 0],
+    "A": [505, 37, 35, 34, 35, 37, 505],
+    "G": [125, 131, 258, 258, 290, 163, 101],
+    "E": [512, 274, 274, 274, 274, 258, 258],
+    "T": [2, 2, 2, 512, 2, 2, 2],
+    "W": [256, 257, 129, 65, 129, 257, 256],
+    "L": [512, 257, 257, 257, 257, 257, 257],
+    "S": [69, 139, 274, 274, 274, 163, 69],
+    "O": [125, 131, 258, 258, 258, 131, 125],
+    "N": [512, 7, 9, 17, 33, 193, 512],
+    "F": [512, 18, 18, 18, 18, 2, 2],
+    "K": [512, 17, 17, 41, 69, 131, 258],
+    "B": [512, 274, 274, 274, 274, 274, 239],
+    "D": [512, 258, 258, 258, 258, 131, 125],
+    "H": [512, 17, 17, 17, 17, 17, 512],
+    "M": [512, 7, 13, 25, 13, 7, 512],
+    "?": [5, 3, 2, 354, 18, 11, 5],
+    "U": [128, 129, 257, 257, 257, 129, 128],
+    "R": [512, 18, 18, 50, 82, 146, 271],
+    "P": [512, 18, 18, 18, 18, 18, 15],
+    "Q": [125, 131, 258, 258, 322, 131, 381],
+    "Y": [8, 9, 17, 481, 17, 9, 8],
+    "V": [64, 65, 129, 257, 129, 65, 64],
+    "X": [388, 69, 41, 17, 41, 69, 388],
+    "Z": [386, 322, 290, 274, 266, 262, 260],
+    "I": [258, 258, 258, 512, 258, 258, 258],
+    "C": [125, 131, 258, 258, 258, 131, 69],
+    "J": [65, 129, 257, 257, 257, 129, 128],
+    "1": [0, 0, 261, 259, 512, 257, 257],
+    "2": [261, 387, 322, 290, 274, 267, 261],
+    "*": [69, 41, 17, 512, 17, 41, 69],
+    "3": [66, 130, 258, 274, 266, 150, 100],
+    "4": [33, 49, 41, 37, 35, 512, 33],
+    "5": [160, 274, 274, 274, 274, 274, 226],
+    "6": [194, 291, 293, 297, 305, 289, 193],
+    "7": [258, 130, 66, 34, 18, 10, 8],
+    "8": [69, 171, 274, 274, 274, 171, 69],
+    "9": [263, 138, 74, 42, 26, 10, 7],
+    "=": [41, 41, 41, 41, 41, 41, 41],
+    "!": [1, 1, 1, 384, 1, 1, 1],
+    "0": [57, 69, 131, 258, 131, 69, 57],
+    ".": [1, 1, 129, 449, 129, 1, 1],
+}
+
+
+def print_banner():
+    """Print the banner"""
+
+    f = [0] * 7
+    j = [0] * 9
+
+    while True:
+        try:
+            x = int(input("Horizontal "))
+            if x < 1:
+                raise ValueError("Horizontal must be greater than zero")
+            break
+
+        except ValueError:
+            print("Please enter a number greater than zero")
+    while True:
+        try:
+            y = int(input("Vertical "))
+            if y < 1:
+                raise ValueError("Vertical must be greater than zero")
+            break
+
+        except ValueError:
+            print("Please enter a number greater than zero")
+    g1 = 0
+    if input("Centered ").lower().startswith("y"):
+        g1 = 1
+    mStr = input(
+        "Character (type 'ALL' if you want character being printed) ").upper()
+    aStr = input("Statement ")
+    # This means to prepare printer, just press Enter
+    oStr = input("Set page ")
+    for lStr in aStr:
+        s = letters[lStr].copy()
+        xStr = mStr
+        if mStr == "ALL":
+            xStr = lStr
+        if xStr == " ":
+            print("\n" * (7 * x))
+        else:
+            for u in range(0, 7):
+                for k in range(8, -1, -1):
+                    if 2 ** k >= s[u]:
+                        j[8 - k] = 0
+                    else:
+                        j[8 - k] = 1
+                        s[u] = s[u] - 2 ** k
+                        if s[u] == 1:
+                            f[u] = 8 - k
+                            break
+                for t1 in range(1, x + 1):
+                    lineStr = " " * int((63 - 4.5 * y) * g1 / len(xStr) + 1)
+                    for b in range(0, f[u] + 1):
+                        if j[b] == 0:
+                            for i in range(1, y + 1):
+                                lineStr = lineStr + " " * len(xStr)
+                        else:
+                            lineStr = lineStr + xStr * y
+                    print(lineStr)
+            print("\n" * (2 * x - 1))
+    # print("\n" * 75)  # Feed some more paper from the printer
+
+
+def main():
+    """Main"""
+
+    print_banner()
+
+
+if __name__ == "__main__":
+    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/18 Bullseye/bullseye.bas b/18 Bullseye/bullseye.bas
index 7a5e432f..eec7cf06 100644
--- a/18 Bullseye/bullseye.bas	
+++ b/18 Bullseye/bullseye.bas	
@@ -16,7 +16,7 @@
 150 R=R+1: PRINT: PRINT "ROUND";R:PRINT "---------"
 160 FOR I=1 TO N
 170 PRINT: PRINT A$(I)"'S THROW";: INPUT T
-180 IF T<0 OR T>3 THEN PRINT "INPUT 1, 2, OR 3!": GOTO 170
+180 IF T<1 OR T>3 THEN PRINT "INPUT 1, 2, OR 3!": GOTO 170
 190 ON T GOTO 200, 210, 200
 200 P1=.65: P2=.55: P3=.5: P4=.5: GOTO 230
 210 P1=.99: P2=.77: P3=.43: P4=.01: GOTO 230
diff --git a/18 Bullseye/javascript/bullseye.html b/18 Bullseye/javascript/bullseye.html
new file mode 100644
index 00000000..82f13306
--- /dev/null
+++ b/18 Bullseye/javascript/bullseye.html	
@@ -0,0 +1,9 @@
+
+
+BULLSEYE
+
+
+

+
+
+
diff --git a/18 Bullseye/javascript/bullseye.js b/18 Bullseye/javascript/bullseye.js
new file mode 100644
index 00000000..0b8d061c
--- /dev/null
+++ b/18 Bullseye/javascript/bullseye.js	
@@ -0,0 +1,142 @@
+// BULLSEYE
+//
+// 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 as = [];
+var s = [];
+var w = [];
+
+// Main program
+async function main()
+{
+    print(tab(32) + "BULLSEYE\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("IN THIS GAME, UP TO 20 PLAYERS THROW DARTS AT A TARGET\n");
+    print("WITH 10, 20, 30, AND 40 POINT ZONES.  THE OBJECTIVE IS\n");
+    print("TO GET 200 POINTS.\n");
+    print("\n");
+    print("THROW\t\tDESCRIPTION\t\tPROBABLE SCORE\n");
+    print("1\t\tFAST OVERARM\t\tBULLSEYE OR COMPLETE MISS\n");
+    print("2\t\tCONTROLLED OVERARM\t10, 20 OR 30 POINTS\n");
+    print("3\t\tUNDERARM\t\tANYTHING\n");
+    print("\n");
+    m = 0;
+    r = 0;
+    for (i = 1; i <= 20; i++)
+        s[i] = 0;
+    print("HOW MANY PLAYERS");
+    n = parseInt(await input());
+    print("\n");
+    for (i = 1; i <= n; i++) {
+        print("NAME OF PLAYER #" + i);
+        as[i] = await input();
+    }
+    do {
+        r++;
+        print("\n");
+        print("ROUND " + r + "\n");
+        print("---------\n");
+        for (i = 1; i <= n; i++) {
+            do {
+                print("\n");
+                print(as[i] + "'S THROW");
+                t = parseInt(await input());
+                if (t < 1 || t > 3)
+                    print("INPUT 1, 2, OR 3!\n");
+            } while (t < 1 || t > 3) ;
+            if (t == 1) {
+                p1 = 0.65;
+                p2 = 0.55;
+                p3 = 0.5;
+                p4 = 0.5;
+            } else if (t == 2) {
+                p1 = 0.99;
+                p2 = 0.77;
+                p3 = 0.43;
+                p4 = 0.01;
+            } else {
+                p1 = 0.95;
+                p2 = 0.75;
+                p3 = 0.45;
+                p4 = 0.05;
+            }
+            u = Math.random();
+            if (u >= p1) {
+                print("BULLSEYE!!  40 POINTS!\n");
+                b = 40;
+            } else if (u >= p2) {
+                print("30-POINT ZONE!\n");
+                b = 30;
+            } else if (u >= p3) {
+                print("20-POINT ZONE\n");
+                b = 20;
+            } else if (u >= p4) {
+                print("WHEW!  10 POINT.\n");
+                b = 10;
+            } else {
+                print("MISSED THE TARGET!  TOO BAD.\n");
+                b = 0;
+            }
+            s[i] += b;
+            print("TOTAL SCORE = " + s[i] + "\n");
+        }
+        for (i = 1; i <= n; i++) {
+            if (s[i] >= 200) {
+                m++;
+                w[m] = i;
+            }
+        }
+    } while (m == 0) ;
+    print("\n");
+    print("WE HAVE A WINNER!!\n");
+    print("\n");
+    for (i = 1; i <= m; i++)
+        print(as[w[i]] + " SCORED " + s[w[i]] + " POINTS.\n");
+    print("\n");
+    print("THANKS FOR THE GAME.\n");
+}
+
+main();
diff --git a/19 Bunny/python/bunny.py b/19 Bunny/python/bunny.py
new file mode 100755
index 00000000..c1c9a697
--- /dev/null
+++ b/19 Bunny/python/bunny.py	
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+
+
+# This data is meant to be read-only, so we are storing it in a tuple
+DATA = (2,21,14,14,25,
+        1,2,-1,0,2,45,50,-1,0,5,43,52,-1,0,7,41,52,-1,
+        1,9,37,50,-1,2,11,36,50,-1,3,13,34,49,-1,4,14,32,48,-1,
+        5,15,31,47,-1,6,16,30,45,-1,7,17,29,44,-1,8,19,28,43,-1,
+        9,20,27,41,-1,10,21,26,40,-1,11,22,25,38,-1,12,22,24,36,-1,
+        13,34,-1,14,33,-1,15,31,-1,17,29,-1,18,27,-1,
+        19,26,-1,16,28,-1,13,30,-1,11,31,-1,10,32,-1,
+        8,33,-1,7,34,-1,6,13,16,34,-1,5,12,16,35,-1,
+        4,12,16,35,-1,3,12,15,35,-1,2,35,-1,1,35,-1,
+        2,34,-1,3,34,-1,4,33,-1,6,33,-1,10,32,34,34,-1,
+        14,17,19,25,28,31,35,35,-1,15,19,23,30,36,36,-1,
+        14,18,21,21,24,30,37,37,-1,13,18,23,29,33,38,-1,
+        12,29,31,33,-1,11,13,17,17,19,19,22,22,24,31,-1,
+        10,11,17,18,22,22,24,24,29,29,-1,
+        22,23,26,29,-1,27,29,-1,28,29,-1,4096)
+
+
+def display_intro():
+    print(tab(33) + "BUNNY")
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
+    print("\n\n")
+
+
+def tab(column):
+    """ Emulates the TAB command in BASIC. Returns a string with ASCII
+        codes for setting the cursor to the specified column. """
+    return "\r\33[{}C".format(column)
+
+
+def play():
+    display_intro()
+
+    # Using an iterator will give us a similar interface to BASIC's READ
+    # command. Instead of READ, we will call 'next(data)' to fetch the next element.
+    data = iter(DATA)
+
+    # Read the first 5 numbers. These correspond to letters of the alphabet.
+    # B=2, U=21, N=14, N=14, Y=25
+
+    # Usually, list comprehensions are good for transforming each element in a sequence.
+    # In this case, we are using range to repeat the call to next(data) 5 times. The underscore (_)
+    # indicates that the values from range are discarded.
+    bunny = [next(data) for _ in range(5)]
+    L = 64
+
+    # Interpretting a stream of data is a very common software task. We've already intepretted
+    # the first 5 numbers as letters of the alphabet (with A being 1). Now, we are going to
+    # combine this with a different interpretation of the following data to draw on the screen.
+    # The drawing data is essentially a series of horizontal line segments given as begin and end
+    # offsets.
+    while True:
+        command = next(data)
+
+        if command < 0:
+            print()
+            continue
+
+        if command > 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/.DS_Store b/20 Buzzword/.DS_Store
new file mode 100644
index 00000000..5008ddfc
Binary files /dev/null and b/20 Buzzword/.DS_Store differ
diff --git a/20 Buzzword/buzzword.bas b/20 Buzzword/buzzword.bas
index 66a0ae06..7c751a70 100644
--- a/20 Buzzword/buzzword.bas	
+++ b/20 Buzzword/buzzword.bas	
@@ -2,7 +2,7 @@
 20 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
 30 PRINT:PRINT:PRINT
 40 PRINT "THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN"
-50 PRINT "'EDUCATOR-SPEAK'THAT YOU CAN WORK INTO REPORTS"
+50 PRINT "'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS"
 60 PRINT "AND SPEECHES.  WHENEVER A QUESTION MARK IS PRINTED,"
 70 PRINT "TYPE A 'Y' FOR ANOTHER PHRASE OR 'N' TO QUIT."
 80 PRINT:PRINT:PRINT "HERE'S THE FIRST PHRASE:"
diff --git a/20 Buzzword/javascript/buzzword.html b/20 Buzzword/javascript/buzzword.html
new file mode 100644
index 00000000..e384b3fc
--- /dev/null
+++ b/20 Buzzword/javascript/buzzword.html	
@@ -0,0 +1,9 @@
+
+
+BUZZWORD
+
+
+

+
+
+
diff --git a/20 Buzzword/javascript/buzzword.js b/20 Buzzword/javascript/buzzword.js
new file mode 100644
index 00000000..80c4e51e
--- /dev/null
+++ b/20 Buzzword/javascript/buzzword.js	
@@ -0,0 +1,83 @@
+// BUZZWORD
+//
+// 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 = ["",
+         "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",
+         ];
+
+// Main program
+async function main()
+{
+    print(tab(26) + "BUZZWORD GENERATOR\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN\n");
+    print("'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS\n");
+    print("AND SPEECHES.  WHENEVER A QUESTION MARK IS PRINTED,\n");
+    print("TYPE A 'Y' FOR ANOTHER PHRASE OR 'N' TO QUIT.\n");
+    print("\n");
+    print("\n");
+    print("HERE'S THE FIRST PHRASE:\n");
+    do {
+        print(a[Math.floor(Math.random() * 13 + 1)] + " ");
+        print(a[Math.floor(Math.random() * 13 + 14)] + " ");
+        print(a[Math.floor(Math.random() * 13 + 27)] + "\n");
+        print("\n");
+        y = await input();
+    } while (y == "Y") ;
+    print("COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!\n");
+}
+
+main();
diff --git a/20 Buzzword/ruby/buzzword.rb b/20 Buzzword/ruby/buzzword.rb
new file mode 100644
index 00000000..3ddcf0fa
--- /dev/null
+++ b/20 Buzzword/ruby/buzzword.rb	
@@ -0,0 +1,101 @@
+######################################################################
+#
+# Buzzword Generator
+#
+# From: BASIC Computer Games (1978)
+#       Edited by David H. Ahl
+#
+# "This program is an invaluable aid for preparing speeches and
+#  briefings about education technology.  This buzzword generator
+#  provides sets of three highly-acceptable words to work into your
+#  material.  Your audience will never know that the phrases don't
+#  really mean much of anything because they sound so great!  Full
+#  instructions for running are given in the program.
+#
+# "This version of Buzzword was written by David Ahl."
+#
+#
+# Ruby port by Leslie Viljoen, 2021
+#
+######################################################################
+
+WORDS = [["Ability", "Basal", "Behavioral", "Child-centered",
+           "Differentiated", "Discovery", "Flexible", "Heterogeneous",
+           "Homogenous", "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"]]
+
+
+# Display intro text
+
+puts "\n           Buzzword Generator"
+puts "Creative Computing  Morristown, New Jersey"
+puts "\n\n"
+puts "This program prints highly acceptable phrases in"
+puts "'educator-speak' that you can work into reports"
+puts "and speeches.  Whenever a question mark is printed,"
+puts "type a 'Y' for another phrase or 'N' to quit."
+puts "\n\nHere's the first phrase:"
+
+loop do
+    phrase = []
+
+    prefix, body, postfix = WORDS
+
+    phrase << prefix[rand(prefix.length)]
+    phrase << body[rand(body.length)]
+    phrase << postfix[rand(postfix.length)]
+            
+    puts phrase.join(' ')
+    puts "\n"
+    
+    print "?"
+    response = gets
+    
+    break unless response.upcase.start_with?('Y')
+end
+
+puts "Come back when you need help with another report!\n"
+
+
+######################################################################
+#
+# Porting Notes
+#
+#   The original program stored all 39 words in one array, then
+#   built the buzzword phrases by randomly sampling from each of the
+#   three regions of the array (1-13, 14-26, and 27-39).
+#
+#   Instead, we're storing the words for each section in three 
+#   separate arrays. That makes it easy to loop through the sections
+#   to stitch the phrase together, and it easily accomodates adding
+#   (or removing) elements from any section.  They don't all need to
+#   be the same length.
+#
+#   The author of this program (and founder of Creative Computing
+#   magazine) first started working at DEC--Digital Equipment
+#   Corporation--as a consultant helping the company market its
+#   computers as educational products.  He later was editor of a DEC
+#   newsletter named "EDU" that focused on using computers in an
+#   educational setting.  No surprise, then, that the buzzwords in
+#   this program were targeted towards educators!
+#   
+#
+# Ideas for Modifications
+#
+#   Try adding more/different words. Better yet, add a third
+#   array to the WORDS array to add new sets of words that
+#   might pertain to different fields. What would business buzzwords
+#   be? Engineering buzzwords?  Art/music buzzwords?  Let the user
+#   choose a field and pick the buzzwords accordingly.
+#
+######################################################################
diff --git a/22 Change/javascript/change.html b/22 Change/javascript/change.html
new file mode 100644
index 00000000..0f1449b6
--- /dev/null
+++ b/22 Change/javascript/change.html	
@@ -0,0 +1,9 @@
+
+
+CHANGE
+
+
+

+
+
+
diff --git a/22 Change/javascript/change.js b/22 Change/javascript/change.js
new file mode 100644
index 00000000..7c25bcbd
--- /dev/null
+++ b/22 Change/javascript/change.js	
@@ -0,0 +1,107 @@
+// CHANGE
+//
+// 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) + "CHANGE\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("I, YOUR FRIENDLY MICROCOMPUTER, WILL DETERMINE\n");
+    print("THE CORRECT CHANGE FOR ITEMS COSTING UP TO $100.\n");
+    print("\n");
+    print("\n");
+    while (1) {
+        print("COST OF ITEM");
+        a = parseFloat(await input());
+        print("AMOUNT OF PAYMENT");
+        p = parseFloat(await input());
+        c = p - a;
+        m = c;
+        if (c == 0) {
+            print("CORRECT AMOUNT, THANK YOU.\n");
+        } else {
+            print("YOUR CHANGE, $" + c + "\n");
+            d = Math.floor(c / 10);
+            if (d)
+                print(d + " TEN DOLLAR BILL(S)\n");
+            c -= d * 10;
+            e = Math.floor(c / 5);
+            if (e)
+                print(e + " FIVE DOLLAR BILL(S)\n");
+            c -= e * 5;
+            f = Math.floor(c);
+            if (f)
+                print(f + " ONE DOLLAR BILL(S)\n");
+            c -= f;
+            c *= 100;
+            g = Math.floor(c / 50);
+            if (g)
+                print(g + " ONE HALF DOLLAR(S)\n");
+            c -= g * 50;
+            h = Math.floor(c / 25);
+            if (h)
+                print(h + " QUARTER(S)\n");
+            c -= h * 25;
+            i = Math.floor(c / 10);
+            if (i)
+                print(i + " DIME(S)\n");
+            c -= i * 10;
+            j = Math.floor(c / 5);
+            if (j)
+                print(j + " NICKEL(S)\n");
+            c -= j * 5;
+            k = Math.floor(c + 0.5);
+            if (k)
+                print(k + " PENNY(S)\n");
+            print("THANK YOU, COME AGAIN.\n");
+            print("\n");
+            print("\n");
+        }
+    }
+}
+
+main();
diff --git a/23 Checkers/.DS_Store b/23 Checkers/.DS_Store
new file mode 100644
index 00000000..5008ddfc
Binary files /dev/null and b/23 Checkers/.DS_Store differ
diff --git a/23 Checkers/javascript/checkers.html b/23 Checkers/javascript/checkers.html
new file mode 100644
index 00000000..61839e25
--- /dev/null
+++ b/23 Checkers/javascript/checkers.html	
@@ -0,0 +1,9 @@
+
+
+CHECKERS
+
+
+

+
+
+
diff --git a/23 Checkers/javascript/checkers.js b/23 Checkers/javascript/checkers.js
new file mode 100644
index 00000000..4d406e0e
--- /dev/null
+++ b/23 Checkers/javascript/checkers.js	
@@ -0,0 +1,300 @@
+// CHECKERS
+//
+// 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;
+}
+
+// x,y = origin square
+// a,b = movement direction
+function try_computer()
+{
+    u = x + a;
+    v = y + b;
+    if (u < 0 || u > 7 || v < 0 || v > 7)
+        return;
+    if (s[u][v] == 0) {
+        eval_move();
+        return;
+    }
+    if (s[u][v] < 0)	// Cannot jump over own pieces
+        return;
+    u += a;
+    u += b;
+    if (u < 0 || u > 7 || v < 0 || v > 7)
+        return;
+    if (s[u][v] == 0)
+        eval_move();
+}
+
+// x,y = origin square
+// u,v = target square
+function eval_move()
+{
+    if (v == 0 && s[x][y] == -1)
+        q += 2;
+    if (Math.abs(y - v) == 2)
+        q += 5;
+    if (y == 7)
+        q -= 2;
+    if (u == 0 || u == 7)
+        q++;
+    for (c = -1; c <= 1; c += 2) {
+        if (u + c < 0 || u + c > 7 || v + g < 0)
+            continue;
+        if (s[u + c][v + g] < 0) {	// Computer piece
+            q++;
+            continue;
+        }
+        if (u - c < 0 || u - c > 7 || v - g > 7)
+            continue;
+        if (s[u + c][v + g] > 0 && (s[u - c][v - g] == 0 || (u - c == x && v - g == y)))
+            q -= 2;
+    }
+    if (q > r[0]) {	// Best movement so far?
+        r[0] = q;	// Take note of score
+        r[1] = x;	// Origin square
+        r[2] = y;
+        r[3] = u;	// Target square
+        r[4] = v;
+    }
+    q = 0;
+}
+
+function more_captures() {
+    u = x + a;
+    v = y + b;
+    if (u < 0 || u > 7 || v < 0 || v > 7)
+        return;
+    if (s[u][v] == 0 && s[x + a / 2][y + b / 2] > 0)
+        eval_move();
+}
+
+var r = [-99, 0, 0, 0, 0];
+var s = [];
+
+for (x = 0; x <= 7; x++)
+    s[x] = [];
+    
+var g = -1;
+var data = [1, 0, 1, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, -1, 0, -1, 15];
+var p = 0;
+var q = 0;
+
+// Main program
+async function main()
+{
+    print(tab(32) + "CHECKERS\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("THIS IS THE GAME OF CHECKERS.  THE COMPUTER IS X,\n");
+    print("AND YOU ARE O.  THE COMPUTER WILL MOVE FIRST.\n");
+    print("SQUARES ARE REFERRED TO BY A COORDINATE SYSTEM.\n");
+    print("(0,0) IS THE LOWER LEFT CORNER\n");
+    print("(0,7) IS THE UPPER LEFT CORNER\n");
+    print("(7,0) IS THE LOWER RIGHT CORNER\n");
+    print("(7,7) IS THE UPPER RIGHT CORNER\n");
+    print("THE COMPUTER WILL TYPE '+TO' WHEN YOU HAVE ANOTHER\n");
+    print("JUMP.  TYPE TWO NEGATIVE NUMBERS IF YOU CANNOT JUMP.\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    for (x = 0; x <= 7; x++) {
+        for (y = 0; y <= 7; y++) {
+            if (data[p] == 15)
+                p = 0;
+            s[x][y] = data[p];
+            p++;
+        }
+    }
+    while (1) {
+
+        // Search the board for the best movement
+        for (x = 0; x <= 7; x++) {
+            for (y = 0; y <= 7; y++) {
+                if (s[x][y] > -1)
+                    continue;
+                if (s[x][y] == -1) {	// Piece
+                    for (a = -1; a <= 1; a += 2) {
+                        b = g;	// Only advances
+                        try_computer();
+                    }
+                } else if (s[x][y] == -2) {	// King
+                    for (a = -1; a <= 1; a += 2) {
+                        for (b = -1; b <= 1; b += 2) {
+                            try_computer();
+                        }
+                    }
+                }
+            }
+        }
+        if (r[0] == -99) {
+            print("\n");
+            print("YOU WIN.\n");
+            break;
+        }
+        print("FROM " + r[1] + "," + r[2] + " TO " + r[3] + "," + r[4]);
+        r[0] = -99;
+        while (1) {
+            if (r[4] == 0) {	// Computer reaches the bottom
+                s[r[3]][r[4]] = -2;	// King
+                break;
+            }
+            s[r[3]][r[4]] = s[r[1]][r[2]];	// Move
+            s[r[1]][r[2]] = 0;
+            if (Math.abs(r[1] - r[3]) == 2) {
+                s[(r[1] + r[3]) / 2][(r[2] + r[4]) / 2] = 0;	// Capture
+                x = r[3];
+                y = r[4];
+                if (s[x][y] == -1) {
+                    b = -2;
+                    for (a = -2; a <= 2; a += 4) {
+                        more_captures();
+                    }
+                } else if (s[x][y] == -2) {
+                    for (a = -2; a <= 2; a += 4) {
+                        for (b = -2; b <= 2; b += 4) {
+                            more_captures();
+                        }
+                    }
+                }
+                if (r[0] != -99) {
+                    print(" TO " + r[3] + "," + r[4]);
+                    r[0] = -99;
+                    continue;
+                }
+            }
+            break;
+        }
+        print("\n");
+        print("\n");
+        print("\n");
+        for (y = 7; y >= 0; y--) {
+            str = "";
+            for (x = 0; x <= 7; x++) {
+                if (s[x][y] == 0)
+                    str += ".";
+                if (s[x][y] == 1)
+                    str += "O";
+                if (s[x][y] == -1)
+                    str += "X";
+                if (s[x][y] == -2)
+                    str += "X*";
+                if (s[x][y] == 2)
+                    str += "O*";
+                while (str.length % 5)
+                    str += " ";
+            }
+            print(str + "\n");
+            print("\n");
+        }
+        print("\n");
+        z = 0;
+        t = 0;
+        for (l = 0; l <= 7; l++) {
+            for (m = 0; m <= 7; m++) {
+                if (s[l][m] == 1 || s[l][m] == 2)
+                    z = 1;
+                if (s[l][m] == -1 || s[l][m] == -2)
+                    t = 1;
+            }
+        }
+        if (z != 1) {
+            print("\n");
+            print("I WIN.\n");
+            break;
+        }
+        if (t != 1) {
+            print("\n");
+            print("YOU WIN.\n");
+            break;
+        }
+        do {
+            print("FROM");
+            e = await input();
+            h = parseInt(e.substr(e.indexOf(",") + 1));
+            e = parseInt(e);
+            x = e;
+            y = h;
+        } while (s[x][y] <= 0) ;
+        do {
+            print("TO");
+            a = await input();
+            b = parseInt(a.substr(a.indexOf(",") + 1));
+            a = parseInt(a);
+            x = a;
+            y = b;
+            if (s[x][y] == 0 && Math.abs(a - e) <= 2 && Math.abs(a - e) == Math.abs(b - h))
+                break;
+            print("WHAT?\n");
+        } while (1) ;
+        i = 46;
+        do {
+            s[a][b] = s[e][h]
+            s[e][h] = 0;
+            if (Math.abs(e - a) != 2)
+                break;
+            s[(e + a) / 2][(h + b) / 2] = 0;
+            while (1) {
+                print("+TO");
+                a1 = await input();
+                b1 = parseInt(a1.substr(a1.indexOf(",") + 1));
+                a1 = parseInt(a1);
+                if (a1 < 0)
+                    break;
+                if (s[a1][b1] == 0 && Math.abs(a1 - a) == 2 && Math.abs(b1 - b) == 2)
+                    break;
+            }
+            if (a1 < 0)
+                break;
+            e = a;
+            h = b;
+            a = a1;
+            b = b1;
+            i += 15;
+        } while (1);
+        if (b == 7)	// Player reaches top
+            s[a][b] = 2;	// Convert to king
+    }
+}
+
+main();
diff --git a/24 Chemist/csharp/Chemist/Chemist.sln b/24 Chemist/csharp/Chemist/Chemist.sln
new file mode 100644
index 00000000..6dc7bfa2
--- /dev/null
+++ b/24 Chemist/csharp/Chemist/Chemist.sln	
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31005.135
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chemist", "Chemist\Chemist.csproj", "{8CC70F80-F2D6-47B6-8976-079352AC6C85}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8CC70F80-F2D6-47B6-8976-079352AC6C85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{8CC70F80-F2D6-47B6-8976-079352AC6C85}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{8CC70F80-F2D6-47B6-8976-079352AC6C85}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{8CC70F80-F2D6-47B6-8976-079352AC6C85}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {4AFDA581-82B1-42C7-9C9C-26F6B4288584}
+	EndGlobalSection
+EndGlobal
diff --git a/24 Chemist/csharp/Chemist/Chemist/Chemist.csproj b/24 Chemist/csharp/Chemist/Chemist/Chemist.csproj
new file mode 100644
index 00000000..20827042
--- /dev/null
+++ b/24 Chemist/csharp/Chemist/Chemist/Chemist.csproj	
@@ -0,0 +1,8 @@
+
+
+  
+    Exe
+    net5.0
+  
+
+
diff --git a/24 Chemist/csharp/Chemist/Chemist/Program.cs b/24 Chemist/csharp/Chemist/Chemist/Program.cs
new file mode 100644
index 00000000..64466bff
--- /dev/null
+++ b/24 Chemist/csharp/Chemist/Chemist/Program.cs	
@@ -0,0 +1,49 @@
+using System;
+const int maxLives = 9;
+
+WriteCentred("Chemist");
+WriteCentred("Creative Computing, Morristown, New Jersey");
+Console.WriteLine(@"
+
+
+The fictitious chemical kryptocyanic acid can only be
+diluted by the ratio of 7 parts water to 3 parts acid.
+If any other ratio is attempted, the acid becomes unstable
+and soon explodes.  Given the amount of acid, you must
+decide who much water to add for dilution.  If you miss
+you face the consequences.
+");
+
+var random = new Random();
+int livesUsed = 0;
+while (livesUsed < maxLives)
+{
+    int krypto = random.Next(1, 50);
+    double water = krypto * 7.0 / 3.0;
+
+    Console.WriteLine($"{krypto} Liters of kryptocyanic acid.  How much water?");
+    double answer = double.Parse(Console.ReadLine());
+
+    double diff = Math.Abs(answer - water);
+    if (diff <= water / 20)
+    {
+        Console.WriteLine("Good job! You may breathe now, but don't inhale the fumes"!);
+        Console.WriteLine();
+    }
+    else
+    {
+        Console.WriteLine("Sizzle!  You have just been desalinated into a blob\nof quivering protoplasm!");
+        Console.WriteLine();
+        livesUsed++;
+
+        if (livesUsed < maxLives)
+            Console.WriteLine("However, you may try again with another life.");
+    }
+}
+Console.WriteLine($"Your {maxLives} lives are used, but you will be long remembered for\nyour contributions to the field of comic book chemistry.");
+
+static void WriteCentred(string text)
+{
+    int indent = (Console.WindowWidth + text.Length) / 2;
+    Console.WriteLine($"{{0,{indent}}}", text);
+}
diff --git a/24 Chemist/javascript/chemist.html b/24 Chemist/javascript/chemist.html
new file mode 100644
index 00000000..c65d7821
--- /dev/null
+++ b/24 Chemist/javascript/chemist.html	
@@ -0,0 +1,9 @@
+
+
+CHEMIST
+
+
+

+
+
+
diff --git a/24 Chemist/javascript/chemist.js b/24 Chemist/javascript/chemist.js
new file mode 100644
index 00000000..8d6aabf5
--- /dev/null
+++ b/24 Chemist/javascript/chemist.js	
@@ -0,0 +1,82 @@
+// CHEMIST
+//
+// 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) + "CHEMIST\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("THE FICTITIOUS CHECMICAL KRYPTOCYANIC ACID CAN ONLY BE\n");
+    print("DILUTED BY THE RATIO OF 7 PARTS WATER TO 3 PARTS ACID.\n");
+    print("IF ANY OTHER RATIO IS ATTEMPTED, THE ACID BECOMES UNSTABLE\n");
+    print("AND SOON EXPLODES.  GIVEN THE AMOUNT OF ACID, YOU MUST\n");
+    print("DECIDE WHO MUCH WATER TO ADD FOR DILUTION.  IF YOU MISS\n");
+    print("YOU FACE THE CONSEQUENCES.\n");
+    t = 0;
+    while (1) {
+        a = Math.floor(Math.random() * 50);
+        w = 7 * a / 3;
+        print(a + " LITERS OF KRYPTOCYANIC ACID.  HOW MUCH WATER");
+        r = parseFloat(await input());
+        d = Math.abs(w - r);
+        if (d > w / 20) {
+            print(" SIZZLE!  YOU HAVE JUST BEEN DESALINATED INTO A BLOB\n");
+            print(" OF QUIVERING PROTOPLASM!\n");
+            t++;
+            if (t == 9)
+                break;
+            print(" HOWEVER, YOU MAY TRY AGAIN WITH ANOTHER LIFE.\n");
+        } else {
+            print(" GOOD JOB! YOU MAY BREATHE NOW, BUT DON'T INHALE THE FUMES!\n");
+            print("\n");
+        }
+    }
+    print(" YOUR 9 LIVES ARE USED, BUT YOU WILL BE LONG REMEMBERED FOR\n");
+    print(" YOUR CONTRIBUTIONS TO THE FIELD OF COMIC BOOK CHEMISTRY.\n");
+}
+
+main();
diff --git a/25 Chief/chief.bas b/25 Chief/chief.bas
index bcf8dd88..d3157e73 100644
--- a/25 Chief/chief.bas	
+++ b/25 Chief/chief.bas	
@@ -47,5 +47,5 @@
 450 PRINT:PRINT"#########################":PRINT
 470 PRINT "I HOPE YOU BELIEVE ME NOW, FOR YOUR SAKE!!"
 480 GOTO 520
-510 PRINT "BYE!!!"
+500 PRINT "BYE!!!"
 520 END
diff --git a/25 Chief/javascript/chief.html b/25 Chief/javascript/chief.html
new file mode 100644
index 00000000..cf272f9b
--- /dev/null
+++ b/25 Chief/javascript/chief.html	
@@ -0,0 +1,9 @@
+
+
+CHIEF
+
+
+

+
+
+
diff --git a/25 Chief/javascript/chief.js b/25 Chief/javascript/chief.js
new file mode 100644
index 00000000..98fde419
--- /dev/null
+++ b/25 Chief/javascript/chief.js	
@@ -0,0 +1,105 @@
+// CHIEF
+//
+// 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) + "CHIEF\n");
+    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
+    print("\n");
+    print("\n");
+    print("\n");
+    print("I AM CHIEF NUMBERS FREEK, THE GREAT INDIAN MATH GOD.\n");
+    print("ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR");
+    a = await input();
+    if (a.substr(0, 1) != "Y")
+        print("SHUT UP, PALE FACE WITH WIE TONGUE.\n");
+    print(" TAKE A NUMBER AND ADD 3. DIVIDE THIS NUMBER BY 5 AND\n");
+    print("MULTIPLY BY 8. DIVIDE BY 5 AND ADD THE SAME. SUBTRACT 1.\n");
+    print("  WHAT DO YOU HAVE");
+    b = parseFloat(await input());
+    c = (b + 1 - 5) * 5 / 8 * 5 - 3;
+    print("I BET YOUR NUMBER WAS " + Math.floor(c + 0.5) + ". AM I RIGHT");
+    d = await input();
+    if (d.substr(0, 1) != "Y") {
+        print("WHAT WAS YOUR ORIGINAL NUMBER");
+        k = parseFloat(await input());
+        f = k + 3;
+        g = f / 5;
+        h = g * 8;
+        i = h / 5 + 5;
+        j = i - 1;
+        print("SO YOU THINK YOU'RE SO SMART, EH?\n");
+        print("NOW WATCH.\n");
+        print(k + " PLUS 3 EQUALS " + f + ". THIS DIVIDED BY 5 EQUALS " + g + ";\n");
+        print("THIS TIMES 8 EQUALS " + h + ". IF WE DIVIDE BY 5 AND ADD 5,\n");
+        print("WE GET " + i + ", WHICH, MINUS 1, EQUALS " + j + ".\n");
+        print("NOW DO YOU BELIEVE ME");
+        z = await input();
+        if (z.substr(0, 1) != "Y") {
+            print("YOU HAVE MADE ME MAD!!!\n");
+            print("THERE MUST BE A GREAT LIGHTNING BOLT!\n");
+            print("\n");
+            print("\n");
+            for (x = 30; x >= 22; x--)
+                print(tab(x) + "X X\n");
+            print(tab(21) + "X XXX\n");
+            print(tab(20) + "X   X\n");
+            print(tab(19) + "XX X\n");
+            for (y = 20; y >= 13; y--)
+                print(tab(y) + "X X\n");
+            print(tab(12) + "XX\n");
+            print(tab(11) + "X\n");
+            print(tab(10) + "*\n");
+            print("\n");
+            print("#########################\n");
+            print("\n");
+            print("I HOPE YOU BELIEVE ME NOW, FOR YOUR SAKE!!\n");
+            return;
+        }
+    }
+    print("BYE!!!\n");
+}
+
+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/csharp/Dice.csproj b/33 Dice/csharp/Dice.csproj
new file mode 100644
index 00000000..54cdbe42
--- /dev/null
+++ b/33 Dice/csharp/Dice.csproj	
@@ -0,0 +1,12 @@
+
+
+  
+    Exe
+    net5.0
+  
+
+  
+    
+  
+
+
diff --git a/33 Dice/csharp/Game.cs b/33 Dice/csharp/Game.cs
new file mode 100644
index 00000000..3938e4c4
--- /dev/null
+++ b/33 Dice/csharp/Game.cs	
@@ -0,0 +1,112 @@
+using System;
+using System.Linq;
+
+namespace BasicComputerGames.Dice
+{
+	public class Game
+	{
+		private readonly RollGenerator _roller = new RollGenerator();
+
+		public void GameLoop()
+		{
+			DisplayIntroText();
+
+			// RollGenerator.ReseedRNG(1234);		// hard-code seed for repeatabilty during testing
+
+			do
+			{
+				int numRolls = GetInput();
+				var counter = CountRolls(numRolls);
+				DisplayCounts(counter);
+			} while (TryAgain());
+		}
+
+		private void DisplayIntroText()
+		{
+			Console.ForegroundColor = ConsoleColor.Yellow;
+			Console.WriteLine("Dice");
+			Console.WriteLine("Creating Computing, Morristown, New Jersey."); Console.WriteLine();
+
+			Console.ForegroundColor = ConsoleColor.DarkGreen;
+			Console.WriteLine("Original code by Danny Freidus.");
+			Console.WriteLine("Originally published in 1978 in the book 'Basic Computer Games' by David Ahl.");
+			Console.WriteLine("Modernized and converted to C# in 2021 by James Curran (noveltheory.com).");
+			Console.WriteLine();
+
+			Console.ForegroundColor = ConsoleColor.Gray;
+			Console.WriteLine("This program simulates the rolling of a pair of dice.");
+			Console.WriteLine("You enter the number of times you want the computer to");
+			Console.WriteLine("'roll' the dice. Watch out, very large numbers take");
+			Console.WriteLine("a long time. In particular, numbers over 10 million.");
+			Console.WriteLine();
+
+			Console.ForegroundColor = ConsoleColor.Yellow;
+			Console.WriteLine("Press any key start the game.");
+			Console.ReadKey(true);
+		}
+
+		private int GetInput()
+		{
+			int num = -1;
+			Console.WriteLine();
+			do
+			{
+				Console.WriteLine();
+				Console.Write("How many rolls? ");
+			} while (!Int32.TryParse(Console.ReadLine(), out num));
+
+			return num;
+		}
+
+		private  void DisplayCounts(int[] counter)
+		{
+			Console.WriteLine();
+			Console.WriteLine($"\tTotal\tTotal Number");
+			Console.WriteLine($"\tSpots\tof Times");
+			Console.WriteLine($"\t===\t=========");
+			for (var n = 1; n < counter.Length; ++n)
+			{
+				Console.WriteLine($"\t{n + 1,2}\t{counter[n],9:#,0}");
+			}
+			Console.WriteLine();
+		}
+
+		private  int[] CountRolls(int x)
+		{
+			var counter = _roller.Rolls().Take(x).Aggregate(new int[12], (cntr, r) =>
+			{
+				cntr[r.die1 + r.die2 - 1]++;
+				return cntr;
+			});
+			return counter;
+		}
+		/// 
+		/// 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 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/33 Dice/csharp/Program.cs b/33 Dice/csharp/Program.cs
new file mode 100644
index 00000000..959587cc
--- /dev/null
+++ b/33 Dice/csharp/Program.cs	
@@ -0,0 +1,14 @@
+namespace BasicComputerGames.Dice
+{
+	public class Program
+	{
+		public static void Main(string[] args)
+		{
+			// Create an instance of our main Game class
+			Game 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/33 Dice/csharp/README.md b/33 Dice/csharp/README.md
index 4daabb5c..23ccd0fe 100644
--- a/33 Dice/csharp/README.md	
+++ b/33 Dice/csharp/README.md	
@@ -1,3 +1,4 @@
 Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
 
-Conversion to [Microsoft C#](https://docs.microsoft.com/en-us/dotnet/csharp/)
+Conversion to [Microsoft C#](https://docs.microsoft.com/en-us/dotnet/csharp/) by James Curran (http://www.noveltheory.com)
+
diff --git a/33 Dice/csharp/RollGenerator.cs b/33 Dice/csharp/RollGenerator.cs
new file mode 100644
index 00000000..08f2df6b
--- /dev/null
+++ b/33 Dice/csharp/RollGenerator.cs	
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+
+namespace BasicComputerGames.Dice
+{
+	public class RollGenerator
+	{
+		static Random _rnd = new Random();
+
+		public static void ReseedRNG(int seed) => _rnd = new Random(seed);
+
+		public IEnumerable<(int die1, int die2)> Rolls()
+		{
+			while (true)
+			{
+				yield return (_rnd.Next(1, 7), _rnd.Next(1, 7));
+			}
+		}
+	}
+}
\ No newline at end of file
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/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/44 Hangman/python/hangman.py b/44 Hangman/python/hangman.py
new file mode 100755
index 00000000..e883bf01
--- /dev/null
+++ b/44 Hangman/python/hangman.py	
@@ -0,0 +1,217 @@
+#!/usr/bin/env python3
+# HANGMAN
+#
+# Converted from BASIC to Python by Trevor Hobson and Daniel Piron
+
+import random
+
+
+class Canvas:
+    """ For drawing text-based figures """
+
+    def __init__(self, width=12, height=12, fill=" "):
+        self._buffer = []
+        for _ in range(height):
+            line = []
+            for _ in range(width):
+                line.append("")
+            self._buffer.append(line)
+
+        self.clear()
+
+    def clear(self, fill=" "):
+        for row in self._buffer:
+            for x in range(len(row)):
+                row[x] = fill
+
+    def render(self):
+        lines = []
+        for line  in self._buffer:
+            # Joining by the empty string ("") smooshes all of the
+            # individual characters together as one line.
+            lines.append("".join(line))
+        return "\n".join(lines)
+
+    def put(self, s, x, y):
+        # In an effort to avoid distorting the drawn image, only write the
+        # first character of the given string to the buffer.
+        self._buffer[y][x] = s[0]
+
+
+def init_gallows(canvas):
+    for i in range(12):
+        canvas.put("X", 0, i)
+    for i in range(7):
+        canvas.put("X", i, 0)
+    canvas.put("X", 6, 1)
+
+
+def draw_head(canvas):
+    canvas.put("-", 5, 2)
+    canvas.put("-", 6, 2)
+    canvas.put("-", 7, 2)
+    canvas.put("(", 4, 3)
+    canvas.put(".", 5, 3)
+    canvas.put(".", 7, 3)
+    canvas.put(")", 8, 3)
+    canvas.put("-", 5, 4)
+    canvas.put("-", 6, 4)
+    canvas.put("-", 7, 4)
+
+
+def draw_body(canvas):
+    for i in range(5, 9, 1):
+        canvas.put("X", 6, i)
+
+
+def draw_right_arm(canvas):
+    for i in range(3, 7):
+        canvas.put("\\", i - 1, i)
+
+
+def draw_left_arm(canvas):
+    canvas.put("/", 10, 3)
+    canvas.put("/", 9, 4)
+    canvas.put("/", 8, 5)
+    canvas.put("/", 7, 6)
+
+
+def draw_right_leg(canvas):
+    canvas.put("/", 5, 9)
+    canvas.put("/", 4, 10)
+
+
+def draw_left_leg(canvas):
+    canvas.put("\\", 7, 9)
+    canvas.put("\\", 8, 10)
+
+
+def draw_left_hand(canvas):
+    canvas.put("\\", 10, 2)
+
+
+def draw_right_hand(canvas):
+    canvas.put("/", 2, 2)
+
+
+def draw_left_foot(canvas):
+    canvas.put("\\", 9, 11)
+    canvas.put("-", 10, 11)
+
+
+def draw_right_foot(canvas):
+    canvas.put("-", 2, 11)
+    canvas.put("/", 3, 11)
+
+
+PHASES = (
+    ("First, we draw a head", draw_head),
+    ("Now we draw a body.", draw_body),
+    ("Next we draw an arm.", draw_right_arm),
+    ("this time it's the other arm.", draw_left_arm),
+    ("Now, let's draw the right leg.", draw_right_leg),
+    ("This time we draw the left leg.", draw_left_leg),
+    ("Now we put up a hand.", draw_left_hand),
+    ("Next the other hand.", draw_right_hand),
+    ("Now we draw one foot", draw_left_foot),
+    ("Here's the other foot -- you're hung!!", draw_right_foot)
+)
+
+
+words = ["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"]
+
+
+def play_game(guess_target):
+    """Play one round of the game"""
+    wrong_guesses = 0
+    guess_progress = ["-"] * len(guess_target)
+    guess_list = []
+
+    gallows = Canvas()
+    init_gallows(gallows)
+
+    guess_count = 0
+    while True:
+        print("Here are the letters you used:")
+        print(",".join(guess_list) + "\n")
+        print("".join(guess_progress) + "\n")
+        guess_letter = ""
+        guess_word = ""
+        while guess_letter == "":
+
+            guess_letter = input("What is your guess? ").upper()[0]
+            if not guess_letter.isalpha():
+                guess_letter = ""
+                print("Only letters are allowed!")
+            elif guess_letter in guess_list:
+                guess_letter = ""
+                print("You guessed that letter before!")
+
+        guess_list.append(guess_letter)
+        guess_count += 1
+        if guess_letter in guess_target:
+            indices = [i for i, letter in enumerate(guess_target) if letter == guess_letter]
+            for i in indices:
+                guess_progress[i] = guess_letter
+            if guess_progress == guess_target:
+                print("You found the word!")
+                break
+            else:
+                print("\n" + "".join(guess_progress) + "\n")
+                while guess_word == "":
+                    guess_word = input("What is your guess for the word? ").upper()
+                    if not guess_word.isalpha():
+                        guess_word = ""
+                        print("Only words are allowed!")
+                if guess_word == guess_target:
+                    print("Right!! It took you", guess_count, "guesses!")
+                    break
+        else:
+            comment, draw_bodypart = PHASES[wrong_guesses]
+
+            print(comment)
+            draw_bodypart(gallows)
+            print(gallows.render())
+
+            wrong_guesses += 1
+            print("Sorry, that letter isn't in the word.")
+
+            if wrong_guesses == 10:
+                print("Sorry, you lose. The word was " + guess_target)
+                break
+
+
+def main():
+    print(" " * 32 + "HANGMAN")
+    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
+
+    random.shuffle(words)
+    current_word = 0
+    word_count = len(words)
+
+    keep_playing = True
+    while keep_playing:
+
+        play_game(words[current_word])
+        current_word += 1
+
+        if current_word == word_count:
+            print("You did all the words!!")
+            keep_playing = False
+        else:
+            keep_playing = input("Want another word? (yes or no) ").lower().startswith("y")
+
+    print("It's been fun! Bye for now.")
+
+
+if __name__ == "__main__":
+    main()
+
diff --git a/47 Hi-Lo/csharp/hi-lo.cs b/47 Hi-Lo/csharp/hi-lo.cs
new file mode 100644
index 00000000..c5cfb3ec
--- /dev/null
+++ b/47 Hi-Lo/csharp/hi-lo.cs	
@@ -0,0 +1,83 @@
+using System;
+
+Console.WriteLine(Tab(34) +                 "HI LO");
+Console.WriteLine(Tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
+Console.WriteLine();
+Console.WriteLine();
+Console.WriteLine();
+Console.WriteLine("THIS IS THE GAME OF HI LO.");
+Console.WriteLine();
+Console.WriteLine("YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE");
+Console.WriteLine("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS.  IF YOU");
+Console.WriteLine("GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!");
+Console.WriteLine("THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY.  HOWEVER,");
+Console.WriteLine("IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.");
+Console.WriteLine();
+
+// rnd is our random number generator
+Random rnd = new();
+
+bool playAgain = false;
+int totalWinnings = 0;
+
+do // Our game loop
+{
+    int jackpot = rnd.Next(100) + 1; // [0..99] + 1 -> [1..100]
+    int guess = 1;
+
+    while (true) // Our guessing loop
+    {
+        Console.WriteLine();
+        int amount = ReadInt("YOUR GUESS ");
+
+        if (amount == jackpot)
+        {
+            Console.WriteLine($"GOT IT!!!!!!!!!!   YOU WIN {jackpot} DOLLARS.");
+            totalWinnings += jackpot;
+            Console.WriteLine($"YOUR TOTAL WINNINGS ARE NOW {totalWinnings} DOLLARS.");
+            break;
+        }
+        else if (amount > jackpot)
+        {
+            Console.WriteLine("YOUR GUESS IS TOO HIGH.");
+        }
+        else
+        {
+            Console.WriteLine("YOUR GUESS IS TOO LOW.");
+        }
+
+        guess++;
+        if (guess > 6)
+        {
+            Console.WriteLine($"YOU BLEW IT...TOO BAD...THE NUMBER WAS {jackpot}");
+            break;
+        }
+    }
+
+    Console.WriteLine();
+    Console.Write("PLAY AGAIN (YES OR NO) ");
+    playAgain = Console.ReadLine().ToUpper().StartsWith("Y");
+
+} while (playAgain);
+
+Console.WriteLine();
+Console.WriteLine("SO LONG.  HOPE YOU ENJOYED YOURSELF!!!");
+
+// Tab(n) returns n spaces
+static string Tab(int n) => new String(' ', n);
+
+// ReadInt asks the user to enter a number
+static int ReadInt(string question)
+{
+    while (true)
+    {
+        Console.Write(question);
+        var input = Console.ReadLine().Trim();
+        if (int.TryParse(input, out int value))
+        {
+            return value;
+        }
+        Console.WriteLine("!Invalid Number Entered.");
+    }
+}
+
diff --git a/47 Hi-Lo/csharp/hi-lo.csproj b/47 Hi-Lo/csharp/hi-lo.csproj
new file mode 100644
index 00000000..20827042
--- /dev/null
+++ b/47 Hi-Lo/csharp/hi-lo.csproj	
@@ -0,0 +1,8 @@
+
+
+  
+    Exe
+    net5.0
+  
+
+
diff --git a/47 Hi-Lo/python/hilo.py b/47 Hi-Lo/python/hilo.py
new file mode 100755
index 00000000..370999a7
--- /dev/null
+++ b/47 Hi-Lo/python/hilo.py	
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+import random
+
+MAX_ATTEMPTS = 6
+QUESTION_PROMPT='? '
+
+def play():
+    print('HI LO')
+    print('CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n')
+    print('THIS IS THE GAME OF HI LO.\n')
+    print('YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE')
+    print('HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS.  IF YOU')
+    print('GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!')
+    print('THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY.  HOWEVER,')
+    print('IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.\n\n')
+
+    total_winnings = 0
+    while True:
+        print()
+        secret = random.randint(1, 100)
+        guessed_correctly = False
+
+        for attempt in range(MAX_ATTEMPTS):
+            print('YOUR GUESS', end=QUESTION_PROMPT)
+            guess = int(input())
+
+            if guess == secret:
+                print('GOT IT!!!!!!!!!!   YOU WIN {} DOLLARS.'.format(secret))
+                guessed_correctly = True
+                break
+            elif guess > secret:
+                print('YOUR GUESS IS TOO HIGH.')
+            else:
+                print('YOUR GUESS IS TOO LOW.')
+
+        if guessed_correctly:
+            total_winnings += secret
+            print('YOUR TOTAL WINNINGS ARE NOW {} DOLLARS.'.format(total_winnings))
+        else:
+            print('YOU BLEW IT...TOO BAD...THE NUMBER WAS {}'.format(secret))
+
+        print('\n')
+        print('PLAY AGAIN (YES OR NO)', end=QUESTION_PROMPT)
+        answer = input().upper()
+        if answer != 'YES':
+            break
+
+    print('\nSO LONG.  HOPE YOU ENJOYED YOURSELF!!!')
+
+if __name__ == '__main__':
+    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/python/rockscissors.py b/74 Rock Scissors Paper/python/rockscissors.py
new file mode 100644
index 00000000..688a894b
--- /dev/null
+++ b/74 Rock Scissors Paper/python/rockscissors.py	
@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+# ROCKSCISSORS
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+
+def play_game():
+    """Play one round of the game"""
+
+    while True:
+        try:
+            games = int(input("How many games? "))
+            if games >= 11:
+                print("Sorry, but we aren't allowed to play that many.")
+            else:
+                break
+
+        except ValueError:
+            print("Please enter a number.")
+
+    won_computer = 0
+    won_human = 0
+
+    for game in range(games):
+        print("\nGame number", game + 1)
+        guess_computer = random.randint(1, 3)
+        print("3=Rock...2=Scissors...1=Paper")
+        guess_human = 0
+        while guess_human == 0:
+            try:
+                guess_human = int(input("1...2...3...What's your choice "))
+                if guess_human not in [1, 2, 3]:
+                    guess_human = 0
+                    print("Invalid")
+
+            except ValueError:
+                print("Please enter a number.")
+        print("This is my choice...")
+        if guess_computer == 1:
+            print("...Paper")
+        elif guess_computer == 2:
+            print("...Scissors")
+        elif guess_computer == 3:
+            print("...Rock")
+        if guess_computer == guess_human:
+            print("Tie Game. No winner")
+        elif guess_computer > guess_human:
+            if guess_human != 1 or guess_computer != 3:
+                print("Wow! I win!!!")
+                won_computer = won_computer + 1
+            else:
+                print("You win!!!")
+                won_human = won_human + 1
+        elif guess_computer == 1:
+            if guess_human != 3:
+                print("You win!!!")
+                won_human = won_human + 1
+            else:
+                print("Wow! I win!!!")
+                won_computer = won_computer + 1
+    print("\nHere is the final game score:")
+    print("I have won", won_computer, "game(s).")
+    print("You have won", won_human, "game(s).")
+    print("and", games - (won_computer + won_human), "game(s) ended in a tie.")
+    print("\nThanks for playing!!\n")
+
+
+def main():
+    print(" " * 21 + "GAME OF ROCK, SCISSORS, PAPER")
+    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
+
+    keep_playing = True
+    while keep_playing:
+
+        play_game()
+
+        keep_playing = input(
+            "Play again? (yes or no) ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/78 Sine Wave/csharp/SineWave/SineWave.sln b/78 Sine Wave/csharp/SineWave/SineWave.sln
new file mode 100644
index 00000000..f32a06cd
--- /dev/null
+++ b/78 Sine Wave/csharp/SineWave/SineWave.sln	
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31005.135
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SineWave", "SineWave\SineWave.csproj", "{B316DD7F-5755-4216-AFDC-D83720F8ACA2}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {32A37343-2955-4124-8765-9143F6C529DC}
+	EndGlobalSection
+EndGlobal
diff --git a/78 Sine Wave/csharp/SineWave/SineWave/Program.cs b/78 Sine Wave/csharp/SineWave/SineWave/Program.cs
new file mode 100644
index 00000000..6f44f8d5
--- /dev/null
+++ b/78 Sine Wave/csharp/SineWave/SineWave/Program.cs	
@@ -0,0 +1,15 @@
+using System;
+
+Console.WriteLine(Tab(30) + "Sine Wave");
+Console.WriteLine(Tab(15) + "Creative Computing Morristown, New Jersey\n\n\n\n\n");
+
+bool isCreative = true;
+for (double t = 0.0; t <= 40.0; t += 0.25)
+{
+    int a = (int)(26 + 25 * Math.Sin(t));
+    string word = isCreative ? "Creative" : "Computing";
+    Console.WriteLine($"{Tab(a)}{word}");
+    isCreative = !isCreative;
+}
+
+static string Tab(int n) => new string(' ', n);
\ No newline at end of file
diff --git a/78 Sine Wave/csharp/SineWave/SineWave/SineWave.csproj b/78 Sine Wave/csharp/SineWave/SineWave/SineWave.csproj
new file mode 100644
index 00000000..20827042
--- /dev/null
+++ b/78 Sine Wave/csharp/SineWave/SineWave/SineWave.csproj	
@@ -0,0 +1,8 @@
+
+
+  
+    Exe
+    net5.0
+  
+
+
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/84 Super Star Trek/README.md b/84 Super Star Trek/README.md
index c101bf65..a67e2eb8 100644
--- a/84 Super Star Trek/README.md	
+++ b/84 Super Star Trek/README.md	
@@ -5,3 +5,7 @@ https://www.atariarchives.org/basicgames/showpage.php?page=157
 
 Downloaded from Vintage Basic at
 http://www.vintage-basic.net/games.html
+
+#### External Links
+ - Super Star Trek in C++ : https://www.codeproject.com/Articles/28399/The-Object-Oriented-Text-Star-Trek-Game-in-C
+
diff --git a/87 3-D Plot/python/3dplot.py b/87 3-D Plot/python/3dplot.py
new file mode 100644
index 00000000..2dda44ff
--- /dev/null
+++ b/87 3-D Plot/python/3dplot.py	
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+
+# 3D PLOT
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import math
+
+def equation(input):
+	return 30 * math.exp(-input * input / 100)
+
+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
+	l = 0
+	y1 = 5 * math.floor(math.sqrt(900 - x1 * x1) / 5)
+	yPlot = [" "] * 80
+
+	for y in range (y1, -(y1 + 5), -5):
+		z = math.floor(25 + equation(math.sqrt(x1 * x1 + y * y)) - .7 * y)
+		if z > l:
+			l = z
+			yPlot[z] = "*"
+	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/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/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/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/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/basic-computer-games-dot-net/basic-computer-games-dot-net.sln b/basic-computer-games-dot-net/basic-computer-games-dot-net.sln
new file mode 100644
index 00000000..f32f088d
--- /dev/null
+++ b/basic-computer-games-dot-net/basic-computer-games-dot-net.sln
@@ -0,0 +1,69 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31004.235
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01 Acey Ducey", "01 Acey Ducey", "{63FEF89A-DAF1-42C6-B86B-AAD51E885553}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp", "csharp", "{9ADA338C-DAB6-4EE8-8F53-F3F711BEA985}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AceyDucey", "..\01 Acey Ducey\csharp\AceyDucey.csproj", "{DA16CAAE-A3BE-42D0-9525-623AA6B0EDC3}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "33 Dice", "33 Dice", "{3C6771F4-513C-4B8D-A042-15E18EB27740}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp", "csharp", "{AC302ACD-C3B2-460D-BA1A-0A511C36A848}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dice", "..\33 Dice\csharp\Dice.csproj", "{26D086DE-0BBD-4A18-AC63-2476A7DB52D3}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "47 Hi-Lo", "47 Hi-Lo", "{A2BC8E4A-B977-46A6-B897-7E675ACB96F0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp", "csharp", "{04298EE8-0EF3-475C-9427-E04C267BBEFB}"
+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
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{DA16CAAE-A3BE-42D0-9525-623AA6B0EDC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DA16CAAE-A3BE-42D0-9525-623AA6B0EDC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DA16CAAE-A3BE-42D0-9525-623AA6B0EDC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DA16CAAE-A3BE-42D0-9525-623AA6B0EDC3}.Release|Any CPU.Build.0 = Release|Any CPU
+		{26D086DE-0BBD-4A18-AC63-2476A7DB52D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{26D086DE-0BBD-4A18-AC63-2476A7DB52D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{26D086DE-0BBD-4A18-AC63-2476A7DB52D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{26D086DE-0BBD-4A18-AC63-2476A7DB52D3}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{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
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{9ADA338C-DAB6-4EE8-8F53-F3F711BEA985} = {63FEF89A-DAF1-42C6-B86B-AAD51E885553}
+		{DA16CAAE-A3BE-42D0-9525-623AA6B0EDC3} = {9ADA338C-DAB6-4EE8-8F53-F3F711BEA985}
+		{AC302ACD-C3B2-460D-BA1A-0A511C36A848} = {3C6771F4-513C-4B8D-A042-15E18EB27740}
+		{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}
+	EndGlobalSection
+EndGlobal