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/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/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/java/src/Bombardment.java b/11 Bombardment/java/src/Bombardment.java
new file mode 100644
index 00000000..06a3043c
--- /dev/null
+++ b/11 Bombardment/java/src/Bombardment.java
@@ -0,0 +1,372 @@
+import java.util.HashSet;
+import java.util.Scanner;
+
+/**
+ * Game of Bombardment
+ *
+ * Based on the Basic game of Bombardment here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/11%20Bombardment/bombardment.bas
+ *
+ * Note: The idea was to create a version of this 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class Bombardment {
+
+ public static final int MAX_GRID_SIZE = 25;
+ public static final int PLATOONS = 4;
+
+ private enum GAME_STATE {
+ STARTING,
+ DRAW_BATTLEFIELD,
+ GET_PLAYER_CHOICES,
+ PLAYERS_TURN,
+ COMPUTER_TURN,
+ PLAYER_WON,
+ PLAYER_LOST,
+ GAME_OVER
+ }
+
+ private GAME_STATE gameState;
+
+ public static final String[] PLAYER_HIT_MESSAGES = { "ONE DOWN, THREE TO GO.",
+ "TWO DOWN, TWO TO GO.", "THREE DOWN, ONE TO GO." };
+
+ public static final String[] COMPUTER_HIT_MESSAGES = {"YOU HAVE ONLY THREE OUTPOSTS LEFT.",
+ "YOU HAVE ONLY TWO OUTPOSTS LEFT.", "YOU HAVE ONLY ONE OUTPOST LEFT." };
+
+ private HashSet computersPlatoons;
+ private HashSet playersPlatoons;
+
+ private HashSet computersGuesses;
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ public Bombardment() {
+
+ this.gameState = GAME_STATE.STARTING;
+
+ // Initialise kb scanner
+ kbScanner = new Scanner(System.in);
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ do {
+ switch (this.gameState) {
+
+ // Show an introduction the first time the game is played.
+ case STARTING:
+ init();
+ intro();
+ this.gameState = GAME_STATE.DRAW_BATTLEFIELD;
+ break;
+
+ // Enter the players name
+ case DRAW_BATTLEFIELD:
+ drawBattlefield();
+ this.gameState = GAME_STATE.GET_PLAYER_CHOICES;
+ break;
+
+ // Get the players 4 locations for their platoons
+ case GET_PLAYER_CHOICES:
+ String playerChoices = displayTextAndGetInput("WHAT ARE YOUR FOUR POSITIONS? ");
+
+ // Store the 4 player choices that were entered separated with commas
+ for(int i=0; i computersChosenPlatoons() {
+
+ // Initialise contents
+ HashSet tempPlatoons = new HashSet<>();
+
+ boolean allPlatoonsAdded = false;
+
+ do {
+ tempPlatoons.add(randomNumber());
+
+ // All four created?
+ if(tempPlatoons.size() == PLATOONS) {
+ // Exit when we have created four
+ allPlatoonsAdded = true;
+ }
+
+ } while(!allPlatoonsAdded);
+
+ return tempPlatoons;
+ }
+ /**
+ * Shows a different message for each number of hits
+ *
+ * @param hits total number of hits by player on computer
+ */
+ private void showPlayerProgress(int hits) {
+
+ System.out.println("YOU GOT ONE OF MY OUTPOSTS!");
+ showProgress(hits, PLAYER_HIT_MESSAGES);
+ }
+
+ /**
+ * Shows a different message for each number of hits
+ *
+ * @param hits total number of hits by computer on player
+ */
+ private void showComputerProgress(int hits, int lastGuess) {
+
+ System.out.println("I GOT YOU. IT WON'T BE LONG NOW. POST " + lastGuess + " WAS HIT.");
+ showProgress(hits, COMPUTER_HIT_MESSAGES);
+ }
+
+ /**
+ * Prints a message from the passed array based on the value of hits
+
+ * @param hits - number of hits the player or computer has made
+ * @param messages - an array of string with messages
+ */
+ private void showProgress(int hits, String[] messages) {
+ System.out.println(messages[hits-1]);
+ }
+
+ /**
+ *
+ * Update a player hit - adds a hit the player made on the computers platoon.
+ * @param fireLocation - computer location that got hit
+ * @return number of hits the player has inflicted on the computer in total
+ */
+ private int updatePlayerHits(int fireLocation) {
+
+ // N.B. only removes if present, so its redundant to check if it exists first
+ this.computersPlatoons.remove(fireLocation);
+
+ // return number of hits in total
+ return PLATOONS - this.computersPlatoons.size();
+ }
+
+ /**
+ *
+ * Update a computer hit - adds a hit the computer made on the players platoon.
+ * @param fireLocation - player location that got hit
+ * @return number of hits the player has inflicted on the computer in total
+ */
+ private int updateComputerHits(int fireLocation) {
+
+ // N.B. only removes if present, so its redundant to check if it exists first
+ this.playersPlatoons.remove(fireLocation);
+
+ // return number of hits in total
+ return PLATOONS - this.playersPlatoons.size();
+ }
+
+ /**
+ * Determine if the player hit one of the computers platoons
+ *
+ * @param fireLocation the players choice of location to fire on
+ * @return true if a computer platoon was at that position
+ */
+ private boolean didPlayerHitComputerPlatoon(int fireLocation) {
+ return this.computersPlatoons.contains(fireLocation);
+ }
+
+ /**
+ * Determine if the computer hit one of the players platoons
+ *
+ * @param fireLocation the computers choice of location to fire on
+ * @return true if a players platoon was at that position
+ */
+ private boolean didComputerHitPlayerPlatoon(int fireLocation) {
+ return this.playersPlatoons.contains(fireLocation);
+ }
+
+ /**
+ * Draw the battlefield grid
+ *
+ */
+ private void drawBattlefield() {
+ for(int i=1; i();
+
+ this.computersGuesses = new HashSet<>();
+ }
+
+ /**
+ * Accepts a string delimited by comma's and returns the nth delimited
+ * value (starting at count 0).
+ *
+ * @param text - text with values separated by comma's
+ * @param pos - which position to return a value for
+ * @return the int representation of the value
+ */
+ private int getDelimitedValue(String text, int pos) {
+ String[] tokens = text.split(",");
+ return Integer.parseInt(tokens[pos]);
+ }
+
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Generate random number
+ *
+ * @return random number
+ */
+ private int randomNumber() {
+ return (int) (Math.random()
+ * (MAX_GRID_SIZE) + 1);
+ }
+}
\ No newline at end of file
diff --git a/11 Bombardment/java/src/BombardmentGame.java b/11 Bombardment/java/src/BombardmentGame.java
new file mode 100644
index 00000000..31f0edfe
--- /dev/null
+++ b/11 Bombardment/java/src/BombardmentGame.java
@@ -0,0 +1,8 @@
+public class BombardmentGame {
+
+ public static void main(String[] args) {
+
+ Bombardment bombardment = new Bombardment();
+ bombardment.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/java/src/Bullseye.java b/18 Bullseye/java/src/Bullseye.java
new file mode 100644
index 00000000..06090351
--- /dev/null
+++ b/18 Bullseye/java/src/Bullseye.java
@@ -0,0 +1,248 @@
+import java.util.ArrayList;
+import java.util.Scanner;
+
+public class Bullseye {
+
+ public static final int FIRST_IDENT = 10;
+ public static final int SECOND_IDENT = 30;
+ public static final int THIRD_INDENT = 30;
+
+ public static final double[] SHOT_ONE = new double[] { .65, .55, .5, .5};
+ public static final double[] SHOT_TWO = new double[] { .99, .77, .43,.01};
+ public static final double[] SHOT_THREE = new double[] { .95, .75, .45, .05 };
+
+ private enum GAME_STATE {
+ STARTING,
+ START_GAME,
+ PLAYING,
+ GAME_OVER
+ }
+
+ private GAME_STATE gameState;
+
+ private ArrayList players;
+
+ private Shot[] shots;
+
+ // Used for keyboard input
+ private Scanner kbScanner;
+
+ private int numberOfPlayers;
+
+ private int round;
+
+ public Bullseye() {
+
+ gameState = GAME_STATE.STARTING;
+ players = new ArrayList<>();
+
+ // Save the random chances of points based on shot type
+
+ shots = new Shot[3];
+ shots[0] = new Shot(SHOT_ONE);
+ shots[1] = new Shot(SHOT_TWO);
+ shots[2] = new Shot(SHOT_THREE);
+
+ // Initialise kb scanner
+ kbScanner = new Scanner(System.in);
+ }
+
+ /**
+ * Main game loop
+ *
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+
+ // Show an introduction the first time the game is played.
+ case STARTING:
+ intro();
+ gameState = GAME_STATE.START_GAME;
+ break;
+
+ // Start the game, set the number of players, names and round
+ case START_GAME:
+
+ this.numberOfPlayers = chooseNumberOfPlayers();
+
+ for(int i=0; i= p1) {
+ System.out.println("BULLSEYE!! 40 POINTS!");
+ points = 40;
+ // If the throw was 1 (bullseye or missed, then make it missed
+ // N.B. This is a fix for the basic code which for shot type 1
+ // allowed a bullseye but did not make the score zero if a bullseye
+ // was not made (which it should have done).
+ } else if (playerThrow == 1) {
+ System.out.println("MISSED THE TARGET! TOO BAD.");
+ points = 0;
+ } else if(random >= p2) {
+ System.out.println("30-POINT ZONE!");
+ points = 30;
+ } else if(random >= p3) {
+ System.out.println("20-POINT ZONE");
+ points = 20;
+ } else if(random >= p4) {
+ System.out.println("WHEW! 10 POINTS.");
+ points = 10;
+ } else {
+ System.out.println("MISSED THE TARGET! TOO BAD.");
+ points = 0;
+ }
+
+ return points;
+ }
+
+ /**
+ * Get players shot 1,2, or 3 - ask again if invalid input
+ *
+ * @param player
+ * @return 1,2, or 3 indicating the players shot
+ */
+ private int getPlayersThrow(Player player) {
+ boolean inputCorrect = false;
+ String theThrow;
+ do {
+ theThrow = displayTextAndGetInput(player.getName() + "'S THROW ");
+ if(theThrow.equals("1") || theThrow.equals("2") || theThrow.equals("3")) {
+ inputCorrect = true;
+ } else {
+ System.out.println("INPUT 1, 2, OR 3!");
+ }
+
+ } while(!inputCorrect);
+
+ return Integer.valueOf(theThrow);
+ }
+
+
+ /**
+ * Get players guess from kb
+ *
+ * @return players guess as an int
+ */
+ private int chooseNumberOfPlayers() {
+
+ return Integer.valueOf((displayTextAndGetInput("HOW MANY PLAYERS? ")));
+ }
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Format three strings to a given number of spaces
+ * Replacing the original basic code which used tabs
+ *
+ * @param first String to print in pos 1
+ * @param second String to print in pos 2
+ * @param third String to print in pos 3
+ * @return formatted string
+ */
+ private String paddedString(String first, String second, String third) {
+ String output = String.format("%1$" + FIRST_IDENT + "s", first);
+ output += String.format("%1$" + SECOND_IDENT + "s", second);
+ output += String.format("%1$" + THIRD_INDENT + "s", third);
+ return output;
+ }
+}
diff --git a/18 Bullseye/java/src/BullseyeGame.java b/18 Bullseye/java/src/BullseyeGame.java
new file mode 100644
index 00000000..19be8fec
--- /dev/null
+++ b/18 Bullseye/java/src/BullseyeGame.java
@@ -0,0 +1,8 @@
+public class BullseyeGame {
+
+ public static void main(String[] args) {
+
+ Bullseye bullseye = new Bullseye();
+ bullseye.play();
+ }
+}
diff --git a/18 Bullseye/java/src/Player.java b/18 Bullseye/java/src/Player.java
new file mode 100644
index 00000000..b67b9309
--- /dev/null
+++ b/18 Bullseye/java/src/Player.java
@@ -0,0 +1,26 @@
+/**
+ * A Player in the game - consists of name and score
+ *
+ */
+public class Player {
+
+ private String name;
+ private int score;
+
+ Player(String name) {
+ this.name = name;
+ this.score = 0;
+ }
+
+ public void addScore(int score) {
+ this.score += score;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getScore() {
+ return score;
+ }
+}
diff --git a/18 Bullseye/java/src/Shot.java b/18 Bullseye/java/src/Shot.java
new file mode 100644
index 00000000..01d8b283
--- /dev/null
+++ b/18 Bullseye/java/src/Shot.java
@@ -0,0 +1,21 @@
+/**
+ * This class records the percentage chance of a given type of shot
+ * scoring specific points
+ * see Bullseye class points calculation method where its used
+ */
+public class Shot {
+
+ double[] chances;
+
+ // Array of doubles are passed for a specific type of shot
+ Shot(double[] shots) {
+ chances = new double[shots.length];
+ for(int i=0; i
+
+BULLSEYE
+
+
+
+
+
+