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/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/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
+
+
+ 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/25 Chief/java/src/Chief.java b/25 Chief/java/src/Chief.java
new file mode 100644
index 00000000..d7fbbc08
--- /dev/null
+++ b/25 Chief/java/src/Chief.java
@@ -0,0 +1,196 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+public class Chief {
+
+ private enum GAME_STATE {
+ STARTING,
+ READY_TO_START,
+ ENTER_NUMBER,
+ CALCULATE_AND_SHOW,
+ END_GAME,
+ GAME_OVER
+ }
+
+ private GAME_STATE gameState;
+
+ private double calculatedNumber;
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ public Chief() {
+
+ gameState = GAME_STATE.STARTING;
+
+ // 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.READY_TO_START;
+ break;
+
+ // show an message to start
+ case READY_TO_START:
+ if(!yesEntered(displayTextAndGetInput("ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR? "))) {
+ System.out.println("SHUT UP, PALE FACE WITH WISE TONGUE.");
+ }
+
+ instructions();
+ gameState = GAME_STATE.ENTER_NUMBER;
+ break;
+
+ // Enter the number to be used to calculate
+ case ENTER_NUMBER:
+ double playerNumber = Double.parseDouble(
+ displayTextAndGetInput(" WHAT DO YOU HAVE? "));
+
+ // Exact same formula used in the original game to calculate the players original number
+ this.calculatedNumber = (playerNumber +1-5)*5/8*5-3;
+
+ this.gameState = GAME_STATE.CALCULATE_AND_SHOW;
+ break;
+
+ // Enter the number to be used to calculate
+ case CALCULATE_AND_SHOW:
+ if(yesEntered(
+ displayTextAndGetInput("I BET YOUR NUMBER WAS " + this.calculatedNumber
+ + ". AM I RIGHT? "))) {
+ this.gameState = GAME_STATE.END_GAME;
+
+ } else {
+ // Player did not agree, so show the breakdown
+ double number = Double.parseDouble(
+ displayTextAndGetInput(" WHAT WAS YOUR ORIGINAL NUMBER? "));
+ double f = number + 3;
+ double g = f / 5;
+ double h = g * 8;
+ double i = h/5 + 5;
+ double j = i -1;
+ System.out.println("SO YOU THINK YOU'RE SO SMART, EH?");
+ System.out.println("NOW WATCH.");
+ System.out.println(number +" PLUS 3 EQUALS " + f + ". THIS DIVIDED BY 5 EQUALS " + g);
+ System.out.println("THIS TIMES 8 EQUALS " + h + ". IF WE DIVIDE BY 5 AND ADD 5,");
+ System.out.println("WE GET " + i + ", WHICH, MINUS 1, EQUALS " + j + ".");
+ if(yesEntered(displayTextAndGetInput("NOW DO YOU BELIEVE ME? "))) {
+ this.gameState = GAME_STATE.END_GAME;
+ } else {
+ // Time for a lightning bolt.
+ System.out.println("YOU HAVE MADE ME MAD!!!");
+ System.out.println("THERE MUST BE A GREAT LIGHTNING BOLT!");
+ System.out.println();
+ for(int x=30; x>=22; x--) {
+ System.out.println(tabbedSpaces(x) + "X X");
+ }
+ System.out.println(tabbedSpaces(21) + "X XXX");
+ System.out.println(tabbedSpaces(20) + "X X");
+ System.out.println(tabbedSpaces(19) + "XX X");
+ for(int y=20; y>=13; y--) {
+ System.out.println(tabbedSpaces(y) + "X X");
+ }
+ System.out.println(tabbedSpaces(12) + "XX");
+ System.out.println(tabbedSpaces(11) + "X");
+ System.out.println(tabbedSpaces(10) + "*");
+ System.out.println();
+ System.out.println("#########################");
+ System.out.println();
+ System.out.println("I HOPE YOU BELIEVE ME NOW, FOR YOUR SAKE!!");
+ this.gameState = GAME_STATE.GAME_OVER;
+ }
+
+ }
+ break;
+
+ // Sign off message for cases where the Chief is not upset
+ case END_GAME:
+ System.out.println("BYE!!!");
+ this.gameState = GAME_STATE.GAME_OVER;
+ break;
+
+ // GAME_OVER State does not specifically have a case
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ /**
+ * Simulate tabs by building up a string of spaces
+ *
+ * @param spaces how many spaces are there to be
+ * @return a string with the requested number of spaces
+ */
+ private String tabbedSpaces(int spaces) {
+ char[] repeat = new char[spaces];
+ Arrays.fill(repeat, ' ');
+ return new String(repeat);
+ }
+ private void instructions() {
+ System.out.println(" TAKE A NUMBER AND ADD 3. DIVIDE THIS NUMBER BY 5 AND");
+ System.out.println("MULTIPLY BY 8. DIVIDE BY 5 AND ADD THE SAME. SUBTRACT 1.");
+ }
+
+ /**
+ * Basic information about the game
+ *
+ */
+ private void intro() {
+ System.out.println("CHIEF");
+ System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("I AM CHIEF NUMBERS FREEK, THE GREAT INDIAN MATH GOD.");
+ }
+
+ /**
+ * Returns true if a given string is equal to at least one of the values specified in the call
+ * to the stringIsAnyValue method
+ *
+ * @param text string to search
+ * @return true if string is equal to one of the varargs
+ */
+ private boolean yesEntered(String text) {
+ return stringIsAnyValue(text, "Y", "YES");
+ }
+
+ /**
+ * Returns true if a given string contains at least one of the varargs (2nd parameter).
+ * Note: Case insensitive comparison.
+ *
+ * @param text string to search
+ * @param values varargs of type string containing values to compare
+ * @return true if one of the varargs arguments was found in text
+ */
+ private boolean stringIsAnyValue(String text, String... values) {
+
+ // Cycle through the variable number of values and test each
+ for(String val:values) {
+ if(text.equalsIgnoreCase(val)) {
+ return true;
+ }
+ }
+
+ // no matches
+ return false;
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+}
\ No newline at end of file
diff --git a/25 Chief/java/src/ChiefGame.java b/25 Chief/java/src/ChiefGame.java
new file mode 100644
index 00000000..25ebc1bc
--- /dev/null
+++ b/25 Chief/java/src/ChiefGame.java
@@ -0,0 +1,8 @@
+public class ChiefGame {
+
+ public static void main(String[] args) {
+
+ Chief chief = new Chief();
+ chief.play();
+ }
+}
\ No newline at end of file
diff --git a/44 Hangman/python/hangman.py b/44 Hangman/python/hangman.py
index 0387e267..2b42a121 100755
--- a/44 Hangman/python/hangman.py
+++ b/44 Hangman/python/hangman.py
@@ -1,6 +1,11 @@
#!/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 '''
@@ -33,6 +38,14 @@ class Canvas:
self._buffer[y][x] = s[0]
+def draw_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)
@@ -46,14 +59,6 @@ def draw_head(canvas):
canvas.put('-', 7, 4)
-def draw_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_body(canvas):
for i in range(5, 9, 1):
canvas.put('X', 6, i)
@@ -100,112 +105,109 @@ def draw_right_foot(canvas):
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)
+ ("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')
-QUESTION_PROMPT = '? '
+print(" " * 32 + "HANGMAN")
+print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n")
+
+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 revealed_word(word, letters_used):
- return ''.join(letter if letter in letters_used else '-'
- for letter in word)
+def play_game(guessTarget):
+ """Play the game"""
+ guessWrong = 0
+ guessProgress = ["-"] * len(guessTarget)
+ guessList = []
+ gallows = Canvas()
+ draw_gallows(gallows)
-def play():
-
- print('HANGMAN')
- print('CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n')
-
- words_available = set(WORDS)
+ guessCount = 0
while True:
-
- if len(words_available) == 0:
- print('YOU DID ALL THE WORDS!!')
- break
-
- # Initize game state for this round
- canvas = Canvas()
- draw_gallows(canvas)
-
- word = random.choice(list(words_available))
- letters_used = set()
- guesses_count = 0
- fail_count = 0
-
- while True:
- print('HERE ARE THE LETTERS YOU USED:')
- print(', '.join(sorted(letters_used)))
- print('\n')
-
- print(revealed_word(word, letters_used))
- print('\n')
-
- print('WHAT IS YOUR GUESS', end=QUESTION_PROMPT)
- guess = input().upper()
-
- if guess in letters_used:
- print('YOU GUESSED THAT LETTER BEFORE!')
- continue
-
- guesses_count += 1
-
- if guess not in word:
- comment, draw_function = PHASES[fail_count]
- print('\n\nSORRY, THAT LETTER ISN\'T IN THE WORD.')
- print(comment)
- draw_function(canvas)
- print(canvas.render())
-
- fail_count += 1
- if fail_count == len(PHASES):
- print('SORRY, YOU LOSE. THE WORD WAS', word)
- print('YOU MISSED THAT ONE. DO YOU', end=' ')
- break
-
- letters_used.add(guess)
- if '-' not in revealed_word(word, letters_used):
- print("YOU FOUND THE WORD!")
- words_available.remove(word)
+ print("Here are the letters you used:")
+ print(",".join(guessList) + "\n")
+ print("".join(guessProgress) + "\n")
+ guessLetter = ""
+ guessWord = ""
+ while guessLetter == "":
+ guessLetter = input("What is your guess? ").upper()[0]
+ if not guessLetter.isalpha():
+ guessLetter = ""
+ print("Only letters are allowed!")
+ elif guessLetter in guessList:
+ guessLetter = ""
+ print("You guessed that letter before!")
+ guessList.append(guessLetter)
+ guessCount = guessCount + 1
+ if guessLetter in guessTarget:
+ indices = [i for i, letter in enumerate(guessTarget) if letter == guessLetter]
+ for i in indices:
+ guessProgress[i] = guessLetter
+ if guessProgress == guessTarget:
+ print("You found the word!")
break
else:
- print('\n' + revealed_word(word, letters_used))
- print('\n\nWHAT IS YOUR GUESS FOR THE WORD', end=QUESTION_PROMPT)
- guessed_word = input().upper()
+ print("\n" + "".join(guessProgress) + "\n")
+ while guessWord == "":
+ guessWord = input("What is your guess for the word? ").upper()
+ if not guessWord.isalpha():
+ guessWord = ""
+ print("Only words are allowed!")
+ if guessWord == guessTarget:
+ print("Right!! It took you", guessCount, "guesses!")
+ break
+ else:
+ comment, drawingBodyPart = PHASES[guessWrong]
- if guessed_word != word:
- print('WRONG. TRY ANOTHER LETTER.\n')
- continue
+ print(comment)
+ drawingBodyPart(gallows)
+ print(gallows.render())
- print('RIGHT!! IT TOOK YOU {} GUESSES!'.format(guesses_count))
- words_available.remove(word)
+ guessWrong = guessWrong + 1
+ print("Sorry, that letter isn't in the word.")
+
+ if guessWrong == 10:
+ print("Sorry, you lose. The word was " + guessTarget)
break
- print('WANT ANOTHER WORD', end=QUESTION_PROMPT)
- reply = input().upper()
- if reply != 'YES':
- break
- print('\nIT\'S BEEN FUN! BYE FOR NOW.')
+def main():
+ """Main"""
+
+ random.shuffle(words)
+ wordCurrent = 0
+ wordCount = 49
+
+ keep_playing = True
+ while keep_playing:
+ play_game(words[wordCurrent])
+ wordCurrent = wordCurrent + 1
+ if wordCurrent >= wordCount:
+ 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__':
- play()
+if __name__ == "__main__":
+ main()
diff --git a/47 Hi-Lo/java/src/HiLo.java b/47 Hi-Lo/java/src/HiLo.java
new file mode 100644
index 00000000..36f44ee5
--- /dev/null
+++ b/47 Hi-Lo/java/src/HiLo.java
@@ -0,0 +1,214 @@
+import java.util.Scanner;
+
+/**
+ * Game of HiLo
+ *
+ * Based on the Basic game of Hi-Lo here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/47%20Hi-Lo/hi-lo.bas
+ *
+ * Note: The idea was to create a version of this 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class HiLo {
+
+ public static final int LOW_NUMBER_RANGE = 1;
+ public static final int HIGH_NUMBER_RANGE = 100;
+ public static final int MAX_GUESSES = 6;
+
+ private enum GAME_STATE {
+ STARTING,
+ START_GAME,
+ GUESSING,
+ PLAY_AGAIN,
+ GAME_OVER
+ }
+
+ // Used for keyboard input
+ private Scanner kbScanner;
+
+ // Current game state
+ private GAME_STATE gameState;
+
+ // Players Winnings
+ private int playerAmountWon;
+
+ // Players guess count;
+ private int playersGuesses;
+
+ // Computers random number
+ private int computersNumber;
+
+ public HiLo() {
+
+ this.gameState = GAME_STATE.STARTING;
+ this.playerAmountWon = 0;
+
+ // 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;
+
+ // Generate computers number for player to guess, etc.
+ case START_GAME:
+ init();
+ System.out.println("O.K. I HAVE A NUMBER IN MIND.");
+ this.gameState = GAME_STATE.GUESSING;
+ break;
+
+ // Player guesses the number until they get it or run out of guesses
+ case GUESSING:
+ int guess = playerGuess();
+
+ // Check if the player guessed the number
+ if(validateGuess(guess)) {
+ System.out.println("GOT IT!!!!!!!!!! YOU WIN " + this.computersNumber
+ + " DOLLARS.");
+ this.playerAmountWon += this.computersNumber;
+ System.out.println("YOUR TOTAL WINNINGS ARE NOW "
+ + this.playerAmountWon + " DOLLARS.");
+ this.gameState = GAME_STATE.PLAY_AGAIN;
+ } else {
+ // incorrect guess
+ this.playersGuesses++;
+ // Ran out of guesses?
+ if (this.playersGuesses == MAX_GUESSES) {
+ System.out.println("YOU BLEW IT...TOO BAD...THE NUMBER WAS "
+ + this.computersNumber);
+ this.playerAmountWon = 0;
+ this.gameState = GAME_STATE.PLAY_AGAIN;
+ }
+ }
+ break;
+
+ // Play again, or exit game?
+ case PLAY_AGAIN:
+ System.out.println();
+ if(yesEntered(displayTextAndGetInput("PLAY AGAIN (YES OR NO) "))) {
+ this.gameState = GAME_STATE.START_GAME;
+ } else {
+ // Chose not to play again
+ System.out.println("SO LONG. HOPE YOU ENJOYED YOURSELF!!!");
+ this.gameState = GAME_STATE.GAME_OVER;
+ }
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ /**
+ * Checks the players guess against the computers randomly generated number
+ *
+ * @param theGuess
+ * @return true if the player guessed correctly, false otherwise
+ */
+ private boolean validateGuess(int theGuess) {
+
+ // Correct guess?
+ if(theGuess == this.computersNumber) {
+ return true;
+ }
+
+ if(theGuess > this.computersNumber) {
+ System.out.println("YOUR GUESS IS TOO HIGH.");
+ } else {
+ System.out.println("YOUR GUESS IS TOO LOW.");
+ }
+
+ return false;
+ }
+
+ private void init() {
+ this.playersGuesses = 0;
+ this.computersNumber = randomNumber();
+ }
+
+ public void intro() {
+ System.out.println("HI LO");
+ System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println();
+ System.out.println("THIS IS THE GAME OF HI LO.");
+ System.out.println();
+ System.out.println("YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE");
+ System.out.println("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS. IF YOU");
+ System.out.println("GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!");
+ System.out.println("THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY. HOWEVER,");
+ System.out.println("IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.");
+ }
+
+ /**
+ * Get players guess from kb
+ *
+ * @return players guess as an int
+ */
+ private int playerGuess() {
+ return Integer.valueOf((displayTextAndGetInput("YOUR GUESS? ")));
+ }
+
+ /**
+ * Checks whether player entered Y or YES to a question.
+ *
+ * @param text player string from kb
+ * @return true of Y or YES was entered, otherwise false
+ */
+ private boolean yesEntered(String text) {
+ return stringIsAnyValue(text, new String[] {"Y", "YES"});
+ }
+
+ /**
+ * Check whether a string equals one of a variable number of values
+ * Useful to check for Y or YES for example
+ * Comparison is case insensitive.
+ *
+ * @param text source string
+ * @param values a range of values to compare against the source string
+ * @return true if a comparison was found in one of the variable number of strings passed
+ */
+ private boolean stringIsAnyValue(String text, String... values) {
+
+ // Cycle through the variable number of values and test each
+ for(String val:values) {
+ if(text.equalsIgnoreCase(val)) {
+ return true;
+ }
+ }
+
+ // no matches
+ return false;
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Generate random number
+ * Used as a single digit of the computer player
+ *
+ * @return random number
+ */
+ private int randomNumber() {
+ return (int) (Math.random()
+ * (HIGH_NUMBER_RANGE - LOW_NUMBER_RANGE + 1) + LOW_NUMBER_RANGE);
+ }
+}
\ No newline at end of file
diff --git a/47 Hi-Lo/java/src/HiLoGame.java b/47 Hi-Lo/java/src/HiLoGame.java
new file mode 100644
index 00000000..314606c4
--- /dev/null
+++ b/47 Hi-Lo/java/src/HiLoGame.java
@@ -0,0 +1,8 @@
+public class HiLoGame {
+
+ public static void main(String[] args) {
+
+ HiLo hiLo = new HiLo();
+ hiLo.play();
+ }
+}
diff --git a/51 Hurkle/java/src/Hurkle.java b/51 Hurkle/java/src/Hurkle.java
new file mode 100644
index 00000000..8af8732f
--- /dev/null
+++ b/51 Hurkle/java/src/Hurkle.java
@@ -0,0 +1,186 @@
+import java.util.ArrayList;
+import java.util.Scanner;
+
+public class Hurkle {
+
+ public static final int GRID_SIZE = 10;
+ public static final int MAX_GUESSES = 5;
+
+ private enum GAME_STATE {
+ STARTING,
+ START_GAME,
+ GUESSING,
+ PLAY_AGAIN,
+ GAME_OVER
+ }
+
+ private GAME_STATE gameState;
+
+ // Used for keyboard input
+ private Scanner kbScanner;
+
+ private int guesses;
+
+ // hurkle position
+ private int hurkleXPos;
+ private int hurkleYPos;
+
+ // player guess
+ private int playerGuessXPos;
+ private int playerGuessYPos;
+
+ public Hurkle() {
+
+ gameState = GAME_STATE.STARTING;
+
+ // 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.hurkleXPos = randomNumber();
+ this.hurkleYPos = randomNumber();
+ System.out.println("HURKLE AT : " + this.hurkleXPos + "," + this.hurkleYPos);
+
+ this.guesses = 1;
+ gameState = GAME_STATE.GUESSING;
+
+ break;
+
+ // Guess an x,y position of the hurkle
+ case GUESSING:
+ String guess = displayTextAndGetInput("GUESS #" + this.guesses + "? ");
+ this.playerGuessXPos = getDelimitedValue(guess, 0);
+ this.playerGuessYPos = getDelimitedValue(guess, 1);
+ if (foundHurkle()) {
+ this.gameState = GAME_STATE.PLAY_AGAIN;
+ } else {
+ showDirectionOfHurkle();
+ this.guesses++;
+ if(this.guesses > MAX_GUESSES) {
+ System.out.println("SORRY, THAT'S "
+ + MAX_GUESSES + " GUESSES.");
+ System.out.println("THE HURKLE IS AT "
+ + this.hurkleXPos + "," + this.hurkleYPos);
+ System.out.println();
+ this.gameState = GAME_STATE.PLAY_AGAIN;
+ }
+ }
+
+ break;
+
+ case PLAY_AGAIN:
+ System.out.println("LET'S PLAY AGAIN, HURKLE IS HIDING.");
+ System.out.println();
+ this.gameState = GAME_STATE.START_GAME;
+ break;
+ }
+ // Effectively an endless loop because the game never quits as per
+ // the original basic code.
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ private void showDirectionOfHurkle() {
+ System.out.print("GO ");
+ if(this.playerGuessYPos == this.hurkleYPos) {
+ // don't print North or South because the player has chosen the
+ // same y grid pos as the hurkle
+ } else if (this.playerGuessYPos < this.hurkleYPos) {
+ System.out.print("NORTH");
+ } else if(this.playerGuessYPos > this.hurkleYPos) {
+ System.out.print("SOUTH");
+ }
+
+ if(this.playerGuessXPos == this.hurkleXPos) {
+ // don't print East or West because the player has chosen the
+ // same x grid pos as the hurkle
+ } else if(this.playerGuessXPos < this.hurkleXPos) {
+ System.out.print("EAST");
+ } else if(this.playerGuessXPos > this.hurkleXPos) {
+ System.out.print("WEST");
+ }
+ System.out.println();
+ return;
+ }
+
+ private boolean foundHurkle() {
+ if ((this.playerGuessXPos - this.hurkleXPos)
+ - (this.playerGuessYPos - this.hurkleYPos) == 0) {
+ System.out.println("YOU FOUND HIM IN " + this.guesses + " GUESSES.");
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Display info about the game
+ */
+ private void intro() {
+ System.out.println("HURKLE");
+ System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("A HURKLE IS HIDING ON A " + GRID_SIZE + " BY "
+ + GRID_SIZE + " GRID. HOMEBASE");
+ System.out.println("ON THE GRID IS POINT 0,0 IN THE SOUTHWEST CORNER,");
+ System.out.println("AND ANY POINT ON THE GRID IS DESIGNATED BY A");
+ System.out.println("PAIR OF WHOLE NUMBERS SEPERATED BY A COMMA. THE FIRST");
+ System.out.println("NUMBER IS THE HORIZONTAL POSITION AND THE SECOND NUMBER");
+ System.out.println("IS THE VERTICAL POSITION. YOU MUST TRY TO");
+ System.out.println("GUESS THE HURKLE'S GRIDPOINT. YOU GET "
+ + MAX_GUESSES + " TRIES.");
+ System.out.println("AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE");
+ System.out.println("DIRECTION TO GO TO LOOK FOR THE HURKLE.");
+ }
+
+ /**
+ * Generate random number
+ * Used to create one part of an x,y grid position
+ *
+ * @return random number
+ */
+ private int randomNumber() {
+ return (int) (Math.random()
+ * (GRID_SIZE) + 1);
+ }
+
+ /*
+ * 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();
+ }
+
+ /**
+ * Accepts a string delimited by comma's and returns the pos'th 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]);
+ }
+}
diff --git a/51 Hurkle/java/src/HurkleGame.java b/51 Hurkle/java/src/HurkleGame.java
new file mode 100644
index 00000000..c582885e
--- /dev/null
+++ b/51 Hurkle/java/src/HurkleGame.java
@@ -0,0 +1,7 @@
+public class HurkleGame {
+
+ public static void main(String[] args) {
+ Hurkle hurkle = new Hurkle();
+ hurkle.play();
+ }
+}
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/java/SineWave.java b/78 Sine Wave/java/SineWave.java
new file mode 100644
index 00000000..7d917a75
--- /dev/null
+++ b/78 Sine Wave/java/SineWave.java
@@ -0,0 +1,35 @@
+import java.util.Arrays;
+
+/**
+ * Sine Wave
+ *
+ * Based on the Sine Wave program here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/78%20Sine%20Wave/sinewave.bas
+ *
+ * Note: The idea was to create a version of this 1970's Basic program in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class SineWave {
+
+ public static void main(String[] args) {
+
+ System.out.println("SINE WAVE");
+ System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+
+ int toggle = 0;
+ for(double t = 0; t<40; t += .25) {
+ int a = 26 + (int) (25 * Math.sin(t));
+ char[] repeat = new char[a];
+ Arrays.fill(repeat,' ');
+ System.out.print(new String(repeat));
+ if (toggle == 1) {
+ System.out.println("COMPUTING");
+ toggle = 0;
+ } else {
+ System.out.println("CREATIVE");
+ toggle = 1;
+ }
+ }
+ }
+}