diff --git a/.gitignore b/.gitignore
index 42752d61..aa42e787 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,3 @@
-################################################################################
-# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
-################################################################################
-
/01 Acey Ducey/csharp/obj
/47 Hi-Lo/csharp/obj
/.vs
@@ -13,3 +9,4 @@
*/csharp/bin
*/csharp/obj
+
diff --git a/01 Acey Ducey/java/src/aceyducey/AceyDucey.java b/01 Acey Ducey/java/src/AceyDucey.java
similarity index 74%
rename from 01 Acey Ducey/java/src/aceyducey/AceyDucey.java
rename to 01 Acey Ducey/java/src/AceyDucey.java
index 37dcc57c..43fc9950 100644
--- a/01 Acey Ducey/java/src/aceyducey/AceyDucey.java
+++ b/01 Acey Ducey/java/src/AceyDucey.java
@@ -1,15 +1,12 @@
-package aceyducey;
-
import java.util.Scanner;
/**
* Game of AceyDucey
- *
+ *
* Based on the Basic game of AceyDucey here
* https://github.com/coding-horror/basic-computer-games/blob/main/01%20Acey%20Ducey/aceyducey.bas
- * Note: The idea was to create a version of this 1970's Basic game in Java, without introducing
- * new features - no additional text, error checking, etc has been added.
- *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
*/
public class AceyDucey {
@@ -32,10 +29,10 @@ public class AceyDucey {
private boolean gameOver = false;
// Used for keyboard input
- private Scanner kbScanner;
+ private final Scanner kbScanner;
// Constant value for cards from a deck - 2 lowest, 14 (Ace) highest
- public static final int LOW_CARD_RANGE =2;
+ public static final int LOW_CARD_RANGE = 2;
public static final int HIGH_CARD_RANGE = 14;
public AceyDucey() {
@@ -58,7 +55,7 @@ public class AceyDucey {
String playAgain = kbScanner.next().toUpperCase();
System.out.println();
System.out.println();
- if(playAgain.equals("YES")) {
+ if (playAgain.equals("YES")) {
return true;
} else {
System.out.println("O.K., HOPE YOU HAD FUN!");
@@ -71,9 +68,8 @@ public class AceyDucey {
public void play() {
// Keep playing hands until player runs out of cash
- // which sets gameover to true
do {
- if(firstTimePlaying) {
+ if (firstTimePlaying) {
intro();
firstTimePlaying = false;
}
@@ -81,17 +77,17 @@ public class AceyDucey {
drawCards();
displayCards();
int betAmount = getBet();
- this.playersCard = randomCard();
+ playersCard = randomCard();
displayPlayerCard();
- if(playerWon()) {
+ if (playerWon()) {
System.out.println("YOU WIN!!");
- this.playerAmount += betAmount;
+ playerAmount += betAmount;
} else {
System.out.println("SORRY, YOU LOSE");
- this.playerAmount -= betAmount;
+ playerAmount -= betAmount;
// Player run out of money?
- if(this.playerAmount <=0) {
- this.gameOver = true;
+ if (playerAmount <= 0) {
+ gameOver = true;
}
}
@@ -102,18 +98,14 @@ public class AceyDucey {
// to win a players card has to be in the range of the first and second dealer
// drawn cards inclusive of first and second cards.
private boolean playerWon() {
- if((this.playersCard.getValue() >= this.firstCard.getValue())
- && this.playersCard.getValue() <= this.secondCard.getValue()) {
- // winner
- return true;
- }
-
- return false;
+ // winner
+ return (playersCard.getValue() >= firstCard.getValue())
+ && playersCard.getValue() <= secondCard.getValue();
}
private void displayPlayerCard() {
- System.out.println(this.playersCard.getName());
+ System.out.println(playersCard.getName());
}
// Get the players bet, and return the amount
@@ -121,16 +113,16 @@ public class AceyDucey {
// method will loop until a valid bet is entered.
private int getBet() {
boolean validBet = false;
- int amount = 0;
+ int amount;
do {
System.out.print("WHAT IS YOUR BET ");
amount = kbScanner.nextInt();
- if(amount == 0) {
+ if (amount == 0) {
System.out.println("CHICKEN!!");
validBet = true;
- } else if(amount > this.playerAmount) {
+ } else if (amount > playerAmount) {
System.out.println("SORRY, MY FRIEND, BUT YOU BET TOO MUCH.");
- System.out.println("YOU HAVE ONLY " + this.playerAmount + " DOLLARS TO BET.");
+ System.out.println("YOU HAVE ONLY " + playerAmount + " DOLLARS TO BET.");
} else {
validBet = true;
}
@@ -140,13 +132,13 @@ public class AceyDucey {
}
private void displayBalance() {
- System.out.println("YOU NOW HAVE " + this.playerAmount + " DOLLARS.");
+ System.out.println("YOU NOW HAVE " + playerAmount + " DOLLARS.");
}
private void displayCards() {
System.out.println("HERE ARE YOUR NEXT TWO CARDS: ");
- System.out.println(this.firstCard.getName());
- System.out.println(this.secondCard.getName());
+ System.out.println(firstCard.getName());
+ System.out.println(secondCard.getName());
}
// Draw two dealer cards, and save them for later use.
@@ -154,9 +146,9 @@ public class AceyDucey {
private void drawCards() {
do {
- this.firstCard = randomCard();
- this.secondCard = randomCard();
- } while(this.firstCard.getValue() >= this.secondCard.getValue());
+ firstCard = randomCard();
+ secondCard = randomCard();
+ } while (firstCard.getValue() >= secondCard.getValue());
}
// Creates a random card
diff --git a/01 Acey Ducey/java/src/aceyducey/Game.java b/01 Acey Ducey/java/src/AceyDuceyGame.java
similarity index 72%
rename from 01 Acey Ducey/java/src/aceyducey/Game.java
rename to 01 Acey Ducey/java/src/AceyDuceyGame.java
index 54582f5f..1ce08c28 100644
--- a/01 Acey Ducey/java/src/aceyducey/Game.java
+++ b/01 Acey Ducey/java/src/AceyDuceyGame.java
@@ -1,20 +1,16 @@
-package aceyducey;
-
/**
* This class is used to invoke the game.
*
*/
-public class Game {
-
- private static AceyDucey game;
+public class AceyDuceyGame {
public static void main(String[] args) {
- boolean keepPlaying = true;
+ boolean keepPlaying;
+ AceyDucey game = new AceyDucey();
// Keep playing game until infinity or the player loses
do {
- game = new AceyDucey();
game.play();
System.out.println();
System.out.println();
diff --git a/01 Acey Ducey/java/src/aceyducey/Card.java b/01 Acey Ducey/java/src/Card.java
similarity index 95%
rename from 01 Acey Ducey/java/src/aceyducey/Card.java
rename to 01 Acey Ducey/java/src/Card.java
index ad15cced..88211002 100644
--- a/01 Acey Ducey/java/src/aceyducey/Card.java
+++ b/01 Acey Ducey/java/src/Card.java
@@ -1,5 +1,3 @@
-package aceyducey;
-
/**
* A card from a deck - the value is between 2-14 to cover
* cards with a face value of 2-9 and then a Jack, Queen, King, and Ace
@@ -14,7 +12,7 @@ public class Card {
private void init(int value) {
this.value = value;
- if(value <11) {
+ if (value < 11) {
this.name = String.valueOf(value);
} else {
switch (value) {
diff --git a/02 Amazing/python/amazing.py b/02 Amazing/python/amazing.py
new file mode 100644
index 00000000..dc9da380
--- /dev/null
+++ b/02 Amazing/python/amazing.py
@@ -0,0 +1,121 @@
+import random
+
+# Python translation by Frank Palazzolo - 2/2021
+
+print(' '*28+'AMAZING PROGRAM')
+print(' '*15+'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY')
+print()
+print()
+print()
+
+while True:
+ width, length = input('What are your width and length?').split(',')
+ width = int(width)
+ length = int(length)
+ if width != 1 and length != 1:
+ break
+ print('Meaningless dimensions. Try again.')
+
+# Build two 2D arrays
+#
+# used:
+# Initially set to zero, unprocessed cells
+# Filled in with consecutive non-zero numbers as cells are processed
+#
+# walls:
+# Initially set to zero, (all paths blocked)
+# Remains 0 if there is no exit down or right
+# Set to 1 if there is an exit down
+# Set to 2 if there is an exit right
+# Set to 3 if there are exits down and right
+
+used = []
+walls = []
+for i in range(length):
+ used.append([0]*width)
+ walls.append([0]*width)
+
+# Use direction variables with nice names
+GO_LEFT,GO_UP,GO_RIGHT,GO_DOWN=[0,1,2,3]
+# Give Exit directions nice names
+EXIT_DOWN = 1
+EXIT_RIGHT = 2
+
+# Pick a random entrance, mark as used
+enter_col=random.randint(0,width-1)
+row,col=0,enter_col
+count=1
+used[row][col]=count
+count=count+1
+
+while count!=width*length+1:
+ # remove possible directions that are blocked or
+ # hit cells that we have already processed
+ possible_dirs = [GO_LEFT,GO_UP,GO_RIGHT,GO_DOWN]
+ if col==0 or used[row][col-1]!=0:
+ possible_dirs.remove(GO_LEFT)
+ if row==0 or used[row-1][col]!=0:
+ possible_dirs.remove(GO_UP)
+ if col==width-1 or used[row][col+1]!=0:
+ possible_dirs.remove(GO_RIGHT)
+ if row==length-1 or used[row+1][col]!=0:
+ possible_dirs.remove(GO_DOWN)
+
+ # If we can move in a direction, move and make opening
+ if len(possible_dirs)!=0:
+ direction=random.choice(possible_dirs)
+ if direction==GO_LEFT:
+ col=col-1
+ walls[row][col]=EXIT_RIGHT
+ elif direction==GO_UP:
+ row=row-1
+ walls[row][col]=EXIT_DOWN
+ elif direction==GO_RIGHT:
+ walls[row][col]=walls[row][col]+EXIT_RIGHT
+ col=col+1
+ elif direction==GO_DOWN:
+ walls[row][col]=walls[row][col]+EXIT_DOWN
+ row=row+1
+ used[row][col]=count
+ count=count+1
+ # otherwise, move to the next used cell, and try again
+ else:
+ while True:
+ if col!=width-1:
+ col=col+1
+ elif row!=length-1:
+ row,col=row+1,0
+ else:
+ row,col=0,0
+ if used[row][col]!=0:
+ break
+
+# Add a random exit
+col=random.randint(0,width-1)
+row=length-1
+walls[row][col]=walls[row][col]+1
+
+# Print the maze
+for col in range(width):
+ if col==enter_col:
+ print('. ',end='')
+ else:
+ print('.--',end='')
+print('.')
+for row in range(length):
+ print('I',end='')
+ for col in range(width):
+ if walls[row][col]<2:
+ print(' I',end='')
+ else:
+ print(' ',end='')
+ print()
+ for col in range(width):
+ if walls[row][col]==0 or walls[row][col]==2:
+ print(':--',end='')
+ else:
+ print(': ',end='')
+ print('.')
+
+
+
\ No newline at end of file
diff --git a/03 Animal/ruby/animal.rb b/03 Animal/ruby/animal.rb
new file mode 100644
index 00000000..5100b2aa
--- /dev/null
+++ b/03 Animal/ruby/animal.rb
@@ -0,0 +1,95 @@
+require 'set'
+
+def intro
+ puts " ANIMAL
+ CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
+
+
+
+PLAY 'GUESS THE ANIMAL'
+
+THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT.
+
+"
+end
+
+def ask(question)
+ print "#{question} "
+ (gets || '').chomp.upcase
+end
+
+Feature = Struct.new(:question, :yes_guess, :no_guess)
+
+def add_guess(animals, guess)
+ guess.is_a?(Struct) ? get_all_animals(guess, animals) : animals.add(guess)
+end
+
+def get_all_animals(feature, animals = Set.new)
+ add_guess(animals, feature.yes_guess)
+ add_guess(animals, feature.no_guess)
+ animals
+end
+
+def create_feature(current_animal)
+ new_animal = ask('THE ANIMAL YOU WERE THINKING OF WAS A ?')
+ puts "PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A #{new_animal} FROM A #{current_animal}"
+ question = ask('?')
+ loop do
+ yes_no = ask("FOR A #{new_animal} THE ANSWER WOULD BE ?")
+ next unless ['Y', 'N'].include?(yes_no[0])
+ guesses = yes_no[0] == 'Y' ? [new_animal, current_animal] : [current_animal, new_animal]
+ return Feature.new(question, *guesses)
+ end
+end
+
+def guess_loop(feature)
+ loop do
+ answer = ask(feature.question)
+ next unless ['Y', 'N'].include?(answer[0])
+ answer_is_yes = answer[0] == 'Y'
+
+ name = answer_is_yes ? feature.yes_guess : feature.no_guess
+ if name.is_a?(Struct)
+ feature = name
+ next
+ end
+
+ guess = ask("IS IT A #{name}?")
+ correct_guess = guess[0] == 'Y'
+
+ if correct_guess
+ puts "WHY NOT TRY ANOTHER ANIMAL?"
+ break
+ end
+
+ if answer_is_yes
+ feature.yes_guess = create_feature(name)
+ else
+ feature.no_guess = create_feature(name)
+ end
+ break
+ end
+end
+
+def main
+ intro
+ feature = Feature.new('DOES IT SWIM?', 'FISH', 'BIRD')
+
+ while true do
+ option = ask("ARE YOU THINKING OF AN ANIMAL?")
+ if option == 'LIST'
+ puts
+ puts "ANIMALS I ALREADY KNOW ARE:"
+ puts get_all_animals(feature).to_a.join(" " * 15)
+ puts
+ elsif option[0] == 'Y'
+ guess_loop(feature)
+ elsif option == ''
+ puts
+ end
+ end
+end
+
+trap "SIGINT" do puts; exit 130 end
+
+main
\ No newline at end of file
diff --git a/05 Bagels/csharp/BagelNumber.cs b/05 Bagels/csharp/BagelNumber.cs
new file mode 100644
index 00000000..2fd660e9
--- /dev/null
+++ b/05 Bagels/csharp/BagelNumber.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace BasicComputerGames.Bagels
+{
+ public enum BagelValidation
+ {
+ Valid,
+ WrongLength,
+ NotUnique,
+ NonDigit
+ };
+ public class BagelNumber
+ {
+ private static readonly Random Rnd = new Random();
+
+ private readonly int[] _digits;
+ public override string ToString()
+ {
+ return String.Join('-', _digits);
+ }
+
+ public static BagelNumber CreateSecretNumber(int numDigits)
+ {
+ if (numDigits < 3 || numDigits > 9)
+ throw new ArgumentOutOfRangeException(nameof(numDigits),
+ "Number of digits must be between 3 and 9, inclusive");
+
+ var digits = GetDigits(numDigits);
+ return new BagelNumber(digits);
+ }
+
+
+
+ public static BagelValidation IsValid(string number, int length)
+ {
+ if (number.Length != length)
+ return BagelValidation.WrongLength;
+
+ if (!number.All(Char.IsDigit))
+ return BagelValidation.NonDigit;
+
+ if (new HashSet(number).Count != length)
+ return BagelValidation.NotUnique;
+
+ return BagelValidation.Valid;
+ }
+
+ public BagelNumber(string number)
+ {
+ if (number.Any(d => !Char.IsDigit(d)))
+ throw new ArgumentException("Number must be all unique digits", nameof(number));
+
+ _digits = number.Select(d => d - '0').ToArray();
+ }
+
+ //public BagelNumber(long number)
+ //{
+ // var digits = new List();
+ // if (number >= 1E10)
+ // throw new ArgumentOutOfRangeException(nameof(number), "Number can be no more than 9 digits");
+
+ // while (number > 0)
+ // {
+ // long num = number / 10;
+ // int digit = (int)(number - (num * 10));
+ // number = num;
+ // digits.Add(digit);
+ // }
+
+ // _digits = digits.ToArray();
+ //}
+
+ public BagelNumber(int[] digits)
+ {
+ _digits = digits;
+ }
+
+ private static int[] GetDigits(int numDigits)
+ {
+ int[] digits = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ Shuffle(digits);
+ return digits.Take(numDigits).ToArray();
+
+ }
+
+ private static void Shuffle(int[] digits)
+ {
+ for (int i = digits.Length - 1; i > 0; --i)
+ {
+ int pos = Rnd.Next(i);
+ var t = digits[i];
+ digits[i] = digits[pos];
+ digits[pos] = t;
+ }
+
+ }
+
+ public (int pico, int fermi) CompareTo(BagelNumber other)
+ {
+ int pico = 0;
+ int fermi = 0;
+ for (int i = 0; i < _digits.Length; i++)
+ {
+ for (int j = 0; j < other._digits.Length; j++)
+ {
+ if (_digits[i] == other._digits[j])
+ {
+ if (i == j)
+ ++fermi;
+ else
+ ++pico;
+ }
+ }
+ }
+
+ return (pico, fermi);
+ }
+ }
+}
\ No newline at end of file
diff --git a/05 Bagels/csharp/Bagels.csproj b/05 Bagels/csharp/Bagels.csproj
new file mode 100644
index 00000000..68fa11ec
--- /dev/null
+++ b/05 Bagels/csharp/Bagels.csproj
@@ -0,0 +1,13 @@
+
+
+
+ Exe
+ net5.0
+ BasicComputerGames.Bagels
+
+
+
+
+
+
+
diff --git a/05 Bagels/csharp/Game.cs b/05 Bagels/csharp/Game.cs
new file mode 100644
index 00000000..f6885464
--- /dev/null
+++ b/05 Bagels/csharp/Game.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+
+namespace BasicComputerGames.Bagels
+{
+ public class Game : GameBase
+ {
+ public void GameLoop()
+ {
+ DisplayIntroText();
+ int points = 0;
+ do
+ {
+ var result =PlayRound();
+ if (result)
+ ++points;
+ } while (TryAgain());
+
+ Console.WriteLine();
+ Console.WriteLine($"A {points} point Bagels buff!!");
+ Console.WriteLine("Hope you had fun. Bye.");
+ }
+
+ private const int Length = 3;
+ private const int MaxGuesses = 20;
+
+ private bool PlayRound()
+ {
+ var secret = BagelNumber.CreateSecretNumber(Length);
+ Console.WriteLine("O.K. I have a number in mind.");
+ for (int guessNo = 1; guessNo <= MaxGuesses; ++guessNo)
+ {
+ string strGuess;
+ BagelValidation isValid;
+ do
+ {
+ Console.WriteLine($"Guess #{guessNo}");
+ strGuess = Console.ReadLine();
+ isValid = BagelNumber.IsValid(strGuess, Length);
+ PrintError(isValid);
+ } while (isValid != BagelValidation.Valid);
+
+ var guess = new BagelNumber(strGuess);
+ var fermi = 0;
+ var pico = 0;
+ (pico, fermi) = secret.CompareTo(guess);
+ if(pico + fermi == 0)
+ Console.Write("BAGELS!");
+ else if (fermi == Length)
+ {
+ Console.WriteLine("You got it!");
+ return true;
+ }
+ else
+ {
+ PrintList("Pico ", pico);
+ PrintList("Fermi ", fermi);
+ }
+ Console.WriteLine();
+ }
+
+ Console.WriteLine("Oh, well.");
+ Console.WriteLine($"That's {MaxGuesses} guesses. My Number was {secret}");
+
+ return false;
+
+ }
+
+ private void PrintError(BagelValidation isValid)
+ {
+ switch (isValid)
+ {
+ case BagelValidation.NonDigit:
+ Console.WriteLine("What?");
+ break;
+
+ case BagelValidation.NotUnique:
+ Console.WriteLine("Oh, I forgot to tell you that the number I have in mind has no two digits the same.");
+ break;
+
+ case BagelValidation.WrongLength:
+ Console.WriteLine($"Try guessing a {Length}-digit number.");
+ break;
+
+ case BagelValidation.Valid:
+ break;
+ }
+ }
+
+ private void PrintList(string msg, int repeat)
+ {
+ for(int i=0; i
+ /// Prompt the player to try again, and wait for them to press Y or N.
+ ///
+ /// Returns true if the player wants to try again, false if they have finished playing.
+ protected bool TryAgain()
+ {
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("Would you like to try again? (Press 'Y' for yes or 'N' for no)");
+
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.Write("> ");
+
+ char pressedKey;
+ // Keep looping until we get a recognised input
+ do
+ {
+ // Read a key, don't display it on screen
+ ConsoleKeyInfo key = Console.ReadKey(true);
+ // Convert to upper-case so we don't need to care about capitalisation
+ pressedKey = Char.ToUpper(key.KeyChar);
+ // Is this a key we recognise? If not, keep looping
+ } while (pressedKey != 'Y' && pressedKey != 'N');
+ // Display the result on the screen
+ Console.WriteLine(pressedKey);
+
+ // Return true if the player pressed 'Y', false for anything else.
+ return (pressedKey == 'Y');
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/05 Bagels/csharp/Program.cs b/05 Bagels/csharp/Program.cs
new file mode 100644
index 00000000..5dd0949a
--- /dev/null
+++ b/05 Bagels/csharp/Program.cs
@@ -0,0 +1,14 @@
+namespace BasicComputerGames.Bagels
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ // Create an instance of our main Game class
+ var game = new Game();
+
+ // Call its GameLoop function. This will play the game endlessly in a loop until the player chooses to quit.
+ game.GameLoop();
+ }
+ }
+}
diff --git a/07 Basketball/javascript/basketball.html b/07 Basketball/javascript/basketball.html
new file mode 100644
index 00000000..e9eedab3
--- /dev/null
+++ b/07 Basketball/javascript/basketball.html
@@ -0,0 +1,9 @@
+
+
+BASKETBALL
+
+
+
+
+
+
diff --git a/07 Basketball/javascript/basketball.js b/07 Basketball/javascript/basketball.js
new file mode 100644
index 00000000..5b0b73e7
--- /dev/null
+++ b/07 Basketball/javascript/basketball.js
@@ -0,0 +1,384 @@
+// BASKETBALL
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+var s = [0, 0];
+var z;
+var d;
+var p;
+var your_turn;
+var game_restart;
+
+function two_minutes()
+{
+ print("\n");
+ print(" *** TWO MINUTES LEFT IN THE GAME ***\n");
+ print("\n");
+}
+
+function show_scores()
+{
+ print("SCORE: " + s[1] + " TO " + s[0] + "\n");
+}
+
+function score_computer()
+{
+ s[0] = s[0] + 2;
+ show_scores();
+}
+
+function score_player()
+{
+ s[1] = s[1] + 2;
+ show_scores();
+}
+
+function half_time()
+{
+ print("\n");
+ print(" ***** END OF FIRST HALF *****\n");
+ print("SCORE: DARMOUTH: " + s[1] + " " + os + ": " + s[0] + "\n");
+ print("\n");
+ print("\n");
+}
+
+function foul()
+{
+ if (Math.random() <= 0.49) {
+ print("SHOOTER MAKES BOTH SHOTS.\n");
+ s[1 - p] = s[1 - p] + 2;
+ show_scores();
+ } else if (Math.random() <= 0.75) {
+ print("SHOOTER MAKES ONE SHOT AND MISSES ONE.\n");
+ s[1 - p] = s[1 - p] + 1;
+ show_scores();
+ } else {
+ print("BOTH SHOTS MISSED.\n");
+ show_scores();
+ }
+}
+
+function player_play()
+{
+ if (z == 1 || z == 2) {
+ t++;
+ if (t == 50) {
+ half_time();
+ game_restart = 1;
+ return;
+ }
+ if (t == 92)
+ two_minutes();
+ print("JUMP SHOT\n");
+ if (Math.random() <= 0.341 * d / 8) {
+ print("SHOT IS GOOD.\n");
+ score_player();
+ return;
+ }
+ if (Math.random() <= 0.682 * d / 8) {
+ print("SHOT IS OFF TARGET.\n");
+ if (d / 6 * Math.random() >= 0.45) {
+ print("REBOUND TO " + os + "\n");
+ return;
+ }
+ print("DARTMOUTH CONTROLS THE REBOUND.\n");
+ if (Math.random() > 0.4) {
+ if (d == 6) {
+ if (Math.random() > 0.6) {
+ print("PASS STOLEN BY " + os + " EASY LAYUP.\n");
+ score_computer();
+ return;
+ }
+ }
+ print("BALL PASSED BACK TO YOU. ");
+ your_turn = 1;
+ return;
+ }
+ } else if (Math.random() <= 0.782 * d / 8) {
+ print("SHOT IS BLOCKED. BALL CONTROLLED BY ");
+ if (Math.random() <= 0.5) {
+ print("DARTMOUTH.\n");
+ your_turn = 1;
+ return;
+ }
+ print(os + ".\n");
+ return;
+ } else if (Math.random() <= 0.843 * d / 8) {
+ print("SHOOTER IS FOULED. TWO SHOTS.\n");
+ foul();
+ return;
+ // In original code but lines 1180-1195 aren't used (maybe replicate from computer's play)
+ // } else if (Math.random() <= 0.9 * d / 8) {
+ // print("PLAYER FOULED, TWO SHOTS.\n");
+ // foul();
+ // return;
+ } else {
+ print("CHARGING FOUL. DARTMOUTH LOSES BALL.\n");
+ return;
+ }
+ }
+ while (1) {
+ if (++t == 50) {
+ half_time();
+ game_restart = 1;
+ return;
+ }
+ if (t == 92)
+ two_minutes();
+ if (z == 0) {
+ your_turn = 2;
+ return;
+ }
+ if (z <= 3)
+ print("LAY UP.\n");
+ else
+ print("SET SHOT.\n");
+ if (7 / d * Math.random() <= 0.4) {
+ print("SHOT IS GOOD. TWO POINTS.\n");
+ score_player();
+ return;
+ }
+ if (7 / d * Math.random() <= 0.7) {
+ print("SHOT IS OFF THE RIM.\n");
+ if (Math.random() <= 2.0 / 3.0) {
+ print(os + " CONTROLS THE REBOUND.\n");
+ return;
+ }
+ print("DARMOUTH CONTROLS THE REBOUND.\n");
+ if (Math.random() <= 0.4)
+ continue;
+ print("BALL PASSED BACK TO YOU.\n");
+ your_turn = 1;
+ return;
+ }
+ if (7 /d * Math.random() <= 0.875) {
+ print("SHOOTER FOULED. TWO SHOTS.\n");
+ foul();
+ return;
+ }
+ if (7 /d * Math.random() <= 0.925) {
+ print("SHOT BLOCKED. " + os + "'S BALL.\n");
+ return;
+ }
+ print("CHARGING FOUL. DARTHMOUTH LOSES THE BALL.\n");
+ return;
+ }
+}
+
+function computer_play()
+{
+ rebound = 0;
+ while (1) {
+ p = 1;
+ if (++t == 50) {
+ half_time();
+ game_restart = 1;
+ return;
+ }
+ print("\n");
+ z1 = 10 / 4 * Math.random() + 1;
+ if (z1 <= 2) {
+ print("JUMP SHOT.\n");
+ if (8 / d * Math.random() <= 0.35) {
+ print("SHOT IS GOOD.\n");
+ score_computer();
+ return;
+ }
+ if (8 / d * Math.random() <= 0.75) {
+ print("SHOT IS OFF RIM.\n");
+ if (d / 6 * Math.random() <= 0.5) {
+ print("DARMOUTH CONTROLS THE REBOUND.\n");
+ return;
+ }
+ print(os + " CONTROLS THE REBOUND.\n");
+ if (d == 6) {
+ if (Math.random() <= 0.75) {
+ print("BALL STOLEN. EASY LAP UP FOR DARTMOUTH.\n");
+ score_player();
+ continue;
+ }
+ if (Math.random() > 0.6) {
+ print("PASS STOLEN BY " + os + " EASY LAYUP.\n");
+ score_computer();
+ return;
+ }
+ print("BALL PASSED BACK TO YOU. ");
+ return;
+ }
+ if (Math.random() <= 0.5) {
+ print("PASS BACK TO " + os + " GUARD.\n");
+ continue;
+ }
+ } else if (8 / d * Math.random() <= 0.90) {
+ print("PLAYER FOULED. TWO SHOTS.\n");
+ foul();
+ return;
+ } else {
+ print("OFFENSIVE FOUL. DARTMOUTH'S BALL.\n");
+ return;
+ }
+ }
+ while (1) {
+ if (z1 > 3) {
+ print("SET SHOT.\n");
+ } else {
+ print("LAY UP.\n");
+ }
+ if (7 / d * Math.random() <= 0.413) {
+ print("SHOT IS GOOD.\n");
+ score_computer();
+ return;
+ }
+ print("SHOT IS MISSED.\n");
+ // Spaguetti jump, better to replicate code
+ if (d / 6 * Math.random() <= 0.5) {
+ print("DARMOUTH CONTROLS THE REBOUND.\n");
+ return;
+ }
+ print(os + " CONTROLS THE REBOUND.\n");
+ if (d == 6) {
+ if (Math.random() <= 0.75) {
+ print("BALL STOLEN. EASY LAP UP FOR DARTMOUTH.\n");
+ score_player();
+ break;
+ }
+ if (Math.random() > 0.6) {
+ print("PASS STOLEN BY " + os + " EASY LAYUP.\n");
+ score_computer();
+ return;
+ }
+ print("BALL PASSED BACK TO YOU. ");
+ return;
+ }
+ if (Math.random() <= 0.5) {
+ print("PASS BACK TO " + os + " GUARD.\n");
+ break;
+ }
+ }
+ }
+}
+
+// Main program
+async function main()
+{
+ print(tab(31) + "BASKETBALL\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("THIS IS DARTMOUTH COLLEGE BASKETBALL. YOU WILL BE DARTMOUTH\n");
+ print(" CAPTAIN AND PLAYMAKER. CALL SHOTS AS FOLLOWS: 1. LONG\n");
+ print(" (30 FT.) JUMP SHOT; 2. SHORT (15 FT.) JUMP SHOT; 3. LAY\n");
+ print(" UP; 4. SET SHOT.\n");
+ print("BOTH TEAMS WILL USE THE SAME DEFENSE. CALL DEFENSE AS\n");
+ print("FOLLOWS: 6. PRESS; 6.5 MAN-TO MAN; 7. ZONE; 7.5 NONE.\n");
+ print("TO CHANGE DEFENSE, JUST TYPE 0 AS YOUR NEXT SHOT.\n");
+ print("YOUR STARTING DEFENSE WILL BE");
+ t = 0;
+ p = 0;
+ d = parseFloat(await input());
+ if (d < 6) {
+ your_turn = 2;
+ } else {
+ print("\n");
+ print("CHOOSE YOUR OPPONENT");
+ os = await input();
+ game_restart = 1;
+ }
+ while (1) {
+ if (game_restart) {
+ game_restart = 0;
+ print("CENTER JUMP\n");
+ if (Math.random() > 3.0 / 5.0) {
+ print("DARMOUTH CONTROLS THE TAP.\n");
+ } else {
+ print(os + " CONTROLS THE TAP.\n");
+ computer_play();
+ }
+ }
+ if (your_turn == 2) {
+ print("YOUR NEW DEFENSIVE ALLIGNMENT IS");
+ d = parseFloat(await input());
+ }
+ print("\n");
+ while (1) {
+ print("YOUR SHOT");
+ z = parseInt(await input());
+ p = 0;
+ if (z != Math.floor(z) || z < 0 || z > 4)
+ print("INCORRECT ANSWER. RETYPE IT. ");
+ else
+ break;
+ }
+ if (Math.random() < 0.5 || t < 100) {
+ game_restart = 0;
+ your_turn = 0;
+ player_play();
+ if (game_restart == 0 && your_turn == 0)
+ computer_play();
+ } else {
+ print("\n");
+ if (s[1] == s[0]) {
+ print("\n");
+ print(" ***** END OF SECOND HALF *****\n");
+ print("\n");
+ print("SCORE AT END OF REGULATION TIME:\n");
+ print(" DARTMOUTH: " + s[1] + " " + os + ": " + s[0] + "\n");
+ print("\n");
+ print("BEGIN TWO MINUTE OVERTIME PERIOD\n");
+ t = 93;
+ print("CENTER JUMP\n");
+ if (Math.random() > 3.0 / 5.0)
+ print("DARMOUTH CONTROLS THE TAP.\n");
+ else
+ print(os + " CONTROLS THE TAP.\n");
+ } else {
+ print(" ***** END OF GAME *****\n");
+ print("FINAL SCORE: DARMOUTH: " + s[1] + " " + os + ": " + s[0] + "\n");
+ break;
+ }
+ }
+ }
+}
+
+main();
diff --git a/08 Batnum/java/src/BatNum.java b/08 Batnum/java/src/BatNum.java
new file mode 100644
index 00000000..4211d74d
--- /dev/null
+++ b/08 Batnum/java/src/BatNum.java
@@ -0,0 +1,292 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of BatNum
+ *
+ * Based on the Basic game of BatNum here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/08%20Batnum/batnum.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class BatNum {
+
+ private enum GAME_STATE {
+ STARTING,
+ START_GAME,
+ CHOOSE_PILE_SIZE,
+ SELECT_WIN_OPTION,
+ CHOOSE_MIN_AND_MAX,
+ SELECT_WHO_STARTS_FIRST,
+ PLAYERS_TURN,
+ COMPUTERS_TURN,
+ ANNOUNCE_WINNER,
+ GAME_OVER
+ }
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ // Current game state
+ private GAME_STATE gameState;
+
+ private int pileSize;
+
+ // How to win the game options
+ enum WIN_OPTION {
+ TAKE_LAST,
+ AVOID_LAST
+ }
+
+ // Tracking the winner
+ enum WINNER {
+ COMPUTER,
+ PLAYER
+ }
+
+ private WINNER winner;
+
+ private WIN_OPTION winOption;
+
+ private int minSelection;
+ private int maxSelection;
+
+ // Used by computer for optimal move
+ private int rangeOfRemovals;
+
+ public BatNum() {
+
+ gameState = GAME_STATE.STARTING;
+
+ // Initialise kb scanner
+ kbScanner = new Scanner(System.in);
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+
+ // Show an introduction and optional instructions the first time the game is played.
+ case STARTING:
+ intro();
+ gameState = GAME_STATE.START_GAME;
+ break;
+
+ // Start new game
+ case START_GAME:
+ gameState = GAME_STATE.CHOOSE_PILE_SIZE;
+ break;
+
+ case CHOOSE_PILE_SIZE:
+ System.out.println();
+ System.out.println();
+ pileSize = displayTextAndGetNumber("ENTER PILE SIZE ");
+ if (pileSize >= 1) {
+ gameState = GAME_STATE.SELECT_WIN_OPTION;
+ }
+ break;
+
+ case SELECT_WIN_OPTION:
+ int winChoice = displayTextAndGetNumber("ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: ");
+ if (winChoice == 1) {
+ winOption = WIN_OPTION.TAKE_LAST;
+ gameState = GAME_STATE.CHOOSE_MIN_AND_MAX;
+ } else if (winChoice == 2) {
+ winOption = WIN_OPTION.AVOID_LAST;
+ gameState = GAME_STATE.CHOOSE_MIN_AND_MAX;
+ }
+ break;
+
+ case CHOOSE_MIN_AND_MAX:
+ String range = displayTextAndGetInput("ENTER MIN AND MAX ");
+ minSelection = getDelimitedValue(range, 0);
+ maxSelection = getDelimitedValue(range, 1);
+ if (maxSelection > minSelection && minSelection >= 1) {
+ gameState = GAME_STATE.SELECT_WHO_STARTS_FIRST;
+ }
+
+ // Used by computer in its turn
+ rangeOfRemovals = minSelection + maxSelection;
+ break;
+
+ case SELECT_WHO_STARTS_FIRST:
+ int playFirstChoice = displayTextAndGetNumber("ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST ");
+ if (playFirstChoice == 1) {
+ gameState = GAME_STATE.COMPUTERS_TURN;
+ } else if (playFirstChoice == 2) {
+ gameState = GAME_STATE.PLAYERS_TURN;
+ }
+ break;
+
+ case PLAYERS_TURN:
+ int playersMove = displayTextAndGetNumber("YOUR MOVE ");
+
+ if (playersMove == 0) {
+ System.out.println("I TOLD YOU NOT TO USE ZERO! COMPUTER WINS BY FORFEIT.");
+ winner = WINNER.COMPUTER;
+ gameState = GAME_STATE.ANNOUNCE_WINNER;
+ break;
+ }
+
+ if (playersMove == pileSize && winOption == WIN_OPTION.AVOID_LAST) {
+ winner = WINNER.COMPUTER;
+ gameState = GAME_STATE.ANNOUNCE_WINNER;
+ break;
+ }
+
+ // Check if players move is with the min and max possible
+ if (playersMove >= minSelection && playersMove <= maxSelection) {
+ // Valid so reduce pileSize by amount player entered
+ pileSize -= playersMove;
+
+ // Did this move result in there being no more objects on pile?
+ if (pileSize == 0) {
+ // Was the game setup so the winner was whoever took the last object
+ if (winOption == WIN_OPTION.TAKE_LAST) {
+ // Player won
+ winner = WINNER.PLAYER;
+ } else {
+ // Computer one
+ winner = WINNER.COMPUTER;
+ }
+ gameState = GAME_STATE.ANNOUNCE_WINNER;
+ } else {
+ // There are still items left.
+ gameState = GAME_STATE.COMPUTERS_TURN;
+ }
+ } else {
+ // Invalid move
+ System.out.println("ILLEGAL MOVE, REENTER IT ");
+ }
+ break;
+
+ case COMPUTERS_TURN:
+ int pileSizeLeft = pileSize;
+ if (winOption == WIN_OPTION.TAKE_LAST) {
+ if (pileSize > maxSelection) {
+
+ int objectsToRemove = calculateComputersTurn(pileSizeLeft);
+
+ pileSize -= objectsToRemove;
+ System.out.println("COMPUTER TAKES " + objectsToRemove + " AND LEAVES " + pileSize);
+ gameState = GAME_STATE.PLAYERS_TURN;
+ } else {
+ System.out.println("COMPUTER TAKES " + pileSize + " AND WINS.");
+ winner = WINNER.COMPUTER;
+ gameState = GAME_STATE.ANNOUNCE_WINNER;
+ }
+ } else {
+ pileSizeLeft--;
+ if (pileSize > minSelection) {
+ int objectsToRemove = calculateComputersTurn(pileSizeLeft);
+ pileSize -= objectsToRemove;
+ System.out.println("COMPUTER TAKES " + objectsToRemove + " AND LEAVES " + pileSize);
+ gameState = GAME_STATE.PLAYERS_TURN;
+ } else {
+ System.out.println("COMPUTER TAKES " + pileSize + " AND LOSES.");
+ winner = WINNER.PLAYER;
+ gameState = GAME_STATE.ANNOUNCE_WINNER;
+ }
+ }
+ break;
+
+ case ANNOUNCE_WINNER:
+ switch (winner) {
+ case PLAYER:
+ System.out.println("CONGRATULATIONS, YOU WIN.");
+ break;
+ case COMPUTER:
+ System.out.println("TOUGH LUCK, YOU LOSE.");
+ break;
+ }
+ gameState = GAME_STATE.START_GAME;
+ break;
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ /**
+ * Figure out the computers turn - i.e. how many objects to remove
+ *
+ * @param pileSizeLeft current size
+ * @return the number of objects to remove.
+ */
+ private int calculateComputersTurn(int pileSizeLeft) {
+ int computersNumberToRemove = pileSizeLeft - rangeOfRemovals * (pileSizeLeft / rangeOfRemovals);
+ if (computersNumberToRemove < minSelection) {
+ computersNumberToRemove = minSelection;
+ }
+ if (computersNumberToRemove > maxSelection) {
+ computersNumberToRemove = maxSelection;
+ }
+
+ return computersNumberToRemove;
+ }
+
+ private void intro() {
+ System.out.println(simulateTabs(33) + "BATNUM");
+ System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE");
+ System.out.println("COMPUTER IS YOUR OPPONENT.");
+ System.out.println();
+ System.out.println("THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU");
+ System.out.println("AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE.");
+ System.out.println("WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR");
+ System.out.println("NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS.");
+ System.out.println("DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME.");
+ System.out.println("ENTER A NEGATIVE NUMBER FOR NEW PILE SIZE TO STOP PLAYING.");
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ * Converts input to Integer
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private int displayTextAndGetNumber(String text) {
+ return Integer.parseInt(displayTextAndGetInput(text));
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Simulate the old basic tab(xx) command which indented text by xx spaces.
+ *
+ * @param spaces number of spaces required
+ * @return String with number of spaces
+ */
+ private String simulateTabs(int spaces) {
+ char[] spacesTemp = new char[spaces];
+ Arrays.fill(spacesTemp, ' ');
+ return new String(spacesTemp);
+ }
+
+ /**
+ * Accepts a string delimited by comma's and returns the nth delimited
+ * value (starting at count 0).
+ *
+ * @param text - text with values separated by comma's
+ * @param pos - which position to return a value for
+ * @return the int representation of the value
+ */
+ private int getDelimitedValue(String text, int pos) {
+ String[] tokens = text.split(",");
+ return Integer.parseInt(tokens[pos]);
+ }
+}
\ No newline at end of file
diff --git a/08 Batnum/java/src/BatNumGame.java b/08 Batnum/java/src/BatNumGame.java
new file mode 100644
index 00000000..b84b61c1
--- /dev/null
+++ b/08 Batnum/java/src/BatNumGame.java
@@ -0,0 +1,8 @@
+public class BatNumGame {
+
+ public static void main(String[] args) {
+
+ BatNum batNum = new BatNum();
+ batNum.play();
+ }
+}
diff --git a/08 Batnum/javascript/batnum.html b/08 Batnum/javascript/batnum.html
new file mode 100644
index 00000000..51d8dd11
--- /dev/null
+++ b/08 Batnum/javascript/batnum.html
@@ -0,0 +1,9 @@
+
+
+BATNUM
+
+
+
+
+
+
diff --git a/08 Batnum/javascript/batnum.js b/08 Batnum/javascript/batnum.js
new file mode 100644
index 00000000..c7d25b78
--- /dev/null
+++ b/08 Batnum/javascript/batnum.js
@@ -0,0 +1,161 @@
+// BATNUM
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+// Main program
+async function main()
+{
+ print(tab(33) + "BATNUM\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE\n");
+ print("COMPUTER IS YOUR OPPONENT.\n");
+ print("\n");
+ print("THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU\n");
+ print("AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE.\n");
+ print("WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR\n");
+ print("NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS.\n");
+ print("DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME.\n");
+ print("ENTER A NEGATIVE NUMBER FOR NEW PILE SIZE TO STOP PLAYING.\n");
+ print("\n");
+ first_time = 1;
+ while (1) {
+ while (1) {
+ if (first_time == 1) {
+ first_time = 0;
+ } else {
+ for (i = 1; i <= 10; i++)
+ print("\n");
+ }
+ print("ENTER PILE SIZE");
+ n = parseInt(await input());
+ if (n >= 1)
+ break;
+ }
+ while (1) {
+ print("ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: ");
+ m = parseInt(await input());
+ if (m == 1 || m == 2)
+ break;
+ }
+ while (1) {
+ print("ENTER MIN AND MAX ");
+ str = await input();
+ a = parseInt(str);
+ b = parseInt(str.substr(str.indexOf(",") + 1));
+ if (a <= b && a >= 1)
+ break;
+ }
+ while (1) {
+ print("ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST ");
+ s = parseInt(await input());
+ print("\n");
+ print("\n");
+ if (s == 1 || s == 2)
+ break;
+ }
+ w = 0;
+ c = a + b;
+ while (1) {
+ if (s == 1) {
+ // Computer's turn
+ q = n;
+ if (m != 1)
+ q--;
+ if (m != 1 && n <= a) {
+ w = 1;
+ print("COMPUTER TAKES " + n + " AND LOSES.\n");
+ } else if (m == 1 && n <= b) {
+ w = 1;
+ print("COMPUTER TAKES " + n + " AND WINS.\n");
+ } else {
+ p = q - c * Math.floor(q / c);
+ if (p < a)
+ p = a;
+ if (p > b)
+ p = b;
+ n -= p;
+ print("COMPUTER TAKES " + p + " AND LEAVES " + n + "\n");
+ w = 0;
+ }
+ s = 2;
+ }
+ if (w)
+ break;
+ if (s == 2) {
+ while (1) {
+ print("\n");
+ print("YOUR MOVE ");
+ p = parseInt(await input());
+ if (p == 0) {
+ print("I TOLD YOU NOT TO USE ZERO! COMPUTER WINS BY FORFEIT.\n");
+ w = 1;
+ break;
+ } else if (p >= a && p <= b && n - p >= 0) {
+ break;
+ }
+ }
+ if (p != 0) {
+ n -= p;
+ if (n == 0) {
+ if (m != 1) {
+ print("TOUGH LUCK, YOU LOSE.\n");
+ } else {
+ print("CONGRATULATIONS, YOU WIN.\n");
+ }
+ w = 1;
+ } else {
+ w = 0;
+ }
+ }
+ s = 1;
+ }
+ if (w)
+ break;
+ }
+ }
+}
+
+main();
diff --git a/10 Blackjack/csharp/Blackjack.csproj b/10 Blackjack/csharp/Blackjack.csproj
new file mode 100644
index 00000000..796a6731
--- /dev/null
+++ b/10 Blackjack/csharp/Blackjack.csproj
@@ -0,0 +1,9 @@
+
+
+
+ Exe
+ Blackjack
+ net5.0
+
+
+
diff --git a/10 Blackjack/csharp/Card.cs b/10 Blackjack/csharp/Card.cs
new file mode 100644
index 00000000..a2b6b6bd
--- /dev/null
+++ b/10 Blackjack/csharp/Card.cs
@@ -0,0 +1,32 @@
+namespace Blackjack
+{
+ public class Card
+ {
+ private static readonly string[] _names = new[] {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
+
+ public Card(int index)
+ {
+ Index = index;
+ }
+
+ public int Index { get; private set; }
+
+ public string Name => _names[Index];
+
+ public string IndefiniteArticle => (Index == 0 || Index == 7) ? "an" : "a";
+
+ public bool IsAce => Index == 0;
+
+ public int Value
+ {
+ get
+ {
+ if (IsAce)
+ return 11;
+ if (Index > 8)
+ return 10;
+ return Index + 1;
+ }
+ }
+ }
+}
diff --git a/10 Blackjack/csharp/Deck.cs b/10 Blackjack/csharp/Deck.cs
new file mode 100644
index 00000000..21b1e9ef
--- /dev/null
+++ b/10 Blackjack/csharp/Deck.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+
+namespace Blackjack
+{
+ public class Deck
+ {
+ private static readonly Random _random = new Random();
+
+ private readonly List _cards = new List(52);
+ private readonly List _discards = new List(52);
+
+ public Deck()
+ {
+ for (var index = 0; index < 12; index++)
+ {
+ for (var suit = 0; suit < 4; suit++)
+ {
+ _discards.Add(new Card(index));
+ }
+ }
+ Reshuffle();
+ }
+
+ private void Reshuffle()
+ {
+ Console.WriteLine("Reshuffling");
+
+ _cards.AddRange(_discards);
+ _discards.Clear();
+
+ for (var index1 = _cards.Count - 1; index1 > 0; index1--)
+ {
+ var index2 = _random.Next(0, index1);
+ var swapCard = _cards[index1];
+ _cards[index1] = _cards[index2];
+ _cards[index2] = swapCard;
+ }
+ }
+
+ public Card DrawCard()
+ {
+ if (_cards.Count < 2)
+ Reshuffle();
+
+ var card = _cards[_cards.Count - 1];
+ _cards.RemoveAt(_cards.Count - 1);
+ return card;
+ }
+
+ public void Discard(IEnumerable cards)
+ {
+ _discards.AddRange(cards);
+ }
+ }
+}
diff --git a/10 Blackjack/csharp/Game.cs b/10 Blackjack/csharp/Game.cs
new file mode 100644
index 00000000..7bb16350
--- /dev/null
+++ b/10 Blackjack/csharp/Game.cs
@@ -0,0 +1,232 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Blackjack
+{
+ public class Game
+ {
+ private readonly Deck _deck = new Deck();
+ private readonly int _numberOfPlayers;
+ private readonly Player[] _players;
+ private readonly Hand _dealerHand;
+
+ public Game(int numberOfPlayers)
+ {
+ _numberOfPlayers = numberOfPlayers;
+ _players = new Player[_numberOfPlayers];
+ for (var playerIndex = 0; playerIndex < _numberOfPlayers; playerIndex++)
+ _players[playerIndex] = new Player(playerIndex);
+ _dealerHand = new Hand();
+ }
+
+ public void PlayGame()
+ {
+ while (true)
+ {
+ PlayRound();
+ TallyResults();
+ ResetRoundState();
+ Console.WriteLine();
+ }
+ }
+
+ public void PlayRound()
+ {
+ GetPlayerBets();
+
+ DealHands();
+
+ // Test for insurance
+ var dealerIsShowingAce = _dealerHand.Cards[0].IsAce;
+ if (dealerIsShowingAce && Prompt.ForYesNo("Any insurance?"))
+ {
+ Console.WriteLine("Insurance bets");
+ var insuranceBets = new int[_numberOfPlayers];
+ foreach (var player in _players)
+ insuranceBets[player.Index] = Prompt.ForInteger($"# {player.Index + 1} ?", 0, player.RoundBet / 2);
+
+ var insuranceEffectMultiplier = _dealerHand.IsBlackjack ? 2 : -1;
+ foreach (var player in _players)
+ player.RoundWinnings += insuranceBets[player.Index] * insuranceEffectMultiplier;
+ }
+
+ // Test for dealer blackjack
+ var concealedCard = _dealerHand.Cards[0];
+ if (_dealerHand.IsBlackjack)
+ {
+ Console.WriteLine();
+ Console.WriteLine("Dealer has {0} {1} in the hole for blackjack.", concealedCard.IndefiniteArticle, concealedCard.Name);
+ return;
+ }
+ else if (dealerIsShowingAce)
+ {
+ Console.WriteLine();
+ Console.WriteLine("No dealer blackjack.");
+ }
+
+ foreach (var player in _players)
+ PlayHand(player);
+
+ // Dealer hand
+ var allPlayersBusted = _players.All(p => p.Hand.IsBusted && (!p.SecondHand.Exists || p.SecondHand.IsBusted));
+ if (allPlayersBusted)
+ Console.WriteLine("Dealer had {0} {1} concealed.", concealedCard.IndefiniteArticle, concealedCard.Name);
+ else
+ {
+ Console.WriteLine("Dealer has {0} {1} concealed for a total of {2}", concealedCard.IndefiniteArticle, concealedCard.Name, _dealerHand.Total);
+ if (_dealerHand.Total < 17)
+ {
+ Console.Write("Draws");
+ while (_dealerHand.Total < 17)
+ {
+ var card = _dealerHand.AddCard(_deck.DrawCard());
+ Console.Write(" {0}", card.Name);
+ }
+ if (_dealerHand.IsBusted)
+ Console.WriteLine(" ...Busted");
+ else
+ Console.WriteLine(" ---Total is {0}", _dealerHand.Total);
+ }
+ }
+ }
+
+ private void GetPlayerBets()
+ {
+ Console.WriteLine("Bets:");
+ foreach (var player in _players)
+ player.RoundBet = Prompt.ForInteger($"# {player.Name} ?", 1, 500);
+ }
+
+ private void DealHands()
+ {
+ Console.Write("Player ");
+ foreach (var player in _players)
+ Console.Write("{0} ", player.Name);
+ Console.WriteLine("Dealer");
+
+ for (var cardIndex = 0; cardIndex < 2; cardIndex++)
+ {
+ Console.Write(" ");
+ foreach (var player in _players)
+ Console.Write(" {0,-4}", player.Hand.AddCard(_deck.DrawCard()).Name);
+ var dealerCard = _dealerHand.AddCard(_deck.DrawCard());
+ Console.Write(" {0,-4}", (cardIndex == 0) ? "XX" : dealerCard.Name);
+
+ Console.WriteLine();
+ }
+ }
+
+ private void PlayHand(Player player)
+ {
+ var hand = player.Hand;
+
+ Console.Write("Player {0} ", player.Name);
+
+ var playerCanSplit = hand.Cards[0].Value == hand.Cards[1].Value;
+ var command = Prompt.ForCommandCharacter("?", playerCanSplit ? "HSD/" : "HSD");
+ switch (command)
+ {
+ case "D":
+ player.RoundBet *= 2;
+ goto case "H";
+
+ case "H":
+ while (TakeHit(hand) && PromptForAnotherHit())
+ { }
+ if (!hand.IsBusted)
+ Console.WriteLine("Total is {0}", hand.Total);
+ break;
+
+ case "S":
+ if (hand.IsBlackjack)
+ {
+ Console.WriteLine("Blackjack!");
+ player.RoundWinnings = (int)(1.5 * player.RoundBet + 0.5);
+ player.RoundBet = 0;
+ }
+ else
+ Console.WriteLine("Total is {0}", hand.Total);
+ break;
+
+ case "/":
+ hand.SplitHand(player.SecondHand);
+ var card = hand.AddCard(_deck.DrawCard());
+ Console.WriteLine("First hand receives {0} {1}", card.IndefiniteArticle, card.Name);
+ card = player.SecondHand.AddCard(_deck.DrawCard());
+ Console.WriteLine("Second hand receives {0} {1}", card.IndefiniteArticle, card.Name);
+
+ for (int handNumber = 1; handNumber <= 2; handNumber++)
+ {
+ hand = (handNumber == 1) ? player.Hand : player.SecondHand;
+
+ Console.Write("Hand {0}", handNumber);
+ while (PromptForAnotherHit() && TakeHit(hand))
+ { }
+ if (!hand.IsBusted)
+ Console.WriteLine("Total is {0}", hand.Total);
+ }
+ break;
+ }
+ }
+
+ private bool TakeHit(Hand hand)
+ {
+ var card = hand.AddCard(_deck.DrawCard());
+ Console.Write("Received {0,-6}", $"{card.IndefiniteArticle} {card.Name}");
+ if (hand.IsBusted)
+ {
+ Console.WriteLine("...Busted");
+ return false;
+ }
+ return true;
+ }
+
+ private bool PromptForAnotherHit()
+ {
+ return String.Equals(Prompt.ForCommandCharacter(" Hit?", "HS"), "H");
+ }
+
+ private void TallyResults()
+ {
+ Console.WriteLine();
+ foreach (var player in _players)
+ {
+ player.RoundWinnings += CalculateWinnings(player, player.Hand);
+ if (player.SecondHand.Exists)
+ player.RoundWinnings += CalculateWinnings(player, player.SecondHand);
+ player.TotalWinnings += player.RoundWinnings;
+
+ Console.WriteLine("Player {0} {1,-6} {2,3} Total= {3,5}",
+ player.Name,
+ (player.RoundWinnings > 0) ? "wins" : (player.RoundWinnings) < 0 ? "loses" : "pushes",
+ (player.RoundWinnings != 0) ? Math.Abs(player.RoundWinnings).ToString() : "",
+ player.TotalWinnings);
+ }
+ Console.WriteLine("Dealer's total= {0}", -_players.Sum(p => p.TotalWinnings));
+ }
+
+ private int CalculateWinnings(Player player, Hand hand)
+ {
+ if (hand.IsBusted)
+ return -player.RoundBet;
+ if (hand.Total == _dealerHand.Total)
+ return 0;
+ if (_dealerHand.IsBusted || hand.Total > _dealerHand.Total)
+ return player.RoundBet;
+ return -player.RoundBet;
+ }
+
+ private void ResetRoundState()
+ {
+ foreach (var player in _players)
+ {
+ player.RoundWinnings = 0;
+ player.RoundBet = 0;
+ player.Hand.Discard(_deck);
+ player.SecondHand.Discard(_deck);
+ }
+ _dealerHand.Discard(_deck);
+ }
+ }
+}
diff --git a/10 Blackjack/csharp/Hand.cs b/10 Blackjack/csharp/Hand.cs
new file mode 100644
index 00000000..49b945bb
--- /dev/null
+++ b/10 Blackjack/csharp/Hand.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+
+namespace Blackjack
+{
+ public class Hand
+ {
+ private readonly List _cards = new List(12);
+ private int _cachedTotal = 0;
+
+ public Card AddCard(Card card)
+ {
+ _cards.Add(card);
+ _cachedTotal = 0;
+ return card;
+ }
+
+ public void Discard(Deck deck)
+ {
+ deck.Discard(_cards);
+ _cards.Clear();
+ _cachedTotal = 0;
+ }
+
+ public void SplitHand(Hand secondHand)
+ {
+ if (Count != 2 || secondHand.Count != 0)
+ throw new InvalidOperationException();
+ secondHand.AddCard(_cards[1]);
+ _cards.RemoveAt(1);
+ _cachedTotal = 0;
+ }
+
+ public IReadOnlyList Cards => _cards;
+
+ public int Count => _cards.Count;
+
+ public bool Exists => _cards.Count > 0;
+
+ public int Total
+ {
+ get
+ {
+ if (_cachedTotal == 0)
+ {
+ var aceCount = 0;
+ foreach (var card in _cards)
+ {
+ _cachedTotal += card.Value;
+ if (card.IsAce)
+ aceCount++;
+ }
+ while (_cachedTotal > 21 && aceCount > 0)
+ {
+ _cachedTotal -= 10;
+ aceCount--;
+ }
+ }
+ return _cachedTotal;
+ }
+ }
+
+ public bool IsBlackjack => Total == 21 && Count == 2;
+
+ public bool IsBusted => Total > 21;
+ }
+}
diff --git a/10 Blackjack/csharp/Player.cs b/10 Blackjack/csharp/Player.cs
new file mode 100644
index 00000000..58664f1d
--- /dev/null
+++ b/10 Blackjack/csharp/Player.cs
@@ -0,0 +1,27 @@
+namespace Blackjack
+{
+ public class Player
+ {
+ public Player(int index)
+ {
+ Index = index;
+ Name = (index + 1).ToString();
+ Hand = new Hand();
+ SecondHand = new Hand();
+ }
+
+ public int Index { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Hand Hand { get; private set; }
+
+ public Hand SecondHand { get; private set;}
+
+ public int RoundBet { get; set; }
+
+ public int RoundWinnings { get; set; }
+
+ public int TotalWinnings { get; set; }
+ }
+}
diff --git a/10 Blackjack/csharp/Program.cs b/10 Blackjack/csharp/Program.cs
new file mode 100644
index 00000000..dac7da86
--- /dev/null
+++ b/10 Blackjack/csharp/Program.cs
@@ -0,0 +1,41 @@
+using System;
+
+namespace Blackjack
+{
+ static class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("{0}BLACK JACK", new string(' ', 31));
+ Console.WriteLine("{0}CREATIVE COMPUTING MORRISTOWN, NEW JERSEY", new string(' ', 15));
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine();
+
+ OfferInstructions();
+
+ var numberOfPlayers = Prompt.ForInteger("Number of players?", 1, 6);
+ var game = new Game(numberOfPlayers);
+ game.PlayGame();
+ }
+
+ private static void OfferInstructions()
+ {
+ if (!Prompt.ForYesNo("Do you want instructions?"))
+ return;
+
+ Console.WriteLine("This is the game of 21. As many as 7 players may play the");
+ Console.WriteLine("game. On each deal, bets will be asked for, and the");
+ Console.WriteLine("players' bets should be typed in. The cards will then be");
+ Console.WriteLine("dealt, and each player in turn plays his hand. The");
+ Console.WriteLine("first response should be either 'D', indicating that the");
+ Console.WriteLine("player is doubling down, 'S', indicating that he is");
+ Console.WriteLine("standing, 'H', indicating he wants another card, or '/',");
+ Console.WriteLine("indicating that he wants to split his cards. After the");
+ Console.WriteLine("initial response, all further responses should be 's' or");
+ Console.WriteLine("'H', unless the cards were split, in which case doubling");
+ Console.WriteLine("down is again permitted. In order to collect for");
+ Console.WriteLine("Blackjack, the initial response should be 'S'.");
+ }
+ }
+}
diff --git a/10 Blackjack/csharp/Prompt.cs b/10 Blackjack/csharp/Prompt.cs
new file mode 100644
index 00000000..9f798965
--- /dev/null
+++ b/10 Blackjack/csharp/Prompt.cs
@@ -0,0 +1,58 @@
+using System;
+
+namespace Blackjack
+{
+ public static class Prompt
+ {
+ public static bool ForYesNo(string prompt)
+ {
+ while(true)
+ {
+ Console.Write("{0} ", prompt);
+ var input = Console.ReadLine();
+ if (input.StartsWith("y", StringComparison.InvariantCultureIgnoreCase))
+ return true;
+ if (input.StartsWith("n", StringComparison.InvariantCultureIgnoreCase))
+ return false;
+ WriteNotUnderstood();
+ }
+ }
+
+ public static int ForInteger(string prompt, int minimum = 1, int maximum = int.MaxValue)
+ {
+ while (true)
+ {
+ Console.Write("{0} ", prompt);
+ if (!int.TryParse(Console.ReadLine(), out var number))
+ WriteNotUnderstood();
+ else if (number < minimum || number > maximum)
+ Console.WriteLine("Sorry, I need a number between {0} and {1}.", minimum, maximum);
+ else
+ return number;
+ }
+ }
+
+ public static string ForCommandCharacter(string prompt, string allowedCharacters)
+ {
+ while (true)
+ {
+ Console.Write("{0} ", prompt);
+ var input = Console.ReadLine();
+ if (input.Length > 0)
+ {
+ var character = input.Substring(0, 1);
+ var characterIndex = allowedCharacters.IndexOf(character, StringComparison.InvariantCultureIgnoreCase);
+ if (characterIndex != -1)
+ return allowedCharacters.Substring(characterIndex, 1);
+ }
+
+ Console.WriteLine("Type one of {0} please", String.Join(", ", allowedCharacters.ToCharArray()));
+ }
+ }
+
+ private static void WriteNotUnderstood()
+ {
+ Console.WriteLine("Sorry, I didn't understand.");
+ }
+ }
+}
diff --git a/11 Bombardment/java/src/Bombardment.java b/11 Bombardment/java/src/Bombardment.java
index 06a3043c..1dede841 100644
--- a/11 Bombardment/java/src/Bombardment.java
+++ b/11 Bombardment/java/src/Bombardment.java
@@ -3,12 +3,12 @@ import java.util.Scanner;
/**
* Game of Bombardment
- *
+ *
* Based on the Basic game of Bombardment here
* https://github.com/coding-horror/basic-computer-games/blob/main/11%20Bombardment/bombardment.bas
- *
- * Note: The idea was to create a version of this 1970's Basic game in Java, without introducing
- * new features - no additional text, error checking, etc has been added.
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
*/
public class Bombardment {
@@ -28,11 +28,11 @@ public class Bombardment {
private GAME_STATE gameState;
- public static final String[] PLAYER_HIT_MESSAGES = { "ONE DOWN, THREE TO GO.",
- "TWO DOWN, TWO TO GO.", "THREE DOWN, ONE TO GO." };
+ public static final String[] PLAYER_HIT_MESSAGES = {"ONE DOWN, THREE TO GO.",
+ "TWO DOWN, TWO TO GO.", "THREE DOWN, ONE TO GO."};
public static final String[] COMPUTER_HIT_MESSAGES = {"YOU HAVE ONLY THREE OUTPOSTS LEFT.",
- "YOU HAVE ONLY TWO OUTPOSTS LEFT.", "YOU HAVE ONLY ONE OUTPOST LEFT." };
+ "YOU HAVE ONLY TWO OUTPOSTS LEFT.", "YOU HAVE ONLY ONE OUTPOST LEFT."};
private HashSet computersPlatoons;
private HashSet playersPlatoons;
@@ -44,7 +44,7 @@ public class Bombardment {
public Bombardment() {
- this.gameState = GAME_STATE.STARTING;
+ gameState = GAME_STATE.STARTING;
// Initialise kb scanner
kbScanner = new Scanner(System.in);
@@ -56,19 +56,19 @@ public class Bombardment {
public void play() {
do {
- switch (this.gameState) {
+ switch (gameState) {
// Show an introduction the first time the game is played.
case STARTING:
init();
intro();
- this.gameState = GAME_STATE.DRAW_BATTLEFIELD;
+ gameState = GAME_STATE.DRAW_BATTLEFIELD;
break;
// Enter the players name
case DRAW_BATTLEFIELD:
drawBattlefield();
- this.gameState = GAME_STATE.GET_PLAYER_CHOICES;
+ gameState = GAME_STATE.GET_PLAYER_CHOICES;
break;
// Get the players 4 locations for their platoons
@@ -76,35 +76,35 @@ public class Bombardment {
String playerChoices = displayTextAndGetInput("WHAT ARE YOUR FOUR POSITIONS? ");
// Store the 4 player choices that were entered separated with commas
- for(int i=0; i computersChosenPlatoons() {
@@ -198,19 +196,20 @@ public class Bombardment {
tempPlatoons.add(randomNumber());
// All four created?
- if(tempPlatoons.size() == PLATOONS) {
+ if (tempPlatoons.size() == PLATOONS) {
// Exit when we have created four
allPlatoonsAdded = true;
}
- } while(!allPlatoonsAdded);
+ } while (!allPlatoonsAdded);
return tempPlatoons;
}
+
/**
* Shows a different message for each number of hits
*
- * @param hits total number of hits by player on computer
+ * @param hits total number of hits by player on computer
*/
private void showPlayerProgress(int hits) {
@@ -221,7 +220,7 @@ public class Bombardment {
/**
* Shows a different message for each number of hits
*
- * @param hits total number of hits by computer on player
+ * @param hits total number of hits by computer on player
*/
private void showComputerProgress(int hits, int lastGuess) {
@@ -231,42 +230,42 @@ public class Bombardment {
/**
* Prints a message from the passed array based on the value of hits
-
- * @param hits - number of hits the player or computer has made
+ *
+ * @param hits - number of hits the player or computer has made
* @param messages - an array of string with messages
*/
private void showProgress(int hits, String[] messages) {
- System.out.println(messages[hits-1]);
+ System.out.println(messages[hits - 1]);
}
/**
- *
* Update a player hit - adds a hit the player made on the computers platoon.
+ *
* @param fireLocation - computer location that got hit
* @return number of hits the player has inflicted on the computer in total
*/
private int updatePlayerHits(int fireLocation) {
// N.B. only removes if present, so its redundant to check if it exists first
- this.computersPlatoons.remove(fireLocation);
+ computersPlatoons.remove(fireLocation);
// return number of hits in total
- return PLATOONS - this.computersPlatoons.size();
+ return PLATOONS - computersPlatoons.size();
}
/**
- *
* Update a computer hit - adds a hit the computer made on the players platoon.
+ *
* @param fireLocation - player location that got hit
* @return number of hits the player has inflicted on the computer in total
*/
private int updateComputerHits(int fireLocation) {
// N.B. only removes if present, so its redundant to check if it exists first
- this.playersPlatoons.remove(fireLocation);
+ playersPlatoons.remove(fireLocation);
// return number of hits in total
- return PLATOONS - this.playersPlatoons.size();
+ return PLATOONS - playersPlatoons.size();
}
/**
@@ -276,7 +275,7 @@ public class Bombardment {
* @return true if a computer platoon was at that position
*/
private boolean didPlayerHitComputerPlatoon(int fireLocation) {
- return this.computersPlatoons.contains(fireLocation);
+ return computersPlatoons.contains(fireLocation);
}
/**
@@ -286,22 +285,20 @@ public class Bombardment {
* @return true if a players platoon was at that position
*/
private boolean didComputerHitPlayerPlatoon(int fireLocation) {
- return this.playersPlatoons.contains(fireLocation);
+ return playersPlatoons.contains(fireLocation);
}
/**
* Draw the battlefield grid
- *
*/
private void drawBattlefield() {
- for(int i=1; i();
+ playersPlatoons = new HashSet<>();
- this.computersGuesses = new HashSet<>();
+ computersGuesses = new HashSet<>();
}
/**
diff --git a/11 Bombardment/javascript/bombardment.html b/11 Bombardment/javascript/bombardment.html
new file mode 100644
index 00000000..5255cdd9
--- /dev/null
+++ b/11 Bombardment/javascript/bombardment.html
@@ -0,0 +1,9 @@
+
+
+BOMBARDMENT
+
+
+
+
+
+
diff --git a/11 Bombardment/javascript/bombardment.js b/11 Bombardment/javascript/bombardment.js
new file mode 100644
index 00000000..3cd0a5d7
--- /dev/null
+++ b/11 Bombardment/javascript/bombardment.js
@@ -0,0 +1,167 @@
+// BOMBARDMENT
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+// Main program
+async function main()
+{
+ print(tab(33) + "BOMBARDMENT\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU\n");
+ print("HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.\n");
+ print("YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST.\n");
+ print("THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS.\n");
+ print("\n");
+ print("THE OBJECT OF THE GAME IS TO FIRE MISSILES AT THE\n");
+ print("OUTPOSTS OF THE COMPUTER. IT WILL DO THE SAME TO YOU.\n");
+ print("THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS\n");
+ print("FIRST IS THE WINNER.\n");
+ print("\n");
+ print("GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!\n");
+ print("\n");
+ // "TEAR OFF" because it supposed this to be printed on a teletype
+ print("TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS.\n");
+ for (r = 1; r <= 5; r++)
+ print("\n");
+ ma = [];
+ for (r = 1; r <= 100; r++)
+ ma[r] = 0;
+ p = 0;
+ q = 0;
+ z = 0;
+ for (r = 1; r <= 5; r++) {
+ i = (r - 1) * 5 + 1;
+ print(i + "\t" + (i + 1) + "\t" + (i + 2) + "\t" + (i + 3) + "\t" + (i + 4) + "\n");
+ }
+ for (r = 1; r <= 10; r++)
+ print("\n");
+ c = Math.floor(Math.random() * 25) + 1;
+ do {
+ d = Math.floor(Math.random() * 25) + 1;
+ e = Math.floor(Math.random() * 25) + 1;
+ f = Math.floor(Math.random() * 25) + 1;
+ } while (c == d || c == e || c == f || d == e || d == f || e == f) ;
+ print("WHAT ARE YOUR FOUR POSITIONS");
+ str = await input();
+ g = parseInt(str);
+ str = str.substr(str.indexOf(",") + 1);
+ h = parseInt(str);
+ str = str.substr(str.indexOf(",") + 1);
+ k = parseInt(str);
+ str = str.substr(str.indexOf(",") + 1);
+ l = parseInt(str);
+ print("\n");
+ // Another "bug" your outpost can be in the same position as a computer outpost
+ // Let us suppose both live in a different matrix.
+ while (1) {
+ // The original game didn't limited the input to 1-25
+ do {
+ print("WHERE DO YOU WISH TO FIRE YOUR MISSLE");
+ y = parseInt(await input());
+ } while (y < 0 || y > 25) ;
+ if (y == c || y == d || y == e || y == f) {
+
+ // The original game has a bug. You can shoot the same outpost
+ // several times. This solves it.
+ if (y == c)
+ c = 0;
+ if (y == d)
+ d = 0;
+ if (y == e)
+ e = 0;
+ if (y == f)
+ f = 0;
+ q++;
+ if (q == 1) {
+ print("ONE DOWN. THREE TO GO.\n");
+ } else if (q == 2) {
+ print("TWO DOWN. TWO TO GO.\n");
+ } else if (q == 3) {
+ print("THREE DOWN. ONE TO GO.\n");
+ } else {
+ print("YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN\n");
+ print("MY TRANSISTO&S RECUP%RA*E!\n");
+ break;
+ }
+ } else {
+ print("HA, HA YOU MISSED. MY TURN NOW:\n");
+ }
+ print("\n");
+ print("\n");
+ do {
+ m = Math.floor(Math.random() * 25 + 1);
+ p++;
+ n = p - 1;
+ for (t = 1; t <= n; t++) {
+ if (m == ma[t])
+ break;
+ }
+ } while (t <= n) ;
+ x = m;
+ ma[p] = m;
+ if (x == g || x == h || x == l || x == k) {
+ z++;
+ if (z < 4)
+ print("I GOT YOU. IT WON'T BE LONG NOW. POST " + x + " WAS HIT.\n");
+ if (z == 1) {
+ print("YOU HAVE ONLY THREE OUTPOSTS LEFT.\n");
+ } else if (z == 2) {
+ print("YOU HAVE ONLY TWO OUTPOSTS LEFT.\n");
+ } else if (z == 3) {
+ print("YOU HAVE ONLY ONE OUTPOST LEFT.\n");
+ } else {
+ print("YOU'RE DEAD. YOUR LAST OUTPOST WAS AT " + x + ". HA, HA, HA.\n");
+ print("BETTER LUCK NEXT TIME.\n");
+ }
+ } else {
+ print("I MISSED YOU, YOU DIRTY RAT. I PICKED " + m + ". YOUR TURN:\n");
+ }
+ print("\n");
+ print("\n");
+ }
+}
+
+main();
diff --git a/11 Bombardment/python/bombardment.py b/11 Bombardment/python/bombardment.py
new file mode 100755
index 00000000..a16113e7
--- /dev/null
+++ b/11 Bombardment/python/bombardment.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python3
+import random
+from functools import partial
+
+def display_intro():
+ print("" * 33 + "BOMBARDMENT")
+ print("" * 15 + " CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
+ print("\n\n")
+ print("YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU")
+ print("HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.")
+ print("YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST.")
+ print("THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS.")
+ print()
+ print("THE OBJECT OF THE GAME IS TO FIRE MISSLES AT THE")
+ print("OUTPOSTS OF THE COMPUTER. IT WILL DO THE SAME TO YOU.")
+ print("THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS")
+ print("FIRST IS THE WINNER.")
+ print()
+ print("GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!")
+ print()
+ print("TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS.")
+ print("\n" * 4)
+
+
+def display_field():
+ for row in range(5):
+ initial = row * 5 + 1
+ print('\t'.join([str(initial + column) for column in range(5)]))
+
+ print("\n" * 9)
+
+
+def positions_list():
+ return list(range(1, 26, 1))
+
+
+def generate_enemy_positions():
+ """ Randomly choose 4 'positions' out of a range of 1 to 25 """
+ positions = positions_list()
+ random.shuffle(positions)
+ return set(positions[:4])
+
+
+def is_valid_position(pos):
+ return pos in positions_list()
+
+
+def prompt_for_player_positions():
+
+ while True:
+ raw_positions = input("WHAT ARE YOUR FOUR POSITIONS? ")
+ positions = set(int(pos) for pos in raw_positions.split())
+ # Verify user inputs (for example, if the player gives a
+ # a position for 26, the enemy can never hit it)
+ if (len(positions) != 4):
+ print("PLEASE ENTER 4 UNIQUE POSITIONS\n")
+ continue
+ elif (any(not is_valid_position(pos) for pos in positions)):
+ print("ALL POSITIONS MUST RANGE (1-25)\n")
+ continue
+ else:
+ return positions
+
+
+def prompt_player_for_target():
+
+ while True:
+ target = int(input("WHERE DO YOU WISH TO FIRE YOUR MISSLE? "))
+ if not is_valid_position(target):
+ print("POSITIONS MUST RANGE (1-25)\n")
+ continue
+
+ return target
+
+
+def attack(target, positions, hit_message, miss_message, progress_messages):
+ """ Performs attack procedure returning True if we are to continue. """
+
+ if target in positions:
+ print(hit_message.format(target))
+ positions.remove(target)
+ print(progress_messages[len(positions)].format(target))
+ else:
+ print(miss_message.format(target))
+
+ return len(positions) > 0
+
+
+def init_enemy():
+ """ Returns a closure analogous to prompt_player_for_target. Will
+ choose from a unique sequence of positions to avoid picking the
+ same position twice. """
+
+ position_sequence = positions_list()
+ random.shuffle(position_sequence)
+ position = iter(position_sequence)
+
+ def choose():
+ return next(position)
+
+ return choose
+
+
+# Messages correspond to outposts remaining (3, 2, 1, 0)
+PLAYER_PROGRESS_MESSAGES = (
+ "YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN\n"
+ "MY TRANSISTO&S RECUP%RA*E!",
+ "THREE DOWN, ONE TO GO.\n\n",
+ "TWO DOWN, TWO TO GO.\n\n",
+ "ONE DOWN, THREE TO GO.\n\n"
+ )
+
+
+ENEMY_PROGRESS_MESSAGES = (
+ "YOU'RE DEAD. YOUR LAST OUTPOST WAS AT {}. HA, HA, HA.\n"
+ "BETTER LUCK NEXT TIME.",
+ "YOU HAVE ONLY ONE OUTPOST LEFT.\n\n",
+ "YOU HAVE ONLY TWO OUTPOSTS LEFT.\n\n",
+ "YOU HAVE ONLY THREE OUTPOSTS LEFT.\n\n",
+ )
+
+
+def play():
+ display_intro()
+ display_field()
+
+ enemy_positions = generate_enemy_positions()
+ player_positions = prompt_for_player_positions()
+
+ # Build partial functions only requiring the target as input
+ player_attacks = partial(attack,
+ positions=enemy_positions,
+ hit_message="YOU GOT ONE OF MY OUTPOSTS!",
+ miss_message="HA, HA YOU MISSED. MY TURN NOW:\n\n",
+ progress_messages=PLAYER_PROGRESS_MESSAGES)
+
+ enemy_attacks = partial(attack,
+ positions=player_positions,
+ hit_message="I GOT YOU. IT WON'T BE LONG NOW. POST {} WAS HIT.",
+ miss_message="I MISSED YOU, YOU DIRTY RAT. I PICKED {}. YOUR TURN:\n\n",
+ progress_messages=ENEMY_PROGRESS_MESSAGES)
+
+ enemy_position_choice = init_enemy()
+
+ # Play as long as both player_attacks and enemy_attacks allow to continue
+ while player_attacks(prompt_player_for_target()) and enemy_attacks(enemy_position_choice()):
+ pass
+
+
+if __name__ == "__main__":
+ play()
diff --git a/12 Bombs Away/java/src/BombsAway.java b/12 Bombs Away/java/src/BombsAway.java
new file mode 100644
index 00000000..e156ea73
--- /dev/null
+++ b/12 Bombs Away/java/src/BombsAway.java
@@ -0,0 +1,505 @@
+import java.util.Scanner;
+
+/**
+ * Game of Bombs Away
+ *
+ * Based on the Basic game of Bombs Away here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/12%20Bombs%20Away/bombsaway.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class BombsAway {
+
+ public static final int MAX_PILOT_MISSIONS = 160;
+ public static final int MAX_CASUALTIES = 100;
+ public static final int MISSED_TARGET_CONST_1 = 2;
+ public static final int MISSED_TARGET_CONST_2 = 30;
+ public static final int CHANCE_OF_BEING_SHOT_DOWN_BASE = 100;
+ public static final double SIXTY_FIVE_PERCENT = .65;
+
+ private enum GAME_STATE {
+ START,
+ CHOOSE_SIDE,
+ CHOOSE_PLANE,
+ CHOOSE_TARGET,
+ CHOOSE_MISSIONS,
+ CHOOSE_ENEMY_DEFENCES,
+ FLY_MISSION,
+ DIRECT_HIT,
+ MISSED_TARGET,
+ PROCESS_FLAK,
+ SHOT_DOWN,
+ MADE_IT_THROUGH_FLAK,
+ PLAY_AGAIN,
+ GAME_OVER
+ }
+
+ public enum SIDE {
+ ITALY(1),
+ ALLIES(2),
+ JAPAN(3),
+ GERMANY(4);
+
+ private final int value;
+
+ SIDE(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+
+ }
+
+ public enum TARGET {
+ ALBANIA(1),
+ GREECE(2),
+ NORTH_AFRICA(3),
+ RUSSIA(4),
+ ENGLAND(5),
+ FRANCE(6);
+
+ private final int value;
+
+ TARGET(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+ }
+
+ public enum ENEMY_DEFENCES {
+ GUNS(1),
+ MISSILES(2),
+ BOTH(3);
+
+ private final int value;
+
+ ENEMY_DEFENCES(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+ }
+
+ public enum AIRCRAFT {
+ LIBERATOR(1),
+ B29(2),
+ B17(3),
+ LANCASTER(4);
+
+ private final int value;
+
+ AIRCRAFT(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+ }
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ // Current game state
+ private GAME_STATE gameState;
+
+ private SIDE side;
+
+ private int missions;
+
+ private int chanceToHit;
+ private int percentageHitRateOfGunners;
+
+ public BombsAway() {
+
+ gameState = GAME_STATE.START;
+
+ // Initialise kb scanner
+ kbScanner = new Scanner(System.in);
+ }
+
+ /**
+ * Main game loop
+ *
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+
+ // Show an introduction the first time the game is played.
+ case START:
+ intro();
+ chanceToHit = 0;
+ percentageHitRateOfGunners = 0;
+
+ gameState = GAME_STATE.CHOOSE_SIDE;
+ break;
+
+ case CHOOSE_SIDE:
+ side = getSide("WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4) ? ");
+ if (side == null) {
+ System.out.println("TRY AGAIN...");
+ } else {
+ // Different game paths depending on which side was chosen
+ switch (side) {
+ case ITALY:
+ case GERMANY:
+ gameState = GAME_STATE.CHOOSE_TARGET;
+ break;
+ case ALLIES:
+ case JAPAN:
+ gameState = GAME_STATE.CHOOSE_PLANE;
+ break;
+ }
+ }
+ break;
+
+ case CHOOSE_TARGET:
+ String prompt;
+ if (side == SIDE.ITALY) {
+ prompt = "YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3) ? ";
+ } else {
+ // Germany
+ System.out.println("A NAZI, EH? OH WELL. ARE YOU GOING FOR RUSSIA(1),");
+ prompt = "ENGLAND(2), OR FRANCE(3) ? ";
+ }
+ TARGET target = getTarget(prompt);
+ if (target == null) {
+ System.out.println("TRY AGAIN...");
+ } else {
+ displayTargetMessage(target);
+ gameState = GAME_STATE.CHOOSE_MISSIONS;
+ }
+
+ case CHOOSE_MISSIONS:
+ missions = getNumberFromKeyboard("HOW MANY MISSIONS HAVE YOU FLOWN? ");
+
+ if(missions <25) {
+ System.out.println("FRESH OUT OF TRAINING, EH?");
+ gameState = GAME_STATE.FLY_MISSION;
+ } else if(missions < 100) {
+ System.out.println("THAT'S PUSHING THE ODDS!");
+ gameState = GAME_STATE.FLY_MISSION;
+ } else if(missions >=160) {
+ System.out.println("MISSIONS, NOT MILES...");
+ System.out.println("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS.");
+ System.out.println("NOW THEN, ");
+ } else {
+ // No specific message if missions is 100-159, but still valid
+ gameState = GAME_STATE.FLY_MISSION;
+ }
+ break;
+
+ case CHOOSE_PLANE:
+ switch(side) {
+ case ALLIES:
+ AIRCRAFT plane = getPlane("AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4)? ");
+ if(plane == null) {
+ System.out.println("TRY AGAIN...");
+ } else {
+ switch(plane) {
+
+ case LIBERATOR:
+ System.out.println("YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI.");
+ break;
+ case B29:
+ System.out.println("YOU'RE DUMPING THE A-BOMB ON HIROSHIMA.");
+ break;
+ case B17:
+ System.out.println("YOU'RE CHASING THE BISMARK IN THE NORTH SEA.");
+ break;
+ case LANCASTER:
+ System.out.println("YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR.");
+ break;
+ }
+
+ gameState = GAME_STATE.CHOOSE_MISSIONS;
+ }
+ break;
+
+ case JAPAN:
+ System.out.println("YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.");
+ if(yesEntered(displayTextAndGetInput("YOUR FIRST KAMIKAZE MISSION(Y OR N) ? "))) {
+ if(randomNumber(1) > SIXTY_FIVE_PERCENT) {
+ gameState = GAME_STATE.DIRECT_HIT;
+ } else {
+ // It's a miss
+ gameState = GAME_STATE.MISSED_TARGET;
+ }
+ } else {
+ gameState = GAME_STATE.PROCESS_FLAK;
+ }
+ break;
+ }
+ break;
+
+ case FLY_MISSION:
+ double missionResult = (MAX_PILOT_MISSIONS * randomNumber(1));
+ if(missions > missionResult) {
+ gameState = GAME_STATE.DIRECT_HIT;
+ } else {
+ gameState = GAME_STATE.MISSED_TARGET;
+ }
+
+ break;
+
+ case DIRECT_HIT:
+ System.out.println("DIRECT HIT!!!! " + (int) Math.round(randomNumber(MAX_CASUALTIES)) + " KILLED.");
+ System.out.println("MISSION SUCCESSFUL.");
+ gameState = GAME_STATE.PLAY_AGAIN;
+ break;
+
+ case MISSED_TARGET:
+ System.out.println("MISSED TARGET BY " + (int) Math.round(MISSED_TARGET_CONST_1 + MISSED_TARGET_CONST_2 * (randomNumber(1))) + " MILES!");
+ System.out.println("NOW YOU'RE REALLY IN FOR IT !!");
+ System.out.println();
+ gameState = GAME_STATE.CHOOSE_ENEMY_DEFENCES;
+ break;
+
+ case CHOOSE_ENEMY_DEFENCES:
+ boolean bothWeapons = true;
+
+ ENEMY_DEFENCES enemyDefences = getEnemyDefences("DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3) ? ");
+ if(enemyDefences == null) {
+ System.out.println("TRY AGAIN...");
+ } else {
+ switch(enemyDefences) {
+ case MISSILES:
+ case GUNS:
+ bothWeapons = false;
+
+ // fall through on purpose to BOTH since its pretty much identical code other than the chance to hit
+ // increasing if both weapons are part of the defence.
+
+ case BOTH:
+ percentageHitRateOfGunners = getNumberFromKeyboard("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? ");
+ if(percentageHitRateOfGunners < 10) {
+ System.out.println("YOU LIE, BUT YOU'LL PAY...");
+ }
+ if(bothWeapons) {
+ chanceToHit = 35;
+
+ }
+ break;
+ }
+ }
+ gameState = GAME_STATE.PROCESS_FLAK;
+
+ // Determine if the players airplan makes it through the Flak.
+ case PROCESS_FLAK:
+ double calc = (CHANCE_OF_BEING_SHOT_DOWN_BASE * randomNumber(1));
+
+ if ((chanceToHit + percentageHitRateOfGunners) > calc) {
+ gameState = GAME_STATE.SHOT_DOWN;
+ } else {
+ gameState = GAME_STATE.MADE_IT_THROUGH_FLAK;
+ }
+ break;
+
+ case SHOT_DOWN:
+ System.out.println("* * * * BOOM * * * *");
+ System.out.println("YOU HAVE BEEN SHOT DOWN.....");
+ System.out.println("DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR");
+ System.out.println("LAST TRIBUTE...");
+ gameState = GAME_STATE.PLAY_AGAIN;
+ break;
+
+ case MADE_IT_THROUGH_FLAK:
+ System.out.println("YOU MADE IT THROUGH TREMENDOUS FLAK!!");
+ gameState = GAME_STATE.PLAY_AGAIN;
+ break;
+
+ case PLAY_AGAIN:
+ if(yesEntered(displayTextAndGetInput("ANOTHER MISSION (Y OR N) ? "))) {
+ gameState = GAME_STATE.START;
+ } else {
+ System.out.println("CHICKEN !!!");
+ gameState = GAME_STATE.GAME_OVER;
+ }
+ break;
+ }
+ } while (gameState != GAME_STATE.GAME_OVER) ;
+ }
+
+ /**
+ * Display a (brief) intro
+ */
+ public void intro() {
+ System.out.println("YOU ARE A PILOT IN A WORLD WAR II BOMBER.");
+ }
+
+ /**
+ * Determine the side the player is going to play on.
+ * @param message displayed before the kb input
+ * @return the SIDE enum selected by the player
+ */
+ private SIDE getSide(String message) {
+ int valueEntered = getNumberFromKeyboard(message);
+ for(SIDE side : SIDE.values()) {
+ if(side.getValue() == valueEntered) {
+ return side;
+ }
+ }
+
+ // Input out of range
+ return null;
+ }
+
+ /**
+ * Determine the target the player is going for.
+ * @param message displayed before the kb input
+ * @return the TARGET enum selected by the player
+ */
+ private TARGET getTarget(String message) {
+ int valueEntered = getNumberFromKeyboard(message);
+
+ for(TARGET target : TARGET.values()) {
+ if(target.getValue() == valueEntered) {
+ return target;
+ }
+ }
+
+ // Input out of range
+ return null;
+ }
+
+ /**
+ * Determine the airplane the player is going to fly.
+ * @param message displayed before the kb input
+ * @return the AIRCRAFT enum selected by the player
+ */
+ private AIRCRAFT getPlane(String message) {
+ int valueEntered = getNumberFromKeyboard(message);
+
+ for(AIRCRAFT plane : AIRCRAFT.values()) {
+ if(plane.getValue() == valueEntered) {
+ return plane;
+ }
+ }
+
+ // Input out of range
+ return null;
+
+ }
+
+ /**
+ * Select the type of enemy defences.
+ *
+ * @param message displayed before kb input
+ * @return the ENEMY_DEFENCES enum as selected by player
+ */
+ private ENEMY_DEFENCES getEnemyDefences(String message) {
+ int valueEntered = getNumberFromKeyboard(message);
+ for (ENEMY_DEFENCES enemyDefences : ENEMY_DEFENCES.values()) {
+ if(enemyDefences.getValue() == valueEntered) {
+ return enemyDefences;
+ }
+ }
+
+ // Input out of range
+ return null;
+ }
+
+ // output a specific message based on the target selected
+ private void displayTargetMessage(TARGET target) {
+
+ switch (target) {
+
+ case ALBANIA:
+ System.out.println("SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE.");
+ break;
+ case GREECE:
+ System.out.println("BE CAREFUL!!!");
+ break;
+ case NORTH_AFRICA:
+ System.out.println("YOU'RE GOING FOR THE OIL, EH?");
+ break;
+ case RUSSIA:
+ System.out.println("YOU'RE NEARING STALINGRAD.");
+ break;
+ case ENGLAND:
+ System.out.println("NEARING LONDON. BE CAREFUL, THEY'VE GOT RADAR.");
+ break;
+ case FRANCE:
+ System.out.println("NEARING VERSAILLES. DUCK SOUP. THEY'RE NEARLY DEFENSELESS.");
+ break;
+ }
+ }
+
+ /**
+ * Accepts a string from the keyboard, and converts to an int
+ *
+ * @param message displayed text on screen before keyboard input
+ *
+ * @return the number entered by the player
+ */
+ private int getNumberFromKeyboard(String message) {
+
+ String answer = displayTextAndGetInput(message);
+ return Integer.parseInt(answer);
+ }
+
+ /**
+ * Checks whether player entered Y or YES to a question.
+ *
+ * @param text player string from kb
+ * @return true of Y or YES was entered, otherwise false
+ */
+ private boolean yesEntered(String text) {
+ return stringIsAnyValue(text, "Y", "YES");
+ }
+
+ /**
+ * Check whether a string equals one of a variable number of values
+ * Useful to check for Y or YES for example
+ * Comparison is case insensitive.
+ *
+ * @param text source string
+ * @param values a range of values to compare against the source string
+ * @return true if a comparison was found in one of the variable number of strings passed
+ */
+ private boolean stringIsAnyValue(String text, String... values) {
+
+ // Cycle through the variable number of values and test each
+ for(String val:values) {
+ if(text.equalsIgnoreCase(val)) {
+ return true;
+ }
+ }
+
+ // no matches
+ return false;
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Generate random number
+ * Used as a single digit of the computer player
+ *
+ * @return random number
+ */
+ private double randomNumber(int range) {
+ return (Math.random()
+ * (range));
+ }
+}
\ No newline at end of file
diff --git a/12 Bombs Away/java/src/BombsAwayGame.java b/12 Bombs Away/java/src/BombsAwayGame.java
new file mode 100644
index 00000000..cfa05cd7
--- /dev/null
+++ b/12 Bombs Away/java/src/BombsAwayGame.java
@@ -0,0 +1,8 @@
+public class BombsAwayGame {
+
+ public static void main(String[] args) {
+
+ BombsAway bombsAway = new BombsAway();
+ bombsAway.play();
+ }
+}
diff --git a/12 Bombs Away/javascript/bombsaway.html b/12 Bombs Away/javascript/bombsaway.html
new file mode 100644
index 00000000..c58c753f
--- /dev/null
+++ b/12 Bombs Away/javascript/bombsaway.html
@@ -0,0 +1,9 @@
+
+
+BOMBARDMENT
+
+
+
+
+
+
diff --git a/12 Bombs Away/javascript/bombsaway.js b/12 Bombs Away/javascript/bombsaway.js
new file mode 100644
index 00000000..835a2608
--- /dev/null
+++ b/12 Bombs Away/javascript/bombsaway.js
@@ -0,0 +1,205 @@
+// BOMBS AWAY
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+// Main program
+async function main()
+{
+ while (1) {
+ print("YOU ARE A PILOT IN A WORLD WAR II BOMBER.\n");
+ while (1) {
+ print("WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4)");
+ a = parseInt(await input());
+ if (a < 1 || a > 4)
+ print("TRY AGAIN...\n");
+ else
+ break;
+ }
+ if (a == 1) {
+ while (1) {
+ print("YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3)");
+ b = parseInt(await input());
+ if (b < 1 || b > 3)
+ print("TRY AGAIN...\n");
+ else
+ break;
+ }
+ print("\n");
+ if (b == 1) {
+ print("SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE.\n");
+ } else if (b == 2) {
+ print("BE CAREFUL!!!\n");
+ } else {
+ print("YOU'RE GOING FOR THE OIL, EH?\n");
+ }
+ } else if (a == 2) {
+ while (1) {
+ print("AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4)");
+ g = parseInt(await input());
+ if (g < 1 || g > 4)
+ print("TRY AGAIN...\n");
+ else
+ break;
+ }
+ print("\n");
+ if (g == 1) {
+ print("YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI.\n");
+ } else if (g == 2) {
+ print("YOU'RE DUMPING THE A-BOMB ON HIROSHIMA.\n");
+ } else if (g == 3) {
+ print("YOU'RE CHASING THE BISMARK IN THE NORTH SEA.\n");
+ } else {
+ print("YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR.\n");
+ }
+ } else if (a == 3) {
+ print("YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.\n");
+ print("YOUR FIRST KAMIKAZE MISSION(Y OR N)");
+ str = await input();
+ if (str == "N") {
+ s = 0;
+ } else {
+ s = 1;
+ print("\n");
+ }
+ } else {
+ while (1) {
+ print("A NAZI, EH? OH WELL. ARE YOU GOING FOR RUSSIA(1),\n");
+ print("ENGLAND(2), OR FRANCE(3)");
+ m = parseInt(await input());
+ if (m < 1 || m > 3)
+ print("TRY AGAIN...\n");
+ else
+ break;
+ }
+ print("\n");
+ if (m == 1) {
+ print("YOU'RE NEARING STALINGRAD.\n");
+ } else if (m == 2) {
+ print("NEARING LONDON. BE CAREFUL, THEY'VE GOT RADAR.\n");
+ } else if (m == 3) {
+ print("NEARING VERSAILLES. DUCK SOUP. THEY'RE NEARLY DEFENSELESS.\n");
+ }
+ }
+ if (a != 3) {
+ print("\n");
+ while (1) {
+ print("HOW MANY MISSIONS HAVE YOU FLOWN");
+ d = parseInt(await input());
+ if (d < 160)
+ break;
+ print("MISSIONS, NOT MILES...\n");
+ print("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS.\n");
+ print("NOW THEN, ");
+ }
+ print("\n");
+ if (d >= 100) {
+ print("THAT'S PUSHING THE ODDS!\n");
+ } else if (d < 25) {
+ print("FRESH OUT OF TRAINING, EH?\n");
+ }
+ print("\n");
+ if (d >= 160 * Math.random())
+ hit = true;
+ else
+ hit = false;
+ } else {
+ if (s == 0) {
+ hit = false;
+ } else if (Math.random() > 0.65) {
+ hit = true;
+ } else {
+ hit = false;
+ s = 100;
+ }
+ }
+ if (hit) {
+ print("DIRECT HIT!!!! " + Math.floor(100 * Math.random()) + " KILLED.\n");
+ print("MISSION SUCCESSFUL.\n");
+ } else {
+ t = 0;
+ if (a != 3) {
+ print("MISSED TARGET BY " + Math.floor(2 + 30 * Math.random()) + " MILES!\n");
+ print("NOW YOU'RE REALLY IN FOR IT !!\n");
+ print("\n");
+ while (1) {
+ print("DOES THE ENEMY HAVE GUNS(1), MISSILE(2), OR BOTH(3)");
+ r = parseInt(await input());
+ if (r < 1 || r > 3)
+ print("TRY AGAIN...\n");
+ else
+ break;
+ }
+ print("\n");
+ if (r != 2) {
+ print("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)");
+ s = parseInt(await input());
+ if (s < 10)
+ print("YOU LIE, BUT YOU'LL PAY...\n");
+ print("\n");
+ }
+ print("\n");
+ if (r > 1)
+ t = 35;
+ }
+ if (s + t <= 100 * Math.random()) {
+ print("YOU MADE IT THROUGH TREMENDOUS FLAK!!\n");
+ } else {
+ print("* * * * BOOM * * * *\n");
+ print("YOU HAVE BEEN SHOT DOWN.....\n");
+ print("DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR\n");
+ print("LAST TRIBUTE...\n");
+ }
+ }
+ print("\n");
+ print("\n");
+ print("\n");
+ print("ANOTHER MISSION (Y OR N)");
+ str = await input();
+ if (str != "Y")
+ break;
+ }
+ print("CHICKEN !!!\n");
+ print("\n");
+}
+
+main();
diff --git a/13 Bounce/javascript/bounce.html b/13 Bounce/javascript/bounce.html
new file mode 100644
index 00000000..b1e8c529
--- /dev/null
+++ b/13 Bounce/javascript/bounce.html
@@ -0,0 +1,9 @@
+
+
+BOUNCE
+
+
+
+
+
+
diff --git a/13 Bounce/javascript/bounce.js b/13 Bounce/javascript/bounce.js
new file mode 100644
index 00000000..d9cac590
--- /dev/null
+++ b/13 Bounce/javascript/bounce.js
@@ -0,0 +1,112 @@
+// BOUNCE
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+// Main program
+async function main()
+{
+ print(tab(33) + "BOUNCE\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ ta = [];
+ print("THIS SIMULATION LETS YOU SPECIFY THE INITIAL VELOCITY\n");
+ print("OF A BALL THROWN STRAIGHT UP, AND THE COEFFICIENT OF\n");
+ print("ELASTICITY OF THE BALL. PLEASE USE A DECIMAL FRACTION\n");
+ print("COEFFICIENCY (LESS THAN 1).\n");
+ print("\n");
+ print("YOU ALSO SPECIFY THE TIME INCREMENT TO BE USED IN\n");
+ print("'STROBING' THE BALL'S FLIGHT (TRY .1 INITIALLY).\n");
+ print("\n");
+ while (1) {
+ print("TIME INCREMENT (SEC)");
+ s2 = parseFloat(await input());
+ print("\n");
+ print("VELOCITY (FPS)");
+ v = parseFloat(await input());
+ print("\n");
+ print("COEFFICIENT");
+ c = parseFloat(await input());
+ print("\n");
+ print("FEET\n");
+ print("\n");
+ s1 = Math.floor(70 / (v / (16 * s2)));
+ for (i = 1; i <= s1; i++)
+ ta[i] = v * Math.pow(c, i - 1) / 16;
+ for (h = Math.floor(-16 * Math.pow(v / 32, 2) + Math.pow(v, 2) / 32 + 0.5); h >= 0; h -= 0.5) {
+ str = "";
+ if (Math.floor(h) == h)
+ str += " " + h + " ";
+ l = 0;
+ for (i = 1; i <= s1; i++) {
+ for (t = 0; t <= ta[i]; t += s2) {
+ l += s2;
+ if (Math.abs(h - (0.5 * (-32) * Math.pow(t, 2) + v * Math.pow(c, i - 1) * t)) <= 0.25) {
+ while (str.length < l / s2)
+ str += " ";
+ str += "0";
+ }
+ }
+ t = ta[i + 1] / 2;
+ if (-16 * Math.pow(t, 2) + v * Math.pow(c, i - 1) * t < h)
+ break;
+ }
+ print(str + "\n");
+ }
+ str = " ";
+ for (i = 1; i < Math.floor(l + 1) / s2 + 1; i++)
+ str += ".";
+ print(str + "\n");
+ str = " 0";
+ for (i = 1; i < Math.floor(l + 0.9995); i++) {
+ while (str.length < Math.floor(i / s2))
+ str += " ";
+ str += i;
+ }
+ print(str + "\n");
+ print(tab(Math.floor(l + 1) / (2 * s2) - 2) + "SECONDS\n");
+ }
+}
+
+main();
diff --git a/16 Bug/java/src/Bug.java b/16 Bug/java/src/Bug.java
new file mode 100644
index 00000000..861afc5a
--- /dev/null
+++ b/16 Bug/java/src/Bug.java
@@ -0,0 +1,253 @@
+import java.util.ArrayList;
+import java.util.Scanner;
+
+/**
+ * Game of Bug
+ *
+ * Based on the Basic game of Bug here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/16%20Bug/bug.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class Bug {
+
+ // Dice roll
+ public static final int SIX = 6;
+
+ private enum GAME_STATE {
+ START,
+ PLAYER_TURN,
+ COMPUTER_TURN,
+ CHECK_FOR_WINNER,
+ GAME_OVER
+ }
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ // Current game state
+ private GAME_STATE gameState;
+
+
+ private final Insect playersBug;
+
+ private final Insect computersBug;
+
+ // Used to show the result of dice roll.
+ private final String[] ROLLS = new String[]{"BODY", "NECK", "HEAD", "FEELERS", "TAIL", "LEGS"};
+
+ public Bug() {
+
+ playersBug = new PlayerBug();
+ computersBug = new ComputerBug();
+
+ gameState = GAME_STATE.START;
+
+ // Initialise kb scanner
+ kbScanner = new Scanner(System.in);
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+
+ // Show an introduction the first time the game is played.
+ // And optionally instructions.
+ case START:
+ intro();
+ if (!noEntered(displayTextAndGetInput("DO YOU WANT INSTRUCTIONS? "))) {
+ instructions();
+ }
+
+ gameState = GAME_STATE.PLAYER_TURN;
+ break;
+
+ case PLAYER_TURN:
+ int playersRoll = randomNumber();
+ System.out.println("YOU ROLLED A " + playersRoll + "=" + ROLLS[playersRoll - 1]);
+ switch (playersRoll) {
+ case 1:
+ System.out.println(playersBug.addBody());
+ break;
+ case 2:
+ System.out.println(playersBug.addNeck());
+ break;
+ case 3:
+ System.out.println(playersBug.addHead());
+ break;
+ case 4:
+ System.out.println(playersBug.addFeelers());
+ break;
+ case 5:
+ System.out.println(playersBug.addTail());
+ break;
+ case 6:
+ System.out.println(playersBug.addLeg());
+ break;
+ }
+
+ gameState = GAME_STATE.COMPUTER_TURN;
+ break;
+
+ case COMPUTER_TURN:
+ int computersRoll = randomNumber();
+ System.out.println("I ROLLED A " + computersRoll + "=" + ROLLS[computersRoll - 1]);
+ switch (computersRoll) {
+ case 1:
+ System.out.println(computersBug.addBody());
+ break;
+ case 2:
+ System.out.println(computersBug.addNeck());
+ break;
+ case 3:
+ System.out.println(computersBug.addHead());
+ break;
+ case 4:
+ System.out.println(computersBug.addFeelers());
+ break;
+ case 5:
+ System.out.println(computersBug.addTail());
+ break;
+ case 6:
+ System.out.println(computersBug.addLeg());
+ break;
+ }
+
+ gameState = GAME_STATE.CHECK_FOR_WINNER;
+ break;
+
+ case CHECK_FOR_WINNER:
+ boolean gameOver = false;
+
+ if (playersBug.complete()) {
+ System.out.println("YOUR BUG IS FINISHED.");
+ gameOver = true;
+ } else if (computersBug.complete()) {
+ System.out.println("MY BUG IS FINISHED.");
+ gameOver = true;
+ }
+
+ if (noEntered(displayTextAndGetInput("DO YOU WANT THE PICTURES? "))) {
+ gameState = GAME_STATE.PLAYER_TURN;
+ } else {
+ System.out.println("*****YOUR BUG*****");
+ System.out.println();
+ draw(playersBug);
+
+ System.out.println();
+ System.out.println("*****MY BUG*****");
+ System.out.println();
+ draw(computersBug);
+ gameState = GAME_STATE.PLAYER_TURN;
+ }
+ if (gameOver) {
+ System.out.println("I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!");
+ gameState = GAME_STATE.GAME_OVER;
+ }
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ /**
+ * Draw the bug (player or computer) based on what has
+ * already been added to it.
+ *
+ * @param bug The bug to be drawn.
+ */
+ private void draw(Insect bug) {
+ ArrayList insectOutput = bug.draw();
+ for (String s : insectOutput) {
+ System.out.println(s);
+ }
+ }
+
+ /**
+ * Display an intro
+ */
+ private void intro() {
+ System.out.println("BUG");
+ System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("THE GAME BUG");
+ System.out.println("I HOPE YOU ENJOY THIS GAME.");
+ }
+
+ private void instructions() {
+ System.out.println("THE OBJECT OF BUG IS TO FINISH YOUR BUG BEFORE I FINISH");
+ System.out.println("MINE. EACH NUMBER STANDS FOR A PART OF THE BUG BODY.");
+ System.out.println("I WILL ROLL THE DIE FOR YOU, TELL YOU WHAT I ROLLED FOR YOU");
+ System.out.println("WHAT THE NUMBER STANDS FOR, AND IF YOU CAN GET THE PART.");
+ System.out.println("IF YOU CAN GET THE PART I WILL GIVE IT TO YOU.");
+ System.out.println("THE SAME WILL HAPPEN ON MY TURN.");
+ System.out.println("IF THERE IS A CHANGE IN EITHER BUG I WILL GIVE YOU THE");
+ System.out.println("OPTION OF SEEING THE PICTURES OF THE BUGS.");
+ System.out.println("THE NUMBERS STAND FOR PARTS AS FOLLOWS:");
+ System.out.println("NUMBER\tPART\tNUMBER OF PART NEEDED");
+ System.out.println("1\tBODY\t1");
+ System.out.println("2\tNECK\t1");
+ System.out.println("3\tHEAD\t1");
+ System.out.println("4\tFEELERS\t2");
+ System.out.println("5\tTAIL\t1");
+ System.out.println("6\tLEGS\t6");
+ System.out.println();
+
+ }
+
+ /**
+ * Checks whether player entered N or NO to a question.
+ *
+ * @param text player string from kb
+ * @return true if N or NO was entered, otherwise false
+ */
+ private boolean noEntered(String text) {
+ return stringIsAnyValue(text, "N", "NO");
+ }
+
+ /**
+ * Check whether a string equals one of a variable number of values
+ * Useful to check for Y or YES for example
+ * Comparison is case insensitive.
+ *
+ * @param text source string
+ * @param values a range of values to compare against the source string
+ * @return true if a comparison was found in one of the variable number of strings passed
+ */
+ private boolean stringIsAnyValue(String text, String... values) {
+
+ // Cycle through the variable number of values and test each
+ for (String val : values) {
+ if (text.equalsIgnoreCase(val)) {
+ return true;
+ }
+ }
+
+ // no matches
+ return false;
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Generate random number
+ *
+ * @return random number
+ */
+ private int randomNumber() {
+ return (int) (Math.random()
+ * (SIX) + 1);
+ }
+}
\ No newline at end of file
diff --git a/16 Bug/java/src/BugGame.java b/16 Bug/java/src/BugGame.java
new file mode 100644
index 00000000..074ff45e
--- /dev/null
+++ b/16 Bug/java/src/BugGame.java
@@ -0,0 +1,10 @@
+
+
+public class BugGame {
+
+ public static void main(String[] args) {
+
+ Bug bug = new Bug();
+ bug.play();
+ }
+}
diff --git a/16 Bug/java/src/ComputerBug.java b/16 Bug/java/src/ComputerBug.java
new file mode 100644
index 00000000..fe232364
--- /dev/null
+++ b/16 Bug/java/src/ComputerBug.java
@@ -0,0 +1,15 @@
+public class ComputerBug extends Insect {
+
+ // Create messages specific to the computer player.
+
+ public ComputerBug() {
+ // Call superclass constructor for initialization.
+ super();
+ addMessages(new String[]{"I GET A FEELER.", "I HAVE " + MAX_FEELERS + " FEELERS ALREADY.", "I DO NOT HAVE A HEAD."}, PARTS.FEELERS);
+ addMessages(new String[]{"I NEEDED A HEAD.", "I DO NOT NEED A HEAD.", "I DO NOT HAVE A NECK."}, PARTS.HEAD);
+ addMessages(new String[]{"I NOW HAVE A NECK.", "I DO NOT NEED A NECK.", "I DO NOT HAVE A BODY."}, PARTS.NECK);
+ addMessages(new String[]{"I NOW HAVE A BODY.", "I DO NOT NEED A BODY."}, PARTS.BODY);
+ addMessages(new String[]{"I NOW HAVE A TAIL.", "I DO NOT NEED A TAIL.", "I DO NOT HAVE A BODY."}, PARTS.TAIL);
+ addMessages(new String[]{"I NOW HAVE ^^^" + " LEG", "I HAVE " + MAX_LEGS + " FEET.", "I DO NOT HAVE A BODY."}, PARTS.LEGS);
+ }
+}
diff --git a/16 Bug/java/src/Insect.java b/16 Bug/java/src/Insect.java
new file mode 100644
index 00000000..08e9414f
--- /dev/null
+++ b/16 Bug/java/src/Insect.java
@@ -0,0 +1,363 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * This tracks the insect (bug) and has methods to
+ * add body parts, create an array of output so it
+ * can be drawn and to determine if a bug is complete.
+ * N.B. This is a super class for ComputerBug and PlayerBug
+ */
+public class Insect {
+
+ public static final int MAX_FEELERS = 2;
+ public static final int MAX_LEGS = 6;
+
+ public static final int ADDED = 0;
+ public static final int NOT_ADDED = 1;
+ public static final int MISSING = 2;
+
+ // Various parts of the bug
+ public enum PARTS {
+ FEELERS,
+ HEAD,
+ NECK,
+ BODY,
+ TAIL,
+ LEGS
+ }
+
+ // Tracks what parts of the bug have been added
+ private boolean body;
+ private boolean neck;
+ private boolean head;
+ private int feelers;
+ private boolean tail;
+ private int legs;
+
+ // Messages about for various body parts
+ // These are set in the subclass ComputerBug or PlayerBug
+ private String[] bodyMessages;
+ private String[] neckMessages;
+ private String[] headMessages;
+ private String[] feelerMessages;
+ private String[] tailMessages;
+ private String[] legMessages;
+
+ public Insect() {
+ init();
+ }
+
+ /**
+ * Add a body to the bug if there is not one already added.
+ *
+ * @return return an appropriate message about the status of the operation.
+ */
+ public String addBody() {
+
+ boolean currentState = false;
+
+ if (!body) {
+ body = true;
+ currentState = true;
+ }
+
+ return addBodyMessage(currentState);
+ }
+
+ /**
+ * Create output based on adding the body or it being already added previously
+ *
+ * @return contains the output message
+ */
+
+ private String addBodyMessage(boolean wasAdded) {
+
+ // Return the appropriate message depending on whether the
+ // body was added or not.
+ if (wasAdded) {
+ return bodyMessages[ADDED];
+ } else {
+ return bodyMessages[NOT_ADDED];
+ }
+ }
+
+ /**
+ * Add a neck if a) a body has previously been added and
+ * b) a neck has not previously been added.
+ *
+ * @return text containing the status of the operation
+ */
+ public String addNeck() {
+
+ int status = NOT_ADDED; // Default is not added
+
+ if (!body) {
+ // No body, cannot add a neck
+ status = MISSING;
+ } else if (!neck) {
+ neck = true;
+ status = ADDED;
+ }
+
+ return neckMessages[status];
+ }
+
+ /**
+ * Add a head to the bug if a) there already exists a neck and
+ * b) a head has not previously been added
+ *
+ * @return text outlining the success of the operation
+ */
+ public String addHead() {
+
+ int status = NOT_ADDED; // Default is not added
+
+ if (!neck) {
+ // No neck, cannot add a head
+ status = MISSING;
+ } else if (!head) {
+ head = true;
+ status = ADDED;
+ }
+
+ return headMessages[status];
+ }
+
+ /**
+ * Add a feeler to the head if a) there has been a head added to
+ * the bug previously, and b) there are not already 2 (MAX_FEELERS)
+ * feelers previously added to the bug.
+ *
+ * @return text outlining the status of the operation
+ */
+ public String addFeelers() {
+
+ int status = NOT_ADDED; // Default is not added
+
+ if (!head) {
+ // No head, cannot add a feeler
+ status = MISSING;
+ } else if (feelers < MAX_FEELERS) {
+ feelers++;
+ status = ADDED;
+ }
+
+ return feelerMessages[status];
+ }
+
+ /**
+ * Add a tail to the bug if a) there is already a body previously added
+ * to the bug and b) there is not already a tail added.
+ *
+ * @return text outlining the status of the operation.
+ */
+ public String addTail() {
+
+ int status = NOT_ADDED; // Default is not added
+
+ if (!body) {
+ // No body, cannot add a tail
+ status = MISSING;
+ } else if (!tail) {
+ tail = true;
+ status = ADDED;
+ }
+
+ return tailMessages[status];
+ }
+
+ /**
+ * Add a leg to the bug if a) there is already a body previously added
+ * b) there are less than 6 (MAX_LEGS) previously added.
+ *
+ * @return text outlining status of the operation.
+ */
+ public String addLeg() {
+
+ int status = NOT_ADDED; // Default is not added
+
+ if (!body) {
+ // No body, cannot add a leg
+ status = MISSING;
+ } else if (legs < MAX_LEGS) {
+ legs++;
+ status = ADDED;
+ }
+
+ String message = "";
+
+ // Create a string showing the result of the operation
+
+ switch(status) {
+ case ADDED:
+ // Replace # with number of legs
+ message = legMessages[status].replace("^^^", String.valueOf(legs));
+ // Add text S. if >1 leg, or just . if one leg.
+ if (legs > 1) {
+ message += "S.";
+ } else {
+ message += ".";
+ }
+ break;
+
+ case NOT_ADDED:
+
+ // Deliberate fall through to next case as its the
+ // same code to be executed
+ case MISSING:
+ message = legMessages[status];
+ break;
+ }
+
+ return message;
+ }
+
+ /**
+ * Initialise
+ */
+ public void init() {
+ body = false;
+ neck = false;
+ head = false;
+ feelers = 0;
+ tail = false;
+ legs = 0;
+ }
+
+ /**
+ * Add unique messages depending on type of player
+ * A subclass of this class calls this method
+ * e.g. See ComputerBug or PlayerBug classes
+ *
+ * @param messages an array of messages
+ * @param bodyPart the bodypart the messages relate to.
+ */
+ public void addMessages(String[] messages, PARTS bodyPart) {
+
+ switch (bodyPart) {
+ case FEELERS:
+ feelerMessages = messages;
+ break;
+
+ case HEAD:
+ headMessages = messages;
+ break;
+
+ case NECK:
+ neckMessages = messages;
+ break;
+
+ case BODY:
+ bodyMessages = messages;
+ break;
+
+ case TAIL:
+ tailMessages = messages;
+ break;
+
+ case LEGS:
+ legMessages = messages;
+ break;
+ }
+ }
+
+ /**
+ * Returns a string array containing
+ * the "bug" that can be output to console
+ *
+ * @return the bug ready to draw
+ */
+ public ArrayList draw() {
+ ArrayList bug = new ArrayList<>();
+ StringBuilder lineOutput;
+
+ // Feelers
+ if (feelers > 0) {
+ for (int i = 0; i < 4; i++) {
+ lineOutput = new StringBuilder(addSpaces(10));
+ for (int j = 0; j < feelers; j++) {
+ lineOutput.append("A ");
+ }
+ bug.add(lineOutput.toString());
+ }
+ }
+
+ if (head) {
+ lineOutput = new StringBuilder(addSpaces(8) + "HHHHHHH");
+ bug.add(lineOutput.toString());
+ lineOutput = new StringBuilder(addSpaces(8) + "H" + addSpaces(5) + "H");
+ bug.add(lineOutput.toString());
+ lineOutput = new StringBuilder(addSpaces(8) + "H O O H");
+ bug.add(lineOutput.toString());
+ lineOutput = new StringBuilder(addSpaces(8) + "H" + addSpaces(5) + "H");
+ bug.add(lineOutput.toString());
+ lineOutput = new StringBuilder(addSpaces(8) + "H" + addSpaces(2) + "V" + addSpaces(2) + "H");
+ bug.add(lineOutput.toString());
+ lineOutput = new StringBuilder(addSpaces(8) + "HHHHHHH");
+ bug.add(lineOutput.toString());
+ }
+
+ if (neck) {
+ for (int i = 0; i < 2; i++) {
+ lineOutput = new StringBuilder(addSpaces(10) + "N N");
+ bug.add(lineOutput.toString());
+ }
+ }
+
+ if (body) {
+ lineOutput = new StringBuilder(addSpaces(5) + "BBBBBBBBBBBB");
+ bug.add(lineOutput.toString());
+ for (int i = 0; i < 2; i++) {
+ lineOutput = new StringBuilder(addSpaces(5) + "B" + addSpaces(10) + "B");
+ bug.add(lineOutput.toString());
+ }
+ if (tail) {
+ lineOutput = new StringBuilder("TTTTTB" + addSpaces(10) + "B");
+ bug.add(lineOutput.toString());
+ }
+ lineOutput = new StringBuilder(addSpaces(5) + "BBBBBBBBBBBB");
+ bug.add(lineOutput.toString());
+ }
+
+ if (legs > 0) {
+ for (int i = 0; i < 2; i++) {
+ lineOutput = new StringBuilder(addSpaces(5));
+ for (int j = 0; j < legs; j++) {
+ lineOutput.append(" L");
+ }
+ bug.add(lineOutput.toString());
+ }
+ }
+
+ return bug;
+ }
+
+ /**
+ * Check if the bug is complete i.e. it has
+ * 2 (MAX_FEELERS) feelers, a head, a neck, a body
+ * a tail and 6 (MAX_FEET) feet.
+ *
+ * @return true if complete.
+ */
+ public boolean complete() {
+ return (feelers == MAX_FEELERS)
+ && head
+ && neck
+ && body
+ && tail
+ && (legs == MAX_LEGS);
+ }
+
+ /**
+ * Simulate tabs be creating a string of X spaces.
+ *
+ * @param number contains number of spaces needed.
+ * @return a String containing the spaces
+ */
+ private String addSpaces(int number) {
+ char[] spaces = new char[number];
+ Arrays.fill(spaces, ' ');
+ return new String(spaces);
+
+ }
+}
\ No newline at end of file
diff --git a/16 Bug/java/src/PlayerBug.java b/16 Bug/java/src/PlayerBug.java
new file mode 100644
index 00000000..1a82e8b3
--- /dev/null
+++ b/16 Bug/java/src/PlayerBug.java
@@ -0,0 +1,18 @@
+public class PlayerBug extends Insect {
+
+ // Create messages specific to the player.
+
+ public PlayerBug() {
+ // Call superclass constructor for initialization.
+ super();
+ addMessages(new String[]{"I NOW GIVE YOU A FEELER.", "YOU HAVE " + MAX_FEELERS + " FEELERS ALREADY.", "YOU DO NOT HAVE A HEAD."}, PARTS.FEELERS);
+ addMessages(new String[]{"YOU NEEDED A HEAD.", "YOU HAVE A HEAD.", "YOU DO NOT HAVE A NECK."}, PARTS.HEAD);
+ addMessages(new String[]{"YOU NOW HAVE A NECK.", "YOU DO NOT NEED A NECK.", "YOU DO NOT HAVE A BODY."}, PARTS.NECK);
+ addMessages(new String[]{"YOU NOW HAVE A BODY.", "YOU DO NOT NEED A BODY."}, PARTS.BODY);
+ addMessages(new String[]{"I NOW GIVE YOU A TAIL.", "YOU ALREADY HAVE A TAIL.", "YOU DO NOT HAVE A BODY."}, PARTS.TAIL);
+ addMessages(new String[]{"YOU NOW HAVE ^^^ LEG", "YOU HAVE " + MAX_LEGS + " FEET ALREADY.", "YOU DO NOT HAVE A BODY."}, PARTS.LEGS);
+ }
+
+
+}
+
diff --git a/18 Bullseye/java/src/Bullseye.java b/18 Bullseye/java/src/Bullseye.java
index 06090351..fda321ae 100644
--- a/18 Bullseye/java/src/Bullseye.java
+++ b/18 Bullseye/java/src/Bullseye.java
@@ -1,15 +1,26 @@
import java.util.ArrayList;
import java.util.Scanner;
+/**
+ * Game of Bullseye
+ *
+ * Based on the Basic game of Bullseye here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/18%20Bullseye/bullseye.bas
+ *
+ * Note: The idea was to create a version of 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
public class Bullseye {
+ // Used for formatting output
public static final int FIRST_IDENT = 10;
public static final int SECOND_IDENT = 30;
public static final int THIRD_INDENT = 30;
- public static final double[] SHOT_ONE = new double[] { .65, .55, .5, .5};
- public static final double[] SHOT_TWO = new double[] { .99, .77, .43,.01};
- public static final double[] SHOT_THREE = new double[] { .95, .75, .45, .05 };
+ // Used to decide throw result
+ public static final double[] SHOT_ONE = new double[]{.65, .55, .5, .5};
+ public static final double[] SHOT_TWO = new double[]{.99, .77, .43, .01};
+ public static final double[] SHOT_THREE = new double[]{.95, .75, .45, .05};
private enum GAME_STATE {
STARTING,
@@ -20,14 +31,12 @@ public class Bullseye {
private GAME_STATE gameState;
- private ArrayList players;
+ private final ArrayList players;
- private Shot[] shots;
+ private final Shot[] shots;
// Used for keyboard input
- private Scanner kbScanner;
-
- private int numberOfPlayers;
+ private final Scanner kbScanner;
private int round;
@@ -49,7 +58,6 @@ public class Bullseye {
/**
* Main game loop
- *
*/
public void play() {
@@ -65,10 +73,10 @@ public class Bullseye {
// Start the game, set the number of players, names and round
case START_GAME:
- this.numberOfPlayers = chooseNumberOfPlayers();
+ int numberOfPlayers = chooseNumberOfPlayers();
- for(int i=0; i=200) {
- if(!foundWinner) {
+ if (score >= 200) {
+ if (!foundWinner) {
System.out.println("WE HAVE A WINNER!!");
System.out.println();
foundWinner = true;
@@ -110,7 +116,7 @@ public class Bullseye {
}
}
- if(foundWinner) {
+ if (foundWinner) {
System.out.println("THANKS FOR THE GAME.");
gameState = GAME_STATE.GAME_OVER;
} else {
@@ -120,12 +126,11 @@ public class Bullseye {
break;
}
- } while(gameState != GAME_STATE.GAME_OVER);
+ } while (gameState != GAME_STATE.GAME_OVER);
}
/**
* Display info about the game
- *
*/
private void intro() {
System.out.println("BULLSEYE");
@@ -136,7 +141,7 @@ public class Bullseye {
System.out.println("TO GET 200 POINTS.");
System.out.println();
System.out.println(paddedString("THROW", "DESCRIPTION", "PROBABLE SCORE"));
- System.out.println(paddedString("1", "FAST OVERARM","BULLSEYE OR COMPLETE MISS"));
+ System.out.println(paddedString("1", "FAST OVERARM", "BULLSEYE OR COMPLETE MISS"));
System.out.println(paddedString("2", "CONTROLLED OVERARM", "10, 20 OR 30 POINTS"));
System.out.println(paddedString("3", "UNDERARM", "ANYTHING"));
}
@@ -151,16 +156,16 @@ public class Bullseye {
private int calculatePlayerPoints(int playerThrow) {
// -1 is because of 0 base Java array
- double p1 = this.shots[playerThrow-1].getShot(0);
- double p2 = this.shots[playerThrow-1].getShot(1);
- double p3 = this.shots[playerThrow-1].getShot(2);
- double p4 = this.shots[playerThrow-1].getShot(3);
+ double p1 = this.shots[playerThrow - 1].getShot(0);
+ double p2 = this.shots[playerThrow - 1].getShot(1);
+ double p3 = this.shots[playerThrow - 1].getShot(2);
+ double p4 = this.shots[playerThrow - 1].getShot(3);
double random = Math.random();
int points;
- if(random >= p1) {
+ if (random >= p1) {
System.out.println("BULLSEYE!! 40 POINTS!");
points = 40;
// If the throw was 1 (bullseye or missed, then make it missed
@@ -170,13 +175,13 @@ public class Bullseye {
} else if (playerThrow == 1) {
System.out.println("MISSED THE TARGET! TOO BAD.");
points = 0;
- } else if(random >= p2) {
+ } else if (random >= p2) {
System.out.println("30-POINT ZONE!");
points = 30;
- } else if(random >= p3) {
+ } else if (random >= p3) {
System.out.println("20-POINT ZONE");
points = 20;
- } else if(random >= p4) {
+ } else if (random >= p4) {
System.out.println("WHEW! 10 POINTS.");
points = 10;
} else {
@@ -190,23 +195,23 @@ public class Bullseye {
/**
* Get players shot 1,2, or 3 - ask again if invalid input
*
- * @param player
- * @return 1,2, or 3 indicating the players shot
+ * @param player the player we are calculating the throw on
+ * @return 1, 2, or 3 indicating the players shot
*/
private int getPlayersThrow(Player player) {
boolean inputCorrect = false;
String theThrow;
do {
theThrow = displayTextAndGetInput(player.getName() + "'S THROW ");
- if(theThrow.equals("1") || theThrow.equals("2") || theThrow.equals("3")) {
+ if (theThrow.equals("1") || theThrow.equals("2") || theThrow.equals("3")) {
inputCorrect = true;
} else {
System.out.println("INPUT 1, 2, OR 3!");
}
- } while(!inputCorrect);
+ } while (!inputCorrect);
- return Integer.valueOf(theThrow);
+ return Integer.parseInt(theThrow);
}
@@ -217,8 +222,9 @@ public class Bullseye {
*/
private int chooseNumberOfPlayers() {
- return Integer.valueOf((displayTextAndGetInput("HOW MANY PLAYERS? ")));
+ return Integer.parseInt((displayTextAndGetInput("HOW MANY PLAYERS? ")));
}
+
/*
* Print a message on the screen, then accept input from Keyboard.
*
@@ -234,9 +240,9 @@ public class Bullseye {
* Format three strings to a given number of spaces
* Replacing the original basic code which used tabs
*
- * @param first String to print in pos 1
+ * @param first String to print in pos 1
* @param second String to print in pos 2
- * @param third String to print in pos 3
+ * @param third String to print in pos 3
* @return formatted string
*/
private String paddedString(String first, String second, String third) {
diff --git a/18 Bullseye/java/src/Player.java b/18 Bullseye/java/src/Player.java
index b67b9309..1a30935a 100644
--- a/18 Bullseye/java/src/Player.java
+++ b/18 Bullseye/java/src/Player.java
@@ -4,7 +4,8 @@
*/
public class Player {
- private String name;
+ private final String name;
+
private int score;
Player(String name) {
diff --git a/18 Bullseye/java/src/Shot.java b/18 Bullseye/java/src/Shot.java
index 01d8b283..43fa84e4 100644
--- a/18 Bullseye/java/src/Shot.java
+++ b/18 Bullseye/java/src/Shot.java
@@ -10,9 +10,7 @@ public class Shot {
// Array of doubles are passed for a specific type of shot
Shot(double[] shots) {
chances = new double[shots.length];
- for(int i=0; i 128:
+ break
+
+ # If we've reached this portion of the code, 'command' indicates the 'start'
+ # position of a line segment.
+ start = command
+ # Position cursor at start
+ print(tab(start), end="")
+
+ # The following number, indicates the end of the segment.
+ end = next(data)
+ # Unlike FOR I=X TO Y, the 'stop' argument of 'range' is non-inclusive, so we must add 1
+ for i in range(start, end+1, 1):
+ # Cycle through the letters in "BUNNY" as we draw line
+ j = i - 5 * int(i / 5)
+ print(chr(L + bunny[j]), end="")
+
+
+if __name__ == "__main__":
+ play()
diff --git a/20 Buzzword/java/src/Buzzword.java b/20 Buzzword/java/src/Buzzword.java
new file mode 100755
index 00000000..82ed9100
--- /dev/null
+++ b/20 Buzzword/java/src/Buzzword.java
@@ -0,0 +1,41 @@
+import java.util.Scanner;
+import static java.lang.System.out;
+
+// This is very close to the original BASIC. Changes:
+// 1) the array indexing is adjusted by 1
+// 2) the user can enter a lower case "y"
+// 3) moved the word list to the top 8~)
+public class Buzzword {
+ private static final String[] A = {
+ "ABILITY","BASAL","BEHAVIORAL","CHILD-CENTERED",
+ "DIFFERENTIATED","DISCOVERY","FLEXIBLE","HETEROGENEOUS",
+ "HOMOGENEOUS","MANIPULATIVE","MODULAR","TAVISTOCK",
+ "INDIVIDUALIZED","LEARNING","EVALUATIVE","OBJECTIVE",
+ "COGNITIVE","ENRICHMENT","SCHEDULING","HUMANISTIC",
+ "INTEGRATED","NON-GRADED","TRAINING","VERTICAL AGE",
+ "MOTIVATIONAL","CREATIVE","GROUPING","MODIFICATION",
+ "ACCOUNTABILITY","PROCESS","CORE CURRICULUM","ALGORITHM",
+ "PERFORMANCE","REINFORCEMENT","OPEN CLASSROOM","RESOURCE",
+ "STRUCTURE","FACILITY","ENVIRONMENT"
+ };
+ private static Scanner scanner = new Scanner( System.in );
+
+ public static void main( final String [] args ) {
+ out.println( " BUZZWORD GENERATOR" );
+ out.println( " CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" );
+ out.println();out.println();out.println();
+ out.println( "THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN" );
+ out.println( "'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS" );
+ out.println( "AND SPEECHES. WHENEVER A QUESTION MARK IS PRINTED," );
+ out.println( "TYPE A 'Y' FOR ANOTHER PHRASE OR 'N' TO QUIT." );
+ out.println();out.println();out.println( "HERE'S THE FIRST PHRASE:" );
+ do {
+ out.print( A[ (int)( 13 * Math.random() ) ] + " " );
+ out.print( A[ (int)( 13 * Math.random() + 13 ) ] + " " );
+ out.print( A[ (int)( 13 * Math.random() + 26 ) ] ); out.println();
+ out.print( "?" );
+ }
+ while ( "Y".equals( scanner.nextLine().toUpperCase() ) );
+ out.println( "COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!" );
+ }
+}
diff --git a/22 Change/java/src/Change.java b/22 Change/java/src/Change.java
new file mode 100644
index 00000000..38177245
--- /dev/null
+++ b/22 Change/java/src/Change.java
@@ -0,0 +1,187 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of Change
+ *
+ * Based on the Basic game of Change here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/22%20Change/change.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class Change {
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ private enum GAME_STATE {
+ START_GAME,
+ INPUT,
+ CALCULATE,
+ END_GAME,
+ GAME_OVER
+ }
+
+ // Current game state
+ private GAME_STATE gameState;
+
+ // Amount of change needed to be given
+ private double change;
+
+ public Change() {
+ kbScanner = new Scanner(System.in);
+
+ gameState = GAME_STATE.START_GAME;
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+ case START_GAME:
+ intro();
+ gameState = GAME_STATE.INPUT;
+ break;
+
+ case INPUT:
+
+ double costOfItem = displayTextAndGetNumber("COST OF ITEM ");
+ double amountPaid = displayTextAndGetNumber("AMOUNT OF PAYMENT ");
+ change = amountPaid - costOfItem;
+ if (change == 0) {
+ // No change needed
+ System.out.println("CORRECT AMOUNT, THANK YOU.");
+ gameState = GAME_STATE.END_GAME;
+ } else if (change < 0) {
+ System.out.println("YOU HAVE SHORT-CHANGES ME $" + (costOfItem - amountPaid));
+ // Don't change game state so it will loop back and try again
+ } else {
+ // Change needed.
+ gameState = GAME_STATE.CALCULATE;
+ }
+ break;
+
+ case CALCULATE:
+ System.out.println("YOUR CHANGE, $" + change);
+ calculateChange();
+ gameState = GAME_STATE.END_GAME;
+ break;
+
+ case END_GAME:
+ System.out.println("THANK YOU, COME AGAIN");
+ System.out.println();
+ gameState = GAME_STATE.INPUT;
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ /**
+ * Calculate and output the change required for the purchase based on
+ * what money was paid.
+ */
+ private void calculateChange() {
+
+ double originalChange = change;
+
+ int tenDollarBills = (int) change / 10;
+ if (tenDollarBills > 0) {
+ System.out.println(tenDollarBills + " TEN DOLLAR BILL(S)");
+ }
+ change = originalChange - (tenDollarBills * 10);
+
+ int fiveDollarBills = (int) change / 5;
+ if (fiveDollarBills > 0) {
+ System.out.println(fiveDollarBills + " FIVE DOLLAR BILL(S)");
+ }
+ change = originalChange - (tenDollarBills * 10 + fiveDollarBills * 5);
+
+ int oneDollarBills = (int) change;
+ if (oneDollarBills > 0) {
+ System.out.println(oneDollarBills + " ONE DOLLAR BILL(S)");
+ }
+ change = originalChange - (tenDollarBills * 10 + fiveDollarBills * 5 + oneDollarBills);
+
+ change = change * 100;
+ double cents = change;
+
+ int halfDollars = (int) change / 50;
+ if (halfDollars > 0) {
+ System.out.println(halfDollars + " ONE HALF DOLLAR(S)");
+ }
+ change = cents - (halfDollars * 50);
+
+ int quarters = (int) change / 25;
+ if (quarters > 0) {
+ System.out.println(quarters + " QUARTER(S)");
+ }
+
+ change = cents - (halfDollars * 50 + quarters * 25);
+
+ int dimes = (int) change / 10;
+ if (dimes > 0) {
+ System.out.println(dimes + " DIME(S)");
+ }
+
+ change = cents - (halfDollars * 50 + quarters * 25 + dimes * 10);
+
+ int nickels = (int) change / 5;
+ if (nickels > 0) {
+ System.out.println(nickels + " NICKEL(S)");
+ }
+
+ change = cents - (halfDollars * 50 + quarters * 25 + dimes * 10 + nickels * 5);
+
+ int pennies = (int) (change + .5);
+ if (pennies > 0) {
+ System.out.println(pennies + " PENNY(S)");
+ }
+
+ }
+
+ private void intro() {
+ System.out.println(simulateTabs(33) + "CHANGE");
+ System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("I, YOUR FRIENDLY MICROCOMPUTER, WILL DETERMINE");
+ System.out.println("THE CORRECT CHANGE FOR ITEMS COSTING UP TO $100.");
+ System.out.println();
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ * Converts input to a Double
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private double displayTextAndGetNumber(String text) {
+ return Double.parseDouble(displayTextAndGetInput(text));
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Simulate the old basic tab(xx) command which indented text by xx spaces.
+ *
+ * @param spaces number of spaces required
+ * @return String with number of spaces
+ */
+ private String simulateTabs(int spaces) {
+ char[] spacesTemp = new char[spaces];
+ Arrays.fill(spacesTemp, ' ');
+ return new String(spacesTemp);
+ }
+}
diff --git a/22 Change/java/src/ChangeGame.java b/22 Change/java/src/ChangeGame.java
new file mode 100644
index 00000000..c2863914
--- /dev/null
+++ b/22 Change/java/src/ChangeGame.java
@@ -0,0 +1,6 @@
+public class ChangeGame {
+ public static void main(String[] args) {
+ Change change = new Change();
+ change.play();
+ }
+}
diff --git a/24 Chemist/java/src/Chemist.java b/24 Chemist/java/src/Chemist.java
new file mode 100644
index 00000000..137b3ce5
--- /dev/null
+++ b/24 Chemist/java/src/Chemist.java
@@ -0,0 +1,143 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of Chemist
+ *
+ * Based on the Basic game of Chemist here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/24%20Chemist/chemist.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class Chemist {
+
+ public static final int MAX_LIVES = 9;
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ private enum GAME_STATE {
+ START_GAME,
+ INPUT,
+ BLOWN_UP,
+ SURVIVED,
+ GAME_OVER
+ }
+
+ // Current game state
+ private GAME_STATE gameState;
+
+ private int timesBlownUp;
+
+ public Chemist() {
+ kbScanner = new Scanner(System.in);
+
+ gameState = GAME_STATE.START_GAME;
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+
+ case START_GAME:
+ intro();
+ timesBlownUp = 0;
+ gameState = GAME_STATE.INPUT;
+ break;
+
+ case INPUT:
+
+ int amountOfAcid = (int) (Math.random() * 50);
+ int correctAmountOfWater = (7 * amountOfAcid) / 3;
+ int water = displayTextAndGetNumber(amountOfAcid + " LITERS OF KRYPTOCYANIC ACID. HOW MUCH WATER? ");
+
+ // Calculate if the player mixed enough water
+ int result = Math.abs(correctAmountOfWater - water);
+
+ // Ratio of water wrong?
+ if (result > (correctAmountOfWater / 20)) {
+ gameState = GAME_STATE.BLOWN_UP;
+ } else {
+ // Got the ratio correct
+ gameState = GAME_STATE.SURVIVED;
+ }
+ break;
+
+ case BLOWN_UP:
+ System.out.println(" SIZZLE! YOU HAVE JUST BEEN DESALINATED INTO A BLOB");
+ System.out.println(" OF QUIVERING PROTOPLASM!");
+
+ timesBlownUp++;
+
+ if (timesBlownUp < MAX_LIVES) {
+ System.out.println(" HOWEVER, YOU MAY TRY AGAIN WITH ANOTHER LIFE.");
+ gameState = GAME_STATE.INPUT;
+ } else {
+ System.out.println(" YOUR " + MAX_LIVES + " LIVES ARE USED, BUT YOU WILL BE LONG REMEMBERED FOR");
+ System.out.println(" YOUR CONTRIBUTIONS TO THE FIELD OF COMIC BOOK CHEMISTRY.");
+ gameState = GAME_STATE.GAME_OVER;
+ }
+
+ break;
+
+ case SURVIVED:
+ System.out.println(" GOOD JOB! YOU MAY BREATHE NOW, BUT DON'T INHALE THE FUMES!");
+ System.out.println();
+ gameState = GAME_STATE.INPUT;
+ break;
+
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ private void intro() {
+ System.out.println(simulateTabs(33) + "CHEMIST");
+ System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("THE FICTITIOUS CHEMICAL KRYPTOCYANIC ACID CAN ONLY BE");
+ System.out.println("DILUTED BY THE RATIO OF 7 PARTS WATER TO 3 PARTS ACID.");
+ System.out.println("IF ANY OTHER RATIO IS ATTEMPTED, THE ACID BECOMES UNSTABLE");
+ System.out.println("AND SOON EXPLODES. GIVEN THE AMOUNT OF ACID, YOU MUST");
+ System.out.println("DECIDE WHO MUCH WATER TO ADD FOR DILUTION. IF YOU MISS");
+ System.out.println("YOU FACE THE CONSEQUENCES.");
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ * Converts input to an Integer
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private int displayTextAndGetNumber(String text) {
+ return Integer.parseInt(displayTextAndGetInput(text));
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Simulate the old basic tab(xx) command which indented text by xx spaces.
+ *
+ * @param spaces number of spaces required
+ * @return String with number of spaces
+ */
+ private String simulateTabs(int spaces) {
+ char[] spacesTemp = new char[spaces];
+ Arrays.fill(spacesTemp, ' ');
+ return new String(spacesTemp);
+ }
+}
diff --git a/24 Chemist/java/src/ChemistGame.java b/24 Chemist/java/src/ChemistGame.java
new file mode 100644
index 00000000..494959a3
--- /dev/null
+++ b/24 Chemist/java/src/ChemistGame.java
@@ -0,0 +1,6 @@
+public class ChemistGame {
+ public static void main(String[] args) {
+ Chemist chemist = new Chemist();
+ chemist.play();
+ }
+}
diff --git a/25 Chief/java/src/Chief.java b/25 Chief/java/src/Chief.java
index d7fbbc08..1db2eb6c 100644
--- a/25 Chief/java/src/Chief.java
+++ b/25 Chief/java/src/Chief.java
@@ -1,6 +1,15 @@
import java.util.Arrays;
import java.util.Scanner;
+/**
+ * Game of Chief
+ *
+ * Based on the Basic game of Hurkle here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/25%20Chief/chief.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
public class Chief {
private enum GAME_STATE {
@@ -14,6 +23,7 @@ public class Chief {
private GAME_STATE gameState;
+ // The number the computer determines to be the players starting number
private double calculatedNumber;
// Used for keyboard input
@@ -43,7 +53,7 @@ public class Chief {
// show an message to start
case READY_TO_START:
- if(!yesEntered(displayTextAndGetInput("ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR? "))) {
+ if (!yesEntered(displayTextAndGetInput("ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR? "))) {
System.out.println("SHUT UP, PALE FACE WITH WISE TONGUE.");
}
@@ -57,17 +67,17 @@ public class Chief {
displayTextAndGetInput(" WHAT DO YOU HAVE? "));
// Exact same formula used in the original game to calculate the players original number
- this.calculatedNumber = (playerNumber +1-5)*5/8*5-3;
+ calculatedNumber = (playerNumber + 1 - 5) * 5 / 8 * 5 - 3;
- this.gameState = GAME_STATE.CALCULATE_AND_SHOW;
+ gameState = GAME_STATE.CALCULATE_AND_SHOW;
break;
// Enter the number to be used to calculate
case CALCULATE_AND_SHOW:
- if(yesEntered(
- displayTextAndGetInput("I BET YOUR NUMBER WAS " + this.calculatedNumber
- + ". AM I RIGHT? "))) {
- this.gameState = GAME_STATE.END_GAME;
+ if (yesEntered(
+ displayTextAndGetInput("I BET YOUR NUMBER WAS " + calculatedNumber
+ + ". AM I RIGHT? "))) {
+ gameState = GAME_STATE.END_GAME;
} else {
// Player did not agree, so show the breakdown
@@ -76,27 +86,27 @@ public class Chief {
double f = number + 3;
double g = f / 5;
double h = g * 8;
- double i = h/5 + 5;
- double j = i -1;
+ double i = h / 5 + 5;
+ double j = i - 1;
System.out.println("SO YOU THINK YOU'RE SO SMART, EH?");
System.out.println("NOW WATCH.");
- System.out.println(number +" PLUS 3 EQUALS " + f + ". THIS DIVIDED BY 5 EQUALS " + g);
- System.out.println("THIS TIMES 8 EQUALS " + h + ". IF WE DIVIDE BY 5 AND ADD 5,");
+ System.out.println(number + " PLUS 3 EQUALS " + f + ". DIVIDED BY 5 EQUALS " + g);
+ System.out.println("TIMES 8 EQUALS " + h + ". IF WE DIVIDE BY 5 AND ADD 5,");
System.out.println("WE GET " + i + ", WHICH, MINUS 1, EQUALS " + j + ".");
- if(yesEntered(displayTextAndGetInput("NOW DO YOU BELIEVE ME? "))) {
- this.gameState = GAME_STATE.END_GAME;
+ if (yesEntered(displayTextAndGetInput("NOW DO YOU BELIEVE ME? "))) {
+ gameState = GAME_STATE.END_GAME;
} else {
// Time for a lightning bolt.
System.out.println("YOU HAVE MADE ME MAD!!!");
System.out.println("THERE MUST BE A GREAT LIGHTNING BOLT!");
System.out.println();
- for(int x=30; x>=22; x--) {
+ for (int x = 30; x >= 22; x--) {
System.out.println(tabbedSpaces(x) + "X X");
}
System.out.println(tabbedSpaces(21) + "X XXX");
System.out.println(tabbedSpaces(20) + "X X");
System.out.println(tabbedSpaces(19) + "XX X");
- for(int y=20; y>=13; y--) {
+ for (int y = 20; y >= 13; y--) {
System.out.println(tabbedSpaces(y) + "X X");
}
System.out.println(tabbedSpaces(12) + "XX");
@@ -106,7 +116,7 @@ public class Chief {
System.out.println("#########################");
System.out.println();
System.out.println("I HOPE YOU BELIEVE ME NOW, FOR YOUR SAKE!!");
- this.gameState = GAME_STATE.GAME_OVER;
+ gameState = GAME_STATE.GAME_OVER;
}
}
@@ -115,7 +125,7 @@ public class Chief {
// Sign off message for cases where the Chief is not upset
case END_GAME:
System.out.println("BYE!!!");
- this.gameState = GAME_STATE.GAME_OVER;
+ gameState = GAME_STATE.GAME_OVER;
break;
// GAME_OVER State does not specifically have a case
@@ -134,14 +144,14 @@ public class Chief {
Arrays.fill(repeat, ' ');
return new String(repeat);
}
+
private void instructions() {
- System.out.println(" TAKE A NUMBER AND ADD 3. DIVIDE THIS NUMBER BY 5 AND");
+ System.out.println(" TAKE A NUMBER AND ADD 3. DIVIDE NUMBER BY 5 AND");
System.out.println("MULTIPLY BY 8. DIVIDE BY 5 AND ADD THE SAME. SUBTRACT 1.");
}
/**
* Basic information about the game
- *
*/
private void intro() {
System.out.println("CHIEF");
@@ -165,15 +175,15 @@ public class Chief {
* Returns true if a given string contains at least one of the varargs (2nd parameter).
* Note: Case insensitive comparison.
*
- * @param text string to search
+ * @param text string to search
* @param values varargs of type string containing values to compare
* @return true if one of the varargs arguments was found in text
*/
private boolean stringIsAnyValue(String text, String... values) {
// Cycle through the variable number of values and test each
- for(String val:values) {
- if(text.equalsIgnoreCase(val)) {
+ for (String val : values) {
+ if (text.equalsIgnoreCase(val)) {
return true;
}
}
diff --git a/26 Chomp/chomp.bas b/26 Chomp/chomp.bas
index 26d0296b..50e5e232 100644
--- a/26 Chomp/chomp.bas
+++ b/26 Chomp/chomp.bas
@@ -99,6 +99,6 @@
1010 PRINT "YOU LOSE, PLAYER";P1
1020 PRINT
1030 PRINT "AGAIN (1=YES, 0=NO!)";
-1040 INPUT R$
+1040 INPUT R
1050 IF R=1 THEN 340
1060 END
diff --git a/26 Chomp/javascript/chomp.html b/26 Chomp/javascript/chomp.html
new file mode 100644
index 00000000..b749afe3
--- /dev/null
+++ b/26 Chomp/javascript/chomp.html
@@ -0,0 +1,9 @@
+
+
+CHOMP
+
+
+
+
+
+
diff --git a/26 Chomp/javascript/chomp.js b/26 Chomp/javascript/chomp.js
new file mode 100644
index 00000000..652023e6
--- /dev/null
+++ b/26 Chomp/javascript/chomp.js
@@ -0,0 +1,175 @@
+// CHOMP
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+var a = [];
+var r;
+var c;
+
+function init_board()
+{
+ for (i = 1; i <= r; i++)
+ for (j = 1; j <= c; j++)
+ a[i][j] = 1;
+ a[1][1] = -1;
+}
+
+function show_board()
+{
+ print("\n");
+ print(tab(7) + "1 2 3 4 5 6 7 8 9\n");
+ for (i = 1; i <= r; i++) {
+ str = i + tab(6);
+ for (j = 1; j <= c; j++) {
+ if (a[i][j] == -1)
+ str += "P ";
+ else if (a[i][j] == 0)
+ break;
+ else
+ str += "* ";
+ }
+ print(str + "\n");
+ }
+ print("\n");
+}
+
+// Main program
+async function main()
+{
+ print(tab(33) + "CHOMP\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ for (i = 1; i <= 10; i++)
+ a[i] = [];
+ // *** THE GAME OF CHOMP *** COPYRIGHT PCC 1973 ***
+ print("\n");
+ print("THIS IS THE GAME OF CHOMP (SCIENTIFIC AMERICAN, JAN 1973)\n");
+ print("DO YOU WANT THE RULES (1=YES, 0=NO!)");
+ r = parseInt(await input());
+ if (r != 0) {
+ f = 1;
+ r = 5;
+ c = 7;
+ print("CHOMP IS FOR 1 OR MORE PLAYERS (HUMANS ONLY).\n");
+ print("\n");
+ print("HERE'S HOW A BOARD LOOKS (THIS ONE IS 5 BY 7):\n");
+ init_board();
+ show_board();
+ print("\n");
+ print("THE BOARD IS A BIG COOKIE - R ROWS HIGH AND C COLUMNS\n");
+ print("WIDE. YOU INPUT R AND C AT THE START. IN THE UPPER LEFT\n");
+ print("CORNER OF THE COOKIE IS A POISON SQUARE (P). THE ONE WHO\n");
+ print("CHOMPS THE POISON SQUARE LOSES. TO TAKE A CHOMP, TYPE THE\n");
+ print("ROW AND COLUMN OF ONE OF THE SQUARES ON THE COOKIE.\n");
+ print("ALL OF THE SQUARES BELOW AND TO THE RIGHT OF THAT SQUARE\n");
+ print("INCLUDING THAT SQUARE, TOO) DISAPPEAR -- CHOMP!!\n");
+ print("NO FAIR CHOMPING SQUARES THAT HAVE ALREADY BEEN CHOMPED,\n");
+ print("OR THAT ARE OUTSIDE THE ORIGINAL DIMENSIONS OF THE COOKIE.\n");
+ print("\n");
+ }
+ while (1) {
+ print("HERE WE GO...\n");
+ f = 0;
+ for (i = 1; i <= 10; i++) {
+ a[i] = [];
+ for (j = 1; j <= 10; j++) {
+ a[i][j] = 0;
+ }
+ }
+ print("\n");
+ print("HOW MANY PLAYERS");
+ p = parseInt(await input());
+ i1 = 0;
+ while (1) {
+ print("HOW MANY ROWS");
+ r = parseInt(await input());
+ if (r <= 9)
+ break;
+ print("TOO MANY ROWS (9 IS MAXIMUM). NOW ");
+ }
+ while (1) {
+ print("HOW MANY COLUMNS");
+ c = parseInt(await input());
+ if (c <= 9)
+ break;
+ print("TOO MANY COLUMNS (9 IS MAXIMUM). NOW ");
+ }
+ print("\n");
+ init_board();
+ while (1) {
+ // Print the board
+ show_board();
+ // Get chomps for each player in turn
+ i1++;
+ p1 = i1 - Math.floor(i1 / p) * p;
+ if (p1 == 0)
+ p1 = p;
+ while (1) {
+ print("PLAYER " + p1 + "\n");
+ print("COORDINATES OF CHOMP (ROW,COLUMN)");
+ str = await input();
+ r1 = parseInt(str);
+ c1 = parseInt(str.substr(str.indexOf(",") + 1));
+ if (r1 >= 1 && r1 <= r && c1 >= 1 && c1 <= c && a[r1][c1] != 0)
+ break;
+ print("NO FAIR. YOU'RE TRYING TO CHOMP ON EMPTY SPACE!\n");
+ }
+ if (a[r1][c1] == -1)
+ break;
+ for (i = r1; i <= r; i++)
+ for (j = c1; j <= c; j++)
+ a[i][j] = 0;
+ }
+ // End of game detected
+ print("YOU LOSE, PLAYER " + p1 + "\n");
+ print("\n");
+ print("AGAIN (1=YES, 0=NO!)");
+ r = parseInt(await input());
+ if (r != 1)
+ break;
+ }
+}
+
+main();
diff --git a/26 Chomp/python/chomp.py b/26 Chomp/python/chomp.py
new file mode 100755
index 00000000..56190a9e
--- /dev/null
+++ b/26 Chomp/python/chomp.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python3
+# CHOMP
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+
+class Canvas:
+ """ For drawing the cookie """
+
+ def __init__(self, width=9, height=9, fill="*"):
+ self._buffer = []
+ for _ in range(height):
+ line = []
+ for _ in range(width):
+ line.append(fill)
+ self._buffer.append(line)
+ self._buffer[0][0] = "P"
+
+ def render(self):
+ lines = [" 1 2 3 4 5 6 7 8 9"]
+ row = 0
+ for line in self._buffer:
+ row += 1
+ lines.append(" " + str(row) + " " * 5 + " ".join(line))
+ return "\n".join(lines)
+
+ def chomp(self, r, c):
+ if not 1 <= r <= len(self._buffer) or not 1 <= c <= len(self._buffer[0]):
+ return "Empty"
+ elif self._buffer[r - 1][c - 1] == " ":
+ return "Empty"
+ elif self._buffer[r - 1][c - 1] == "P":
+ return "Poison"
+ else:
+ for row in range(r - 1, len(self._buffer)):
+ for column in range(c - 1, len(self._buffer[row])):
+ self._buffer[row][column] = " "
+ return "Chomp"
+
+
+def play_game():
+ """Play one round of the game"""
+ players = 0
+ while players == 0:
+ try:
+ players = int(input("How many players "))
+
+ except ValueError:
+ print("Please enter a number.")
+ rows = 0
+ while rows == 0:
+ try:
+ rows = int(input("How many rows "))
+ if rows > 9 or rows < 1:
+ rows = 0
+ print("Too many rows (9 is maximum).")
+
+ except ValueError:
+ print("Please enter a number.")
+ columns = 0
+ while columns == 0:
+ try:
+ columns = int(input("How many columns "))
+ if columns > 9 or columns < 1:
+ columns = 0
+ print("Too many columns (9 is maximum).")
+
+ except ValueError:
+ print("Please enter a number.")
+ cookie = Canvas(width=columns, height=rows)
+ player = 0
+ alive = True
+ while alive:
+ print("")
+ print(cookie.render())
+ print("")
+ player += 1
+ if player > players:
+ player = 1
+ while True:
+ print("Player", player)
+ player_row = -1
+ player_column = -1
+ while player_row == -1 or player_column == -1:
+ try:
+ coordinates = [int(item) for item in input(
+ "Coordinates of chomp (Row, Column) ").split(",")]
+ player_row = coordinates[0]
+ player_column = coordinates[1]
+
+ except (ValueError, IndexError):
+ print("Please enter valid coordinates.")
+ result = cookie.chomp(player_row, player_column)
+ if result == "Empty":
+ print("No fair. You're trying to chomp on empty space!")
+ elif result == "Poison":
+ print("\nYou lose player", player)
+ alive = False
+ break
+ else:
+ break
+
+
+def main():
+ print(" " * 33 + "CHOMP")
+ print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n")
+ print("THIS IS THE GAME OF CHOMP (SCIENTIFIC AMERICAN, JAN 1973)")
+ if input("Do you want the rules (1=Yes, 0=No!) ") != "0":
+ print("Chomp is for 1 or more players (Humans only).\n")
+ print("Here's how a board looks (This one is 5 by 7):")
+ example = Canvas(width=7, height=5)
+ print(example.render())
+ print("\nThe board is a big cookie - R rows high and C columns")
+ print("wide. You input R and C at the start. In the upper left")
+ print("corner of the cookie is a poison square (P). The one who")
+ print("chomps the poison square loses. To take a chomp, type the")
+ print("row and column of one of the squares on the cookie.")
+ print("All of the squares below and to the right of that square")
+ print("(Including that square, too) disappear -- CHOMP!!")
+ print("No fair chomping squares that have already been chomped,")
+ print("or that are outside the original dimensions of the cookie.\n")
+ print("Here we go...")
+
+ keep_playing = True
+ while keep_playing:
+
+ play_game()
+ keep_playing = input("\nAgain (1=Yes, 0=No!) ") == "1"
+
+
+if __name__ == "__main__":
+ main()
diff --git a/30 Cube/python/cube.py b/30 Cube/python/cube.py
new file mode 100755
index 00000000..8bb540e0
--- /dev/null
+++ b/30 Cube/python/cube.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+# CUBE
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+
+def mine_position():
+ mine = []
+ for _ in range(3):
+ mine.append(random.randint(1, 3))
+ return mine
+
+
+def play_game():
+ """Play one round of the game"""
+
+ money = 500
+ print("\nYou have", money, "dollars.")
+ while True:
+ mines = []
+ for _ in range(5):
+ mine = []
+ while True:
+ mine = mine_position()
+ if not(mine in mines or mine == [1, 1, 1] or mine == [3, 3, 3]):
+ break
+ mines.append(mine)
+ wager = -1
+ while wager == -1:
+ try:
+ wager = int(input("\nHow much do you want to wager? "))
+ if not 0 <= wager <= money:
+ wager = -1
+ print("Tried to fool me; bet again")
+ except ValueError:
+ print("Please enter a number.")
+ prompt = "\nIt's your move: "
+ position = [1, 1, 1]
+ while True:
+ move = [-1, -1, -1]
+ while move == [-1, -1, -1]:
+ try:
+ coordinates = [int(item)
+ for item in input(prompt).split(",")]
+ if len(coordinates) == 3:
+ move = coordinates
+ else:
+ raise ValueError
+ except (ValueError, IndexError):
+ print("Please enter valid coordinates.")
+ if (abs(move[0]-position[0]) + abs(move[1]-position[1]) + abs(move[2]-position[2])) > 1:
+ print("\nIllegal move. You lose")
+ money = money - wager
+ break
+ elif not move[0] in [1, 2, 3] or not move[1] in [1, 2, 3] or not move[2] in [1, 2, 3]:
+ print("\nIllegal move. You lose")
+ money = money - wager
+ break
+ elif move == [3, 3, 3]:
+ print("\nCongratulations!")
+ money = money + wager
+ break
+ elif move in mines:
+ print("\n******BANG******")
+ print("You lose!")
+ money = money - wager
+ break
+ else:
+ position = move
+ prompt = "\nNext move: "
+ if money > 0:
+ print("\nYou now have", money, "dollars.")
+ if not input("Do you want to try again ").lower().startswith("y"):
+ break
+ else:
+ print("\nYou bust.")
+ print("\nTough luck")
+ print("\nGoodbye.")
+
+
+def main():
+ print(" " * 34 + "CUBE")
+ print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n")
+ if input("Do you want to see the instructions ").lower().startswith("y"):
+ print("\nThis is a game in which you will be playing against the")
+ print("random decisions of the computer. The field of play is a")
+ print("cube of side 3. Any of the 27 locations can be designated")
+ print("by inputing three numbers such as 2,3,1. At the start,")
+ print("you are automatically at location 1,1,1. The object of")
+ print("the game is to get to location 3,3,3. One minor detail:")
+ print("the computer will pick, at random, 5 locations at which")
+ print("it will plant land mines. If you hit one of these locations")
+ print("you lose. One other detail: You may move only one space")
+ print("in one direction each move. For example: From 1,1,2 you")
+ print("may move to 2,1,2 or 1,1,3. You may not change")
+ print("two of the numbers on the same move. If you make an illegal")
+ print("move, you lose and the computer takes the money you may")
+ print("have bet on that round.\n")
+ print("When stating the amount of a wager, print only the number")
+ print("of dollars (example: 250) you are automatically started with")
+ print("500 dollars in your account.\n")
+ print("Good luck!")
+
+ keep_playing = True
+ while keep_playing:
+ play_game()
+ keep_playing = input(
+ "\nPlay again? (yes or no) ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/31 Depth Charge/javascript/depthcharge.html b/31 Depth Charge/javascript/depthcharge.html
new file mode 100644
index 00000000..7a1e3add
--- /dev/null
+++ b/31 Depth Charge/javascript/depthcharge.html
@@ -0,0 +1,9 @@
+
+
+DEPTH CHARGE
+
+
+
+
+
+
diff --git a/31 Depth Charge/javascript/depthcharge.js b/31 Depth Charge/javascript/depthcharge.js
new file mode 100644
index 00000000..6b0a7813
--- /dev/null
+++ b/31 Depth Charge/javascript/depthcharge.js
@@ -0,0 +1,112 @@
+// DEPTH CHARGE
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+// Main program
+async function main()
+{
+ print(tab(30) + "DEPTH CHARGE\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("DIMENSION OF THE SEARCH AREA");
+ g = Math.floor(await input());
+ n = Math.floor(Math.log(g) / Math.log(2)) + 1;
+ print("YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER\n");
+ print("AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE. YOUR\n");
+ print("MISSION IS TO DESTROY IT. YOU HAVE " + n + " SHOTS.\n");
+ print("SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A\n");
+ print("TRIO OF NUMBERS -- THE FIRST TWO ARE THE\n");
+ print("SURFACE COORDINATES; THE THIRD IS THE DEPTH.\n");
+ do {
+ print("\n");
+ print("GOOD LUCK !\n");
+ print("\n");
+ a = Math.floor(Math.random() * g);
+ b = Math.floor(Math.random() * g);
+ c = Math.floor(Math.random() * g);
+ for (d = 1; d <= n; d++) {
+ print("\n");
+ print("TRIAL #" + d + " ");
+ str = await input();
+ x = parseInt(str);
+ y = parseInt(str.substr(str.indexOf(",") + 1));
+ z = parseInt(str.substr(str.lastIndexOf(",") + 1));
+ if (Math.abs(x - a) + Math.abs(y - b) + Math.abs(z - c) == 0)
+ break;
+ if (y > b)
+ print("NORTH");
+ if (y < b)
+ print("SOUTH");
+ if (x > a)
+ print("EAST");
+ if (x < a)
+ print("WEST");
+ if (y != b || x != a)
+ print(" AND");
+ if (z > c)
+ print(" TOO LOW.\n");
+ if (z < c)
+ print(" TOO HIGH.\n");
+ if (z == c)
+ print(" DEPTH OK.\n");
+ print("\n");
+ }
+ if (d <= n) {
+ print("\n");
+ print("B O O M ! ! YOU FOUND IT IN " + d + " TRIES!\n");
+ } else {
+ print("\n");
+ print("YOU HAVE BEEN TORPEDOED! ABANDON SHIP!\n");
+ print("THE SUBMARINE WAS AT " + a + "," + b + "," + c + "\n");
+ }
+ print("\n");
+ print("\n");
+ print("ANOTHER GAME (Y OR N)");
+ str = await input();
+ } while (str.substr(0, 1) == "Y") ;
+ print("OK. HOPE YOU ENJOYED YOURSELF.\n");
+}
+
+main();
diff --git a/32 Diamond/javascript/diamond.html b/32 Diamond/javascript/diamond.html
new file mode 100644
index 00000000..9756b2ab
--- /dev/null
+++ b/32 Diamond/javascript/diamond.html
@@ -0,0 +1,9 @@
+
+
+DIAMOND
+
+
+
+
+
+
diff --git a/32 Diamond/javascript/diamond.js b/32 Diamond/javascript/diamond.js
new file mode 100644
index 00000000..bb6f0fe9
--- /dev/null
+++ b/32 Diamond/javascript/diamond.js
@@ -0,0 +1,94 @@
+// DIAMOND
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+// Main program
+async function main()
+{
+ print(tab(33) + "DIAMOND\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("FOR A PRETTY DIAMOND PATTERN,\n");
+ print("TYPE IN AN ODD NUMBER BETWEEN 5 AND 21");
+ r = parseInt(await input());
+ q = Math.floor(60 / r);
+ as = "CC"
+ x = 1;
+ y = r;
+ z = 2;
+ for (l = 1; l <= q; l++) {
+ for (n = x; z < 0 ? n >= y : n <= y; n += z) {
+ str = "";
+ while (str.length < (r - n) / 2)
+ str += " ";
+ for (m = 1; m <= q; m++) {
+ c = 1;
+ for (a = 1; a <= n; a++) {
+ if (c > as.length)
+ str += "!";
+ else
+ str += as[c++ - 1];
+ }
+ if (m == q)
+ break;
+ while (str.length < r * m + (r - n) / 2)
+ str += " ";
+ }
+ print(str + "\n");
+ }
+ if (x != 1) {
+ x = 1;
+ y = r;
+ z = 2;
+ } else {
+ x = r - 2;
+ y = 1;
+ z = -2;
+ l--;
+ }
+ }
+}
+
+main();
diff --git a/32 Diamond/ruby/diamond.rb b/32 Diamond/ruby/diamond.rb
new file mode 100644
index 00000000..251cee25
--- /dev/null
+++ b/32 Diamond/ruby/diamond.rb
@@ -0,0 +1,45 @@
+def intro
+ print " DIAMOND
+ CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
+
+
+
+FOR A PRETTY DIAMOND PATTERN,
+TYPE IN AN ODD NUMBER BETWEEN 5 AND 21? "
+end
+
+def get_facets
+ while true
+ number = gets.chomp
+ return number.to_i if /^\d+$/.match(number)
+ puts "!NUMBER EXPECTED - RETRY INPUT LINE"
+ print "? "
+ end
+end
+
+def get_diamond_lines(facets)
+ spacers = (facets - 1) / 2
+ lines = [' ' * spacers + 'C' + ' ' * spacers]
+ lines += (1...facets).step(2).to_a.map { |v|
+ spacers -= 1
+ ' ' * spacers + 'CC' + '!' * v + ' ' * spacers
+ }
+ lines + lines[0..-2].reverse
+end
+
+def draw_diamonds(lines)
+ repeat = 60 / lines[0].length
+ (0...repeat).each { lines.map { |l| l * repeat }.each { |l| puts l } }
+end
+
+def main
+ intro
+ facets = get_facets
+ puts
+ lines = get_diamond_lines(facets)
+ draw_diamonds(lines)
+end
+
+trap "SIGINT" do puts; exit 130 end
+
+main
\ No newline at end of file
diff --git a/33 Dice/java/src/Dice.java b/33 Dice/java/src/Dice.java
new file mode 100644
index 00000000..739b2084
--- /dev/null
+++ b/33 Dice/java/src/Dice.java
@@ -0,0 +1,146 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of Dice
+ *
+ * Based on the Basic game of Dice here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/33%20Dice/dice.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class Dice {
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ private enum GAME_STATE {
+ START_GAME,
+ INPUT_AND_CALCULATE,
+ RESULTS,
+ GAME_OVER
+ }
+
+ // Current game state
+ private GAME_STATE gameState;
+
+ private int[] spots;
+
+ public Dice() {
+ kbScanner = new Scanner(System.in);
+
+ gameState = GAME_STATE.START_GAME;
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+
+ case START_GAME:
+ intro();
+ spots = new int[12];
+ gameState = GAME_STATE.INPUT_AND_CALCULATE;
+ break;
+
+ case INPUT_AND_CALCULATE:
+
+ int howManyRolls = displayTextAndGetNumber("HOW MANY ROLLS? ");
+ for (int i = 0; i < howManyRolls; i++) {
+ int diceRoll = (int) (Math.random() * 6 + 1) + (int) (Math.random() * 6 + 1);
+ // save dice roll in zero based array
+ spots[diceRoll - 1]++;
+ }
+ gameState = GAME_STATE.RESULTS;
+ break;
+
+ case RESULTS:
+ System.out.println("TOTAL SPOTS" + simulateTabs(8) + "NUMBER OF TIMES");
+ for (int i = 1; i < 12; i++) {
+ // show output using zero based array
+ System.out.println(simulateTabs(5) + (i + 1) + simulateTabs(20) + spots[i]);
+ }
+ System.out.println();
+ if (yesEntered(displayTextAndGetInput("TRY AGAIN? "))) {
+ gameState = GAME_STATE.START_GAME;
+ } else {
+ gameState = GAME_STATE.GAME_OVER;
+ }
+ break;
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ private void intro() {
+ System.out.println(simulateTabs(34) + "DICE");
+ System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("THIS PROGRAM SIMULATES THE ROLLING OF A");
+ System.out.println("PAIR OF DICE.");
+ System.out.println("YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO");
+ System.out.println("'ROLL' THE DICE. WATCH OUT, VERY LARGE NUMBERS TAKE");
+ System.out.println("A LONG TIME. IN PARTICULAR, NUMBERS OVER 5000.");
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ * Converts input to an Integer
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private int displayTextAndGetNumber(String text) {
+ return Integer.parseInt(displayTextAndGetInput(text));
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Checks whether player entered Y or YES to a question.
+ *
+ * @param text player string from kb
+ * @return true of Y or YES was entered, otherwise false
+ */
+ private boolean yesEntered(String text) {
+ return stringIsAnyValue(text, "Y", "YES");
+ }
+
+ /**
+ * Check whether a string equals one of a variable number of values
+ * Useful to check for Y or YES for example
+ * Comparison is case insensitive.
+ *
+ * @param text source string
+ * @param values a range of values to compare against the source string
+ * @return true if a comparison was found in one of the variable number of strings passed
+ */
+ private boolean stringIsAnyValue(String text, String... values) {
+
+ return Arrays.stream(values).anyMatch(str -> str.equalsIgnoreCase(text));
+ }
+
+ /**
+ * Simulate the old basic tab(xx) command which indented text by xx spaces.
+ *
+ * @param spaces number of spaces required
+ * @return String with number of spaces
+ */
+ private String simulateTabs(int spaces) {
+ char[] spacesTemp = new char[spaces];
+ Arrays.fill(spacesTemp, ' ');
+ return new String(spacesTemp);
+ }
+}
diff --git a/33 Dice/java/src/DiceGame.java b/33 Dice/java/src/DiceGame.java
new file mode 100644
index 00000000..97f24e61
--- /dev/null
+++ b/33 Dice/java/src/DiceGame.java
@@ -0,0 +1,6 @@
+public class DiceGame {
+ public static void main(String[] args) {
+ Dice dice = new Dice();
+ dice.play();
+ }
+}
diff --git a/33 Dice/javascript/dice.html b/33 Dice/javascript/dice.html
new file mode 100644
index 00000000..420dbc5d
--- /dev/null
+++ b/33 Dice/javascript/dice.html
@@ -0,0 +1,9 @@
+
+
+DICE
+
+
+
+
+
+
diff --git a/33 Dice/javascript/dice.js b/33 Dice/javascript/dice.js
new file mode 100644
index 00000000..e33e538a
--- /dev/null
+++ b/33 Dice/javascript/dice.js
@@ -0,0 +1,84 @@
+// DICE
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+// Main program
+async function main()
+{
+ print(tab(34) + "DICE\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ f = [];
+ // Danny Freidus
+ print("THIS PROGRAM SIMULATES THE ROLLING OF A\n");
+ print("PAIR OF DICE.\n");
+ print("YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO\n");
+ print("'ROLL' THE DICE. WATCH OUT, VERY LARGE NUMBERS TAKE\n");
+ print("A LONG TIME. IN PARTICULAR, NUMBERS OVER 5000.\n");
+ do {
+ for (q = 1; q <= 12; q++)
+ f[q] = 0;
+ print("\n");
+ print("HOW MANY ROLLS");
+ x = parseInt(await input());
+ for (s = 1; s <= x; s++) {
+ a = Math.floor(Math.random() * 6 + 1);
+ b = Math.floor(Math.random() * 6 + 1);
+ r = a + b;
+ f[r]++;
+ }
+ print("\n");
+ print("TOTAL SPOTS\tNUMBER OF TIMES\n");
+ for (v = 2; v <= 12; v++) {
+ print("\t" + v + "\t" + f[v] + "\n");
+ }
+ print("\n");
+ print("\n");
+ print("TRY AGAIN");
+ str = await input();
+ } while (str.substr(0, 1) == "Y") ;
+}
+
+main();
diff --git a/33 Dice/ruby/dice.rb b/33 Dice/ruby/dice.rb
new file mode 100644
index 00000000..58380928
--- /dev/null
+++ b/33 Dice/ruby/dice.rb
@@ -0,0 +1,51 @@
+def intro
+ puts " DICE
+ CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
+
+
+
+THIS PROGRAM SIMULATES THE ROLLING OF A
+PAIR OF DICE.
+YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO
+'ROLL' THE DICE. WATCH OUT, VERY LARGE NUMBERS TAKE
+A LONG TIME. IN PARTICULAR, NUMBERS OVER 5000.
+
+"
+end
+
+def get_rolls
+ while true
+ number = gets.chomp
+ return number.to_i if /^\d+$/.match(number)
+ puts "!NUMBER EXPECTED - RETRY INPUT LINE"
+ print "? "
+ end
+end
+
+def dice_roll = rand(6) + 1 # ruby 3, woot!
+
+def print_rolls(rolls)
+ values = Array.new(11, 0)
+ (1..rolls).each { values[dice_roll + dice_roll - 2] += 1 }
+ puts "\nTOTAL SPOTS NUMBER OF TIMES"
+ (0..10).each { |k| puts " %-2d %-2d" % [k + 2, values[k]] }
+end
+
+def main
+ intro
+ loop do
+ print "HOW MANY ROLLS? "
+ rolls = get_rolls
+
+ print_rolls(rolls)
+
+ print "\n\nTRY AGAIN? "
+ option = (gets || '').chomp.upcase
+ break unless option == 'YES'
+ puts
+ end
+end
+
+trap "SIGINT" do puts; exit 130 end
+
+main
\ No newline at end of file
diff --git a/38 Fur Trader/csharp/FurTrader.csproj b/38 Fur Trader/csharp/FurTrader.csproj
new file mode 100644
index 00000000..c73e0d16
--- /dev/null
+++ b/38 Fur Trader/csharp/FurTrader.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
diff --git a/38 Fur Trader/csharp/FurTrader.sln b/38 Fur Trader/csharp/FurTrader.sln
new file mode 100644
index 00000000..54a1760c
--- /dev/null
+++ b/38 Fur Trader/csharp/FurTrader.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30804.86
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FurTrader", "FurTrader.csproj", "{1FB826B9-8794-4DB7-B676-B51F177B7B87}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1FB826B9-8794-4DB7-B676-B51F177B7B87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1FB826B9-8794-4DB7-B676-B51F177B7B87}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1FB826B9-8794-4DB7-B676-B51F177B7B87}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1FB826B9-8794-4DB7-B676-B51F177B7B87}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {DDB24448-50EB-47C6-BDB9-465896A81779}
+ EndGlobalSection
+EndGlobal
diff --git a/38 Fur Trader/csharp/Game.cs b/38 Fur Trader/csharp/Game.cs
new file mode 100644
index 00000000..fc1aae25
--- /dev/null
+++ b/38 Fur Trader/csharp/Game.cs
@@ -0,0 +1,506 @@
+using System;
+
+namespace FurTrader
+{
+ public class Game
+ {
+ ///
+ /// random number generator; no seed to be faithful to original implementation
+ ///
+ private Random Rnd { get; } = new Random();
+
+ ///
+ /// Generate a price for pelts based off a factor and baseline value
+ ///
+ /// Multiplier for the price
+ /// The baseline price
+ /// A randomised price for pelts
+ internal double RandomPriceGenerator(double factor, double baseline)
+ {
+ var price = (Convert.ToInt32((factor * Rnd.NextDouble() + baseline) * 100d) + 5) / 100d;
+ return price;
+ }
+
+ ///
+ /// Main game loop function. This will play the game endlessly until the player chooses to quit or a GameOver event occurs
+ ///
+ ///
+ /// General structure followed from Adam Dawes (@AdamDawes575) implementation of Acey Ducey.");
+ ///
+ internal void GameLoop()
+ {
+ // display instructions to the player
+ DisplayIntroText();
+
+ var state = new GameState();
+
+ // loop for each turn until the player decides not to continue (or has a Game Over event)
+ while ((!state.GameOver) && ContinueGame())
+ {
+ // clear display at start of each turn
+ Console.Clear();
+
+ // play the next turn; pass game state for details and updates from the turn
+ PlayTurn(state);
+ }
+
+ // end screen; show some statistics to the player
+ Console.Clear();
+ Console.WriteLine("Thanks for playing!");
+ Console.WriteLine("");
+ Console.WriteLine($"Total Expeditions: {state.ExpeditionCount}");
+ Console.WriteLine($"Final Amount: {state.Savings.ToString("c")}");
+ }
+
+ ///
+ /// Display instructions on how to play the game and wait for the player to press a key.
+ ///
+ private void DisplayIntroText()
+ {
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine("Fur Trader.");
+ Console.WriteLine("Creating Computing, Morristown, New Jersey.");
+ Console.WriteLine("");
+
+ Console.ForegroundColor = ConsoleColor.DarkGreen;
+ Console.WriteLine("Originally published in 1978 in the book 'Basic Computer Games' by David Ahl.");
+ Console.WriteLine("");
+
+ Console.ForegroundColor = ConsoleColor.Gray;
+ Console.WriteLine("You are the leader of a French fur trading expedition in 1776 leaving the Lake Ontario area to sell furs and get supplies for the next year.");
+ Console.WriteLine("");
+ Console.WriteLine("You have a choice of three forts at which you may trade. The cost of supplies and the amount you receive for your furs will depend on the fort that you choose.");
+ Console.WriteLine("");
+
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine("Press any key start the game.");
+ Console.ReadKey(true);
+
+ }
+
+ ///
+ /// Prompt the player to try again, and wait for them to press Y or N.
+ ///
+ /// Returns true if the player wants to try again, false if they have finished playing.
+ private bool ContinueGame()
+ {
+ Console.WriteLine("");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("Do you wish to trade furs? ");
+ Console.Write("Answer (Y)es or (N)o ");
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.Write("> ");
+
+ char pressedKey;
+ // Keep looping until we get a recognised input
+ do
+ {
+ // Read a key, don't display it on screen
+ ConsoleKeyInfo key = Console.ReadKey(true);
+ // Convert to upper-case so we don't need to care about capitalisation
+ pressedKey = Char.ToUpper(key.KeyChar);
+ // Is this a key we recognise? If not, keep looping
+ } while (pressedKey != 'Y' && pressedKey != 'N');
+
+ // Display the result on the screen
+ Console.WriteLine(pressedKey);
+
+ // Return true if the player pressed 'Y', false for anything else.
+ return (pressedKey == 'Y');
+ }
+
+ ///
+ /// Play a turn
+ ///
+ /// The current game state
+ private void PlayTurn(GameState state)
+ {
+ state.UnasignedFurCount = 190; /// start with 190 furs each turn
+
+ // provide current status to user
+ Console.WriteLine(new string('_', 70));
+ Console.WriteLine("");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("");
+ Console.WriteLine($"You have {state.Savings.ToString("c")} savings and {state.UnasignedFurCount} furs to begin the expedition.");
+ Console.WriteLine("");
+ Console.WriteLine($"Your {state.UnasignedFurCount} furs are distributed among the following kinds of pelts: Mink, Beaver, Ermine, and Fox");
+ Console.WriteLine("");
+
+ // get input on number of pelts
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write("How many Mink pelts do you have? ");
+ state.MinkPelts = GetPelts(state.UnasignedFurCount);
+ state.UnasignedFurCount -= state.MinkPelts;
+ Console.WriteLine("");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");
+ Console.Write("How many Beaver pelts do you have? ");
+ state.BeaverPelts = GetPelts(state.UnasignedFurCount);
+ state.UnasignedFurCount -= state.BeaverPelts;
+ Console.WriteLine("");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");
+ Console.Write("How many Ermine pelts do you have? ");
+ state.ErminePelts = GetPelts(state.UnasignedFurCount);
+ state.UnasignedFurCount -= state.ErminePelts;
+ Console.WriteLine("");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");
+ Console.Write("How many Fox pelts do you have? ");
+ state.FoxPelts = GetPelts(state.UnasignedFurCount);
+ state.UnasignedFurCount -= state.FoxPelts;
+
+ // get input on which fort to trade with; user gets an opportunity to evaluate and re-select fort after selection until user confirms selection
+ do
+ {
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("");
+ Console.WriteLine("Do you want to trade your furs at Fort 1, Fort 2, or Fort 3");
+ Console.WriteLine("Fort 1 is Fort Hochelaga (Montreal) and is under the protection of the French army.");
+ Console.WriteLine("Fort 2 is Fort Stadacona (Quebec) and is under the protection of the French army. However, you must make a portage and cross the Lachine rapids.");
+ Console.WriteLine("Fort 3 is Fort New York and is under Dutch control. You must cross through Iroquois land.");
+ Console.WriteLine("");
+ state.SelectedFort = GetSelectedFort();
+
+ DisplaySelectedFortInformation(state.SelectedFort);
+
+ } while (TradeAtAnotherFort());
+
+ // process the travel to the fort
+ ProcessExpeditionOutcome(state);
+
+ // display results of expedition (savings change) to the user
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write("You now have ");
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.Write($"{state.Savings.ToString("c")}");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine(" including your previous savings.");
+
+ // update the turn count now that another turn has been played
+ state.ExpeditionCount += 1;
+ }
+
+ ///
+ /// Method to show the expedition costs to the player with some standard formatting
+ ///
+ /// The name of the fort traded with
+ /// The cost of the supplies at the fort
+ /// The travel expenses for the expedition
+ internal void DisplayCosts(string fortname, double supplies, double expenses)
+ {
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write($"Supplies at {fortname} cost".PadLeft(55));
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine($"{supplies.ToString("c").PadLeft(10)}");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write($"Your travel expenses to {fortname} were".PadLeft(55));
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine($"{expenses.ToString("c").PadLeft(10)}");
+ Console.ForegroundColor = ConsoleColor.White;
+ }
+
+ ///
+ /// Process the results of the expedition
+ ///
+ /// the game state
+ private void ProcessExpeditionOutcome(GameState state)
+ {
+ var beaverPrice = RandomPriceGenerator(0.25d, 1.00d);
+ var foxPrice = RandomPriceGenerator(0.2d , 0.80d);
+ var erminePrice = RandomPriceGenerator(0.15d, 0.95d);
+ var minkPrice = RandomPriceGenerator(0.2d , 0.70d);
+
+ var fortname = String.Empty;
+ var suppliesCost = 0.0d;
+ var travelExpenses = 0.0d;
+
+ // create a random value 1 to 10 for the different outcomes at each fort
+ var p = ((int)(10 * Rnd.NextDouble())) + 1;
+ Console.WriteLine("");
+
+ switch (state.SelectedFort)
+ {
+ case 1: // outcome for expedition to Fort Hochelaga
+ beaverPrice = RandomPriceGenerator(0.2d, 0.75d);
+ foxPrice = RandomPriceGenerator(0.2d, 0.80d);
+ erminePrice = RandomPriceGenerator(0.2d, 0.65d);
+ minkPrice = RandomPriceGenerator(0.2d, 0.70d);
+ fortname = "Fort Hochelaga";
+ suppliesCost = 150.0d;
+ travelExpenses = 10.0d;
+ break;
+ case 2: // outcome for expedition to Fort Stadacona
+ beaverPrice = RandomPriceGenerator(0.2d , 0.90d);
+ foxPrice = RandomPriceGenerator(0.2d , 0.80d);
+ erminePrice = RandomPriceGenerator(0.15d, 0.80d);
+ minkPrice = RandomPriceGenerator(0.3d , 0.85d);
+ fortname = "Fort Stadacona";
+ suppliesCost = 125.0d;
+ travelExpenses = 15.0d;
+ if (p <= 2)
+ {
+ state.BeaverPelts = 0;
+ Console.WriteLine("Your beaver were to heavy to carry across the portage.");
+ Console.WriteLine("You had to leave the pelts but found them stolen when you returned");
+ }
+ else if (p <= 6)
+ {
+ Console.WriteLine("You arrived safely at Fort Stadacona");
+ }
+ else if (p <= 8)
+ {
+ state.BeaverPelts = 0;
+ state.FoxPelts = 0;
+ state.ErminePelts = 0;
+ state.MinkPelts = 0;
+ Console.WriteLine("Your canoe upset in the Lachine Rapids.");
+ Console.WriteLine("Your lost all your furs");
+ }
+ else if (p <= 10)
+ {
+ state.FoxPelts = 0;
+ Console.WriteLine("Your fox pelts were not cured properly.");
+ Console.WriteLine("No one will buy them.");
+ }
+ else
+ {
+ throw new Exception($"Unexpected Outcome p = {p}");
+ }
+ break;
+ case 3: // outcome for expedition to Fort New York
+ beaverPrice = RandomPriceGenerator(0.2d , 1.00d);
+ foxPrice = RandomPriceGenerator(0.25d, 1.10d);
+ erminePrice = RandomPriceGenerator(0.2d , 0.95d);
+ minkPrice = RandomPriceGenerator(0.15d, 1.05d);
+ fortname = "Fort New York";
+ suppliesCost = 80.0d;
+ travelExpenses = 25.0d;
+ if (p <= 2)
+ {
+ state.BeaverPelts = 0;
+ state.FoxPelts = 0;
+ state.ErminePelts = 0;
+ state.MinkPelts = 0;
+ suppliesCost = 0.0d;
+ travelExpenses = 0.0d;
+ Console.WriteLine("You were attacked by a party of Iroquois.");
+ Console.WriteLine("All people in your trading group were killed.");
+ Console.WriteLine("This ends the game (press any key).");
+ Console.ReadKey(true);
+ state.GameOver = true;
+ }
+ else if (p <= 6)
+ {
+ Console.WriteLine("You were lucky. You arrived safely at Fort New York.");
+ }
+ else if (p <= 8)
+ {
+ state.BeaverPelts = 0;
+ state.FoxPelts = 0;
+ state.ErminePelts = 0;
+ state.MinkPelts = 0;
+ Console.WriteLine("You narrowly escaped an Iroquois raiding party.");
+ Console.WriteLine("However, you had to leave all your furs behind.");
+ }
+ else if (p <= 10)
+ {
+ beaverPrice = beaverPrice / 2;
+ minkPrice = minkPrice / 2;
+ Console.WriteLine("Your mink and beaver were damaged on your trip.");
+ Console.WriteLine("You receive only half the current price for these furs.");
+ }
+ else
+ {
+ throw new Exception($"Unexpected Outcome p = {p}");
+ }
+ break;
+ default:
+ break;
+ }
+
+ var beaverSale = state.BeaverPelts * beaverPrice;
+ var foxSale = state.FoxPelts * foxPrice;
+ var ermineSale = state.ErminePelts * erminePrice;
+ var minkSale = state.MinkPelts * minkPrice;
+ var profit = beaverSale + foxSale + ermineSale + minkSale - suppliesCost - travelExpenses;
+ state.Savings += profit;
+
+ Console.WriteLine("");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write($"Your {state.BeaverPelts.ToString().PadLeft(3, ' ')} beaver pelts sold @ {beaverPrice.ToString("c")} per pelt for a total");
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine($"{beaverSale.ToString("c").PadLeft(10)}");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write($"Your {state.FoxPelts.ToString().PadLeft(3, ' ')} fox pelts sold @ {foxPrice.ToString("c")} per pelt for a total");
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine($"{foxSale.ToString("c").PadLeft(10)}");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write($"Your {state.ErminePelts.ToString().PadLeft(3, ' ')} ermine pelts sold @ {erminePrice.ToString("c")} per pelt for a total");
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine($"{ermineSale.ToString("c").PadLeft(10)}");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write($"Your {state.MinkPelts.ToString().PadLeft(3, ' ')} mink pelts sold @ {minkPrice.ToString("c")} per pelt for a total");
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine($"{minkSale.ToString("c").PadLeft(10)}");
+ Console.WriteLine("");
+ DisplayCosts(fortname, suppliesCost, travelExpenses);
+ Console.WriteLine("");
+ Console.Write($"Profit / Loss".PadLeft(55));
+ Console.ForegroundColor = profit >= 0.0d ? ConsoleColor.Green : ConsoleColor.Red;
+ Console.WriteLine($"{profit.ToString("c").PadLeft(10)}");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("");
+ }
+
+ private void DisplaySelectedFortInformation(int selectedFort)
+ {
+ Console.WriteLine("");
+ Console.ForegroundColor = ConsoleColor.White;
+
+ switch (selectedFort)
+ {
+ case 1: // selected fort details for Fort Hochelaga
+ Console.WriteLine("You have chosen the easiest route.");
+ Console.WriteLine("However, the fort is far from any seaport.");
+ Console.WriteLine("The value you receive for your furs will be low.");
+ Console.WriteLine("The cost of supplies will be higher than at Forts Stadacona or New York");
+ break;
+ case 2: // selected fort details for Fort Stadacona
+ Console.WriteLine("You have chosen a hard route.");
+ Console.WriteLine("It is, in comparsion, harder than the route to Hochelaga but easier than the route to New York.");
+ Console.WriteLine("You will receive an average value for your furs.");
+ Console.WriteLine("The cost of your supplies will be average.");
+ break;
+ case 3: // selected fort details for Fort New York
+ Console.WriteLine("You have chosen the most difficult route.");
+ Console.WriteLine("At Fort New York you will receive the higest value for your furs.");
+ Console.WriteLine("The cost of your supplies will be lower than at all the other forts.");
+ break;
+ default:
+ break;
+ }
+ }
+
+ private bool TradeAtAnotherFort()
+ {
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("");
+ Console.WriteLine("Do you want to trade at another fort?");
+ Console.Write("Answer (Y)es or (N)o ");
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.Write("> ");
+
+ char pressedKey;
+ // Keep looping until we get a recognised input
+ do
+ {
+ // Read a key, don't display it on screen
+ ConsoleKeyInfo key = Console.ReadKey(true);
+ // Convert to upper-case so we don't need to care about capitalisation
+ pressedKey = Char.ToUpper(key.KeyChar);
+ // Is this a key we recognise? If not, keep looping
+ } while (pressedKey != 'Y' && pressedKey != 'N');
+
+ // Display the result on the screen
+ Console.WriteLine(pressedKey);
+
+ // Return true if the player pressed 'Y', false for anything else.
+ return (pressedKey == 'Y');
+ }
+
+ ///
+ /// Get an amount of pelts from the user
+ ///
+ /// The total pelts available
+ /// Returns the amount the player selects
+ private int GetPelts(int furCount)
+ {
+ int peltCount;
+
+ // loop until the user enters a valid value
+ do
+ {
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.Write("> ");
+ string input = Console.ReadLine();
+
+ // parse user information to check if it is a valid entry
+ if (!int.TryParse(input, out peltCount))
+ {
+ // invalid entry; message back to user
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine("Sorry, I didn't understand. Please enter the number of pelts.");
+
+ // continue looping
+ continue;
+ }
+
+ // check if plet amount is more than the available pelts
+ if (peltCount > furCount)
+ {
+ // too many pelts selected
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine($"You may not have that many furs. Do not try to cheat. I can add.");
+
+ // continue looping
+ continue;
+ }
+
+ // valid pelt amount entered
+ break;
+ } while (true);
+
+ // return pelt count to the user
+ return peltCount;
+ }
+
+ ///
+ /// Prompt the user for their selected fort
+ ///
+ /// returns the fort the user has selected
+ private int GetSelectedFort()
+ {
+ int selectedFort;
+
+ // loop until the user enters a valid value
+ do
+ {
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write("Answer 1, 2, or 3 ");
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.Write("> ");
+ string input = Console.ReadLine();
+
+ // is the user entry valid
+ if (!int.TryParse(input, out selectedFort))
+ {
+ // no, invalid data
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine("Sorry, I didn't understand. Please answer 1, 2, or 3.");
+
+ // continue looping
+ continue;
+ }
+
+ // is the selected fort an option (one, two or three only)
+ if (selectedFort != 1 && selectedFort != 2 && selectedFort != 3)
+ {
+ // no, invalid for selected
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine($"Please answer 1, 2, or 3.");
+
+ // continue looping
+ continue;
+ }
+
+ // valid fort selected, stop looping
+ break;
+ } while (true);
+
+ // return the players selected fort
+ return selectedFort;
+ }
+ }
+}
diff --git a/38 Fur Trader/csharp/GameState.cs b/38 Fur Trader/csharp/GameState.cs
new file mode 100644
index 00000000..4e174040
--- /dev/null
+++ b/38 Fur Trader/csharp/GameState.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FurTrader
+{
+ internal class GameState
+ {
+ internal bool GameOver { get; set; }
+
+ internal double Savings { get; set; }
+
+ internal int ExpeditionCount { get; set; }
+
+ internal int UnasignedFurCount { get; set; }
+
+ internal int[] Pelts { get; private set; }
+
+ internal int MinkPelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
+ internal int BeaverPelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
+ internal int ErminePelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
+ internal int FoxPelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
+
+ internal int SelectedFort { get; set; }
+
+ internal GameState()
+ {
+ this.Savings = 600;
+ this.ExpeditionCount = 0;
+ this.UnasignedFurCount = 190;
+ this.Pelts = new int[4];
+ this.SelectedFort = 0;
+ }
+
+ internal void StartTurn()
+ {
+ this.SelectedFort = 0; // reset to a default value
+ this.UnasignedFurCount = 190; // each turn starts with 190 furs
+ this.Pelts = new int[4]; // reset pelts on each turn
+ }
+ }
+}
diff --git a/38 Fur Trader/csharp/Program.cs b/38 Fur Trader/csharp/Program.cs
new file mode 100644
index 00000000..438d5c4c
--- /dev/null
+++ b/38 Fur Trader/csharp/Program.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace FurTrader
+{
+ public class Program
+ {
+ ///
+ /// This function will be called automatically when the application begins
+ ///
+ ///
+ public static void Main(string[] args)
+ {
+ // Create an instance of our main Game class
+ var game = new Game();
+
+ // Call its GameLoop function. This will play the game endlessly in a loop until the player chooses to quit.
+ game.GameLoop();
+ }
+ }
+}
diff --git a/41 Guess/java/src/Guess.java b/41 Guess/java/src/Guess.java
new file mode 100644
index 00000000..667411ab
--- /dev/null
+++ b/41 Guess/java/src/Guess.java
@@ -0,0 +1,161 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of Guess
+ *
+ * Based on the Basic game of Guess here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/41%20Guess/guess.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class Guess {
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ private enum GAME_STATE {
+ STARTUP,
+ INPUT_RANGE,
+ DEFINE_COMPUTERS_NUMBER,
+ GUESS,
+ GAME_OVER
+ }
+
+ // Current game state
+ private GAME_STATE gameState;
+
+ // User supplied maximum number to guess
+ private int limit;
+
+ // Computers calculated number for the player to guess
+
+ private int computersNumber;
+
+ // Number of turns the player has had guessing
+ private int tries;
+
+ // Optimal number of turns it should take to guess
+ private int calculatedTurns;
+
+ public Guess() {
+ kbScanner = new Scanner(System.in);
+
+ gameState = GAME_STATE.STARTUP;
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+
+ case STARTUP:
+ intro();
+ gameState = GAME_STATE.INPUT_RANGE;
+ break;
+
+ case INPUT_RANGE:
+
+ limit = displayTextAndGetNumber("WHAT LIMIT DO YOU WANT? ");
+ calculatedTurns = (int) (Math.log(limit) / Math.log(2)) + 1;
+ gameState = GAME_STATE.DEFINE_COMPUTERS_NUMBER;
+ break;
+
+ case DEFINE_COMPUTERS_NUMBER:
+
+ tries = 1;
+ System.out.println("I'M THINKING OF A NUMBER BETWEEN 1 AND " + limit);
+ computersNumber = (int) (Math.random() * limit + 1);
+
+ gameState = GAME_STATE.GUESS;
+ break;
+
+ case GUESS:
+ int playersGuess = displayTextAndGetNumber("NOW YOU TRY TO GUESS WHAT IT IS ");
+
+ // Allow player to restart game with entry of 0
+ if (playersGuess == 0) {
+ linePadding();
+ gameState = GAME_STATE.STARTUP;
+ break;
+ }
+
+ if (playersGuess == computersNumber) {
+ System.out.println("THAT'S IT! YOU GOT IT IN " + tries + " TRIES.");
+ if (tries < calculatedTurns) {
+ System.out.println("VERY ");
+ }
+ System.out.println("GOOD.");
+ System.out.println("YOU SHOULD HAVE BEEN ABLE TO GET IT IN ONLY " + calculatedTurns);
+ linePadding();
+ gameState = GAME_STATE.DEFINE_COMPUTERS_NUMBER;
+ break;
+ } else if (playersGuess < computersNumber) {
+ System.out.println("TOO LOW. TRY A BIGGER ANSWER.");
+ } else {
+ System.out.println("TOO HIGH. TRY A SMALLER ANSWER.");
+ }
+ tries++;
+ break;
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ private void intro() {
+ System.out.println(simulateTabs(33) + "GUESS");
+ System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("THIS IS A NUMBER GUESSING GAME. I'LL THINK");
+ System.out.println("OF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT.");
+ System.out.println("THEN YOU HAVE TO GUESS WHAT IT IS.");
+ }
+
+ /**
+ * Print a predefined number of blank lines
+ *
+ */
+ private void linePadding() {
+ for (int i = 1; i <= 5; i++) {
+ System.out.println();
+ }
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ * Converts input to an Integer
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private int displayTextAndGetNumber(String text) {
+ return Integer.parseInt(displayTextAndGetInput(text));
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Simulate the old basic tab(xx) command which indented text by xx spaces.
+ *
+ * @param spaces number of spaces required
+ * @return String with number of spaces
+ */
+ private String simulateTabs(int spaces) {
+ char[] spacesTemp = new char[spaces];
+ Arrays.fill(spacesTemp, ' ');
+ return new String(spacesTemp);
+ }
+
+}
diff --git a/41 Guess/java/src/GuessGame.java b/41 Guess/java/src/GuessGame.java
new file mode 100644
index 00000000..603cdbfb
--- /dev/null
+++ b/41 Guess/java/src/GuessGame.java
@@ -0,0 +1,6 @@
+public class GuessGame {
+ public static void main(String[] args) {
+ Guess guess = new Guess();
+ guess.play();
+ }
+}
diff --git a/41 Guess/javascript/guess.html b/41 Guess/javascript/guess.html
new file mode 100644
index 00000000..22a1bee0
--- /dev/null
+++ b/41 Guess/javascript/guess.html
@@ -0,0 +1,9 @@
+
+
+GUESS
+
+
+
+
+
+
diff --git a/41 Guess/javascript/guess.js b/41 Guess/javascript/guess.js
new file mode 100644
index 00000000..e313169c
--- /dev/null
+++ b/41 Guess/javascript/guess.js
@@ -0,0 +1,104 @@
+// GUESS
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+function make_space()
+{
+ for (h = 1; h <= 5; h++)
+ print("\n");
+}
+
+// Main control section
+async function main()
+{
+ while (1) {
+ print(tab(33) + "GUESS\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("THIS IS A NUMBER GUESSING GAME. I'LL THINK\n");
+ print("OF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT.\n");
+ print("THEN YOU HAVE TO GUESS WHAT IT IS.\n");
+ print("\n");
+
+ print("WHAT LIMIT DO YOU WANT");
+ l = parseInt(await input());
+ print("\n");
+ l1 = Math.floor(Math.log(l) / Math.log(2)) + 1;
+ while (1) {
+ print("I'M THINKING OF A NUMBER BETWEEN 1 AND " + l + "\n");
+ g = 1;
+ print("NOW YOU TRY TO GUESS WHAT IT IS.\n");
+ m = Math.floor(l * Math.random() + 1);
+ while (1) {
+ n = parseInt(await input());
+ if (n <= 0) {
+ make_space();
+ break;
+ }
+ if (n == m) {
+ print("THAT'S IT! YOU GOT IT IN " + g + " TRIES.\n");
+ if (g == l1) {
+ print("GOOD.\n");
+ } else if (g < l1) {
+ print("VERY GOOD.\n");
+ } else {
+ print("YOU SHOULD HAVE BEEN TO GET IT IN ONLY " + l1 + "\n");
+ }
+ make_space();
+ break;
+ }
+ g++;
+ if (n > m)
+ print("TOO HIGH. TRY A SMALLER ANSWER.\n");
+ else
+ print("TOO LOW. TRY A BIGGER ANSWER.\n");
+ }
+ if (n <= 0)
+ break;
+ }
+ }
+}
+
+main();
diff --git a/42 Gunner/javascript/gunner.html b/42 Gunner/javascript/gunner.html
new file mode 100644
index 00000000..431c9064
--- /dev/null
+++ b/42 Gunner/javascript/gunner.html
@@ -0,0 +1,9 @@
+
+
+GUNNER
+
+
+
+
+
+
diff --git a/42 Gunner/javascript/gunner.js b/42 Gunner/javascript/gunner.js
new file mode 100644
index 00000000..64a427a1
--- /dev/null
+++ b/42 Gunner/javascript/gunner.js
@@ -0,0 +1,139 @@
+// GUNNER
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+print(tab(30) + "GUNNER\n");
+print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+print("\n");
+print("\n");
+print("\n");
+print("YOU ARE THE OFFICER-IN-CHARGE, GIVING ORDERS TO A GUN\n");
+print("CREW, TELLING THEM THE DEGREES OF ELEVATION YOU ESTIMATE\n");
+print("WILL PLACE A PROJECTILE ON TARGET. A HIT WITHIN 100 YARDS\n");
+print("OF THE TARGET WILL DESTROY IT.\n");
+print("\n");
+
+// Main control section
+async function main()
+{
+ while (1) {
+ r = Math.floor(40000 * Math.random() + 20000);
+ print("MAXIMUM RANGE OF YOUR GUN IS " + r + " YARDS.\n");
+ z = 0;
+ print("\n");
+ s1 = 0;
+ while (1) {
+ t = Math.floor(r * (0.1 + 0.8 * Math.random()));
+ s = 0;
+ print("DISTANCE TO THE TARGET IS " + t + " YARDS.\n");
+ print("\n");
+
+ while (1) {
+ print("\n");
+ print("ELEVATION");
+ b = parseFloat(await input());
+ if (b > 89) {
+ print("MAXIMUM ELEVATION IS 89 DEGREES.\n");
+ continue;
+ }
+ if (b < 1) {
+ print("MINIMUM ELEVATION IS ONE DEGREE.\n");
+ continue;
+ }
+ if (++s >= 6) {
+ print("\n");
+ print("BOOM !!!! YOU HAVE JUST BEEN DESTROYED BY THE ENEMY.\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ e = 0;
+ break;
+ }
+ b2 = 2 * b / 57.3;
+ i = r * Math.sin(b2);
+ x = t - i;
+ e = Math.floor(x);
+ if (true) { //Math.abs(e) < 100) {
+ e = 1;
+ break;
+ }
+ if (e > 100) {
+ print("SHORT OF TARGET BY " + Math.abs(e) + " YARDS.\n");
+ } else {
+ print("OVER TARGET BY " + Math.abs(e) + " YARDS.\n");
+ }
+ }
+ if (e == 1) {
+ print("*** TARGET DESTROYED *** " + s + " ROUNDS OF AMMUNITION EXPENDED.\n");
+ s1 += s;
+ if (z == 4) {
+ print("\n");
+ print("\n");
+ print("TOTAL ROUND EXPENDED WERE: " + s1 + "\n");
+ break;
+ } else {
+ z++;
+ print("\n");
+ print("THE FORWARD OBSERVER HAS SIGHTED MORE ENEMY ACTIVITY...\n");
+ }
+ } else {
+ s1 = 19;
+ break;
+ }
+ }
+ if (s1 > 18) {
+ print("BETTER GO BACK TO FORT SILL FOR REFRESHER TRAINING!\n");
+ } else {
+ print("NICE SHOOTING !!");
+ }
+ print("\n");
+ print("TRY AGAIN (Y OR N)");
+ str = await input();
+ if (str.substr(0, 1) != "Y")
+ break;
+ }
+ print("\n");
+ print("OK. RETURN TO BASE CAMP.\n");
+}
+
+main();
diff --git a/43 Hammurabi/javascript/hammurabi.html b/43 Hammurabi/javascript/hammurabi.html
new file mode 100644
index 00000000..2facdcb4
--- /dev/null
+++ b/43 Hammurabi/javascript/hammurabi.html
@@ -0,0 +1,9 @@
+
+
+HAMMURABI
+
+
+
+
+
+
diff --git a/43 Hammurabi/javascript/hammurabi.js b/43 Hammurabi/javascript/hammurabi.js
new file mode 100644
index 00000000..285753c7
--- /dev/null
+++ b/43 Hammurabi/javascript/hammurabi.js
@@ -0,0 +1,253 @@
+// HAMMURABI
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+var a;
+var s;
+
+function exceeded_grain()
+{
+ print("HAMURABI: THINK AGAIN. YOU HAVE ONLY\n");
+ print(s + " BUSHELS OF GRAIN. NOW THEN,\n");
+
+}
+
+function exceeded_acres()
+{
+ print("HAMURABI: THINK AGAIN. YOU OWN ONLY " + a + " ACRES. NOW THEN,\n");
+}
+
+// Main control section
+async function main()
+{
+ print(tab(32) + "HAMURABI\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA\n");
+ print("FOR A TEN-YEAR TERM OF OFFICE.\n");
+ print("\n");
+
+ d1 = 0;
+ p1 = 0;
+ z = 0;
+ p = 95;
+ s = 2800;
+ h = 3000;
+ e = h - s;
+ y = 3;
+ a = h / y;
+ i = 5;
+ q = 1;
+ d = 0;
+ while (1) {
+ print("\n");
+ print("\n");
+ print("\n");
+ print("HAMURABI: I BEG TO REPORT TO YOU,\n");
+ z++;
+ print("IN YEAR " + z + ", " + d + " PEOPLE STARVED, " + i + " CAME TO THE CITY,\n");
+ p += i;
+ if (q <= 0) {
+ p = Math.floor(p / 2);
+ print("A HORRIBLE PLAGUE STRUCK! HALF THE PEOPLE DIED.\n");
+ }
+ print("POPULATION IS NOW " + p + "\n");
+ print("THE CITY NOW OWNS " + a + " ACRES.\n");
+ print("YOU HARVESTED " + y + " BUSHELS PER ACRE.\n");
+ print("THE RATS ATE " + e + " BUSHELS.\n");
+ print("YOU NOW HAVE " + s + " BUSHELS IN STORE.\n");
+ print("\n");
+ if (z == 11) {
+ q = 0;
+ break;
+ }
+ c = Math.floor(10 * Math.random());
+ y = c + 17;
+ print("LAND IS TRADING AT " + y + " BUSHELS PER ACRE.\n");
+ while (1) {
+ print("HOW MANY ACRES DO YOU WISH TO BUY");
+ q = parseInt(await input());
+ if (q < 0)
+ break;
+ if (y * q > s) {
+ exceeded_grain();
+ } else
+ break;
+ }
+ if (q < 0)
+ break;
+ if (q != 0) {
+ a += q;
+ s -= y * q;
+ c = 0;
+ } else {
+ while (1) {
+ print("HOW MANY ACRES DO YOU WISH TO SELL");
+ q = parseInt(await input());
+ if (q < 0)
+ break;
+ if (q >= a) {
+ exceeded_acres();
+ } else {
+ break;
+ }
+ }
+ if (q < 0)
+ break;
+ a -= q;
+ s += y * q;
+ c = 0;
+ }
+ print("\n");
+ while (1) {
+ print("HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE");
+ q = parseInt(await input());
+ if (q < 0)
+ break;
+ if (q > s) // Trying to use more grain than is in silos?
+ exceeded_grain();
+ else
+ break;
+ }
+ if (q < 0)
+ break;
+ s -= q;
+ c = 1;
+ print("\n");
+ while (1) {
+ print("HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED");
+ d = parseInt(await input());
+ if (d != 0) {
+ if (d < 0)
+ break;
+ if (d > a) { // Trying to plant more acres than you own?
+ exceeded_acres();
+ } else {
+ if (Math.floor(d / 2) > s) // Enough grain for seed?
+ exceeded_grain();
+ else {
+ if (d >= 10 * p) {
+ print("BUT YOU HAVE ONLY " + p + " PEOPLE TO TEND THE FIELDS! NOW THEN,\n");
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (d < 0) {
+ q = -1;
+ break;
+ }
+ s -= Math.floor(d / 2);
+ c = Math.floor(Math.random() * 5) + 1;
+ // A bountiful harvest!
+ if (c % 2 == 0) {
+ // Rats are running wild!!
+ e = Math.floor(s / c);
+ }
+ s = s - e + h;
+ c = Math.floor(Math.random() * 5) + 1;
+ // Let's have some babies
+ i = Math.floor(c * (20 * a + s) / p / 100 + 1);
+ // How many people had full tummies?
+ c = Math.floor(q / 20);
+ // Horros, a 15% chance of plague
+ q = Math.floor(10 * (2 * Math.random() - 0.3));
+ if (p < c) {
+ d = 0;
+ continue;
+ }
+ // Starve enough for impeachment?
+ d = p - c;
+ if (d <= 0.45 * p) {
+ p1 = ((z - 1) * p1 + d * 100 / p) / z;
+ p = c;
+ d1 += d;
+ continue;
+ }
+ print("\n");
+ print("YOU STARVED " + d + " PEOPLE IN ONE YEAR!!!\n");
+ q = 0;
+ p1 = 34;
+ p = 1;
+ break;
+ }
+ if (q < 0) {
+ print("\n");
+ print("HAMURABI: I CANNOT DO WHAT YOU WISH.\n");
+ print("GET YOURSELF ANOTHER STEWARD!!!!!\n");
+ } else {
+ print("IN YOUR 10-YEAR TERM OF OFFICE, " + p1 + " PERCENT OF THE\n");
+ print("POPULATION STARVED PER YEAR ON THE AVERAGE, I.E. A TOTAL OF\n");
+ print(d1 + " PEOPLE DIED!!\n");
+ l = a / p;
+ print("YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH\n");
+ print(l + " ACRES PER PERSON.\n");
+ print("\n");
+ if (p1 > 33 || l < 7) {
+ print("DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY\n");
+ print("BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE\n");
+ print("ALSO BEEN DECLARED NATIONAL FINK!!!!\n");
+ } else if (p1 > 10 || l < 9) {
+ print("YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.\n");
+ print("THE PEOPLE (REMIANING) FIND YOU AN UNPLEASANT RULER, AND,\n");
+ print("FRANKLY, HATE YOUR GUTS!!\n");
+ } else if (p1 > 3 || l < 10) {
+ print("YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT\n");
+ print("REALLY WASN'T TOO BAD AT ALL. " + Math.floor(p * 0.8 * Math.random()) + " PEOPLE\n");
+ print("WOULD DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR\n");
+ print("TRIVIAL PROBLEMS.\n");
+ } else {
+ print("A FANTASTIC PERFORMANCE!!! CHARLEMANGE, DISRAELI, AND\n");
+ print("JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!\n");
+ }
+ }
+ print("\n");
+ print("SO LONG FOR NOW.\n");
+ print("\n");
+}
+
+main();
diff --git a/44 Hangman/csharp/Hangman/Graphic.cs b/44 Hangman/csharp/Hangman/Graphic.cs
new file mode 100644
index 00000000..ba01fcac
--- /dev/null
+++ b/44 Hangman/csharp/Hangman/Graphic.cs
@@ -0,0 +1,129 @@
+using System;
+
+namespace Hangman
+{
+ ///
+ /// Represents the main "Hangman" graphic.
+ ///
+ public class Graphic
+ {
+ private readonly char[,] _graphic;
+ private const int Width = 12;
+ private const int Height = 12;
+
+ public Graphic()
+ {
+ // 12 x 12 array to represent the graphics.
+ _graphic = new char[Height, Width];
+
+ // Fill it with empty spaces.
+ for (var i = 0; i < Height; i++)
+ {
+ for (var j = 0; j < Width; j++)
+ {
+ _graphic[i, j] = ' ';
+ }
+ }
+
+ // Draw the vertical line.
+ for (var i = 0; i < Height; i++)
+ {
+ _graphic[i, 0] = 'X';
+ }
+
+ // Draw the horizontal line.
+ for (var i = 0; i < 7; i++)
+ {
+ _graphic[0, i] = 'X';
+ }
+
+ // Draw the rope.
+ _graphic[1, 6] = 'X';
+ }
+
+ public void Print()
+ {
+ for (var i = 0; i < Height; i++)
+ {
+ for (var j = 0; j < Width; j++)
+ {
+ Console.Write(_graphic[i, j]);
+ }
+
+ Console.Write("\n"); // New line.
+ }
+ }
+
+ public void AddHead()
+ {
+ _graphic[2, 5] = '-';
+ _graphic[2, 6] = '-';
+ _graphic[2, 7] = '-';
+ _graphic[3, 4] = '(';
+ _graphic[3, 5] = '.';
+ _graphic[3, 7] = '.';
+ _graphic[3, 8] = ')';
+ _graphic[4, 5] = '-';
+ _graphic[4, 6] = '-';
+ _graphic[4, 7] = '-';
+ }
+
+ public void AddBody()
+ {
+ for (var i = 5; i < 9; i++)
+ {
+ _graphic[i, 6] = 'X';
+ }
+ }
+
+ public void AddRightArm()
+ {
+ for (var i = 3; i < 7; i++)
+ {
+ _graphic[i, i - 1] = '\\'; // This is the escape character for the back slash.
+ }
+ }
+
+ public void AddLeftArm()
+ {
+ _graphic[3, 10] = '/';
+ _graphic[4, 9] = '/';
+ _graphic[5, 8] = '/';
+ _graphic[6, 7] = '/';
+ }
+
+ public void AddRightLeg()
+ {
+ _graphic[9, 5] = '/';
+ _graphic[10, 4] = '/';
+ }
+
+ public void AddLeftLeg()
+ {
+ _graphic[9, 7] = '\\';
+ _graphic[10, 8] = '\\';
+ }
+
+ public void AddRightHand()
+ {
+ _graphic[2, 2] = '/';
+ }
+
+ public void AddLeftHand()
+ {
+ _graphic[2, 10] = '\\';
+ }
+
+ public void AddRightFoot()
+ {
+ _graphic[11, 9] = '\\';
+ _graphic[11, 10] = '-';
+ }
+
+ public void AddLeftFoot()
+ {
+ _graphic[11, 3] = '/';
+ _graphic[11, 2] = '-';
+ }
+ }
+}
\ No newline at end of file
diff --git a/44 Hangman/csharp/Hangman/Hangman.csproj b/44 Hangman/csharp/Hangman/Hangman.csproj
new file mode 100644
index 00000000..9590466a
--- /dev/null
+++ b/44 Hangman/csharp/Hangman/Hangman.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ net5.0
+
+
+
diff --git a/44 Hangman/csharp/Hangman/Hangman.sln b/44 Hangman/csharp/Hangman/Hangman.sln
new file mode 100644
index 00000000..ef93fef7
--- /dev/null
+++ b/44 Hangman/csharp/Hangman/Hangman.sln
@@ -0,0 +1,16 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hangman", "Hangman.csproj", "{1C516A9E-F4F2-4C79-8C37-0162C403B1F7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/44 Hangman/csharp/Hangman/Program.cs b/44 Hangman/csharp/Hangman/Program.cs
new file mode 100644
index 00000000..7ecb09df
--- /dev/null
+++ b/44 Hangman/csharp/Hangman/Program.cs
@@ -0,0 +1,313 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json.Serialization;
+
+namespace Hangman
+{
+ ///
+ /// C# version of the game "Hangman" from the book BASIC Computer Games.
+ ///
+ static class Program
+ {
+ static void Main()
+ {
+ Console.WriteLine(Tab(32) + "HANGMAN");
+ Console.WriteLine(Tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine();
+ MainLoop();
+ Console.WriteLine();
+ Console.WriteLine("IT'S BEEN FUN! BYE FOR NOW.");
+ }
+
+ static void MainLoop()
+ {
+ var words = GetWords();
+ var stillPlaying = true;
+
+ while (stillPlaying)
+ {
+ if (words.Count == 0)
+ {
+ Console.WriteLine("YOU DID ALL THE WORDS!!");
+ break;
+ }
+
+ // Get a random number from 0 to the number of words we have minus one (C# arrays are zero-based).
+ var rnd = new Random();
+ var randomNumber = rnd.Next(words.Count - 1);
+
+ // Pick a random word and remove it from the list.
+ var word = words[randomNumber];
+ words.Remove(word);
+
+ GameLoop(word);
+
+ // Game finished. Ask if player wants another one.
+ Console.WriteLine("WANT ANOTHER WORD? ");
+ var response = Console.ReadLine();
+ if (response == null || response.ToUpper() != "YES")
+ {
+ stillPlaying = false; // Exit the loop if the player didn't answer "yes".
+ }
+ }
+ }
+
+ static void GameLoop(string word)
+ {
+ var graphic = new Graphic();
+ var wrongGuesses = 0;
+ var numberOfGuesses = 0;
+ var usedLetters = new List();
+
+ // The word that the user sees. Since we just started, it's just dashes.
+ var displayedWord = new char[word.Length];
+ for (var i = 0; i < word.Length; i++)
+ {
+ displayedWord[i] = '-';
+ }
+
+ var stillPlaying = true;
+ while (stillPlaying)
+ {
+ var guess = GetLetterFromPlayer(displayedWord, usedLetters);
+ usedLetters.Add(guess);
+ numberOfGuesses++;
+ var correctLetterCount = 0;
+ // Now we check every letter in the word to see if the player guessed any of them correctly.
+ for(var i = 0; i < word.Length; i++)
+ {
+ if (word[i] == guess)
+ {
+ correctLetterCount++;
+ displayedWord[i] = guess;
+ }
+ }
+
+ if (correctLetterCount == 0)
+ {
+ // Wrong guess.
+ Console.WriteLine("SORRY, THAT LETTER ISN'T IN THE WORD.");
+ wrongGuesses++;
+ DrawBody(graphic, wrongGuesses);
+ if (wrongGuesses == 10)
+ {
+ // Player exhausted all their guesses. Finish the game loop.
+ Console.WriteLine($"SORRY, YOU LOSE. THE WORD WAS {word}");
+ Console.Write("YOU MISSED THAT ONE. DO YOU ");
+ stillPlaying = false;
+ }
+ }
+ else
+ {
+ // Player guessed a correct letter. Let's see if there are any unguessed letters left in the word.
+ if (displayedWord.Contains('-'))
+ {
+ Console.WriteLine(displayedWord);
+
+ // Give the player a chance to guess the whole word.
+ var wordGuess = GetWordFromPlayer();
+ if (word == wordGuess)
+ {
+ // Player found the word. Mark it found.
+ Console.WriteLine("YOU FOUND THE WORD!");
+ stillPlaying = false; // Exit game loop.
+ }
+ else
+ {
+ // Player didn't guess the word. Continue the game loop.
+ Console.WriteLine("WRONG. TRY ANOTHER LETTER.");
+ }
+ }
+ else
+ {
+ // Player guessed all the letters.
+ Console.WriteLine("YOU FOUND THE WORD!");
+ stillPlaying = false; // Exit game loop.
+ }
+ }
+ } // End of game loop.
+ }
+
+ ///
+ /// Display the current state of the word and all the already guessed letters, and get a new guess from the player
+ ///
+ /// A char array that represents the current state of the guessed word
+ /// A list of chars that represents all the letters guessed so far
+ /// The letter that the player has just entered as a guess
+ private static char GetLetterFromPlayer(char[] displayedWord, List usedLetters)
+ {
+ while (true) // Infinite loop, unless the player enters an unused letter.
+ {
+ Console.WriteLine();
+ Console.WriteLine(displayedWord);
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine("HERE ARE THE LETTERS YOU USED:");
+ for (var i = 0; i < usedLetters.Count; i++)
+ {
+ Console.Write(usedLetters[i]);
+
+ // If it's not the last letter, print a comma.
+ if (i != usedLetters.Count - 1)
+ {
+ Console.Write(",");
+ }
+ }
+
+ Console.WriteLine();
+ Console.WriteLine("WHAT IS YOUR GUESS?");
+ var guess = char.ToUpper(Console.ReadKey().KeyChar);
+ Console.WriteLine();
+
+ if (usedLetters.Contains(guess))
+ {
+ // After this the loop will continue.
+ Console.WriteLine("YOU GUESSED THAT LETTER BEFORE!");
+ }
+ else
+ {
+ // Break out of the loop by returning guessed letter.
+ return guess;
+ }
+ }
+ }
+
+ ///
+ /// Gets a word guess from the player.
+ ///
+ /// The guessed word.
+ private static string GetWordFromPlayer()
+ {
+ while (true) // Infinite loop, unless the player enters something.
+ {
+ Console.WriteLine("WHAT IS YOUR GUESS FOR THE WORD? ");
+ var guess = Console.ReadLine();
+ if (guess != null)
+ {
+ return guess.ToUpper();
+ }
+ }
+ }
+
+ ///
+ /// Draw body after wrong guess.
+ ///
+ /// The instance of the Graphic class being used.
+ /// Number of wrong guesses.
+ private static void DrawBody(Graphic graphic, int wrongGuesses)
+ {
+ switch (wrongGuesses)
+ {
+ case 1:
+ Console.WriteLine("FIRST, WE DRAW A HEAD.");
+ graphic.AddHead();
+ break;
+ case 2:
+ Console.WriteLine("NOW WE DRAW A BODY.");
+ graphic.AddBody();
+ break;
+ case 3:
+ Console.WriteLine("NEXT WE DRAW AN ARM.");
+ graphic.AddRightArm();
+ break;
+ case 4:
+ Console.WriteLine("THIS TIME IT'S THE OTHER ARM.");
+ graphic.AddLeftArm();
+ break;
+ case 5:
+ Console.WriteLine("NOW, LET'S DRAW THE RIGHT LEG.");
+ graphic.AddRightLeg();
+ break;
+ case 6:
+ Console.WriteLine("THIS TIME WE DRAW THE LEFT LEG.");
+ graphic.AddLeftLeg();
+ break;
+ case 7:
+ Console.WriteLine("NOW WE PUT UP A HAND.");
+ graphic.AddRightHand();
+ break;
+ case 8:
+ Console.WriteLine("NEXT THE OTHER HAND.");
+ graphic.AddLeftHand();
+ break;
+ case 9:
+ Console.WriteLine("NOW WE DRAW ONE FOOT.");
+ graphic.AddRightFoot();
+ break;
+ case 10:
+ Console.WriteLine("HERE'S THE OTHER FOOT -- YOU'RE HUNG!!");
+ graphic.AddLeftFoot();
+ break;
+ }
+ graphic.Print();
+ }
+
+ ///
+ /// Get a list of words to use in the game.
+ ///
+ /// List of strings.
+ private static List GetWords() => new()
+ {
+ "GUM",
+ "SIN",
+ "FOR",
+ "CRY",
+ "LUG",
+ "BYE",
+ "FLY",
+ "UGLY",
+ "EACH",
+ "FROM",
+ "WORK",
+ "TALK",
+ "WITH",
+ "SELF",
+ "PIZZA",
+ "THING",
+ "FEIGN",
+ "FIEND",
+ "ELBOW",
+ "FAULT",
+ "DIRTY",
+ "BUDGET",
+ "SPIRIT",
+ "QUAINT",
+ "MAIDEN",
+ "ESCORT",
+ "PICKAX",
+ "EXAMPLE",
+ "TENSION",
+ "QUININE",
+ "KIDNEY",
+ "REPLICA",
+ "SLEEPER",
+ "TRIANGLE",
+ "KANGAROO",
+ "MAHOGANY",
+ "SERGEANT",
+ "SEQUENCE",
+ "MOUSTACHE",
+ "DANGEROUS",
+ "SCIENTIST",
+ "DIFFERENT",
+ "QUIESCENT",
+ "MAGISTRATE",
+ "ERRONEOUSLY",
+ "LOUDSPEAKER",
+ "PHYTOTOXIC",
+ "MATRIMONIAL",
+ "PARASYMPATHOMIMETIC",
+ "THIGMOTROPISM"
+ };
+
+ ///
+ /// Leave a number of spaces empty.
+ ///
+ /// Number of spaces.
+ /// The result string.
+ private static string Tab(int length) => new string(' ', length);
+ }
+}
\ No newline at end of file
diff --git a/47 Hi-Lo/java/src/HiLo.java b/47 Hi-Lo/java/src/HiLo.java
index 36f44ee5..2d0263e9 100644
--- a/47 Hi-Lo/java/src/HiLo.java
+++ b/47 Hi-Lo/java/src/HiLo.java
@@ -6,7 +6,7 @@ import java.util.Scanner;
* Based on the Basic game of Hi-Lo here
* https://github.com/coding-horror/basic-computer-games/blob/main/47%20Hi-Lo/hi-lo.bas
*
- * Note: The idea was to create a version of this 1970's Basic game in Java, without introducing
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
* new features - no additional text, error checking, etc has been added.
*/
public class HiLo {
@@ -24,7 +24,7 @@ public class HiLo {
}
// Used for keyboard input
- private Scanner kbScanner;
+ private final Scanner kbScanner;
// Current game state
private GAME_STATE gameState;
@@ -40,8 +40,8 @@ public class HiLo {
public HiLo() {
- this.gameState = GAME_STATE.STARTING;
- this.playerAmountWon = 0;
+ gameState = GAME_STATE.STARTING;
+ playerAmountWon = 0;
// Initialise kb scanner
kbScanner = new Scanner(System.in);
@@ -66,7 +66,7 @@ public class HiLo {
case START_GAME:
init();
System.out.println("O.K. I HAVE A NUMBER IN MIND.");
- this.gameState = GAME_STATE.GUESSING;
+ gameState = GAME_STATE.GUESSING;
break;
// Player guesses the number until they get it or run out of guesses
@@ -75,21 +75,21 @@ public class HiLo {
// Check if the player guessed the number
if(validateGuess(guess)) {
- System.out.println("GOT IT!!!!!!!!!! YOU WIN " + this.computersNumber
+ System.out.println("GOT IT!!!!!!!!!! YOU WIN " + computersNumber
+ " DOLLARS.");
- this.playerAmountWon += this.computersNumber;
+ playerAmountWon += computersNumber;
System.out.println("YOUR TOTAL WINNINGS ARE NOW "
- + this.playerAmountWon + " DOLLARS.");
- this.gameState = GAME_STATE.PLAY_AGAIN;
+ + playerAmountWon + " DOLLARS.");
+ gameState = GAME_STATE.PLAY_AGAIN;
} else {
// incorrect guess
- this.playersGuesses++;
+ playersGuesses++;
// Ran out of guesses?
- if (this.playersGuesses == MAX_GUESSES) {
+ if (playersGuesses == MAX_GUESSES) {
System.out.println("YOU BLEW IT...TOO BAD...THE NUMBER WAS "
- + this.computersNumber);
- this.playerAmountWon = 0;
- this.gameState = GAME_STATE.PLAY_AGAIN;
+ + computersNumber);
+ playerAmountWon = 0;
+ gameState = GAME_STATE.PLAY_AGAIN;
}
}
break;
@@ -98,11 +98,11 @@ public class HiLo {
case PLAY_AGAIN:
System.out.println();
if(yesEntered(displayTextAndGetInput("PLAY AGAIN (YES OR NO) "))) {
- this.gameState = GAME_STATE.START_GAME;
+ gameState = GAME_STATE.START_GAME;
} else {
// Chose not to play again
System.out.println("SO LONG. HOPE YOU ENJOYED YOURSELF!!!");
- this.gameState = GAME_STATE.GAME_OVER;
+ gameState = GAME_STATE.GAME_OVER;
}
}
} while (gameState != GAME_STATE.GAME_OVER);
@@ -111,17 +111,17 @@ public class HiLo {
/**
* Checks the players guess against the computers randomly generated number
*
- * @param theGuess
+ * @param theGuess the players guess
* @return true if the player guessed correctly, false otherwise
*/
private boolean validateGuess(int theGuess) {
// Correct guess?
- if(theGuess == this.computersNumber) {
+ if(theGuess == computersNumber) {
return true;
}
- if(theGuess > this.computersNumber) {
+ if(theGuess > computersNumber) {
System.out.println("YOUR GUESS IS TOO HIGH.");
} else {
System.out.println("YOUR GUESS IS TOO LOW.");
@@ -131,8 +131,8 @@ public class HiLo {
}
private void init() {
- this.playersGuesses = 0;
- this.computersNumber = randomNumber();
+ playersGuesses = 0;
+ computersNumber = randomNumber();
}
public void intro() {
@@ -140,7 +140,7 @@ public class HiLo {
System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
System.out.println();
System.out.println();
- System.out.println("THIS IS THE GAME OF HI LO.");
+ System.out.println("IS THE GAME OF HI LO.");
System.out.println();
System.out.println("YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE");
System.out.println("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS. IF YOU");
@@ -155,7 +155,7 @@ public class HiLo {
* @return players guess as an int
*/
private int playerGuess() {
- return Integer.valueOf((displayTextAndGetInput("YOUR GUESS? ")));
+ return Integer.parseInt((displayTextAndGetInput("YOUR GUESS? ")));
}
/**
@@ -165,7 +165,7 @@ public class HiLo {
* @return true of Y or YES was entered, otherwise false
*/
private boolean yesEntered(String text) {
- return stringIsAnyValue(text, new String[] {"Y", "YES"});
+ return stringIsAnyValue(text, "Y", "YES");
}
/**
diff --git a/51 Hurkle/java/src/Hurkle.java b/51 Hurkle/java/src/Hurkle.java
index 8af8732f..7fc2ed1e 100644
--- a/51 Hurkle/java/src/Hurkle.java
+++ b/51 Hurkle/java/src/Hurkle.java
@@ -1,6 +1,14 @@
-import java.util.ArrayList;
import java.util.Scanner;
+/**
+ * Game of Hurkle
+ *
+ * Based on the Basic game of Hurkle here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/51%20Hurkle/hurkle.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
public class Hurkle {
public static final int GRID_SIZE = 10;
@@ -17,7 +25,7 @@ public class Hurkle {
private GAME_STATE gameState;
// Used for keyboard input
- private Scanner kbScanner;
+ private final Scanner kbScanner;
private int guesses;
@@ -54,32 +62,31 @@ public class Hurkle {
// Start the game, set the number of players, names and round
case START_GAME:
- this.hurkleXPos = randomNumber();
- this.hurkleYPos = randomNumber();
- System.out.println("HURKLE AT : " + this.hurkleXPos + "," + this.hurkleYPos);
+ hurkleXPos = randomNumber();
+ hurkleYPos = randomNumber();
- this.guesses = 1;
+ guesses = 1;
gameState = GAME_STATE.GUESSING;
break;
// Guess an x,y position of the hurkle
case GUESSING:
- String guess = displayTextAndGetInput("GUESS #" + this.guesses + "? ");
- this.playerGuessXPos = getDelimitedValue(guess, 0);
- this.playerGuessYPos = getDelimitedValue(guess, 1);
+ String guess = displayTextAndGetInput("GUESS #" + guesses + "? ");
+ playerGuessXPos = getDelimitedValue(guess, 0);
+ playerGuessYPos = getDelimitedValue(guess, 1);
if (foundHurkle()) {
- this.gameState = GAME_STATE.PLAY_AGAIN;
+ gameState = GAME_STATE.PLAY_AGAIN;
} else {
showDirectionOfHurkle();
- this.guesses++;
- if(this.guesses > MAX_GUESSES) {
+ guesses++;
+ if (guesses > MAX_GUESSES) {
System.out.println("SORRY, THAT'S "
+ MAX_GUESSES + " GUESSES.");
System.out.println("THE HURKLE IS AT "
- + this.hurkleXPos + "," + this.hurkleYPos);
+ + hurkleXPos + "," + hurkleYPos);
System.out.println();
- this.gameState = GAME_STATE.PLAY_AGAIN;
+ gameState = GAME_STATE.PLAY_AGAIN;
}
}
@@ -88,7 +95,7 @@ public class Hurkle {
case PLAY_AGAIN:
System.out.println("LET'S PLAY AGAIN, HURKLE IS HIDING.");
System.out.println();
- this.gameState = GAME_STATE.START_GAME;
+ gameState = GAME_STATE.START_GAME;
break;
}
// Effectively an endless loop because the game never quits as per
@@ -98,31 +105,30 @@ public class Hurkle {
private void showDirectionOfHurkle() {
System.out.print("GO ");
- if(this.playerGuessYPos == this.hurkleYPos) {
+ if (playerGuessYPos == hurkleYPos) {
// don't print North or South because the player has chosen the
// same y grid pos as the hurkle
- } else if (this.playerGuessYPos < this.hurkleYPos) {
+ } else if (playerGuessYPos < hurkleYPos) {
System.out.print("NORTH");
- } else if(this.playerGuessYPos > this.hurkleYPos) {
+ } else if (playerGuessYPos > hurkleYPos) {
System.out.print("SOUTH");
}
- if(this.playerGuessXPos == this.hurkleXPos) {
+ if (playerGuessXPos == hurkleXPos) {
// don't print East or West because the player has chosen the
// same x grid pos as the hurkle
- } else if(this.playerGuessXPos < this.hurkleXPos) {
+ } else if (playerGuessXPos < hurkleXPos) {
System.out.print("EAST");
- } else if(this.playerGuessXPos > this.hurkleXPos) {
+ } else if (playerGuessXPos > hurkleXPos) {
System.out.print("WEST");
}
System.out.println();
- return;
}
private boolean foundHurkle() {
- if ((this.playerGuessXPos - this.hurkleXPos)
- - (this.playerGuessYPos - this.hurkleYPos) == 0) {
- System.out.println("YOU FOUND HIM IN " + this.guesses + " GUESSES.");
+ if ((playerGuessXPos - hurkleXPos)
+ - (playerGuessYPos - hurkleYPos) == 0) {
+ System.out.println("YOU FOUND HIM IN " + guesses + " GUESSES.");
return true;
}
diff --git a/51 Hurkle/java/src/HurkleGame.java b/51 Hurkle/java/src/HurkleGame.java
index c582885e..1b527398 100644
--- a/51 Hurkle/java/src/HurkleGame.java
+++ b/51 Hurkle/java/src/HurkleGame.java
@@ -1,7 +1,7 @@
public class HurkleGame {
public static void main(String[] args) {
- Hurkle hurkle = new Hurkle();
- hurkle.play();
+ Hurkle hurkle = new Hurkle();
+ hurkle.play();
}
}
diff --git a/52 Kinema/java/src/Kinema.java b/52 Kinema/java/src/Kinema.java
new file mode 100644
index 00000000..afbacbe8
--- /dev/null
+++ b/52 Kinema/java/src/Kinema.java
@@ -0,0 +1,176 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of Kinema
+ *
+ * Based on the Basic game of Kinema here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/52%20Kinema/kinema.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class Kinema {
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ private enum GAME_STATE {
+ STARTUP,
+ INIT,
+ HOW_HIGH,
+ SECONDS_TILL_IT_RETURNS,
+ ITS_VELOCITY,
+ RESULTS,
+ GAME_OVER
+ }
+
+ // Current game state
+ private GAME_STATE gameState;
+
+ private int numberAnswersCorrect;
+
+ // How many meters per second a ball is thrown
+ private int velocity;
+
+ public Kinema() {
+ kbScanner = new Scanner(System.in);
+
+ gameState = GAME_STATE.STARTUP;
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ double playerAnswer;
+ double correctAnswer;
+ do {
+ switch (gameState) {
+
+ case STARTUP:
+ intro();
+ gameState = GAME_STATE.INIT;
+ break;
+
+ case INIT:
+ numberAnswersCorrect = 0;
+
+ // calculate a random velocity for the player to use in the calculations
+ velocity = 5 + (int) (35 * Math.random());
+ System.out.println("A BALL IS THROWN UPWARDS AT " + velocity + " METERS PER SECOND.");
+ gameState = GAME_STATE.HOW_HIGH;
+ break;
+
+ case HOW_HIGH:
+
+ playerAnswer = displayTextAndGetNumber("HOW HIGH WILL IT GO (IN METERS)? ");
+
+ // Calculate the correct answer to how high it will go
+ correctAnswer = 0.05 * Math.pow(velocity, 2);
+ if (calculate(playerAnswer, correctAnswer)) {
+ numberAnswersCorrect++;
+ }
+ gameState = GAME_STATE.ITS_VELOCITY;
+ break;
+
+ case ITS_VELOCITY:
+
+ playerAnswer = displayTextAndGetNumber("HOW LONG UNTIL IT RETURNS (IN SECONDS)? ");
+
+ // Calculate current Answer for how long until it returns to the ground in seconds
+ correctAnswer = (double) velocity / 5;
+ if (calculate(playerAnswer, correctAnswer)) {
+ numberAnswersCorrect++;
+ }
+ gameState = GAME_STATE.SECONDS_TILL_IT_RETURNS;
+ break;
+
+ case SECONDS_TILL_IT_RETURNS:
+
+ // Calculate random number of seconds for 3rd question
+ double seconds = 1 + (Math.random() * (2 * velocity)) / 10;
+
+ // Round to one decimal place.
+ double scale = Math.pow(10, 1);
+ seconds = Math.round(seconds * scale) / scale;
+
+ playerAnswer = displayTextAndGetNumber("WHAT WILL ITS VELOCITY BE AFTER " + seconds + " SECONDS? ");
+
+ // Calculate the velocity after the given number of seconds
+ correctAnswer = velocity - (10 * seconds);
+ if (calculate(playerAnswer, correctAnswer)) {
+ numberAnswersCorrect++;
+ }
+ gameState = GAME_STATE.RESULTS;
+ break;
+
+ case RESULTS:
+ System.out.println(numberAnswersCorrect + " RIGHT OUT OF 3");
+ if (numberAnswersCorrect > 1) {
+ System.out.println(" NOT BAD.");
+ }
+ gameState = GAME_STATE.STARTUP;
+ break;
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ private void intro() {
+ System.out.println(simulateTabs(33) + "KINEMA");
+ System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ }
+
+ private boolean calculate(double playerAnswer, double correctAnswer) {
+
+ boolean gotItRight = false;
+
+ if (Math.abs((playerAnswer - correctAnswer) / correctAnswer) < 0.15) {
+ System.out.println("CLOSE ENOUGH");
+ gotItRight = true;
+ } else {
+ System.out.println("NOT EVEN CLOSE");
+ }
+ System.out.println("CORRECT ANSWER IS " + correctAnswer);
+ System.out.println();
+
+ return gotItRight;
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ * Converts input to a Double
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private double displayTextAndGetNumber(String text) {
+ return Double.parseDouble(displayTextAndGetInput(text));
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Simulate the old basic tab(xx) command which indented text by xx spaces.
+ *
+ * @param spaces number of spaces required
+ * @return String with number of spaces
+ */
+ private String simulateTabs(int spaces) {
+ char[] spacesTemp = new char[spaces];
+ Arrays.fill(spacesTemp, ' ');
+ return new String(spacesTemp);
+ }
+
+}
diff --git a/52 Kinema/java/src/KinemaGame.java b/52 Kinema/java/src/KinemaGame.java
new file mode 100644
index 00000000..b84d0019
--- /dev/null
+++ b/52 Kinema/java/src/KinemaGame.java
@@ -0,0 +1,7 @@
+public class KinemaGame {
+ public static void main(String[] args) {
+
+ Kinema kinema = new Kinema();
+ kinema.play();
+ }
+}
diff --git a/54 Letter/java/src/Letter.java b/54 Letter/java/src/Letter.java
new file mode 100644
index 00000000..36582894
--- /dev/null
+++ b/54 Letter/java/src/Letter.java
@@ -0,0 +1,142 @@
+import java.awt.*;
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of Letter
+ *
+ * Based on the Basic game of Letter here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/54%20Letter/letter.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class Letter {
+
+ public static final int OPTIMAL_GUESSES = 5;
+ public static final int ASCII_A = 65;
+ public static final int ALL_LETTERS = 26;
+
+ private enum GAME_STATE {
+ STARTUP,
+ INIT,
+ GUESSING,
+ RESULTS,
+ GAME_OVER
+ }
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ // Current game state
+ private GAME_STATE gameState;
+
+ // Players guess count;
+ private int playerGuesses;
+
+ // Computers ascii code for a random letter between A..Z
+ private int computersLetter;
+
+ public Letter() {
+
+ gameState = GAME_STATE.STARTUP;
+
+ // Initialise kb scanner
+ kbScanner = new Scanner(System.in);
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+
+ // Show an introduction the first time the game is played.
+ case STARTUP:
+ intro();
+ gameState = GAME_STATE.INIT;
+ break;
+
+ case INIT:
+ playerGuesses = 0;
+ computersLetter = ASCII_A + (int) (Math.random() * ALL_LETTERS);
+ System.out.println("O.K., I HAVE A LETTER. START GUESSING.");
+ gameState = GAME_STATE.GUESSING;
+ break;
+
+ // Player guesses the number until they get it or run out of guesses
+ case GUESSING:
+ String playerGuess = displayTextAndGetInput("WHAT IS YOUR GUESS? ").toUpperCase();
+
+ // Convert first character of input string to ascii
+ int toAscii = playerGuess.charAt(0);
+ playerGuesses++;
+ if (toAscii == computersLetter) {
+ gameState = GAME_STATE.RESULTS;
+ break;
+ }
+
+ if (toAscii > computersLetter) {
+ System.out.println("TOO HIGH. TRY A LOWER LETTER.");
+ } else {
+ System.out.println("TOO LOW. TRY A HIGHER LETTER.");
+ }
+ break;
+
+ // Play again, or exit game?
+ case RESULTS:
+ System.out.println();
+ System.out.println("YOU GOT IT IN " + playerGuesses + " GUESSES!!");
+ if (playerGuesses <= OPTIMAL_GUESSES) {
+ System.out.println("GOOD JOB !!!!!");
+ // Original game beeped 15 tims if you guessed in the optimal guesses or less
+ // Changed this to do a single beep only
+ Toolkit.getDefaultToolkit().beep();
+ } else {
+ // Took more than optimal number of guesses
+ System.out.println("BUT IT SHOULDN'T TAKE MORE THAN " + OPTIMAL_GUESSES + " GUESSES!");
+ }
+ System.out.println();
+ System.out.println("LET'S PLAN AGAIN.....");
+ gameState = GAME_STATE.INIT;
+ break;
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ public void intro() {
+ System.out.println(simulateTabs(33) + "LETTER");
+ System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("LETTER GUESSING GAME");
+ System.out.println();
+ System.out.println("I'LL THINK OF A LETTER OF THE ALPHABET, A TO Z.");
+ System.out.println("TRY TO GUESS MY LETTER AND I'LL GIVE YOU CLUES");
+ System.out.println("AS TO HOW CLOSE YOU'RE GETTING TO MY LETTER.");
+ }
+
+ /**
+ * Simulate the old basic tab(xx) command which indented text by xx spaces.
+ *
+ * @param spaces number of spaces required
+ * @return String with number of spaces
+ */
+ private String simulateTabs(int spaces) {
+ char[] spacesTemp = new char[spaces];
+ Arrays.fill(spacesTemp, ' ');
+ return new String(spacesTemp);
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+}
\ No newline at end of file
diff --git a/54 Letter/java/src/LetterGame.java b/54 Letter/java/src/LetterGame.java
new file mode 100644
index 00000000..fa023329
--- /dev/null
+++ b/54 Letter/java/src/LetterGame.java
@@ -0,0 +1,8 @@
+public class LetterGame {
+
+ public static void main(String[] args) {
+
+ Letter letter = new Letter();
+ letter.play();
+ }
+}
diff --git a/57 Literature Quiz/java/src/LiteratureQuiz.java b/57 Literature Quiz/java/src/LiteratureQuiz.java
new file mode 100644
index 00000000..d98d58a8
--- /dev/null
+++ b/57 Literature Quiz/java/src/LiteratureQuiz.java
@@ -0,0 +1,176 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of Literature Quiz
+ *
+ * Based on the Basic game of Literature Quiz here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/57%20Literature%20Quiz/litquiz.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class LiteratureQuiz {
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ private enum GAME_STATE {
+ STARTUP,
+ QUESTIONS,
+ RESULTS,
+ GAME_OVER
+ }
+
+ // Current game state
+ private GAME_STATE gameState;
+ // Players correct answers
+ private int correctAnswers;
+
+ public LiteratureQuiz() {
+
+ gameState = GAME_STATE.STARTUP;
+
+ // Initialise kb scanner
+ kbScanner = new Scanner(System.in);
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+
+ // Show an introduction the first time the game is played.
+ case STARTUP:
+ intro();
+ correctAnswers = 0;
+ gameState = GAME_STATE.QUESTIONS;
+ break;
+
+ // Ask the player four questions
+ case QUESTIONS:
+
+ // Question 1
+ System.out.println("IN PINOCCHIO, WHAT WAS THE NAME OF THE CAT");
+ int question1Answer = displayTextAndGetNumber("1)TIGGER, 2)CICERO, 3)FIGARO, 4)GUIPETTO ? ");
+ if (question1Answer == 3) {
+ System.out.println("VERY GOOD! HERE'S ANOTHER.");
+ correctAnswers++;
+ } else {
+ System.out.println("SORRY...FIGARO WAS HIS NAME.");
+ }
+
+ System.out.println();
+
+ // Question 2
+ System.out.println("FROM WHOSE GARDEN DID BUGS BUNNY STEAL THE CARROTS?");
+ int question2Answer = displayTextAndGetNumber("1)MR. NIXON'S, 2)ELMER FUDD'S, 3)CLEM JUDD'S, 4)STROMBOLI'S ? ");
+ if (question2Answer == 2) {
+ System.out.println("PRETTY GOOD!");
+ correctAnswers++;
+ } else {
+ System.out.println("TOO BAD...IT WAS ELMER FUDD'S GARDEN.");
+ }
+
+ System.out.println();
+
+ // Question 3
+ System.out.println("IN THE WIZARD OF OS, DOROTHY'S DOG WAS NAMED");
+ int question3Answer = displayTextAndGetNumber("1)CICERO, 2)TRIXIA, 3)KING, 4)TOTO ? ");
+ if (question3Answer == 4) {
+ System.out.println("YEA! YOU'RE A REAL LITERATURE GIANT.");
+ correctAnswers++;
+ } else {
+ System.out.println("BACK TO THE BOOKS,...TOTO WAS HIS NAME.");
+ }
+
+ System.out.println();
+
+ // Question 4
+ System.out.println("WHO WAS THE FAIR MAIDEN WHO ATE THE POISON APPLE");
+ int question4Answer = displayTextAndGetNumber("1)SLEEPING BEAUTY, 2)CINDERELLA, 3)SNOW WHITE, 4)WENDY ? ");
+ if (question4Answer == 3) {
+ System.out.println("GOOD MEMORY!");
+ correctAnswers++;
+ } else {
+ System.out.println("OH, COME ON NOW...IT WAS SNOW WHITE.");
+ }
+
+ System.out.println();
+ gameState = GAME_STATE.RESULTS;
+ break;
+
+ // How did the player do?
+ case RESULTS:
+ if (correctAnswers == 4) {
+ // All correct
+ System.out.println("WOW! THAT'S SUPER! YOU REALLY KNOW YOUR NURSERY");
+ System.out.println("YOUR NEXT QUIZ WILL BE ON 2ND CENTURY CHINESE");
+ System.out.println("LITERATURE (HA, HA, HA)");
+ // one or none correct
+ } else if (correctAnswers < 2) {
+ System.out.println("UGH. THAT WAS DEFINITELY NOT TOO SWIFT. BACK TO");
+ System.out.println("NURSERY SCHOOL FOR YOU, MY FRIEND.");
+ // two or three correct
+ } else {
+ System.out.println("NOT BAD, BUT YOU MIGHT SPEND A LITTLE MORE TIME");
+ System.out.println("READING THE NURSERY GREATS.");
+ }
+ gameState = GAME_STATE.GAME_OVER;
+ break;
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ public void intro() {
+ System.out.println(simulateTabs(25) + "LITERATURE QUIZ");
+ System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("LITERATURE QUIZ");
+ System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("TEST YOUR KNOWLEDGE OF CHILDREN'S LITERATURE.");
+ System.out.println("THIS IS A MULTIPLE-CHOICE QUIZ.");
+ System.out.println("TYPE A 1, 2, 3, OR 4 AFTER THE QUESTION MARK.");
+ System.out.println();
+ System.out.println("GOOD LUCK!");
+ System.out.println();
+ }
+
+ /**
+ * Simulate the old basic tab(xx) command which indented text by xx spaces.
+ *
+ * @param spaces number of spaces required
+ * @return String with number of spaces
+ */
+ private String simulateTabs(int spaces) {
+ char[] spacesTemp = new char[spaces];
+ Arrays.fill(spacesTemp, ' ');
+ return new String(spacesTemp);
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ * Converts input to an Integer
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private int displayTextAndGetNumber(String text) {
+ return Integer.parseInt(displayTextAndGetInput(text));
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+}
\ No newline at end of file
diff --git a/57 Literature Quiz/java/src/LiteratureQuizGame.java b/57 Literature Quiz/java/src/LiteratureQuizGame.java
new file mode 100644
index 00000000..3f7d9fd4
--- /dev/null
+++ b/57 Literature Quiz/java/src/LiteratureQuizGame.java
@@ -0,0 +1,8 @@
+public class LiteratureQuizGame {
+
+ public static void main(String[] args) {
+
+ LiteratureQuiz literatureQuiz = new LiteratureQuiz();
+ literatureQuiz.play();
+ }
+}
diff --git a/60 Mastermind/python/mastermind.py b/60 Mastermind/python/mastermind.py
new file mode 100644
index 00000000..ccc2ae9c
--- /dev/null
+++ b/60 Mastermind/python/mastermind.py
@@ -0,0 +1,230 @@
+import random, sys
+
+
+
+def main():
+
+ global colors, color_letters, num_positions, num_colors, human_score, computer_score
+ colors = ["BLACK", "WHITE", "RED", "GREEN", "ORANGE", "YELLOW", "PURPLE", "TAN"]
+ color_letters = "BWRGOYPT"
+
+ num_colors = 100
+ human_score = 0
+ computer_score = 0
+
+ # get user inputs for game conditions
+ print("Mastermind")
+ print('Creative Computing Morristown, New Jersey')
+ while num_colors > 8:
+ num_colors = int(input("Number of colors (max 8): ")) # C9 in BASIC
+ num_positions = int(input("Number of positions: ")) # P9 in BASIC
+ num_rounds = int(input("Number of rounds: ")) # R9 in BASIC
+ possibilities = num_colors**num_positions
+ all_possibilities = [1] * possibilities
+
+ print("Number of possibilities {}".format(possibilities))
+ print('Color\tLetter')
+ print('=====\t======')
+ for element in range(0, num_colors):
+ print("{}\t{}".format(colors[element], colors[element][0]))
+
+ current_round = 1
+
+ while current_round <= num_rounds:
+ print('Round number {}'.format(current_round))
+ num_moves = 1
+ guesses = []
+ turn_over = False
+ print('Guess my combination ...')
+ answer = int(possibilities * random.random())
+ numeric_answer = [-1] * num_positions
+ for i in range(0, answer):
+ numeric_answer = get_possibility(numeric_answer)
+ #human_readable_answer = make_human_readable(numeric_answer)
+ while (num_moves < 10 and not turn_over ):
+ print('Move # {} Guess : '.format(num_moves))
+ user_command = input('Guess ')
+ if user_command == "BOARD":
+ print_board(guesses) #2000
+ elif user_command == "QUIT": #2500
+ human_readable_answer = make_human_readable(numeric_answer)
+ print('QUITTER! MY COMBINATION WAS: {}'.format(human_readable_answer))
+ print('GOOD BYE')
+ quit()
+ elif len(user_command) != num_positions: #410
+ print("BAD NUMBER OF POSITIONS")
+ else:
+ invalid_letters = get_invalid_letters(user_command)
+ if invalid_letters > "":
+ print("INVALID GUESS: {}".format(invalid_letters))
+ else:
+ guess_results = compare_two_positions(user_command, make_human_readable(numeric_answer))
+ print("Results: {}".format(guess_results))
+ if guess_results[1] == num_positions: # correct guess
+ turn_over = True
+ print("You guessed it in {} moves!".format(num_moves))
+ human_score = human_score + num_moves
+ print_score()
+ else:
+ print("You have {} blacks and {} whites".format(guess_results[1], guess_results[2]))
+ num_moves = num_moves + 1
+ guesses.append(guess_results)
+ if not turn_over: # RAN OUT OF MOVES
+ print ("YOU RAN OUT OF MOVES! THAT'S ALL YOU GET!")
+ print("THE ACTUAL COMBINATION WAS: {}".format(make_human_readable(numeric_answer)))
+ human_score = human_score + num_moves
+ print_score()
+
+ # COMPUTER TURN
+ guesses = []
+ turn_over = False
+ inconsistent_information = False
+ while(not turn_over and not inconsistent_information ):
+ all_possibilities = [1] * possibilities
+ num_moves = 1
+ inconsistent_information = False
+ print ("NOW I GUESS. THINK OF A COMBINATION.")
+ player_ready = input("HIT RETURN WHEN READY: ")
+ while (num_moves < 10 and not turn_over and not inconsistent_information):
+ found_guess = False
+ computer_guess = int(possibilities * random.random())
+ if all_possibilities[computer_guess] == 1: # random guess is possible, use it
+ found_guess = True
+ guess = computer_guess
+ else:
+ for i in range (computer_guess, possibilities):
+ if all_possibilities[i] == 1:
+ found_guess = True
+ guess = i
+ break
+ if not found_guess:
+ for i in range (0, computer_guess):
+ if all_possibilities[i] == 1:
+ found_guess = True
+ guess = i
+ break
+ if not found_guess: # inconsistent info from user
+ print('YOU HAVE GIVEN ME INCONSISTENT INFORMATION.')
+ print('TRY AGAIN, AND THIS TIME PLEASE BE MORE CAREFUL.')
+ turn_over = True
+ inconsistent_information = True
+ else:
+ numeric_guess = [-1] * num_positions
+ for i in range(0, guess):
+ numeric_guess = get_possibility(numeric_guess)
+ human_readable_guess = make_human_readable(numeric_guess)
+ print('My guess is: {}'.format(human_readable_guess))
+ blacks, whites = input("ENTER BLACKS, WHITES (e.g. 1,2): ").split(",")
+ blacks = int(blacks)
+ whites = int(whites)
+ if blacks == num_positions: #Correct guess
+ print('I GOT IT IN {} MOVES'.format(num_moves))
+ turn_over = True
+ computer_score = computer_score + num_moves
+ print_score()
+ else:
+ num_moves += 1
+ for i in range (0, possibilities):
+ if all_possibilities[i] == 0: #already ruled out
+ continue
+ numeric_possibility = [-1] * num_positions
+ for j in range (0, i):
+ numeric_possibility = get_possibility(numeric_possibility)
+ human_readable_possibility = make_human_readable(numeric_possibility) #4000
+ comparison = compare_two_positions(human_readable_possibility, human_readable_guess)
+ print(comparison)
+ if ((blacks != comparison[1]) or (whites != comparison[2])):
+ all_possibilities[i] = 0
+ if not turn_over: # COMPUTER DID NOT GUESS
+ print("I USED UP ALL MY MOVES!")
+ print("I GUESS MY CPU IS JUST HAVING AN OFF DAY.")
+ computer_score = computer_score + num_moves
+ print_score()
+ current_round += 1
+ print_score(is_final_score=True)
+ sys.exit()
+
+#470
+def get_invalid_letters(user_command):
+ """Makes sure player input consists of valid colors for selected game configuration."""
+ valid_colors = color_letters[:num_colors]
+ invalid_letters = ""
+ for letter in user_command:
+ if letter not in valid_colors:
+ invalid_letters = invalid_letters + letter
+ return invalid_letters
+
+#2000
+def print_board(guesses):
+ """Prints previous guesses within the round."""
+ print("Board")
+ print("Move\tGuess\tBlack White")
+ for idx, guess in enumerate(guesses):
+ print('{}\t{}\t{} {}'.format(idx+1, guess[0], guess[1], guess[2]))
+
+#3500
+# Easily the place for most optimization, since they generate every possibility
+# every time when checking for potential solutions
+# From the original article:
+# "We did try a version that kept an actual list of all possible combinations
+# (as a string array), which was significantly faster than this versionn but
+# which ate tremendous amounts of memory."
+def get_possibility(possibility):
+ #print(possibility)
+ if possibility[0] > -1: #3530
+ current_position = 0 # Python arrays are zero-indexed
+ while True:
+ if possibility[current_position] < num_colors-1: # zero-index again
+ possibility[current_position] += 1
+ return possibility
+ else:
+ possibility[current_position] = 0
+ current_position += 1
+ else: #3524
+ possibility = [0] * num_positions
+ return possibility
+
+#4500
+def compare_two_positions(guess, answer):
+ """Returns blacks (correct color and position) and whites (correct color only) for candidate position (guess) versus reference position (answer)."""
+ increment = 0
+ blacks = 0
+ whites = 0
+ initial_guess = guess
+ for pos in range(0, num_positions):
+ if guess[pos] != answer[pos]:
+ for pos2 in range(0, num_positions):
+ if not(guess[pos] != answer[pos2] or guess[pos2] == answer[pos2]): # correct color but not correct place
+ whites = whites + 1
+ answer = answer[:pos2] + chr(increment) + answer[pos2+1:]
+ guess = guess[:pos] + chr(increment+1) + guess[pos+1:]
+ increment = increment + 2
+ else: #correct color and placement
+ blacks = blacks + 1
+ # THIS IS DEVIOUSLY CLEVER
+ guess = guess[:pos] + chr(increment+1) + guess[pos+1:]
+ answer = answer[:pos] + chr(increment) + answer[pos+1:]
+ increment = increment + 2
+ return [initial_guess, blacks, whites]
+
+#5000 + logic from 1160
+def print_score(is_final_score=False):
+ """Prints score after each turn ends, including final score at end of game."""
+ if is_final_score:
+ print("GAME OVER")
+ print("FINAL SCORE:")
+ else:
+ print("SCORE:")
+ print(" COMPUTER {}".format(computer_score))
+ print(" HUMAN {}".format(human_score))
+
+#4000, 5500, 6000 subroutines are all identical
+def make_human_readable(num):
+ """Make the numeric representation of a position human readable."""
+ retval = ''
+ for i in range(0, len(num)):
+ retval = retval + color_letters[int(num[i])]
+ return retval
+
+if __name__ == "__main__":
+ main()
diff --git a/69 Pizza/java/src/Pizza.java b/69 Pizza/java/src/Pizza.java
index f7e68f0e..55bf8ceb 100644
--- a/69 Pizza/java/src/Pizza.java
+++ b/69 Pizza/java/src/Pizza.java
@@ -1,5 +1,14 @@
import java.util.Scanner;
+/**
+ * Game of Pizza
+ *
+ * Based on the Basic game of Hurkle here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/69%20Pizza/pizza.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
public class Pizza {
private final int MAX_DELIVERIES = 5;
@@ -17,11 +26,11 @@ public class Pizza {
}
// houses that can order pizza
- private final char[] houses = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
+ private final char[] houses = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P'};
// size of grid
- private final int[] gridPos = new int[] { 1, 2, 3, 4};
+ private final int[] gridPos = new int[]{1, 2, 3, 4};
private GAME_STATE gameState;
@@ -38,7 +47,7 @@ public class Pizza {
public Pizza() {
- this.gameState = GAME_STATE.STARTING;
+ gameState = GAME_STATE.STARTING;
// Initialise kb scanner
kbScanner = new Scanner(System.in);
@@ -50,40 +59,40 @@ public class Pizza {
public void play() {
do {
- switch (this.gameState) {
+ switch (gameState) {
// Show an introduction the first time the game is played.
case STARTING:
init();
intro();
- this.gameState = GAME_STATE.ENTER_NAME;
+ gameState = GAME_STATE.ENTER_NAME;
break;
// Enter the players name
case ENTER_NAME:
- this.playerName = displayTextAndGetInput("WHAT IS YOUR FIRST NAME? ");
- System.out.println("HI " + this.playerName + ". IN THIS GAME YOU ARE TO TAKE ORDERS");
+ playerName = displayTextAndGetInput("WHAT IS YOUR FIRST NAME? ");
+ System.out.println("HI " + playerName + ". IN GAME YOU ARE TO TAKE ORDERS");
System.out.println("FOR PIZZAS. THEN YOU ARE TO TELL A DELIVERY BOY");
System.out.println("WHERE TO DELIVER THE ORDERED PIZZAS.");
System.out.println();
- this.gameState = GAME_STATE.DRAW_MAP;
+ gameState = GAME_STATE.DRAW_MAP;
break;
// Draw the map
case DRAW_MAP:
drawMap();
- this.gameState = GAME_STATE.MORE_DIRECTIONS;
+ gameState = GAME_STATE.MORE_DIRECTIONS;
break;
// need more directions (how to play) ?
case MORE_DIRECTIONS:
extendedIntro();
String moreInfo = displayTextAndGetInput("DO YOU NEED MORE DIRECTIONS? ");
- if(!yesOrNoEntered(moreInfo)) {
+ if (!yesOrNoEntered(moreInfo)) {
System.out.println("'YES' OR 'NO' PLEASE, NOW THEN,");
} else {
// More instructions selected
- if(yesEntered(moreInfo)) {
+ if (yesEntered(moreInfo)) {
displayMoreDirections();
// Player understand now?
if (yesEntered(displayTextAndGetInput("UNDERSTAND? "))) {
@@ -91,86 +100,86 @@ public class Pizza {
System.out.println();
System.out.println("GOOD LUCK!!");
System.out.println();
- this.gameState = GAME_STATE.START_DELIVER;
+ gameState = GAME_STATE.START_DELIVER;
} else {
// Not understood, essentially game over
- this.gameState = GAME_STATE.TOO_DIFFICULT;
+ gameState = GAME_STATE.TOO_DIFFICULT;
}
} else {
// no more directions were needed, start delivering pizza
- this.gameState = GAME_STATE.START_DELIVER;
+ gameState = GAME_STATE.START_DELIVER;
}
}
- break;
+ break;
// Too difficult to understand, game over!
case TOO_DIFFICULT:
- System.out.println("THIS JOB IS DEFINITELY TOO DIFFICULT FOR YOU. THANKS ANYWAY");
- this.gameState = GAME_STATE.GAME_OVER;
+ System.out.println("JOB IS DEFINITELY TOO DIFFICULT FOR YOU. THANKS ANYWAY");
+ gameState = GAME_STATE.GAME_OVER;
break;
// Delivering pizza
case START_DELIVER:
// select a random house and "order" a pizza for them.
- this.currentHouseDelivery = (int) (Math.random()
- * (this.houses.length) + 1) -1; // Deduct 1 for 0-based array
+ currentHouseDelivery = (int) (Math.random()
+ * (houses.length) + 1) - 1; // Deduct 1 for 0-based array
- System.out.println("HELLO " + this.playerName + "'S PIZZA. THIS IS "
- + this.houses[this.currentHouseDelivery] + ".");
+ System.out.println("HELLO " + playerName + "'S PIZZA. IS "
+ + houses[currentHouseDelivery] + ".");
System.out.println(" PLEASE SEND A PIZZA.");
- this.gameState = GAME_STATE.DELIVER_PIZZA;
+ gameState = GAME_STATE.DELIVER_PIZZA;
break;
// Try and deliver the pizza
case DELIVER_PIZZA:
- String question = " DRIVER TO " + this.playerName + ": WHERE DOES "
- + this.houses[this.currentHouseDelivery] + " LIVE ? ";
+ String question = " DRIVER TO " + playerName + ": WHERE DOES "
+ + houses[currentHouseDelivery] + " LIVE ? ";
String answer = displayTextAndGetInput(question);
// Convert x,y entered by player to grid position of a house
int x = getDelimitedValue(answer, 0);
int y = getDelimitedValue(answer, 1);
- int calculatedPos = (x + (y -1) * 4) -1;
+ int calculatedPos = (x + (y - 1) * 4) - 1;
// Did the player select the right house to deliver?
- if(calculatedPos == this.currentHouseDelivery) {
- System.out.println("HELLO " + this.playerName + ". THIS IS " + this.houses[this.currentHouseDelivery]
+ if (calculatedPos == currentHouseDelivery) {
+ System.out.println("HELLO " + playerName + ". IS " + houses[currentHouseDelivery]
+ ", THANKS FOR THE PIZZA.");
- this.pizzaDeliveryCount++;
+ pizzaDeliveryCount++;
// Delivered enough pizza?
- if(this.pizzaDeliveryCount > MAX_DELIVERIES) {
- this.gameState = GAME_STATE.END_GAME;
+ if (pizzaDeliveryCount > MAX_DELIVERIES) {
+ gameState = GAME_STATE.END_GAME;
} else {
- this.gameState = GAME_STATE.START_DELIVER;
+ gameState = GAME_STATE.START_DELIVER;
}
} else {
- System.out.println("THIS IS " + houses[calculatedPos] + ". I DID NOT ORDER A PIZZA.");
+ System.out.println("IS " + houses[calculatedPos] + ". I DID NOT ORDER A PIZZA.");
System.out.println("I LIVE AT " + x + "," + y);
- // Don't change gameState so this state is executed again
+ // Don't change gameState so state is executed again
}
break;
// Sign off message for cases where the Chief is not upset
case END_GAME:
- if(yesEntered(displayTextAndGetInput("DO YOU WANT TO DELIVER MORE PIZZAS? "))) {
+ if (yesEntered(displayTextAndGetInput("DO YOU WANT TO DELIVER MORE PIZZAS? "))) {
init();
- this.gameState = GAME_STATE.START_DELIVER;
+ gameState = GAME_STATE.START_DELIVER;
} else {
System.out.println();
- System.out.println("O.K. " + this.playerName + ", SEE YOU LATER!");
+ System.out.println("O.K. " + playerName + ", SEE YOU LATER!");
System.out.println();
- this.gameState = GAME_STATE.GAME_OVER;
+ gameState = GAME_STATE.GAME_OVER;
}
break;
// GAME_OVER State does not specifically have a case
}
- } while (this.gameState != GAME_STATE.GAME_OVER);
+ } while (gameState != GAME_STATE.GAME_OVER);
}
private void drawMap() {
@@ -179,19 +188,19 @@ public class Pizza {
System.out.println();
System.out.println(" -----1-----2-----3-----4-----");
int k = 3;
- for(int i=1; i<5; i++) {
+ for (int i = 1; i < 5; i++) {
System.out.println("-");
System.out.println("-");
System.out.println("-");
System.out.println("-");
- System.out.print(this.gridPos[k]);
+ System.out.print(gridPos[k]);
int pos = 16 - 4 * i;
- System.out.print(" " + this.houses[pos]);
- System.out.print(" " + this.houses[pos + 1]);
- System.out.print(" " + this.houses[pos + 2]);
- System.out.print(" " + this.houses[pos + 3]);
- System.out.println(" " + this.gridPos[k]);
+ System.out.print(" " + houses[pos]);
+ System.out.print(" " + houses[pos + 1]);
+ System.out.print(" " + houses[pos + 2]);
+ System.out.print(" " + houses[pos + 3]);
+ System.out.println(" " + gridPos[k]);
k = k - 1;
}
System.out.println("-");
@@ -199,10 +208,10 @@ public class Pizza {
System.out.println("-");
System.out.println("-");
System.out.println(" -----1-----2-----3-----4-----");
-}
+ }
+
/**
* Basic information about the game
- *
*/
private void intro() {
System.out.println("PIZZA");
@@ -229,14 +238,14 @@ public class Pizza {
System.out.println("DELIVERED. THEN A DELIVERY BOY WILL");
System.out.println("ASK YOU FOR THE LOCATION.");
System.out.println(" EXAMPLE:");
- System.out.println("THIS IS J. PLEASE SEND A PIZZA.");
- System.out.println("DRIVER TO " + this.playerName + ". WHERE DOES J LIVE?");
+ System.out.println("IS J. PLEASE SEND A PIZZA.");
+ System.out.println("DRIVER TO " + playerName + ". WHERE DOES J LIVE?");
System.out.println("YOUR ANSWER WOULD BE 2,3");
System.out.println();
}
private void init() {
- this.pizzaDeliveryCount = 1;
+ pizzaDeliveryCount = 1;
}
/**
@@ -273,19 +282,20 @@ public class Pizza {
private boolean yesOrNoEntered(String text) {
return stringIsAnyValue(text, "Y", "YES", "N", "NO");
}
+
/**
* Returns true if a given string contains at least one of the varargs (2nd parameter).
* Note: Case insensitive comparison.
*
- * @param text string to search
+ * @param text string to search
* @param values varargs of type string containing values to compare
* @return true if one of the varargs arguments was found in text
*/
private boolean stringIsAnyValue(String text, String... values) {
// Cycle through the variable number of values and test each
- for(String val:values) {
- if(text.equalsIgnoreCase(val)) {
+ for (String val : values) {
+ if (text.equalsIgnoreCase(val)) {
return true;
}
}
diff --git a/69 Pizza/java/src/PizzaGame.java b/69 Pizza/java/src/PizzaGame.java
index 2a94afc9..b7074fa4 100644
--- a/69 Pizza/java/src/PizzaGame.java
+++ b/69 Pizza/java/src/PizzaGame.java
@@ -2,7 +2,7 @@ public class PizzaGame {
public static void main(String[] args) {
- Pizza pizza = new Pizza();
- pizza.play();
+ Pizza pizza = new Pizza();
+ pizza.play();
}
}
diff --git a/73 Reverse/python/reverse.py b/73 Reverse/python/reverse.py
new file mode 100755
index 00000000..b73c779d
--- /dev/null
+++ b/73 Reverse/python/reverse.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+import random
+import textwrap
+
+
+NUMCNT = 9 # How many numbers are we playing with?
+
+
+def play():
+ print('REVERSE'.center(72))
+ print('CREATIVE COMPUTING MORRISTOWN, NEW JERSEY'.center(72))
+ print()
+ print()
+ print('REVERSE -- A GAME OF SKILL')
+ print()
+
+ if not input('DO YOU WANT THE RULES? (yes/no) ').lower().startswith('n'):
+ rules()
+
+ while True:
+ game_loop()
+
+ if not input('TRY AGAIN? (yes/no) ').lower().startswith('y'):
+ return
+
+
+def game_loop():
+ """Play the main game."""
+ # Make a random list from 1 to NUMCNT
+ numbers = list(range(1, NUMCNT + 1))
+ random.shuffle(numbers)
+
+ # Print original list and start the game
+ print()
+ print('HERE WE GO ... THE LIST IS:')
+ print_list(numbers)
+
+ turns = 0
+ while True:
+ try:
+ howmany = int(input('HOW MANY SHALL I REVERSE? '))
+ assert howmany >= 0
+ except (ValueError, AssertionError):
+ continue
+
+ if howmany == 0:
+ return
+
+ if howmany > NUMCNT:
+ print('OOPS! WRONG! I CAN REVERSE AT MOST', NUMCNT)
+ continue
+
+ turns += 1
+
+ # Reverse as many items as requested.
+ newnums = numbers[0:howmany]
+ newnums.reverse()
+ newnums.extend(numbers[howmany:])
+ numbers = newnums
+
+ print_list(numbers)
+
+ # Check for a win
+ if all(numbers[i] == i + 1 for i in range(NUMCNT)):
+ print('YOU WON IT IN {} MOVES!'.format(turns))
+ print()
+ return
+
+
+def print_list(numbers):
+ """Print out the list"""
+ print(' '.join(map(str, numbers)))
+
+
+def rules():
+ """Print out the rules"""
+ help = textwrap.dedent("""
+ THIS IS THE GAME OF "REVERSE". TO WIN, ALL YOU HAVE
+ TO DO IS ARRANGE A LIST OF NUMBERS (1 THROUGH {})
+ IN NUMERICAL ORDER FROM LEFT TO RIGHT. TO MOVE, YOU
+ TELL ME HOW MANY NUMBERS (COUNTING FROM THE LEFT) TO
+ REVERSE. FOR EXAMPLE, IF THE CURRENT LIST IS:
+
+ 2 3 4 5 1 6 7 8 9
+
+ AND YOU REVERSE 4, THE RESULT WILL BE:
+
+ 5 4 3 2 1 6 7 8 9
+
+ NOW IF YOU REVERSE 5, YOU WIN!
+
+ 1 2 3 4 5 6 7 8 9
+
+ NO DOUBT YOU WILL LIKE THIS GAME, BUT
+ IF YOU WANT TO QUIT, REVERSE 0 (ZERO).
+ """.format(NUMCNT))
+ print(help)
+ print()
+
+
+if __name__ == '__main__':
+ try:
+ play()
+ except KeyboardInterrupt:
+ pass
diff --git a/74 Rock Scissors Paper/csharp/Choice.cs b/74 Rock Scissors Paper/csharp/Choice.cs
new file mode 100644
index 00000000..c981a45a
--- /dev/null
+++ b/74 Rock Scissors Paper/csharp/Choice.cs
@@ -0,0 +1,19 @@
+namespace RockScissorsPaper
+{
+ public class Choice
+ {
+ public string Selector {get; private set; }
+ public string Name { get; private set; }
+ internal Choice CanBeat { get; set; }
+
+ public Choice(string selector, string name) {
+ Selector = selector;
+ Name = name;
+ }
+
+ public bool Beats(Choice choice)
+ {
+ return choice == CanBeat;
+ }
+ }
+}
diff --git a/74 Rock Scissors Paper/csharp/Choices.cs b/74 Rock Scissors Paper/csharp/Choices.cs
new file mode 100644
index 00000000..3026d7cc
--- /dev/null
+++ b/74 Rock Scissors Paper/csharp/Choices.cs
@@ -0,0 +1,42 @@
+using System;
+
+namespace RockScissorsPaper
+{
+ public class Choices
+ {
+ public static readonly Choice Rock = new Choice("3", "Rock");
+ public static readonly Choice Scissors = new Choice("2", "Scissors");
+ public static readonly Choice Paper = new Choice("1", "Paper");
+
+ private static readonly Choice[] _allChoices;
+ private static readonly Random _random = new Random();
+
+ static Choices()
+ {
+ Rock.CanBeat = Scissors;
+ Scissors.CanBeat = Paper;
+ Paper.CanBeat = Rock;
+
+ _allChoices = new[] { Rock, Scissors, Paper };
+ }
+
+ public static Choice GetRandom()
+ {
+ return _allChoices[_random.Next(_allChoices.GetLength(0))];
+ }
+
+ public static bool TryGetBySelector(string selector, out Choice choice)
+ {
+ foreach (var possibleChoice in _allChoices)
+ {
+ if (string.Equals(possibleChoice.Selector, selector))
+ {
+ choice = possibleChoice;
+ return true;
+ }
+ }
+ choice = null;
+ return false;
+ }
+ }
+}
diff --git a/74 Rock Scissors Paper/csharp/Game.cs b/74 Rock Scissors Paper/csharp/Game.cs
new file mode 100644
index 00000000..8916a217
--- /dev/null
+++ b/74 Rock Scissors Paper/csharp/Game.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Linq;
+
+namespace RockScissorsPaper
+{
+ public class Game
+ {
+ public int ComputerWins { get; private set; }
+ public int HumanWins { get; private set; }
+ public int TieGames { get; private set; }
+
+ public void PlayGame()
+ {
+ var computerChoice = Choices.GetRandom();
+ var humanChoice = GetHumanChoice();
+
+ Console.WriteLine("This is my choice...");
+ Console.WriteLine("...{0}", computerChoice.Name);
+
+ if (humanChoice.Beats(computerChoice))
+ {
+ Console.WriteLine("You win!!!");
+ HumanWins++;
+ }
+ else if (computerChoice.Beats(humanChoice))
+ {
+ Console.WriteLine("Wow! I win!!!");
+ ComputerWins++;
+ }
+ else
+ {
+ Console.WriteLine("Tie game. No winner.");
+ TieGames++;
+ }
+ }
+
+ public void WriteFinalScore()
+ {
+ Console.WriteLine();
+ Console.WriteLine("Here is the final game score:");
+ Console.WriteLine("I have won {0} game(s).", ComputerWins);
+ Console.WriteLine("You have one {0} game(s).", HumanWins);
+ Console.WriteLine("And {0} game(s) ended in a tie.", TieGames);
+ }
+
+ public Choice GetHumanChoice()
+ {
+ while (true)
+ {
+ Console.WriteLine("3=Rock...2=Scissors...1=Paper");
+ Console.WriteLine("1...2...3...What's your choice");
+ if (Choices.TryGetBySelector(Console.ReadLine(), out var choice))
+ return choice;
+ Console.WriteLine("Invalid.");
+ }
+ }
+ }
+}
diff --git a/74 Rock Scissors Paper/csharp/Program.cs b/74 Rock Scissors Paper/csharp/Program.cs
new file mode 100644
index 00000000..acd49e4b
--- /dev/null
+++ b/74 Rock Scissors Paper/csharp/Program.cs
@@ -0,0 +1,48 @@
+using System;
+
+namespace RockScissorsPaper
+{
+ static class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("GAME OF ROCK, SCISSORS, PAPER");
+ Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine();
+
+ var numberOfGames = GetNumberOfGames();
+
+ var game = new Game();
+ for (var gameNumber = 1; gameNumber <= numberOfGames; gameNumber++) {
+ Console.WriteLine();
+ Console.WriteLine("Game number {0}", gameNumber);
+
+ game.PlayGame();
+ }
+
+ game.WriteFinalScore();
+
+ Console.WriteLine();
+ Console.WriteLine("Thanks for playing!!");
+ }
+
+ static int GetNumberOfGames()
+ {
+ while (true) {
+ Console.WriteLine("How many games");
+ if (int.TryParse(Console.ReadLine(), out var number))
+ {
+ if (number < 11 && number > 0)
+ return number;
+ Console.WriteLine("Sorry, but we aren't allowed to play that many.");
+ }
+ else
+ {
+ Console.WriteLine("Sorry, I didn't understand.");
+ }
+ }
+ }
+ }
+}
diff --git a/74 Rock Scissors Paper/csharp/RockScissorsPaper.csproj b/74 Rock Scissors Paper/csharp/RockScissorsPaper.csproj
new file mode 100644
index 00000000..6e6a5510
--- /dev/null
+++ b/74 Rock Scissors Paper/csharp/RockScissorsPaper.csproj
@@ -0,0 +1,9 @@
+
+
+
+ Exe
+ net5.0
+ RockScissorsPaper
+
+
+
diff --git a/74 Rock Scissors Paper/javascript/rockscissors.html b/74 Rock Scissors Paper/javascript/rockscissors.html
new file mode 100644
index 00000000..2b938a5f
--- /dev/null
+++ b/74 Rock Scissors Paper/javascript/rockscissors.html
@@ -0,0 +1,9 @@
+
+
+ROCK, SCISSORS, PAPER
+
+
+
+
+
+
diff --git a/74 Rock Scissors Paper/javascript/rockscissors.js b/74 Rock Scissors Paper/javascript/rockscissors.js
new file mode 100644
index 00000000..a5d86862
--- /dev/null
+++ b/74 Rock Scissors Paper/javascript/rockscissors.js
@@ -0,0 +1,107 @@
+// ROCK, SCISSORS, PAPER
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+// Main control section
+async function main()
+{
+ print(tab(21) + "GAME OF ROCK, SCISSORS, PAPER\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ while (1) {
+ print("HOW MANY GAMES");
+ q = parseInt(await input());
+ if (q >= 11)
+ print("SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY.\n");
+ else
+ break;
+ }
+ h = 0; // Human
+ c = 0; // Computer
+ for (g = 1; g <= q; g++ ) {
+ print("\n");
+ print("GAME NUMBER " + g + "\n");
+ x = Math.floor(Math.random() * 3 + 1);
+ while (1) {
+ print("3=ROCK...2=SCISSORS...1=PAPER\n");
+ print("1...2...3...WHAT'S YOUR CHOICE");
+ k = parseInt(await input());
+ if (k != 1 && k != 2 && k != 3)
+ print("INVALID.\n");
+ else
+ break;
+ }
+ print("THIS IS MY CHOICE...");
+ switch (x) {
+ case 1:
+ print("...PAPER\n");
+ break;
+ case 2:
+ print("...SCISSORS\n");
+ break;
+ case 3:
+ print("...ROCK\n");
+ break;
+ }
+ if (x == k) {
+ print("TIE GAME. NO WINNER.\n");
+ } else if ((x > k && (k != 1 || x != 3)) || (x == 1 && k == 3)) {
+ print("WOW! I WIN!!!\n");
+ c++;
+ } else {
+ print("YOU WIN!!!\n");
+ h++;
+ }
+ }
+ print("\n");
+ print("HERE IS THE FINAL GAME SCORE:\n");
+ print("I HAVE WON " + c + " GAME(S).\n");
+ print("YOU HAVE WON " + h + " GAME(S).\n");
+ print("AND " + (q - (c + h)) + " GAME(S) ENDED IN A TIE.\n");
+ print("\n");
+ print("THANKS FOR PLAYING!!\n");
+}
+
+main();
diff --git a/76 Russian Roulette/csharp/RussianRoulette/Program.cs b/76 Russian Roulette/csharp/RussianRoulette/Program.cs
new file mode 100644
index 00000000..43a8d4bc
--- /dev/null
+++ b/76 Russian Roulette/csharp/RussianRoulette/Program.cs
@@ -0,0 +1,106 @@
+using System;
+
+namespace RussianRoulette
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ PrintTitle();
+
+ var includeRevolver = true;
+ while (true)
+ {
+ PrintInstructions(includeRevolver);
+ switch (PlayGame())
+ {
+ case GameResult.Win:
+ includeRevolver = true;
+ break;
+ case GameResult.Chicken:
+ case GameResult.Dead:
+ includeRevolver = false;
+ break;
+ }
+ }
+ }
+
+ private static void PrintTitle()
+ {
+ Console.WriteLine(" Russian Roulette");
+ Console.WriteLine("Creative Computing Morristown, New Jersey");
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine("This is a game of >>>>>>>>>>Russian Roulette.");
+ }
+
+ private static void PrintInstructions(bool includeRevolver)
+ {
+ Console.WriteLine();
+ if (includeRevolver)
+ {
+ Console.WriteLine("Here is a revolver.");
+ }
+ else
+ {
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine("...Next Victim...");
+ }
+ Console.WriteLine("Type '1' to spin chamber and pull trigger.");
+ Console.WriteLine("Type '2' to give up.");
+ }
+
+ private static GameResult PlayGame()
+ {
+ var rnd = new Random();
+ var round = 0;
+ while (true)
+ {
+ round++;
+ Console.Write("Go: ");
+ var input = Console.ReadKey().KeyChar;
+ Console.WriteLine();
+ if (input != '2')
+ {
+ // Random.Next will retun a value that is the same or greater than the minimum and
+ // less than the maximum.
+ // A revolver has 6 rounds.
+ if (rnd.Next(1, 7) == 6)
+ {
+ Console.WriteLine(" Bang!!!!! You're dead!");
+ Console.WriteLine("Condolences will be sent to your relatives.");
+ return GameResult.Dead;
+ }
+ else
+ {
+ if (round > 10)
+ {
+ Console.WriteLine("You win!!!!!");
+ Console.WriteLine("Let someone else blow their brains out.");
+ return GameResult.Win;
+ }
+ else
+ {
+ Console.WriteLine("- CLICK -");
+ Console.WriteLine();
+ }
+ }
+ }
+ else
+ {
+ Console.WriteLine(" CHICKEN!!!!!");
+ return GameResult.Chicken;
+ }
+ }
+ }
+
+ private enum GameResult
+ {
+ Win,
+ Chicken,
+ Dead
+ }
+ }
+}
diff --git a/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.csproj b/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.csproj
new file mode 100644
index 00000000..20827042
--- /dev/null
+++ b/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ net5.0
+
+
+
diff --git a/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.sln b/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.sln
new file mode 100644
index 00000000..1e4b621e
--- /dev/null
+++ b/76 Russian Roulette/csharp/RussianRoulette/RussianRoulette.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31019.35
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RussianRoulette", "RussianRoulette.csproj", "{9F052B4A-FA33-4BBE-9D9D-3CF8152569F1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9F052B4A-FA33-4BBE-9D9D-3CF8152569F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9F052B4A-FA33-4BBE-9D9D-3CF8152569F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9F052B4A-FA33-4BBE-9D9D-3CF8152569F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9F052B4A-FA33-4BBE-9D9D-3CF8152569F1}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {97F5B1B0-A80A-4C1F-9F76-8D68B4A49E82}
+ EndGlobalSection
+EndGlobal
diff --git a/78 Sine Wave/java/SineWave.java b/78 Sine Wave/java/src/SineWave.java
similarity index 90%
rename from 78 Sine Wave/java/SineWave.java
rename to 78 Sine Wave/java/src/SineWave.java
index 7d917a75..f3b3c7eb 100644
--- a/78 Sine Wave/java/SineWave.java
+++ b/78 Sine Wave/java/src/SineWave.java
@@ -6,7 +6,7 @@ import java.util.Arrays;
* Based on the Sine Wave program here
* https://github.com/coding-horror/basic-computer-games/blob/main/78%20Sine%20Wave/sinewave.bas
*
- * Note: The idea was to create a version of this 1970's Basic program in Java, without introducing
+ * Note: The idea was to create a version of the 1970's Basic program in Java, without introducing
* new features - no additional text, error checking, etc has been added.
*/
public class SineWave {
diff --git a/78 Sine Wave/perl/sinewave.pl b/78 Sine Wave/perl/sinewave.pl
new file mode 100644
index 00000000..a28d3865
--- /dev/null
+++ b/78 Sine Wave/perl/sinewave.pl
@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+print ' ' x 30 ."SINE WAVE\n";
+print ' ' x 15 ."CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n";
+print "\n\n\n\n\n";
+
+my $B=0;
+
+for (my $T=0; $T<40; $T+=.25) {
+ my $A=int(26+25*sin($T));
+ print ' ' x $A;
+ if ($B==0) { print "CREATIVE\n"; }
+ if ($B==1) { print "COMPUTING\n"; }
+ $B= !$B; #Toggle
+ }
diff --git a/78 Sine Wave/ruby/sinewave.rb b/78 Sine Wave/ruby/sinewave.rb
new file mode 100644
index 00000000..001e2cd8
--- /dev/null
+++ b/78 Sine Wave/ruby/sinewave.rb
@@ -0,0 +1,15 @@
+def intro
+ puts " SINE WAVE
+ CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n\n\n\n"
+end
+
+def main
+ intro
+ (0..40).step(0.25).each do |t|
+ a = (26 + 25 * Math.sin(t)).to_i
+ text = (t % 0.5) == 0 ? "CREATIVE" : "COMPUTING"
+ puts " " * a + text
+ end
+end
+
+main
\ No newline at end of file
diff --git a/80 Slots/python/slots.py b/80 Slots/python/slots.py
new file mode 100644
index 00000000..fbae665b
--- /dev/null
+++ b/80 Slots/python/slots.py
@@ -0,0 +1,159 @@
+########################################################
+#
+# Slots
+#
+# From Basic Computer Games (1978)
+#
+# "The slot machine or one-arm bandit is a mechanical
+# device that will absorb coins just about as fast as
+# you can feed it. After inserting a coin, you pull a
+# handle that sets three indepent reels spining. If the
+# reels stop with certain symbols appearing in the pay
+# line, you get a certain payoff. The original slot
+# machine, called the Liberty bell, was invented in 1895
+# by Charles Fey in San Francisco. Fey refused to sell
+# or lease the manufacturing rights, so H.S. Mills in
+# Chicago built a similar, but much improved, machine
+# called the Operators Bell. This has survived nearly
+# unchanged to today.
+# On the operators Bell and other standard slot
+# machines, there are 20 symbols on each wheel but they
+# are not distributed evenly among the objects(cherries,
+# bar, apples, etc). Of the 8000 possible combinations,
+# the expected payoff(to the player) is 7049 or $89.11
+# for every $100.00 put in, one of the lowest expected
+# payoffs of all casino games.
+# In the program here, the payoff is considerably more
+# liberal; indeed it appears to favor the player by 11%
+# -- i.e., an expected payoff of $111 for each $100 bet."
+# The program was originally written by Fred Mirabelle
+# and Bob Harper
+#
+########################################################
+
+from random import choices
+from collections import Counter
+import sys
+
+
+def initial_message():
+ print(" "*30 + "Slots")
+ print(" "*15 + "Creative Computing Morrison, New Jersey")
+ print("\n"*3)
+ print("You are in the H&M Casino, in front of one of our")
+ print("one-arm Bandits. Bet from $1 to $100.")
+ print("To pull the arm, punch the return key after making your bet.")
+
+
+def input_betting():
+ print("\n")
+ b = -1
+ while b < 1 or b > 100:
+ try:
+ b = int(input("Your bet:"))
+ except ValueError:
+ b = -1
+ if b > 100:
+ print("House limits are $100")
+ elif b < 1:
+ print("Minium bet is $1")
+ beeping()
+ return int(b)
+
+
+def beeping():
+ # Function to produce a beep sound.
+ # In the original program is the subroutine at line 1270
+ for _ in range(5):
+ sys.stdout.write('\a')
+ sys.stdout.flush()
+
+
+def spin_wheels():
+ possible_fruits = ["Bar", "Bell", "Orange", "Lemon", "Plum", "Cherry"]
+ wheel = choices(possible_fruits, k=3)
+
+ print(*wheel)
+ beeping()
+
+ return wheel
+
+
+def adjust_profits(wheel, m, profits):
+ # we remove the duplicates
+ s = set(wheel)
+
+ if len(s) == 1:
+ # the three fruits are the same
+ fruit = s.pop()
+
+ if fruit == "Bar":
+ print("\n***Jackpot***")
+ profits = (((100*m)+m)+profits)
+ else:
+ print("\n**Top Dollar**")
+ profits = (((10*m)+m)+profits)
+
+ print("You Won!")
+ elif len(s) == 2:
+ # two fruits are equal
+ c = Counter(wheel)
+ # we get the fruit that appears two times
+ fruit = sorted(c.items(), key=lambda x: x[1], reverse=True)[0][0]
+
+ if fruit == "Bar":
+ print("\n*Double Bar*")
+ profits = (((5*m)+m)+profits)
+ else:
+ print("\nDouble!!")
+ profits = (((2*m)+m)+profits)
+
+ print("You Won!")
+ else:
+ # three different fruits
+ print("\nYou Lost.")
+ profits = profits - m
+
+ return profits
+
+
+def final_message(profits):
+ if profits < 0:
+ print("Pay up! Please leave your money on the terminal")
+ elif profits == 0:
+ print("Hey, You broke even.")
+ else:
+ print("Collect your winings from the H&M cashier.")
+
+
+profits = 0
+keep_betting = True
+
+initial_message()
+while keep_betting:
+ m = input_betting()
+ w = spin_wheels()
+ profits = adjust_profits(w, m, profits)
+
+ print("Your standings are ${}".format(profits))
+ answer = input("Again?")
+
+ try:
+ if not answer[0].lower() == "y":
+ keep_betting = False
+ except IndexError:
+ keep_betting = False
+
+final_message(profits)
+
+
+######################################################################
+#
+# Porting notes
+#
+# The selections of the fruits(Bar, apples, lemon, etc.) are made
+# with equal probability, accordingly to random.choices documentation.
+# It could be added a weights list to the function and therefore
+# adjust the expected payoff
+#
+######################################################################
diff --git a/82 Stars/java/src/Stars.java b/82 Stars/java/src/Stars.java
index f28a0510..75e7cdd6 100644
--- a/82 Stars/java/src/Stars.java
+++ b/82 Stars/java/src/Stars.java
@@ -7,7 +7,7 @@ import java.util.Scanner;
* Based on the Basic game of Stars here
* https://github.com/coding-horror/basic-computer-games/blob/main/82%20Stars/stars.bas
*
- * Note: The idea was to create a version of this 1970's Basic game in Java, without introducing
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
* new features - no additional text, error checking, etc has been added.
*/
public class Stars {
@@ -42,7 +42,7 @@ public class Stars {
public Stars() {
- this.gameState = GAME_STATE.STARTING;
+ gameState = GAME_STATE.STARTING;
// Initialise kb scanner
kbScanner = new Scanner(System.in);
@@ -68,30 +68,30 @@ public class Stars {
if(yesEntered(displayTextAndGetInput("DO YOU WANT INSTRUCTIONS? "))) {
instructions();
}
- this.gameState = GAME_STATE.START_GAME;
+ gameState = GAME_STATE.START_GAME;
break;
// Generate computers number for player to guess, etc.
case START_GAME:
init();
System.out.println("OK, I AM THINKING OF A NUMBER, START GUESSING.");
- this.gameState = GAME_STATE.GUESSING;
+ gameState = GAME_STATE.GUESSING;
break;
// Player guesses the number until they get it or run out of guesses
case GUESSING:
- this.playerCurrentGuess = playerGuess();
+ playerCurrentGuess = playerGuess();
// Check if the player guessed the number
- if(this.playerCurrentGuess == this.computersNumber) {
- this.gameState = GAME_STATE.WON;
+ if(playerCurrentGuess == computersNumber) {
+ gameState = GAME_STATE.WON;
} else {
// incorrect guess
showStars();
- this.playerTotalGuesses++;
+ playerTotalGuesses++;
// Ran out of guesses?
- if (this.playerTotalGuesses > MAX_GUESSES) {
- this.gameState = GAME_STATE.LOST;
+ if (playerTotalGuesses > MAX_GUESSES) {
+ gameState = GAME_STATE.LOST;
}
}
break;
@@ -100,16 +100,16 @@ public class Stars {
case WON:
System.out.println(stars(79));
- System.out.println("YOU GOT IT IN " + this.playerTotalGuesses
+ System.out.println("YOU GOT IT IN " + playerTotalGuesses
+ " GUESSES!!! LET'S PLAY AGAIN...");
- this.gameState = GAME_STATE.START_GAME;
+ gameState = GAME_STATE.START_GAME;
break;
// Lost game by running out of guesses
case LOST:
System.out.println("SORRY, THAT'S " + MAX_GUESSES
- + " GUESSES. THE NUMBER WAS " + this.computersNumber);
- this.gameState = GAME_STATE.START_GAME;
+ + " GUESSES. THE NUMBER WAS " + computersNumber);
+ gameState = GAME_STATE.START_GAME;
break;
}
// Endless loop since the original code did not allow the player to exit
@@ -123,7 +123,7 @@ public class Stars {
*
*/
private void showStars() {
- int d = Math.abs(this.playerCurrentGuess - this.computersNumber);
+ int d = Math.abs(playerCurrentGuess - computersNumber);
int starsToShow;
if(d >=64) {
starsToShow = 1;
@@ -159,8 +159,8 @@ public class Stars {
*
*/
private void init() {
- this.playerTotalGuesses = 1;
- this.computersNumber = randomNumber();
+ playerTotalGuesses = 1;
+ computersNumber = randomNumber();
}
public void instructions() {
diff --git a/87 3-D Plot/perl/3dplot.pl b/87 3-D Plot/perl/3dplot.pl
new file mode 100644
index 00000000..a7cfb1c6
--- /dev/null
+++ b/87 3-D Plot/perl/3dplot.pl
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+print ' 'x32 ."3D PLOT\n";
+print ' 'x15 ."CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n";
+print "\n\n\n";
+
+sub FNA {
+ my ($Z)= @_;
+ return 30*exp(-$Z*$Z/100);
+ }
+
+print "\n";
+
+for (my $X=-30; $X<=30; $X+=1.5) {
+ my $L=0;
+ my $Line=" "x80; #Empty buffer string;
+ my $Y1=5*int(sqrt(900-$X*$X)/5);
+ for (my $Y=$Y1; $Y>=-$Y1; $Y-=5) {
+ my $Z=int(25+&FNA(sqrt($X*$X+$Y*$Y))-.7*$Y);
+ if ($Z<=$L) { next; }
+ $L= $Z;
+ substr $Line, $Z, 1, "*"; #Plot on the line by sustitution.
+ }
+ print "$Line\n"; #Now print the line.
+ }
diff --git a/87 3-D Plot/python/3dplot.py b/87 3-D Plot/python/3dplot.py
index 99e8c438..2dda44ff 100644
--- a/87 3-D Plot/python/3dplot.py
+++ b/87 3-D Plot/python/3dplot.py
@@ -9,8 +9,8 @@ import math
def equation(input):
return 30 * math.exp(-input * input / 100)
-print(" " * 32 + "3D PLOT\n")
-print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n")
+print(" " * 32 + "3D PLOT")
+print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n\n")
for x in range (-300, 315, 15):
x1 = x / 10
@@ -23,4 +23,4 @@ for x in range (-300, 315, 15):
if z > l:
l = z
yPlot[z] = "*"
- print("".join(yPlot) + "\n")
\ No newline at end of file
+ print("".join(yPlot))
\ No newline at end of file
diff --git a/87 3-D Plot/ruby/3dplot.rb b/87 3-D Plot/ruby/3dplot.rb
new file mode 100644
index 00000000..9c4e8394
--- /dev/null
+++ b/87 3-D Plot/ruby/3dplot.rb
@@ -0,0 +1,28 @@
+def intro
+ puts " 3D PLOT
+ CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n\n\n"
+end
+
+def fna(z) = 30 * Math.exp(-z * z / 100)
+
+def render
+ (-30..30).step(1.5).each do |x|
+ l = 0
+ y1 = 5 * (Math.sqrt(900 - x * x) / 5).to_i
+ y_plot = " " * 80
+ (y1..-y1).step(-5).each do |y|
+ z = (25 + fna(Math.sqrt(x * x + y * y)) - 0.7 * y).to_i
+ next if z <= l
+ l = z
+ y_plot[z] = '*'
+ end
+ puts y_plot
+ end
+end
+
+def main
+ intro
+ render
+end
+
+main
\ No newline at end of file
diff --git a/91 Train/java/src/Train.java b/91 Train/java/src/Train.java
new file mode 100644
index 00000000..0fc5ff12
--- /dev/null
+++ b/91 Train/java/src/Train.java
@@ -0,0 +1,109 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Train
+ *
+ * Based on the Basic program Train here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/91%20Train/train.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic program in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class Train {
+
+ private final Scanner kbScanner;
+
+ public Train() {
+ kbScanner = new Scanner(System.in);
+ }
+
+ public void process() {
+
+ intro();
+
+ boolean gameOver = false;
+
+ do {
+ double carMph = (int) (25 * Math.random() + 40);
+ double hours = (int) (15 * Math.random() + 5);
+ double train = (int) (19 * Math.random() + 20);
+
+ System.out.println(" A CAR TRAVELING " + (int) carMph + " MPH CAN MAKE A CERTAIN TRIP IN");
+ System.out.println((int) hours + " HOURS LESS THAN A TRAIN TRAVELING AT " + (int) train + " MPH.");
+
+ double howLong = Double.parseDouble(displayTextAndGetInput("HOW LONG DOES THE TRIP TAKE BY CAR? "));
+
+ double hoursAnswer = hours * train / (carMph - train);
+ int percentage = (int) (Math.abs((hoursAnswer - howLong) * 100 / howLong) + .5);
+ if (percentage > 5) {
+ System.out.println("SORRY. YOU WERE OFF BY " + percentage + " PERCENT.");
+ } else {
+ System.out.println("GOOD! ANSWER WITHIN " + percentage + " PERCENT.");
+ }
+ System.out.println("CORRECT ANSWER IS " + hoursAnswer + " HOURS.");
+
+ System.out.println();
+ if (!yesEntered(displayTextAndGetInput("ANOTHER PROBLEM (YES OR NO)? "))) {
+ gameOver = true;
+ }
+
+ } while (!gameOver);
+
+
+ }
+
+ private void intro() {
+ System.out.println("TRAIN");
+ System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println("TIME - SPEED DISTANCE EXERCISE");
+ System.out.println();
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Checks whether player entered Y or YES to a question.
+ *
+ * @param text player string from kb
+ * @return true of Y or YES was entered, otherwise false
+ */
+ private boolean yesEntered(String text) {
+ return stringIsAnyValue(text, "Y", "YES");
+ }
+
+ /**
+ * Check whether a string equals one of a variable number of values
+ * Useful to check for Y or YES for example
+ * Comparison is case insensitive.
+ *
+ * @param text source string
+ * @param values a range of values to compare against the source string
+ * @return true if a comparison was found in one of the variable number of strings passed
+ */
+ private boolean stringIsAnyValue(String text, String... values) {
+
+ return Arrays.stream(values).anyMatch(str -> str.equalsIgnoreCase(text));
+
+ }
+
+ /**
+ * Program startup.
+ *
+ * @param args not used (from command line).
+ */
+ public static void main(String[] args) {
+ Train train = new Train();
+ train.process();
+ }
+}
diff --git a/91 Train/javascript/train.html b/91 Train/javascript/train.html
new file mode 100644
index 00000000..3aee95e2
--- /dev/null
+++ b/91 Train/javascript/train.html
@@ -0,0 +1,9 @@
+
+
+TRAIN
+
+
+
+
+
+
diff --git a/91 Train/javascript/train.js b/91 Train/javascript/train.js
new file mode 100644
index 00000000..e49d00bc
--- /dev/null
+++ b/91 Train/javascript/train.js
@@ -0,0 +1,80 @@
+// TRAIN
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+// Main control section
+async function main()
+{
+ print(tab(33) + "TRAIN\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("TIME - SPEED DISTANCE EXERCISE\n");
+ print("\n ");
+ while (1) {
+ c = Math.floor(25 * Math.random()) + 40;
+ d = Math.floor(15 * Math.random()) + 5;
+ t = Math.floor(19 * Math.random()) + 20;
+ print(" A CAR TRAVELING " + c + " MPH CAN MAKE A CERTAIN TRIP IN\n");
+ print(d + " HOURS LESS THAN A TRAIN TRAVELING AT " + t + " MPH.\n");
+ print("HOW LONG DOES THE TRIP TAKE BY CAR");
+ a = parseFloat(await input());
+ v = d * t / (c - t);
+ e = Math.floor(Math.abs((v - a) * 100 / a) + 0.5);
+ if (e > 5) {
+ print("SORRY. YOU WERE OFF BY " + e + " PERCENT.\n");
+ } else {
+ print("GOOD! ANSWER WITHIN " + e + " PERCENT.\n");
+ }
+ print("CORRECT ANSWER IS " + v + " HOURS.\n");
+ print("\n");
+ print("ANOTHER PROBLEM (YES OR NO)\n");
+ str = await input();
+ print("\n");
+ if (str.substr(0, 1) != "Y")
+ break;
+ }
+}
+
+main();
diff --git a/91 Train/perl/train.pl b/91 Train/perl/train.pl
new file mode 100644
index 00000000..d628b12c
--- /dev/null
+++ b/91 Train/perl/train.pl
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+print ' 'x33 ."TRAIN\n";
+print ' 'x15 ."CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n";
+print "\n\n\n";
+print "TIME - SPEED DISTANCE EXERCISE\n"; print "\n";
+
+
+my $A= ""; #We must declare this before...
+do {
+ my $C= int(25*rand(1))+40;
+ my $D= int(15*rand(1))+5;
+ my $T= int(19*rand(1))+20;
+
+ print " A CAR TRAVELING $C MPH CAN MAKE A CERTAIN TRIP IN\n";
+ print "$D HOURS LESS THAN A TRAIN TRAVELING AT $T MPH.\n";
+ print "HOW LONG DOES THE TRIP TAKE BY CAR\n";
+ chomp ($A = );
+
+ my $V= $D*$T/($C-$T);
+ my $E= int(abs(($V-$A)*100/$A)+.5);
+ if ($E>5) {
+ print "SORRY. YOU WERE OFF BY $E PERCENT.\n";
+ } else {
+ print "GOOD! ANSWER WITHIN $E PERCENT.\n";
+ }
+
+ print "CORRECT ANSWER IS $V HOURS.\n";
+ print "\n";
+ print "ANOTHER PROBLEM (YES OR NO)\n";
+ chomp ($A = uc()); #Uppercased
+ } until ($A ne "YES");
diff --git a/91 Train/python/train.py b/91 Train/python/train.py
new file mode 100644
index 00000000..0fd68b3c
--- /dev/null
+++ b/91 Train/python/train.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+# TRAIN
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+
+def play_game():
+ """Play one round of the game"""
+ car_speed = random.randint(40, 65)
+ time_difference = random.randint(5, 20)
+ train_speed = random.randint(20, 39)
+ print("\nA car travelling", car_speed, "MPH can make a certain trip in")
+ print(time_difference, "hours less than a train travelling at", train_speed, "MPH")
+ time_answer = 0
+ while time_answer == 0:
+ try:
+ time_answer = float(input("How long does the trip take by car "))
+ except ValueError:
+ print("Please enter a number.")
+ car_time = time_difference*train_speed/(car_speed-train_speed)
+ error_percent = int(abs((car_time-time_answer)*100/time_answer)+.5)
+ if error_percent > 5:
+ print("Sorry. You were off by", error_percent, "percent.")
+ print("Correct answer is", round(car_time, 6), "hours")
+ else:
+ print("Good! Answer within", error_percent, "percent.")
+
+
+def main():
+ print(" " * 33 + "TRAIN")
+ print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n")
+ print("Time - speed distance exercise")
+
+ keep_playing = True
+ while keep_playing:
+ play_game()
+ keep_playing = input(
+ "\nAnother problem (yes or no) ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/91 Train/ruby/train.rb b/91 Train/ruby/train.rb
new file mode 100644
index 00000000..c6850035
--- /dev/null
+++ b/91 Train/ruby/train.rb
@@ -0,0 +1,58 @@
+def intro
+ puts " TRAIN
+ CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
+
+
+
+TIME - SPEED DISTANCE EXERCISE
+
+"
+end
+
+def get_user_guess
+ while true
+ begin
+ number = Float(gets.chomp)
+ return number
+ rescue ArgumentError
+ # Ignored
+ end
+
+ puts "!NUMBER EXPECTED - RETRY INPUT LINE"
+ print "? "
+ end
+end
+
+def main
+ intro
+
+ loop do
+ car_speed = rand(25) + 40
+ car_time = rand(15) + 5
+ train_speed = rand(19) + 20
+
+ print " A CAR TRAVELING #{car_speed} MPH CAN MAKE A CERTAIN TRIP IN
+ #{car_time} HOURS LESS THAN A TRAIN TRAVELING AT #{train_speed} MPH.
+HOW LONG DOES THE TRIP TAKE BY CAR? "
+ guess = get_user_guess
+
+ answer = ((car_time * train_speed) / (car_speed - train_speed).to_f).round(5)
+ delta = (((answer - guess) * 100 / guess) + 0.5).abs.to_i
+
+ if delta > 5
+ puts "SORRY. YOU WERE OFF BY #{delta} PERCENT."
+ else
+ puts "GOOD! ANSWER WITHIN #{delta} PERCENT."
+ end
+
+ print "CORRECT ANSWER IS #{answer == answer.to_i ? answer.to_i : answer} HOURS.
+
+ANOTHER PROBLEM (YES OR NO)? "
+ option = (gets || '').chomp.upcase
+ break unless option == 'YES'
+ end
+end
+
+trap "SIGINT" do puts; exit 130 end
+
+main
\ No newline at end of file
diff --git a/92 Trap/java/src/Trap.java b/92 Trap/java/src/Trap.java
new file mode 100644
index 00000000..d3dd5824
--- /dev/null
+++ b/92 Trap/java/src/Trap.java
@@ -0,0 +1,201 @@
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Game of Trap
+ *
+ * Based on the Basic game of Trap here
+ * https://github.com/coding-horror/basic-computer-games/blob/main/92%20Trap/trap.bas
+ *
+ * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
+ * new features - no additional text, error checking, etc has been added.
+ */
+public class Trap {
+
+ public static final int HIGH_NUMBER_RANGE = 100;
+ public static final int MAX_GUESSES = 6;
+
+ private enum GAME_STATE {
+ STARTING,
+ START_GAME,
+ GUESSING,
+ PLAY_AGAIN,
+ GAME_OVER
+ }
+
+ // Used for keyboard input
+ private final Scanner kbScanner;
+
+ // Current game state
+ private GAME_STATE gameState;
+
+ // Players guess count;
+ private int currentPlayersGuess;
+
+ // Computers random number
+ private int computersNumber;
+
+ public Trap() {
+
+ gameState = GAME_STATE.STARTING;
+
+ // Initialise kb scanner
+ kbScanner = new Scanner(System.in);
+ }
+
+ /**
+ * Main game loop
+ */
+ public void play() {
+
+ do {
+ switch (gameState) {
+
+ // Show an introduction and optional instructions the first time the game is played.
+ case STARTING:
+ intro();
+ if (yesEntered(displayTextAndGetInput("INSTRUCTIONS? "))) {
+ instructions();
+ }
+ gameState = GAME_STATE.START_GAME;
+ break;
+
+ // Start new game
+ case START_GAME:
+ computersNumber = randomNumber();
+ currentPlayersGuess = 1;
+ gameState = GAME_STATE.GUESSING;
+ break;
+
+ // Player guesses the number until they get it or run out of guesses
+ case GUESSING:
+ System.out.println();
+ String playerRangeGuess = displayTextAndGetInput("GUESS # " + currentPlayersGuess + "? ");
+ int startRange = getDelimitedValue(playerRangeGuess, 0);
+ int endRange = getDelimitedValue(playerRangeGuess, 1);
+
+ // Has the player won?
+ if (startRange == computersNumber && endRange == computersNumber) {
+ System.out.println("YOU GOT IT!!!");
+ System.out.println();
+ gameState = GAME_STATE.PLAY_AGAIN;
+ } else {
+ // show where the guess is at
+ System.out.println(showGuessResult(startRange, endRange));
+ currentPlayersGuess++;
+ if (currentPlayersGuess > MAX_GUESSES) {
+ System.out.println("SORRY, THAT'S " + MAX_GUESSES + " GUESSES. THE NUMBER WAS "
+ + computersNumber);
+ gameState = GAME_STATE.PLAY_AGAIN;
+ }
+ }
+ break;
+
+ // Play again, or exit game?
+ case PLAY_AGAIN:
+ System.out.println("TRY AGAIN");
+ gameState = GAME_STATE.START_GAME;
+ }
+ } while (gameState != GAME_STATE.GAME_OVER);
+ }
+
+ /**
+ * Show the players guess result
+ *
+ * @param start start range entered by player
+ * @param end end range
+ * @return text to indicate their progress.
+ */
+ private String showGuessResult(int start, int end) {
+
+ String status;
+ if (start <= computersNumber && computersNumber <= end) {
+ status = "YOU HAVE TRAPPED MY NUMBER.";
+ } else if (computersNumber < start) {
+ status = "MY NUMBER IS SMALLER THAN YOUR TRAP NUMBERS.";
+ } else {
+ status = "MY NUMBER IS LARGER THAN YOUR TRAP NUMBERS.";
+ }
+
+ return status;
+ }
+
+ private void instructions() {
+ System.out.println("I AM THINKING OF A NUMBER BETWEEN 1 AND " + HIGH_NUMBER_RANGE);
+ System.out.println("TRY TO GUESS MY NUMBER. ON EACH GUESS,");
+ System.out.println("YOU ARE TO ENTER 2 NUMBERS, TRYING TO TRAP");
+ System.out.println("MY NUMBER BETWEEN THE TWO NUMBERS. I WILL");
+ System.out.println("TELL YOU IF YOU HAVE TRAPPED MY NUMBER, IF MY");
+ System.out.println("NUMBER IS LARGER THAN YOUR TWO NUMBERS, OR IF");
+ System.out.println("MY NUMBER IS SMALLER THAN YOUR TWO NUMBERS.");
+ System.out.println("IF YOU WANT TO GUESS ONE SINGLE NUMBER, TYPE");
+ System.out.println("YOUR GUESS FOR BOTH YOUR TRAP NUMBERS.");
+ System.out.println("YOU GET " + MAX_GUESSES + " GUESSES TO GET MY NUMBER.");
+ }
+
+ private void intro() {
+ System.out.println("TRAP");
+ System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ System.out.println();
+ System.out.println();
+ }
+
+ /**
+ * Accepts a string delimited by comma's and returns the nth delimited
+ * value (starting at count 0).
+ *
+ * @param text - text with values separated by comma's
+ * @param pos - which position to return a value for
+ * @return the int representation of the value
+ */
+ private int getDelimitedValue(String text, int pos) {
+ String[] tokens = text.split(",");
+ return Integer.parseInt(tokens[pos]);
+ }
+
+ /**
+ * Checks whether player entered Y or YES to a question.
+ *
+ * @param text player string from kb
+ * @return true of Y or YES was entered, otherwise false
+ */
+ private boolean yesEntered(String text) {
+ return stringIsAnyValue(text, "Y", "YES");
+ }
+
+ /**
+ * Check whether a string equals one of a variable number of values
+ * Useful to check for Y or YES for example
+ * Comparison is case insensitive.
+ *
+ * @param text source string
+ * @param values a range of values to compare against the source string
+ * @return true if a comparison was found in one of the variable number of strings passed
+ */
+ private boolean stringIsAnyValue(String text, String... values) {
+
+ return Arrays.stream(values).anyMatch(str -> str.equalsIgnoreCase(text));
+ }
+
+ /*
+ * Print a message on the screen, then accept input from Keyboard.
+ *
+ * @param text message to be displayed on screen.
+ * @return what was typed by the player.
+ */
+ private String displayTextAndGetInput(String text) {
+ System.out.print(text);
+ return kbScanner.next();
+ }
+
+ /**
+ * Generate random number
+ * Used as a single digit of the computer player
+ *
+ * @return random number
+ */
+ private int randomNumber() {
+ return (int) (Math.random()
+ * (HIGH_NUMBER_RANGE) + 1);
+ }
+}
\ No newline at end of file
diff --git a/92 Trap/java/src/TrapGame.java b/92 Trap/java/src/TrapGame.java
new file mode 100644
index 00000000..754446e2
--- /dev/null
+++ b/92 Trap/java/src/TrapGame.java
@@ -0,0 +1,8 @@
+public class TrapGame {
+
+ public static void main(String[] args) {
+
+ Trap trap = new Trap();
+ trap.play();
+ }
+}
diff --git a/92 Trap/javascript/trap.html b/92 Trap/javascript/trap.html
new file mode 100644
index 00000000..1084e1de
--- /dev/null
+++ b/92 Trap/javascript/trap.html
@@ -0,0 +1,9 @@
+
+
+TRAP
+
+
+
+
+
+
diff --git a/92 Trap/javascript/trap.js b/92 Trap/javascript/trap.js
new file mode 100644
index 00000000..c2a5a2f3
--- /dev/null
+++ b/92 Trap/javascript/trap.js
@@ -0,0 +1,102 @@
+// TRAP
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+// Main control section
+async function main()
+{
+ print(tab(34) + "TRAP\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ g = 6;
+ n = 100;
+ // Trap
+ // Steve Ullman, Aug/01/1972
+ print("INSTRUCTIONS");
+ str = await input();
+ if (str.substr(0, 1) == "Y") {
+ print("I AM THINKING OF A NUMBER BETWEEN 1 AND " + n + "\n");
+ print("TRY TO GUESS MY NUMBER. ON EACH GUESS,\n");
+ print("YOU ARE TO ENTER 2 NUMBERS, TRYING TO TRAP\n");
+ print("MY NUMBER BETWEEN THE TWO NUMBERS. I WILL\n");
+ print("TELL YOU IF YOU HAVE TRAPPED MY NUMBER, IF MY\n");
+ print("NUMBER IS LARGER THAN YOUR TWO NUMBERS, OR IF\n");
+ print("MY NUMBER IS SMALLER THAN YOUR TWO NUMBERS.\n");
+ print("IF YOU WANT TO GUESS ONE SINGLE NUMBER, TYPE\n");
+ print("YOUR GUESS FOR BOTH YOUR TRAP NUMBERS.\n");
+ print("YOU GET " + g + " GUESSES TO GET MY NUMBER.\n");
+ }
+ while (1) {
+ x = Math.floor(n * Math.random()) + 1;
+ for (q = 1; q <= g; q++) {
+ print("\n");
+ print("GUESS #" + q + " ");
+ str = await input();
+ a = parseInt(str);
+ b = parseInt(str.substr(str.indexOf(",") + 1));
+ if (a == b && x == a) {
+ print("YOU GOT IT!!!\n");
+ break;
+ }
+ if (a > b) {
+ r = a;
+ a = b;
+ b = r;
+ }
+ if (a <= x && x <= b) {
+ print("YOU HAVE TRAPPED MY NUMBER.\n");
+ } else if (x >= a) {
+ print("MY NUMBER IS LARGER THAN YOUR TRAP NUMBERS.\n");
+ } else {
+ print("MY NUMBER IS SMALLER THAN YOUR TRAP NUMBERS.\n");
+ }
+ }
+ print("\n");
+ print("TRY AGAIN.\n");
+ print("\n");
+ }
+}
+
+main();
diff --git a/92 Trap/python/trap.py b/92 Trap/python/trap.py
new file mode 100644
index 00000000..772bd3c5
--- /dev/null
+++ b/92 Trap/python/trap.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+# TRAP
+#
+# STEVE ULLMAN, 8-1-72
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+number_max = 100
+guess_max = 6
+
+
+def play_game():
+ """Play one round of the game"""
+
+ number_computer = random.randint(1, number_max)
+ turn = 0
+ while True:
+ turn += 1
+ user_guess = [-1, -1]
+ while user_guess == [-1, -1]:
+ try:
+ user_input = [int(item) for item in input(
+ "\nGuess # " + str(turn) + " ? ").split(",")]
+ if len(user_input) == 2:
+ if sum(1 < x < number_max for x in user_input) == 2:
+ user_guess = user_input
+ else:
+ raise ValueError
+ else:
+ raise ValueError
+ except (ValueError, IndexError):
+ print("Please enter a valid guess.")
+ if user_guess[0] > user_guess[1]:
+ user_guess[0], user_guess[1] = user_guess[1], user_guess[0]
+ if user_guess[0] == user_guess[1] == number_computer:
+ print("You got it!!!")
+ break
+ elif user_guess[0] <= number_computer <= user_guess[1]:
+ print("You have trapped my number.")
+ elif number_computer < user_guess[0]:
+ print("My number is smaller than your trap numbers.")
+ else:
+ print("My number is larger than your trap numbers.")
+ if turn == guess_max:
+ print("That's", turn, "guesses. The number was", number_computer)
+ break
+
+
+def main():
+ print(" " * 34 + "TRAP")
+ print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n")
+ if input("Instructions ").lower().startswith("y"):
+ print("\nI am thinking of a number between 1 and", number_max)
+ print("try to guess my number. On each guess,")
+ print("you are to enter 2 numbers, trying to trap")
+ print("my number between the two numbers. I will")
+ print("tell you if you have trapped my number, if my")
+ print("number is larger than your two numbers, or if")
+ print("my number is smaller than your two numbers.")
+ print("If you want to guess one single number, type")
+ print("your guess for both your trap numbers.")
+ print("You get", guess_max, "guesses to get my number.")
+
+ keep_playing = True
+ while keep_playing:
+ play_game()
+ keep_playing = input(
+ "\nTry again. ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/93 23 Matches/javascript/23matches.html b/93 23 Matches/javascript/23matches.html
new file mode 100644
index 00000000..70d67217
--- /dev/null
+++ b/93 23 Matches/javascript/23matches.html
@@ -0,0 +1,9 @@
+
+
+23 MATCHES
+
+
+
+
+
+
diff --git a/93 23 Matches/javascript/23matches.js b/93 23 Matches/javascript/23matches.js
new file mode 100644
index 00000000..2233cda6
--- /dev/null
+++ b/93 23 Matches/javascript/23matches.js
@@ -0,0 +1,122 @@
+// 23 MATCHES
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+// Main control section
+async function main()
+{
+ print(tab(31) + "23 MATCHES\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print(" THIS IS A GAME CALLED '23 MATCHES'.\n");
+ print("\n");
+ print("WHEN IT IS YOUR TURN, YOU MAY TAKE ONE, TWO, OR THREE\n");
+ print("MATCHES. THE OBJECT OF THE GAME IS NOT TO HAVE TO TAKE\n");
+ print("THE LAST MATCH.\n");
+ print("\n");
+ print("LET'S FLIP A COIN TO SEE WHO GOES FIRST.\n");
+ print("IF IT COMES UP HEADS, I WILL WIN THE TOSS.\n");
+ print("\n");
+ n = 23;
+ q = Math.floor(2 * Math.random());
+ if (q != 1) {
+ print("TAILS! YOU GO FIRST. \n");
+ print("\n");
+ } else {
+ print("HEADS! I WIN! HA! HA!\n");
+ print("PREPARE TO LOSE, MEATBALL-NOSE!!\n");
+ print("\n");
+ print("I TAKE 2 MATCHES\n");
+ n -= 2;
+ }
+ while (1) {
+ if (q == 1) {
+ print("THE NUMBER OF MATCHES IS NOW " + n + "\n");
+ print("\n");
+ print("YOUR TURN -- YOU MAY TAKE 1, 2 OR 3 MATCHES.\n");
+ }
+ print("HOW MANY DO YOU WISH TO REMOVE ");
+ while (1) {
+ k = parseInt(await input());
+ if (k <= 0 || k > 3) {
+ print("VERY FUNNY! DUMMY!\n");
+ print("DO YOU WANT TO PLAY OR GOOF AROUND?\n");
+ print("NOW, HOW MANY MATCHES DO YOU WANT ");
+ } else {
+ break;
+ }
+ }
+ n -= k;
+ print("THERE ARE NOW " + n + " MATCHES REMAINING.\n");
+ if (n == 4) {
+ z = 3;
+ } else if (n == 3) {
+ z = 2;
+ } else if (n == 2) {
+ z = 1;
+ } else if (n > 1) {
+ z = 4 - k;
+ } else {
+ print("YOU WON, FLOPPY EARS !\n");
+ print("THINK YOU'RE PRETTY SMART !\n");
+ print("LETS PLAY AGAIN AND I'LL BLOW YOUR SHOES OFF !!\n");
+ break;
+ }
+ print("MY TURN ! I REMOVE " + z + " MATCHES\n");
+ n -= z;
+ if (n <= 1) {
+ print("\n");
+ print("YOU POOR BOOB! YOU TOOK THE LAST MATCH! I GOTCHA!!\n");
+ print("HA ! HA ! I BEAT YOU !!!\n");
+ print("\n");
+ print("GOOD BYE LOSER!\n");
+ break;
+ }
+ q = 1;
+ }
+
+}
+
+main();
diff --git a/93 23 Matches/python/23matches.py b/93 23 Matches/python/23matches.py
new file mode 100755
index 00000000..189f5aa6
--- /dev/null
+++ b/93 23 Matches/python/23matches.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+# 23 Matches
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+
+def play_game():
+ """Play one round of the game"""
+
+ matches = 23
+ humans_turn = random.randint(0, 1) == 1
+ if humans_turn:
+ print("Tails! You go first.\n")
+ prompt_human = "How many do you wish to remove "
+ else:
+ print("Heads! I win! Ha! Ha!")
+ print("Prepare to lose, meatball-nose!!")
+
+ choice_human = 2
+ while matches > 0:
+ if humans_turn:
+ choice_human = 0
+ if matches == 1:
+ choice_human = 1
+ while choice_human == 0:
+ try:
+ choice_human = int(input(prompt_human))
+ if choice_human not in [1, 2, 3] or choice_human > matches:
+ choice_human = 0
+ print("Very funny! Dummy!")
+ print("Do you want to play or goof around?")
+ prompt_human = "Now, how many matches do you want "
+ except ValueError:
+ print("Please enter a number.")
+ prompt_human = "How many do you wish to remove "
+ matches = matches - choice_human
+ if matches == 0:
+ print("You poor boob! You took the last match! I gotcha!!")
+ print("Ha ! Ha ! I beat you !!\n")
+ print("Good bye loser!")
+ else:
+ print("There are now", matches, "matches remaining.\n")
+ else:
+ choice_computer = 4 - choice_human
+ if matches == 1:
+ choice_computer = 1
+ elif 1 < matches < 4:
+ choice_computer = matches - 1
+ matches = matches - choice_computer
+ if matches == 0:
+ print("You won, floppy ears !")
+ print("Think you're pretty smart !")
+ print("Let's play again and I'll blow your shoes off !!")
+ else:
+ print("My turn ! I remove", choice_computer, "matches")
+ print("The number of matches is now", matches, "\n")
+ humans_turn = not humans_turn
+ prompt_human = "Your turn -- you may take 1, 2 or 3 matches.\nHow many do you wish to remove "
+
+
+def main():
+ print(" " * 31 + "23 MATCHHES")
+ print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n")
+ print("This is a game called '23 Matches'.\n")
+ print("When it is your turn, you may take one, two, or three")
+ print("matches. The object of the game is not to have to take")
+ print("the last match.\n")
+ print("Let's flip a coin to see who goes first.")
+ print("If it comes up heads, I will win the toss.\n")
+
+ keep_playing = True
+ while keep_playing:
+ play_game()
+ keep_playing = input(
+ "\nPlay again? (yes or no) ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/94 War/javascript/war.html b/94 War/javascript/war.html
new file mode 100644
index 00000000..67cab7d2
--- /dev/null
+++ b/94 War/javascript/war.html
@@ -0,0 +1,9 @@
+
+
+WAR
+
+
+
+
+
+
diff --git a/94 War/javascript/war.js b/94 War/javascript/war.js
new file mode 100644
index 00000000..eb74fb0c
--- /dev/null
+++ b/94 War/javascript/war.js
@@ -0,0 +1,136 @@
+// WAR
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+var a = [, "S-2","H-2","C-2","D-2","S-3","H-3","C-3","D-3",
+ "S-4","H-4","C-4","D-4","S-5","H-5","C-5","D-5",
+ "S-6","H-6","C-6","D-6","S-7","H-7","C-7","D-7",
+ "S-8","H-8","C-8","D-8","S-9","H-9","C-9","D-9",
+ "S-10","H-10","C-10","D-10","S-J","H-J","C-J","D-J",
+ "S-Q","H-Q","C-Q","D-Q","S-K","H-K","C-K","D-K",
+ "S-A","H-A","C-A","D-A"];
+
+var l = [];
+
+// Main control section
+async function main()
+{
+ print(tab(33) + "WAR\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("THIS IS THE CARD GAME OF WAR. EACH CARD IS GIVEN BY SUIT-#\n");
+ print("AS S-7 FOR SPADE 7. ");
+ while (1) {
+ print("DO YOU WANT DIRECTIONS");
+ str = await input();
+ if (str == "YES") {
+ print("THE COMPUTER GIVES YOU AND IT A 'CARD'. THE HIGHER CARD\n");
+ print("(NUMERICALLY) WINS. THE GAME ENDS WHEN YOU CHOOSE NOT TO\n");
+ print("CONTINUE OR WHEN YOU HAVE FINISHED THE PACK.\n");
+ break;
+ }
+ if (str == "NO")
+ break;
+ print("YES OR NO, PLEASE. ");
+ }
+ print("\n");
+ print("\n");
+
+ a1 = 0;
+ b1 = 0;
+ p = 0;
+
+ // Generate a random deck
+ for (j = 1; j <= 52; j++) {
+ do {
+ l[j] = Math.floor(52 * Math.random()) + 1;
+ for (k = 1; k < j; k++) {
+ if (l[k] == l[j]) // Already in deck?
+ break;
+ }
+ } while (j != 1 && k < j) ;
+ }
+ l[j] = 0; // Mark the end of the deck
+
+ while (1) {
+ m1 = l[++p]; // Take a card
+ m2 = l[++p]; // Take a card
+ print("\n");
+ print("YOU: " + a[m1] + "\tCOMPUTER: " + a[m2] + "\n");
+ n1 = Math.floor((m1 - 0.5) / 4);
+ n2 = Math.floor((m2 - 0.5) / 4);
+ if (n1 < n2) {
+ a1++;
+ print("THE COMPUTER WINS!!! YOU HAVE " + b1 + " AND THE COMPUTER HAS " + a1 + "\n");
+ } else if (n1 > n2) {
+ b1++;
+ print("YOU WIN. YOU HAVE " + b1 + " AND THE COMPUTER HAS " + a1 + "\n");
+ } else {
+ print("TIE. NO SCORE CHANGE.\n");
+ }
+ if (l[p + 1] == 0) {
+ print("\n");
+ print("\n");
+ print("WE HAVE RUN OUT OF CARDS. FINAL SCORE: YOU: " + b1 + " THE COMPUTER: " + a1 + "\n");
+ print("\n");
+ break;
+ }
+ while (1) {
+ print("DO YOU WANT TO CONTINUE");
+ str = await input();
+ if (str == "YES")
+ break;
+ if (str == "NO")
+ break;
+ print("YES OR NO, PLEASE. ");
+ }
+ if (str == "NO")
+ break;
+ }
+ print("THANKS FOR PLAYING. IT WAS FUN.\n");
+ print("\n");
+}
+
+main();
diff --git a/94 War/python/war.py b/94 War/python/war.py
new file mode 100755
index 00000000..ebd87036
--- /dev/null
+++ b/94 War/python/war.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+# WAR
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+
+def card_value(input):
+ return ["2", "3", "4", "5", "6", "7", "8",
+ "9", "10", "J", "Q", "K", "A"].index(input.split("-")[1])
+
+
+cards = ["S-2", "H-2", "C-2", "D-2", "S-3", "H-3", "C-3", "D-3",
+ "S-4", "H-4", "C-4", "D-4", "S-5", "H-5", "C-5", "D-5",
+ "S-6", "H-6", "C-6", "D-6", "S-7", "H-7", "C-7", "D-7",
+ "S-8", "H-8", "C-8", "D-8", "S-9", "H-9", "C-9", "D-9",
+ "S-10", "H-10", "C-10", "D-10", "S-J", "H-J", "C-J", "D-J",
+ "S-Q", "H-Q", "C-Q", "D-Q", "S-K", "H-K", "C-K", "D-K",
+ "S-A", "H-A", "C-A", "D-A"]
+
+
+def play_game():
+ """Play one round of the game"""
+
+ random.shuffle(cards)
+ score_you = 0
+ score_computer = 0
+ cards_left = 52
+ for round in range(26):
+ print()
+ card_you = cards[round]
+ card_computer = cards[round * 2]
+ print("You:", card_you, " " * (8 - len(card_you)) +
+ "Computer:", card_computer)
+ value_you = card_value(card_you)
+ value_computer = card_value(card_computer)
+ if value_you > value_computer:
+ score_you += 1
+ print("You win. You have", score_you,
+ "and the computer has", score_computer)
+ elif value_computer > value_you:
+ score_computer += 1
+ print("The computer wins!!! You have", score_you,
+ "and the computer has", score_computer)
+ else:
+ print("Tie. No score change.")
+ cards_left -= 2
+ if cards_left > 2:
+ if input("Do you want to continue ").lower().startswith("n"):
+ break
+ if cards_left == 0:
+ print("\nWe have run out of cards. Final score: You:",
+ score_you, "the computer:", score_computer)
+ print("\nThanks for playing. It was fun.")
+
+
+def main():
+ print(" " * 33 + "WAR")
+ print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n")
+ print("This is the card game of war. Each card is given by suit-#")
+ print("as S-7 for Spade 7.")
+ if input("Do you want directions ").lower().startswith("y"):
+ print("The computer gives you and it a 'card'. The higher card")
+ print("(numerically) wins. The game ends when you choose not to")
+ print("contine or when you have finished the pack.")
+
+ keep_playing = True
+ while keep_playing:
+ play_game()
+ keep_playing = input(
+ "\nPlay again? (yes or no) ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/95 Weekday/javascript/weekday.html b/95 Weekday/javascript/weekday.html
new file mode 100644
index 00000000..928df878
--- /dev/null
+++ b/95 Weekday/javascript/weekday.html
@@ -0,0 +1,9 @@
+
+
+WEEKDAY
+
+
+
+
+
+
diff --git a/95 Weekday/javascript/weekday.js b/95 Weekday/javascript/weekday.js
new file mode 100644
index 00000000..276e1817
--- /dev/null
+++ b/95 Weekday/javascript/weekday.js
@@ -0,0 +1,208 @@
+// WEEKDAY
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+function fna(arg) {
+ return Math.floor(arg / 4);
+}
+
+function fnb(arg) {
+ return Math.floor(arg / 7);
+}
+
+var t = [, 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5];
+
+var k5;
+var k6;
+var k7;
+
+function time_spent(f, a8)
+{
+ k1 = Math.floor(f * a8);
+ i5 = Math.floor(k1 / 365);
+ k1 -= i5 * 365;
+ i6 = Math.floor(k1 / 30);
+ i7 = k1 - (i6 * 30);
+ k5 -= i5;
+ k6 -= i6;
+ k7 -= i7;
+ if (k7 < 0) {
+ k7 += 30;
+ k6--;
+ }
+ if (k6 <= 0) {
+ k6 += 12;
+ k5--;
+ }
+ print(i5 + "\t" + i6 + "\t" + i7 + "\n");
+}
+
+// Main control section
+async function main()
+{
+ print(tab(32) + "WEEKDAY\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("WEEKDAY IS A COMPUTER DEMONSTRATION THAT\n");
+ print("GIVES FACTS ABOUT A DATE OF INTEREST TO YOU.\n");
+ print("\n");
+ print("ENTER TODAY'S DATE IN THE FORM: 3,24,1979 ");
+ str = await input();
+ m1 = parseInt(str);
+ d1 = parseInt(str.substr(str.indexOf(",") + 1));
+ y1 = parseInt(str.substr(str.lastIndexOf(",") + 1));
+ // This program determines the day of the week
+ // for a date after 1582
+ print("ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST)");
+ str = await input();
+ m = parseInt(str);
+ d = parseInt(str.substr(str.indexOf(",") + 1));
+ y = parseInt(str.substr(str.lastIndexOf(",") + 1));
+ print("\n");
+ i1 = Math.floor((y - 1500) / 100);
+ // Test for date before current calendar.
+ if (y - 1582 < 0) {
+ print("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII.\n");
+ } else {
+ a = i1 * 5 + (i1 + 3) / 4;
+ i2 = Math.floor(a - fnb(a) * 7);
+ y2 = Math.floor(y / 100);
+ y3 = Math.floor(y - y2 * 100);
+ a = y3 / 4 + y3 + d + t[m] + i2;
+ b = Math.floor(a - fnb(a) * 7) + 1;
+ if (m <= 2) {
+ if (y3 != 0) {
+ t1 = Math.floor(y - fna(y) * 4);
+ } else {
+ a = i1 - 1;
+ t1 = Math.floor(a - fna(a) * 4);
+ }
+ if (t1 == 0) {
+ if (b == 0)
+ b = 6;
+ b--;
+ }
+ }
+ if (b == 0)
+ b = 7;
+ if ((y1 * 12 + m1) * 31 + d1 < (y * 12 + m) * 31 + d) {
+ print(m + "/" + d + "/" + y + " WILL BE A ");
+ } else if ((y1 * 12 + m1) * 31 + d1 == (y * 12 + m) * 31 + d) {
+ print(m + "/" + d + "/" + y + " IS A ");
+ } else {
+ print(m + "/" + d + "/" + y + " WAS A ");
+ }
+ switch (b) {
+ case 1: print("SUNDAY.\n"); break;
+ case 2: print("MONDAY.\n"); break;
+ case 3: print("TUESDAY.\n"); break;
+ case 4: print("WEDNESDAY.\n"); break;
+ case 5: print("THURSDAY.\n"); break;
+ case 6:
+ if (d == 13) {
+ print("FRIDAY THE THIRTEENTH---BEWARE!\n");
+ } else {
+ print("FRIDAY.\n");
+ }
+ break;
+ case 7: print("SATURDAY.\n"); break;
+ }
+ if ((y1 * 12 + m1) * 31 + d1 != (y * 12 + m) * 31 + d) {
+ i5 = y1 - y;
+ print("\n");
+ i6 = m1 - m;
+ i7 = d1 - d;
+ if (i7 < 0) {
+ i6--;
+ i7 += 30;
+ }
+ if (i6 < 0) {
+ i5--;
+ i6 += 12;
+ }
+ if (i5 >= 0) {
+ if (i7 == 0 && i6 == 0)
+ print("***HAPPY BIRTHDAY***\n");
+ print(" \tYEARS\tMONTHS\tDAYS\n");
+ print(" \t-----\t------\t----\n");
+ print("YOUR AGE (IF BIRTHDATE) \t" + i5 + "\t" + i6 + "\t" + i7 + "\n");
+ a8 = (i5 * 365) + (i6 * 30) + i7 + Math.floor(i6 / 2);
+ k5 = i5;
+ k6 = i6;
+ k7 = i7;
+ // Calculate retirement date.
+ e = y + 65;
+ // Calculate time spent in the following functions.
+ print("YOU HAVE SLEPT \t\t\t");
+ time_spent(0.35, a8);
+ print("YOU HAVE EATEN \t\t\t");
+ time_spent(0.17, a8);
+ if (k5 <= 3) {
+ print("YOU HAVE PLAYED \t\t\t");
+ } else if (k5 <= 9) {
+ print("YOU HAVE PLAYED/STUDIED \t\t");
+ } else {
+ print("YOU HAVE WORKED/PLAYED \t\t");
+ }
+ time_spent(0.23, a8);
+ if (k6 == 12) {
+ k5++;
+ k6 = 0;
+ }
+ print("YOU HAVE RELAXED \t\t" + k5 + "\t" + k6 + "\t" + k7 + "\n");
+ print("\n");
+ print(tab(16) + "*** YOU MAY RETIRE IN " + e + " ***\n");
+ print("\n");
+ }
+ }
+ }
+ print("\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("\n");
+}
+
+main();
diff --git a/96 Word/javascript/word.html b/96 Word/javascript/word.html
new file mode 100644
index 00000000..ddc88134
--- /dev/null
+++ b/96 Word/javascript/word.html
@@ -0,0 +1,9 @@
+
+
+WORD
+
+
+
+
+
+
diff --git a/96 Word/javascript/word.js b/96 Word/javascript/word.js
new file mode 100644
index 00000000..6e5acf50
--- /dev/null
+++ b/96 Word/javascript/word.js
@@ -0,0 +1,150 @@
+// WORD
+//
+// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
+//
+
+function print(str)
+{
+ document.getElementById("output").appendChild(document.createTextNode(str));
+}
+
+function input()
+{
+ var input_element;
+ var input_str;
+
+ return new Promise(function (resolve) {
+ input_element = document.createElement("INPUT");
+
+ print("? ");
+ input_element.setAttribute("type", "text");
+ input_element.setAttribute("length", "50");
+ document.getElementById("output").appendChild(input_element);
+ input_element.focus();
+ input_str = undefined;
+ input_element.addEventListener("keydown", function (event) {
+ if (event.keyCode == 13) {
+ input_str = input_element.value;
+ document.getElementById("output").removeChild(input_element);
+ print(input_str);
+ print("\n");
+ resolve(input_str);
+ }
+ });
+ });
+}
+
+function tab(space)
+{
+ var str = "";
+ while (space-- > 0)
+ str += " ";
+ return str;
+}
+
+var words = ["DINKY", "SMOKE", "WATER", "GLASS", "TRAIN",
+ "MIGHT", "FIRST", "CANDY", "CHAMP", "WOULD",
+ "CLUMP", "DOPEY"];
+
+var s = [];
+var a = [];
+var l = [];
+var d = [];
+var p = [];
+
+// Main control section
+async function main()
+{
+ print(tab(33) + "WORD\n");
+ print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
+ print("\n");
+ print("\n");
+ print("\n");
+ print("I AM THINKING OF A WORD -- YOU GUESS IT. I WILL GIVE YOU\n");
+ print("CLUE TO HELP YO GET IT. GOOD LUCK!!\n");
+ print("\n");
+ print("\n");
+ while (1) {
+ print("\n");
+ print("\n");
+ print("YOU ARE STARTING A NEW GAME...\n");
+ n = words.length;
+ ss = words[Math.floor(Math.random() * n)];
+ g = 0;
+ s[0] = ss.length;
+ for (i = 1; i <= ss.length; i++)
+ s[i] = ss.charCodeAt(i - 1);
+ for (i = 1; i <= 5; i++)
+ a[i] = 45;
+ for (j = 1; j <= 5; j++)
+ p[j] = 0;
+ while (1) {
+ print("GUESS A FIVE LETTER WORD");
+ ls = await input();
+ g++;
+ if (ss == ls)
+ break;
+ for (i = 1; i <= 7; i++)
+ p[i] = 0;
+ l[0] = ls.length;
+ for (i = 1; i <= ls.length; i++) {
+ l[i] = ls.charCodeAt(i - 1);
+ }
+ if (l[1] == 63) {
+ print("THE SECRET WORD IS " + ss + "\n");
+ print("\n");
+ break;
+ }
+ if (l[0] != 5) {
+ print("YOU MUST GUESS A 5 LETTER WORD. START AGAIN.\n");
+ print("\n");
+ g--;
+ continue;
+ }
+ m = 0;
+ q = 1;
+ for (i = 1; i <= 5; i++) {
+ for (j = 1; j <= 5; j++) {
+ if (s[i] == l[j]) {
+ p[q] = l[j];
+ q++;
+ if (i == j)
+ a[j] = l[j];
+ m++;
+ }
+ }
+ }
+ a[0] = 5;
+ p[0] = m;
+ as = "";
+ for (i = 1; i <= a[0]; i++)
+ as += String.fromCharCode(a[i]);
+ ps = "";
+ for (i = 1; i <= p[0]; i++)
+ ps += String.fromCharCode(p[i]);
+ print("THERE WERE " + m + " MATCHES AND THE COMMON LETTERS WERE... " + ps + "\n");
+ print("FROM THE EXACT LETTER MATCHES, YOU KNOW............ " + as + "\n");
+ if (as == ss) {
+ ls = as;
+ break;
+ }
+ if (m <= 1) {
+ print("\n");
+ print("IF YOU GIVE UP, TYPE '?' FOR YOUR NEXT GUESS.\n");
+ print("\n");
+ }
+ }
+ if (ss == ls) {
+ print("YOU HAVE GUESSED THE WORD. IT TOOK " + g + " GUESSES!\n");
+ print("\n");
+ } else {
+ continue;
+ }
+ print("WANT TO PLAY AGAIN");
+ qs = await input();
+ if (qs != "YES")
+ break;
+ }
+}
+
+main();
diff --git a/96 Word/python/word.py b/96 Word/python/word.py
new file mode 100644
index 00000000..a3689f96
--- /dev/null
+++ b/96 Word/python/word.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+# WORD
+#
+# Converted from BASIC to Python by Trevor Hobson
+
+import random
+
+words = ["DINKY", "SMOKE", "WATER", "GRASS", "TRAIN", "MIGHT", "FIRST",
+ "CANDY", "CHAMP", "WOULD", "CLUMP", "DOPEY"]
+
+
+def play_game():
+ """Play one round of the game"""
+
+ random.shuffle(words)
+ target_word = words[0]
+ guess_count = 0
+ guess_progress = ["-"] * 5
+
+ print("You are starting a new game...")
+ while True:
+ guess_word = ""
+ while guess_word == "":
+ guess_word = input("\nGuess a five letter word. ").upper()
+ if guess_word == "?":
+ break
+ elif not guess_word.isalpha() or len(guess_word) != 5:
+ guess_word = ""
+ print("You must guess a five letter word. Start again.")
+ guess_count += 1
+ if guess_word == "?":
+ print("The secret word is", target_word)
+ break
+ else:
+ common_letters = ""
+ matches = 0
+ for i in range(5):
+ for j in range(5):
+ if guess_word[i] == target_word[j]:
+ matches += 1
+ common_letters = common_letters + guess_word[i]
+ if i == j:
+ guess_progress[j] = guess_word[i]
+ print("There were", matches,
+ "matches and the common letters were... " + common_letters)
+ print(
+ "From the exact letter matches, you know............ " + "".join(guess_progress))
+ if "".join(guess_progress) == guess_word:
+ print("\nYou have guessed the word. It took",
+ guess_count, "guesses!")
+ break
+ elif matches == 0:
+ print("\nIf you give up, type '?' for you next guess.")
+
+
+def main():
+ print(" " * 33 + "WORD")
+ print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n")
+
+ print("I am thinking of a word -- you guess it. I will give you")
+ print("clues to help you get it. Good luck!!\n")
+
+ keep_playing = True
+ while keep_playing:
+ play_game()
+ keep_playing = input(
+ "\nWant to play again? ").lower().startswith("y")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/96 Word/word.bas b/96 Word/word.bas
index 8435310f..46e69061 100644
--- a/96 Word/word.bas
+++ b/96 Word/word.bas
@@ -24,7 +24,7 @@
150 PRINT "GUESS A FIVE LETTER WORD";
160 INPUT L$
170 G=G+1
-172 IF S$=G$ THEN 500
+172 IF S$=L$ THEN 500
173 FOR I=1 TO 7: P(I)=0: NEXT I
175 L(0)=LEN(L$)
180 FOR I=1 TO LEN(L$): L(I)=ASC(MID$(L$,I,1)): NEXT I
diff --git a/basic-computer-games-dot-net/basic-computer-games-dot-net.sln b/basic-computer-games-dot-net/basic-computer-games-dot-net.sln
index a5b03908..f32f088d 100644
--- a/basic-computer-games-dot-net/basic-computer-games-dot-net.sln
+++ b/basic-computer-games-dot-net/basic-computer-games-dot-net.sln
@@ -21,6 +21,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp", "csharp", "{04298E
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "hi-lo", "..\47 Hi-Lo\csharp\hi-lo.csproj", "{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "05 Bagels", "05 Bagels", "{946C0E7C-8A83-4C7F-9959-1AF0AEF4A027}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp", "csharp", "{91DA95EE-DD42-4AEC-A886-07F834061BFC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bagels", "..\05 Bagels\csharp\Bagels.csproj", "{DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -39,6 +45,10 @@ Global
{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -50,6 +60,8 @@ Global
{26D086DE-0BBD-4A18-AC63-2476A7DB52D3} = {AC302ACD-C3B2-460D-BA1A-0A511C36A848}
{04298EE8-0EF3-475C-9427-E04C267BBEFB} = {A2BC8E4A-B977-46A6-B897-7E675ACB96F0}
{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6} = {04298EE8-0EF3-475C-9427-E04C267BBEFB}
+ {91DA95EE-DD42-4AEC-A886-07F834061BFC} = {946C0E7C-8A83-4C7F-9959-1AF0AEF4A027}
+ {DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A} = {91DA95EE-DD42-4AEC-A886-07F834061BFC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {703D538E-7F20-4DD0-A3DD-7BBE36AC82AF}