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