From d6446929121c7fc05cfc7e2c4e2e168205d648bd Mon Sep 17 00:00:00 2001 From: Alaa Sarhan Date: Sun, 2 Jan 2022 08:13:52 +0100 Subject: [PATCH 001/102] implement the 13th game - Bounce in ruby --- 13_Bounce/ruby/bounce.rb | 181 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 13_Bounce/ruby/bounce.rb diff --git a/13_Bounce/ruby/bounce.rb b/13_Bounce/ruby/bounce.rb new file mode 100644 index 00000000..97c42999 --- /dev/null +++ b/13_Bounce/ruby/bounce.rb @@ -0,0 +1,181 @@ +## Global constants + +# Gravity accelaration (F/S^2) ~= 32 +G = 32 + +# Used to indent the plotting of ball positions +# so that the height digits don't affect +# where we start plotting ball positions +BALL_PLOT_INDENT = "\t" + +# The deviation between current plotted height and the actual +# height of the ball that we will accept to plot the ball in +# that plotted height +BALL_PLOT_DEVIATION = 0.25 + +# The step we will take as we move down vertically while +# plotting ball positions +BALL_PLOT_HEIGHT_STEP = 0.5 + + +## Helper functions + +# Calculates the bounce speed (up) of the ball for a given +# bounce number and coefficient +def calc_velocity_for_bounce(v0, bounce, coefficient) + v = v0 * coefficient**bounce +end + +# Check https://physics.stackexchange.com/a/333436 for nice explanation +def calc_bounce_total_time(v0, bounce, coefficient) + v = calc_velocity_for_bounce(v0, bounce, coefficient) + t = 2 * v / G +end + +# Check https://physics.stackexchange.com/a/333436 for nice explanation +def calc_ball_height(v0, bounce, coefficient, t) + v = calc_velocity_for_bounce(v0, bounce, coefficient) + h = v * t - 0.5 * G * t**2 +end + +def heighest_position_in_next_bounce(time_in_bounce, i) + time_in_next_bounce = time_in_bounce[i+1] + return -1 if time_in_next_bounce.nil? + return calc_ball_height(v0, i, c, time_in_next_bounce / 2) unless time_in_next_bounce.nil? +end + +def intro + puts <<~INSTRUCTIONS + BOUNCE + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + + THIS SIMULATION LETS YOU SPECIFY THE INITIAL VELOCITY + OF A BALL THROWN STRAIGHT UP, AND THE COEFFICIENT OF + ELASTICITY OF THE BALL. PLEASE USE A DECIMAL FRACTION + COEFFICIENCY (LESS THAN 1). + + YOU ALSO SPECIFY THE TIME INCREMENT TO BE USED IN + 'STROBING' THE BALL'S FLIGHT (TRY .1 INITIALLY). + INSTRUCTIONS +end + + +## Plottin functions + +def plot_header + puts + puts "FEET" +end + +def plot_bouncing_ball(strobbing_time, v0, c) + ## Initializing helper values + + # How many bounces we want to plot + # original BASIC version is 70 / (V / (16 * S2)) + # 70 is assumed to be an arbitrary number higher than 2G and 16 is 1/2G + bounces_to_plot = (G**2 / (v0 / strobbing_time)).to_i + + # Holds the total time the ball spends in the air in every bounce + time_in_bounce = bounces_to_plot.times.map { |i| calc_bounce_total_time v0, i, c } + + plot_width = 0 + + # Calculate the highest position for the ball after the very first bounce + plot_y = (calc_ball_height(v0, 0, c, v0/G) + 0.5).to_i + + while plot_y >= 0 do + # We will print only whole-number heights + print plot_y.to_i if plot_y.to_i === plot_y + + print BALL_PLOT_INDENT + + bounces_to_plot.times { |i| + (0..time_in_bounce[i]).step(strobbing_time) { |t| + ball_pos = calc_ball_height v0, i, c, t + + # If the ball is within the acceptable deviation + # from the current height, we will plot it + if (plot_y - ball_pos).abs <= BALL_PLOT_DEVIATION then + print "0" + else + print " " + end + + # Increment the plot width when we are plotting height = 0 + # which will definitely be the longest since it never gets + # skipped by line 98 + plot_width += 1 if plot_y == 0 + } + + if heighest_position_in_next_bounce(time_in_bounce, i) < plot_y then + # If we got no more ball positions at or above current height, we can skip + # the rest of the bounces and move down to the next height to plot + puts + break + end + } + + plot_y -= BALL_PLOT_HEIGHT_STEP + end + + # Return plot_width to be used by the plot_footer + plot_width +end + +def plot_footer (plot_width, strobbing_time) + # Dotted separator line + puts + print BALL_PLOT_INDENT + (plot_width).times { |_| print "." } + puts + + # Time values line + print BALL_PLOT_INDENT + points_in_sec = (1 / strobbing_time).to_i + plot_width.times { |i| + if i % points_in_sec == 0 then + print (i / points_in_sec).to_i + else + print " " + end + } + puts + + # Time unit line + print BALL_PLOT_INDENT + (plot_width / 2 - 4).to_i.times { |_| print " " } + puts "SECONDS" + puts +end + +def game_loop + # Read strobing, velocity and coefficient parameters from user input + puts "TIME INCREMENT (SEC)" + strobbing_time = gets.to_f + + puts "VELOCITY (FPS)" + v0 = gets.to_f + + puts "COEFFICIENT" + c = gets.to_f + + ## Plotting + plot_header + + plot_width = plot_bouncing_ball strobbing_time, v0, c + + plot_footer plot_width, strobbing_time +end + +## Entry point +begin + intro + while true + game_loop + end +rescue SystemExit, Interrupt + exit +rescue => exception + p exception +end \ No newline at end of file From 3f42a1b4d63f18cb927a3a08ffce8b5900171058 Mon Sep 17 00:00:00 2001 From: Alaa Sarhan Date: Mon, 3 Jan 2022 02:06:08 +0100 Subject: [PATCH 002/102] add newline eof --- 13_Bounce/ruby/bounce.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/13_Bounce/ruby/bounce.rb b/13_Bounce/ruby/bounce.rb index 97c42999..9740509d 100644 --- a/13_Bounce/ruby/bounce.rb +++ b/13_Bounce/ruby/bounce.rb @@ -178,4 +178,4 @@ rescue SystemExit, Interrupt exit rescue => exception p exception -end \ No newline at end of file +end From 807d6e5bf53f5b216f8d24874f08a40e6731a3d3 Mon Sep 17 00:00:00 2001 From: Alaa Sarhan Date: Mon, 3 Jan 2022 02:15:59 +0100 Subject: [PATCH 003/102] fix missing parameters --- 13_Bounce/ruby/bounce.rb | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/13_Bounce/ruby/bounce.rb b/13_Bounce/ruby/bounce.rb index 9740509d..339c7851 100644 --- a/13_Bounce/ruby/bounce.rb +++ b/13_Bounce/ruby/bounce.rb @@ -38,7 +38,7 @@ def calc_ball_height(v0, bounce, coefficient, t) h = v * t - 0.5 * G * t**2 end -def heighest_position_in_next_bounce(time_in_bounce, i) +def heighest_position_in_next_bounce(time_in_bounce, v0, i, c) time_in_next_bounce = time_in_bounce[i+1] return -1 if time_in_next_bounce.nil? return calc_ball_height(v0, i, c, time_in_next_bounce / 2) unless time_in_next_bounce.nil? @@ -82,11 +82,12 @@ def plot_bouncing_ball(strobbing_time, v0, c) plot_width = 0 # Calculate the highest position for the ball after the very first bounce - plot_y = (calc_ball_height(v0, 0, c, v0/G) + 0.5).to_i + plotted_height = (calc_ball_height(v0, 0, c, v0/G) + 0.5).to_i - while plot_y >= 0 do + ## Plotting bouncing ball + while plotted_height >= 0 do # We will print only whole-number heights - print plot_y.to_i if plot_y.to_i === plot_y + print plotted_height.to_i if plotted_height.to_i === plotted_height print BALL_PLOT_INDENT @@ -96,7 +97,7 @@ def plot_bouncing_ball(strobbing_time, v0, c) # If the ball is within the acceptable deviation # from the current height, we will plot it - if (plot_y - ball_pos).abs <= BALL_PLOT_DEVIATION then + if (plotted_height - ball_pos).abs <= BALL_PLOT_DEVIATION then print "0" else print " " @@ -105,10 +106,10 @@ def plot_bouncing_ball(strobbing_time, v0, c) # Increment the plot width when we are plotting height = 0 # which will definitely be the longest since it never gets # skipped by line 98 - plot_width += 1 if plot_y == 0 + plot_width += 1 if plotted_height == 0 } - if heighest_position_in_next_bounce(time_in_bounce, i) < plot_y then + if heighest_position_in_next_bounce(time_in_bounce, v0, i, c) < plotted_height then # If we got no more ball positions at or above current height, we can skip # the rest of the bounces and move down to the next height to plot puts @@ -116,7 +117,7 @@ def plot_bouncing_ball(strobbing_time, v0, c) end } - plot_y -= BALL_PLOT_HEIGHT_STEP + plotted_height -= BALL_PLOT_HEIGHT_STEP end # Return plot_width to be used by the plot_footer @@ -160,7 +161,7 @@ def game_loop puts "COEFFICIENT" c = gets.to_f - ## Plotting + # Plotting plot_header plot_width = plot_bouncing_ball strobbing_time, v0, c @@ -168,7 +169,9 @@ def game_loop plot_footer plot_width, strobbing_time end -## Entry point + +## Game entry point + begin intro while true From 1e9c8008d162d294515ab4b454b29ee008f0c7a8 Mon Sep 17 00:00:00 2001 From: John Long Date: Mon, 3 Jan 2022 16:37:04 -0800 Subject: [PATCH 004/102] Add Kotlin for Synonym This is so much cleaner than the Java :). --- 85_Synonym/kotlin/README.md | 3 ++ 85_Synonym/kotlin/Synonym.kt | 71 ++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 85_Synonym/kotlin/README.md create mode 100644 85_Synonym/kotlin/Synonym.kt diff --git a/85_Synonym/kotlin/README.md b/85_Synonym/kotlin/README.md new file mode 100644 index 00000000..f43a5b70 --- /dev/null +++ b/85_Synonym/kotlin/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Kotlin](https://kotlinlang.org/) diff --git a/85_Synonym/kotlin/Synonym.kt b/85_Synonym/kotlin/Synonym.kt new file mode 100644 index 00000000..94066d03 --- /dev/null +++ b/85_Synonym/kotlin/Synonym.kt @@ -0,0 +1,71 @@ +/** + * Game of Synonym + * + * + * Based on the Basic game of Synonym here + * https://github.com/coding-horror/basic-computer-games/blob/main/85%20Synonym/synonym.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. + */ + +fun main() { + println(introText) + synonyms.forEach { + // Inside with, "this" is the current synonym + with(it) { + do { + val answer = ask(" WHAT IS A SYNONYM OF $word ? ") + when { + answer == "HELP" -> + println("""**** A SYNONYM OF $word IS ${synonyms.random()}.""") + synonyms.contains(answer) -> + println(RANDOM_ANSWERS.random()) + else -> + println("TRY AGAIN.") + } + } while (!synonyms.contains(answer)) + } + } + println("SYNONYM DRILL COMPLETED.") +} + +val introText = """ +${tab(33)}SYNONYM +${tab(15)}CREATIVE COMPUTING MORRISTOWN, NEW JERSEY +A SYNONYM OF A WORD MEANS ANOTHER WORD IN THE ENGLISH +LANGUAGE WHICH HAS THE SAME OR VERY NEARLY THE SAME + MEANING. +I CHOOSE A WORD -- YOU TYPE A SYNONYM. +IF YOU CAN'T THINK OF A SYNONYM, TYPE THE WORD 'HELP' +AND I WILL TELL YOU A SYNONYM. + + """ + +// prints a question and reads a string (and converts to uppercase) +private fun ask(text: String): String { + print(text) + return readln().uppercase() +} + +// Just like TAB in BASIC +private fun tab(spaces: Int): String = " ".repeat(spaces) + +val RANDOM_ANSWERS = arrayOf("RIGHT", "CORRECT", "FINE", "GOOD!", "CHECK") + +// List of words and synonyms +private val synonyms = listOf( + SynonymList("FIRST", listOf("START", "BEGINNING", "ONSET", "INITIAL")), + SynonymList("SIMILAR", listOf("SAME", "LIKE", "RESEMBLING")), + SynonymList("MODEL", listOf("PATTERN", "PROTOTYPE", "STANDARD", "CRITERION")), + SynonymList("SMALL", listOf("INSIGNIFICANT", "LITTLE", "TINY", "MINUTE")), + SynonymList("STOP", listOf("HALT", "STAY", "ARREST", "CHECK", "STANDSTILL")), + SynonymList("HOUSE", listOf("DWELLING", "RESIDENCE", "DOMICILE", "LODGING", "HABITATION")), + SynonymList("PIT", listOf("HOLE", "HOLLOW", "WELL", "GULF", "CHASM", "ABYSS")), + SynonymList("PUSH", listOf("SHOVE", "THRUST", "PROD", "POKE", "BUTT", "PRESS")), + SynonymList("RED", listOf("ROUGE", "SCARLET", "CRIMSON", "FLAME", "RUBY")), + SynonymList("PAIN", listOf("SUFFERING", "HURT", "MISERY", "DISTRESS", "ACHE", "DISCOMFORT")) +) + +class SynonymList(val word: String, val synonyms: List) \ No newline at end of file From 8be28cd39a3ee3a642a047a8e303f70a24b1e5a4 Mon Sep 17 00:00:00 2001 From: John Long Date: Mon, 3 Jan 2022 16:45:26 -0800 Subject: [PATCH 005/102] A little cleaner implementation --- 85_Synonym/kotlin/Synonym.kt | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/85_Synonym/kotlin/Synonym.kt b/85_Synonym/kotlin/Synonym.kt index 94066d03..d2e68dc4 100644 --- a/85_Synonym/kotlin/Synonym.kt +++ b/85_Synonym/kotlin/Synonym.kt @@ -13,23 +13,25 @@ fun main() { println(introText) synonyms.forEach { - // Inside with, "this" is the current synonym - with(it) { - do { - val answer = ask(" WHAT IS A SYNONYM OF $word ? ") - when { - answer == "HELP" -> - println("""**** A SYNONYM OF $word IS ${synonyms.random()}.""") - synonyms.contains(answer) -> - println(RANDOM_ANSWERS.random()) - else -> - println("TRY AGAIN.") - } - } while (!synonyms.contains(answer)) - } + it.testUser() } println("SYNONYM DRILL COMPLETED.") } +// We could put this inside of SynonymList, but this keeps the core implementation +// right here at the top +private fun SynonymList.testUser() { + do { + val answer = ask(" WHAT IS A SYNONYM OF $word ? ") + when { + answer == "HELP" -> + println("""**** A SYNONYM OF $word IS ${synonyms.random()}.""") + synonyms.contains(answer) -> + println(RANDOM_ANSWERS.random()) + else -> + println("TRY AGAIN.") + } + } while (!synonyms.contains(answer)) +} val introText = """ ${tab(33)}SYNONYM From 1520a8f225ec55582cb4ff9070389fab56c9e1f5 Mon Sep 17 00:00:00 2001 From: John Long Date: Mon, 3 Jan 2022 16:47:47 -0800 Subject: [PATCH 006/102] Affirmation more accurate than Answer --- 85_Synonym/kotlin/Synonym.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/85_Synonym/kotlin/Synonym.kt b/85_Synonym/kotlin/Synonym.kt index d2e68dc4..dda96a82 100644 --- a/85_Synonym/kotlin/Synonym.kt +++ b/85_Synonym/kotlin/Synonym.kt @@ -26,7 +26,7 @@ private fun SynonymList.testUser() { answer == "HELP" -> println("""**** A SYNONYM OF $word IS ${synonyms.random()}.""") synonyms.contains(answer) -> - println(RANDOM_ANSWERS.random()) + println(RANDOM_AFFIRMATION.random()) else -> println("TRY AGAIN.") } @@ -54,7 +54,7 @@ private fun ask(text: String): String { // Just like TAB in BASIC private fun tab(spaces: Int): String = " ".repeat(spaces) -val RANDOM_ANSWERS = arrayOf("RIGHT", "CORRECT", "FINE", "GOOD!", "CHECK") +val RANDOM_AFFIRMATION = arrayOf("RIGHT", "CORRECT", "FINE", "GOOD!", "CHECK") // List of words and synonyms private val synonyms = listOf( From 916fa6f252188b1fa8a9bb605eda1d29569defb0 Mon Sep 17 00:00:00 2001 From: John Long Date: Mon, 3 Jan 2022 16:48:49 -0800 Subject: [PATCH 007/102] And now RANDOM is redundant --- 85_Synonym/kotlin/Synonym.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/85_Synonym/kotlin/Synonym.kt b/85_Synonym/kotlin/Synonym.kt index dda96a82..386a2525 100644 --- a/85_Synonym/kotlin/Synonym.kt +++ b/85_Synonym/kotlin/Synonym.kt @@ -26,7 +26,7 @@ private fun SynonymList.testUser() { answer == "HELP" -> println("""**** A SYNONYM OF $word IS ${synonyms.random()}.""") synonyms.contains(answer) -> - println(RANDOM_AFFIRMATION.random()) + println(AFFIRMATIONS.random()) else -> println("TRY AGAIN.") } @@ -54,7 +54,7 @@ private fun ask(text: String): String { // Just like TAB in BASIC private fun tab(spaces: Int): String = " ".repeat(spaces) -val RANDOM_AFFIRMATION = arrayOf("RIGHT", "CORRECT", "FINE", "GOOD!", "CHECK") +val AFFIRMATIONS = arrayOf("RIGHT", "CORRECT", "FINE", "GOOD!", "CHECK") // List of words and synonyms private val synonyms = listOf( From 2c1dea4de7cef0c0e8f6b0a3843b55396af0658f Mon Sep 17 00:00:00 2001 From: a2wd Date: Tue, 4 Jan 2022 01:57:36 +0100 Subject: [PATCH 008/102] Added bombardment in c# --- 11_Bombardment/csharp/Bombardment.cs | 183 +++++++++++++++++++++++ 11_Bombardment/csharp/Bombardment.csproj | 8 + 11_Bombardment/csharp/Program.cs | 13 ++ 3 files changed, 204 insertions(+) create mode 100644 11_Bombardment/csharp/Bombardment.cs create mode 100644 11_Bombardment/csharp/Bombardment.csproj create mode 100644 11_Bombardment/csharp/Program.cs diff --git a/11_Bombardment/csharp/Bombardment.cs b/11_Bombardment/csharp/Bombardment.cs new file mode 100644 index 00000000..bcbdcc26 --- /dev/null +++ b/11_Bombardment/csharp/Bombardment.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; + +namespace Bombardment +{ + // + // 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 the 1970's Basic game in C#, without introducing + // new features - no additional text, error checking, etc has been added. + // + internal class Bombardment + { + private static int MAX_GRID_SIZE = 25; + private static int MAX_PLATOONS = 4; + private static Random random = new Random(); + private List computerPositions = new List(); + private List playerPositions = new List(); + private List computerGuesses = new List(); + + private void PrintStartingMessage() + { + Console.WriteLine("{0}BOMBARDMENT", new string(' ', 33)); + Console.WriteLine("{0}CREATIVE COMPUTING MORRISTOWN, NEW JERSEY", new string(' ', 15)); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine(); + + Console.WriteLine("YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU"); + Console.WriteLine("HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED."); + Console.WriteLine("YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST."); + Console.WriteLine("THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS."); + Console.WriteLine(); + Console.WriteLine("THE OBJECT OF THE GAME IS TO FIRE MISSLES AT THE"); + Console.WriteLine("OUTPOSTS OF THE COMPUTER. IT WILL DO THE SAME TO YOU."); + Console.WriteLine("THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS"); + Console.WriteLine("FIRST IS THE WINNER."); + Console.WriteLine(); + Console.WriteLine("GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!"); + Console.WriteLine(); + Console.WriteLine("TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS."); + + // As an alternative to repeating the call to WriteLine(), + // we can print the new line character five times. + Console.Write(new string('\n', 5)); + + // Print a sample board (presumably the game was originally designed to be + // physically printed on paper while played). + for (var i = 1; i <= 25; i += 5) + { + // The token replacement can be padded by using the format {tokenPosition, padding} + // Negative values for the padding cause the output to be left-aligned. + Console.WriteLine("{0,-3}{1,-3}{2,-3}{3,-3}{4,-3}", i, i + 1, i + 2, i + 3, i + 4); + } + + Console.WriteLine("\n"); + } + + // Generate 5 random positions for the computer's platoons. + private void PlaceComputerPlatoons() + { + do + { + var nextPosition = random.Next(1, MAX_GRID_SIZE); + if (!computerPositions.Contains(nextPosition)) + { + computerPositions.Add(nextPosition); + } + + } while (computerPositions.Count < MAX_PLATOONS); + } + + private void StoreHumanPositions() + { + Console.WriteLine("WHAT ARE YOUR FOUR POSITIONS"); + + // The original game assumed that the input would be five comma-separated values, all on one line. + // For example: 12,22,1,4,17 + var input = Console.ReadLine(); + var playerPositionsAsStrings = input.Split(","); + foreach (var playerPosition in playerPositionsAsStrings) { + playerPositions.Add(int.Parse(playerPosition)); + } + } + + private void HumanTurn() + { + Console.WriteLine("WHERE DO YOU WISH TO FIRE YOUR MISSLE"); + var input = Console.ReadLine(); + var humanGuess = int.Parse(input); + + if(computerPositions.Contains(humanGuess)) + { + Console.WriteLine("YOU GOT ONE OF MY OUTPOSTS!"); + computerPositions.Remove(humanGuess); + + switch(computerPositions.Count) + { + case 3: + Console.WriteLine("ONE DOWN, THREE TO GO."); + break; + case 2: + Console.WriteLine("TWO DOWN, TWO TO GO."); + break; + case 1: + Console.WriteLine("THREE DOWN, ONE TO GO."); + break; + case 0: + Console.WriteLine("YOU GOT ME, I'M GOING FAST."); + Console.WriteLine("BUT I'LL GET YOU WHEN MY TRANSISTO&S RECUP%RA*E!"); + break; + } + } + else + { + Console.WriteLine("HA, HA YOU MISSED. MY TURN NOW:"); + } + } + + private int GenerateComputerGuess() + { + int computerGuess; + do + { + computerGuess = random.Next(1, 25); + } + while(computerGuesses.Contains(computerGuess)); + computerGuesses.Add(computerGuess); + + return computerGuess; + } + + private void ComputerTurn() + { + var computerGuess = GenerateComputerGuess(); + + if (playerPositions.Contains(computerGuess)) + { + Console.WriteLine("I GOT YOU. IT WON'T BE LONG NOW. POST {0} WAS HIT.", computerGuess); + playerPositions.Remove(computerGuess); + + switch(playerPositions.Count) + { + case 3: + Console.WriteLine("YOU HAVE ONLY THREE OUTPOSTS LEFT."); + break; + case 2: + Console.WriteLine("YOU HAVE ONLY TWO OUTPOSTS LEFT."); + break; + case 1: + Console.WriteLine("YOU HAVE ONLY ONE OUTPOST LEFT."); + break; + case 0: + Console.WriteLine("YOU'RE DEAD. YOUR LAST OUTPOST WAS AT {0}. HA, HA, HA.", computerGuess); + Console.WriteLine("BETTER LUCK NEXT TIME."); + break; + } + } + else + { + Console.WriteLine("I MISSED YOU, YOU DIRTY RAT. I PICKED {0}. YOUR TURN:", computerGuess); + } + } + + public void Play() + { + PrintStartingMessage(); + PlaceComputerPlatoons(); + StoreHumanPositions(); + + while (playerPositions.Count > 0 && computerPositions.Count > 0) + { + HumanTurn(); + + if (computerPositions.Count > 0) + { + ComputerTurn(); + } + } + } + } +} diff --git a/11_Bombardment/csharp/Bombardment.csproj b/11_Bombardment/csharp/Bombardment.csproj new file mode 100644 index 00000000..e5e0e164 --- /dev/null +++ b/11_Bombardment/csharp/Bombardment.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp2.1 + + + diff --git a/11_Bombardment/csharp/Program.cs b/11_Bombardment/csharp/Program.cs new file mode 100644 index 00000000..acc438ba --- /dev/null +++ b/11_Bombardment/csharp/Program.cs @@ -0,0 +1,13 @@ +using System; + +namespace Bombardment +{ + class Program + { + static void Main(string[] args) + { + var bombardment = new Bombardment(); + bombardment.Play(); + } + } +} From e8849566baf01424909f797d9db7db36e432b0c2 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 4 Jan 2022 12:35:51 +1100 Subject: [PATCH 009/102] fix(amazing): guarantee exit on bottom row of maze This issue only tends to show up on very small mazes (e.g. 2x2, 3x3). It is possible for the algorithm to never generate an exit to the maze. While the algorithm guarantees with the `Z` variable that only one exit will be generated, it does not test for the situation where we just happen to never get the right random value to open an exit on the bottom row. The simplest resolution is just to check for this before rendering the final result (i.e. `IF Z=0`), and add an exit to a random cell on the bottom row. --- 02_Amazing/amazing.bas | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/02_Amazing/amazing.bas b/02_Amazing/amazing.bas index 63255319..3b39c93a 100644 --- a/02_Amazing/amazing.bas +++ b/02_Amazing/amazing.bas @@ -117,10 +117,15 @@ 975 V(R,S)=3:Q=0:GOTO 1000 980 V(R,S)=1:Q=0:R=1:S=1:GOTO 250 1000 GOTO 210 -1010 FOR J=1 TO V -1011 PRINT "I"; -1012 FOR I=1 TO H -1013 IF V(I,J)<2 THEN 1030 +1010 IF Z=1 THEN 1015 +1011 X=INT(RND(1)*H+1) +1012 IF V(X,V)=0 THEN 1014 +1013 V(X,V)=3: GOTO 1015 +1014 V(X,V)=1 +1015 FOR J=1 TO V +1016 PRINT "I"; +1017 FOR I=1 TO H +1018 IF V(I,J)<2 THEN 1030 1020 PRINT " "; 1021 GOTO 1040 1030 PRINT " I"; From 321205cc7769f75671028fc3190b1aa45b338b78 Mon Sep 17 00:00:00 2001 From: Alaa Sarhan Date: Tue, 4 Jan 2022 02:49:50 +0100 Subject: [PATCH 010/102] minor changes --- 13_Bounce/ruby/bounce.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/13_Bounce/ruby/bounce.rb b/13_Bounce/ruby/bounce.rb index 339c7851..e215a897 100644 --- a/13_Bounce/ruby/bounce.rb +++ b/13_Bounce/ruby/bounce.rb @@ -110,8 +110,8 @@ def plot_bouncing_ball(strobbing_time, v0, c) } if heighest_position_in_next_bounce(time_in_bounce, v0, i, c) < plotted_height then - # If we got no more ball positions at or above current height, we can skip - # the rest of the bounces and move down to the next height to plot + # If we got no more ball positions at or above current height in the next bounce, + # we can skip the rest of the bounces and move down to the next height to plot puts break end @@ -170,11 +170,11 @@ def game_loop end -## Game entry point +## Entry point begin intro - while true + loop do game_loop end rescue SystemExit, Interrupt From f98c8af9f82a3cfe36c5ca2c18f3b70af6b94149 Mon Sep 17 00:00:00 2001 From: RibTips <36372030+ribtips@users.noreply.github.com> Date: Tue, 4 Jan 2022 00:21:38 -0500 Subject: [PATCH 011/102] Perl version of 35_evenwins --- 35_Even_Wins/perl/evenwins.pl | 168 ++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 35_Even_Wins/perl/evenwins.pl diff --git a/35_Even_Wins/perl/evenwins.pl b/35_Even_Wins/perl/evenwins.pl new file mode 100644 index 00000000..20065c23 --- /dev/null +++ b/35_Even_Wins/perl/evenwins.pl @@ -0,0 +1,168 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +&main; + +sub main { + &print_intro; + &game_play; +} + +sub game_play { + my $marbles = 27; + my $turn = 0; + my $player_total = 0; + my $computer_total = 0; + print "TYPE A '1' IF YOU WANT TO GO FIRST AND TYPE A '0' IF YOU WANT ME TO GO FIRST\n"; + my $choice = ; + chomp($choice); + if ($choice == 0) { + until ($marbles == 0) { + + my $computer_choice = &computer_select($marbles,$turn); + $marbles = $marbles - $computer_choice; + $computer_total = $computer_total + $computer_choice; + print "MY TOTAL IS $computer_total\n"; + + print "TOTAL= $marbles\n"; + + if ($marbles == 0) {&determine_winner($computer_total,$player_total)}; + + my $player_choice = &player_select($marbles,$turn); + $marbles = $marbles - $player_choice; + $player_total = $player_total + $player_choice; + print "YOUR TOTAL IS $player_total\n"; + $turn++; + print "TOTAL= $marbles\n"; + if ($marbles == 0) {&determine_winner($computer_total,$player_total)}; + } + } + elsif ($choice == 1) { + until ($marbles == 0) { + + my $player_choice = &player_select($marbles,$turn); + $marbles = $marbles - $player_choice; + $player_total = $player_total + $player_choice; + $turn++; + print "YOUR TOTAL IS $player_total\n"; + + print "TOTAL= $marbles\n"; + + if ($marbles == 0) {&determine_winner($computer_total,$player_total)}; + + my $computer_choice = &computer_select($marbles,$turn); + $marbles = $marbles - $computer_choice; + $computer_total = $computer_total + $computer_choice; + print "MY TOTAL IS $computer_total\n"; + + print "TOTAL= $marbles\n"; + + if ($marbles == 0) {&determine_winner($computer_total,$player_total)}; + + } + } +} + +sub determine_winner { + my $computer = shift; + my $player = shift; + print "THAT IS ALL OF THE MARBLES.\n\n"; + print "MY TOTAL IS $computer, YOUR TOTAL IS $player\n"; + if ($player % 2 == 0) { + print " YOU WON.\n"; + } + if ($computer % 2 == 0) { + print " I WON.\n"; + } + my $answer = -1; + until ($answer == 1 || $answer == 0) { + print "DO YOU WANT TO PLAY AGAIN? TYPE 1 FOR YES AND 0 FOR NO.\n"; + $answer=; + chomp($answer); + } + if ($answer == 1) { + &game_play; + } + else { + print "OK. SEE YOU LATER.\n"; + exit; + } +} + +sub player_select { + my $marbles = shift; + my $turn = shift; + my $validity="invalid"; + if ($turn == 0) { + print "WHAT IS YOUR FIRST MOVE\n"; + } + else { + print "WHAT IS YOUR NEXT MOVE\n"; + } + until ($validity eq "valid") { + my $num = ; + chomp($num); + my $validity=&validity_check($marbles,$num); + if ($validity eq "valid") { + return $num; + } + } +} + +sub computer_select { + my $marbles = shift; + my $turn = shift; + my $num = 2; + my $validity = "invalid"; + if ($turn == 0) { + print "I PICK UP $num MARBLES.\n\n"; + } + else { + until ($validity eq "valid") { + my $R=$marbles-6*int(($marbles/6)); + if ($marbles < 4.2) { + $num = $marbles; + } + if ($R > 3.4) { + if ($R < 4.7 || $R > 3.5) { + $num = 4; + } + else { + $num = 1; + } + } + $validity=&validity_check($marbles,$num); + } + print "\nI PICK UP $num MARBLES.\n\n"; + } + return $num; +} + +sub validity_check { + my $marbles = shift; + my $num = shift; + if ($num > $marbles) { + print "YOU HAVE TRIED TO TAKE MORE MARBLES THAN THERE ARE LEFT. TRY AGAIN. THERE ARE $marbles MARBLES LEFT\n"; + return "invalid"; + } + if ($num > 0 && $num <= 4) { + return "valid"; + } + if ($num < 1 || $num > 4) { + print "THE NUMBER OF MARBLES YOU TAKE MUST BE A POSITIVE INTEGER BETWEEN 1 AND 4\nWHAT IS YOUR NEXT MOVE?\n"; + return "invalid"; + } + else { + return "invalid"; + } +} + +sub print_intro { + print ' ' x 31 . "EVEN WINS\n"; + print ' ' x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n"; + print "THIS IS A 2 PERSON GAME CALLED 'EVEN WINS'. TO PLAY THE GAME, THE PLAYERS NEED 27 MARBLES OR OTHER OBJECTS ON THE TABLE\n\n"; + print "THE 2 PLAYERS ALTERNATE TURNS, WITH EACH PLAYER REMOVING FROM 1 TO 4 MARBLES ON EACH MOVE. THE GAME ENDS WHEN THERE ARE NO MARBLES LEFT, AND THE WINNER IS THE ONE WITH AN EVEN NUMBER OF MARBLES\n"; + print "THE ONLY RULES ARE THAT (1) YOU MUST ALTERNATE TURNS, (2) YOU MUST TAKE BETWEEN 1 AND 4 MARBLES EACH TURN, AND (3) YOU CANNOT SKIP A TURN.\n\n"; +} From d82a637152968ff3dd6e035965b6bf65f1a228de Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 4 Jan 2022 16:47:32 +1100 Subject: [PATCH 012/102] chore(amazing): add note to README.md for #400 --- 02_Amazing/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/02_Amazing/README.md b/02_Amazing/README.md index 8f7b271b..e94949bd 100644 --- a/02_Amazing/README.md +++ b/02_Amazing/README.md @@ -12,3 +12,7 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html + +--- + +**2022-01-04:** patched original source in [#400](https://github.com/coding-horror/basic-computer-games/pull/400) to fix a minor bug where a generated maze may be missing an exit, particularly at small maze sizes. From 55b3c0d4e76142312e9abf2276b51b097aa5631d Mon Sep 17 00:00:00 2001 From: RibTips <36372030+ribtips@users.noreply.github.com> Date: Tue, 4 Jan 2022 01:33:11 -0500 Subject: [PATCH 013/102] Add files via upload --- 35_Even_Wins/perl/evenwins.pl | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/35_Even_Wins/perl/evenwins.pl b/35_Even_Wins/perl/evenwins.pl index 20065c23..c2fdc2d8 100644 --- a/35_Even_Wins/perl/evenwins.pl +++ b/35_Even_Wins/perl/evenwins.pl @@ -21,7 +21,7 @@ sub game_play { if ($choice == 0) { until ($marbles == 0) { - my $computer_choice = &computer_select($marbles,$turn); + my $computer_choice = &computer_select($marbles,$turn,$player_total); $marbles = $marbles - $computer_choice; $computer_total = $computer_total + $computer_choice; print "MY TOTAL IS $computer_total\n"; @@ -52,7 +52,7 @@ sub game_play { if ($marbles == 0) {&determine_winner($computer_total,$player_total)}; - my $computer_choice = &computer_select($marbles,$turn); + my $computer_choice = &computer_select($marbles,$turn,$player_total); $marbles = $marbles - $computer_choice; $computer_total = $computer_total + $computer_choice; print "MY TOTAL IS $computer_total\n"; @@ -114,6 +114,7 @@ sub player_select { sub computer_select { my $marbles = shift; my $turn = shift; + my $player_total = shift; my $num = 2; my $validity = "invalid"; if ($turn == 0) { @@ -122,14 +123,24 @@ sub computer_select { else { until ($validity eq "valid") { my $R=$marbles-6*int(($marbles/6)); - if ($marbles < 4.2) { + + if (int($player_total/2) == $player_total/2) { + if ($R < 1.5 || $R > 5.3) { + $num = 1; + } + else { + $num = $R - 1; + } + } + + elsif ($marbles < 4.2) { $num = $marbles; } - if ($R > 3.4) { + elsif ($R > 3.4) { if ($R < 4.7 || $R > 3.5) { $num = 4; } - else { + else { $num = 1; } } From 41183198a8d9e57135b079c48923ef7207d87404 Mon Sep 17 00:00:00 2001 From: RibTips <36372030+ribtips@users.noreply.github.com> Date: Tue, 4 Jan 2022 01:37:57 -0500 Subject: [PATCH 014/102] added logic/intelligence into the AI modified the logic from how the computer was making its selections. Original code had a simple random number, this incorporates the original logic from the BASIC game. --- 35_Even_Wins/python/evenwins.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/35_Even_Wins/python/evenwins.py b/35_Even_Wins/python/evenwins.py index fba20024..3fb9d4af 100644 --- a/35_Even_Wins/python/evenwins.py +++ b/35_Even_Wins/python/evenwins.py @@ -142,17 +142,32 @@ def game_over(): print('') def computer_turn(): - global marbles_in_middle - global computer_marbles + global marbles_in_middle + global computer_marbles + global human_marbles - print("It's the computer's turn ...") - max_choice = min(4, marbles_in_middle) + marbles_to_take=0 - # choose at random - n = random.randint(1, max_choice) - print(f'Computer takes {marbles_str(n)} ...') - marbles_in_middle -= n - computer_marbles += n + print("It's the computer's turn ...") + r = marbles_in_middle - 6 * int((marbles_in_middle/6)) #line 500 + + if int(human_marbles/2) == human_marbles/2: #line 510 + if r < 1.5 or r > 5.3: #lines 710 and 720 + marbles_to_take = 1 + else: + marbles_to_take = r - 1 + + elif marbles_in_middle < 4.2: #line 580 + marbles_to_take = marbles_in_middle + elif r > 3.4: #line 530 + if r < 4.7 or r > 3.5: + marbles_to_take = 4 + else: + marbles_to_take = r + 1 + + print(f'Computer takes {marbles_str(marbles_to_take)} ...') + marbles_in_middle -= marbles_to_take + computer_marbles += marbles_to_take def play_game(): global marbles_in_middle From 3b4b14427c6da19f03fd557afd380e20b65bd638 Mon Sep 17 00:00:00 2001 From: Alex Kapranoff Date: Tue, 4 Jan 2022 00:38:57 -0800 Subject: [PATCH 015/102] 02_Amazing in Perl --- 02_Amazing/perl/amazing.pl | 155 +++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 02_Amazing/perl/amazing.pl diff --git a/02_Amazing/perl/amazing.pl b/02_Amazing/perl/amazing.pl new file mode 100644 index 00000000..a474ba59 --- /dev/null +++ b/02_Amazing/perl/amazing.pl @@ -0,0 +1,155 @@ +#! /usr/bin/perl +use strict; +use warnings; + +# Translated from BASIC by Alex Kapranoff + +use feature qw/say/; + +# width and height of the maze +my ($width, $height) = input_dimensions(); + +# wall masks for all cells +my @walls; + +# flags of previous visitation for all cells +my %is_visited; + +# was the path out of the maze found? +my $path_found = 0; + +# column of entry to the maze in the top line +my $entry_col = int(rand($width)); + +# cell coordinates for traversal +my $col = $entry_col; +my $row = 0; + +$is_visited{$row, $col} = 1; + +# looping until we visit every cell +while (keys %is_visited < $width * $height) { + if (my @dirs = get_possible_directions()) { + my $dir = $dirs[rand @dirs]; + + # modify current cell wall if needed + $walls[$row]->[$col] |= $dir->[2]; + + # move the position + $row += $dir->[0]; + $col += $dir->[1]; + + # we found the exit! + if ($row == $height) { + $path_found = 1; + --$row; + + if ($walls[$row]->[$col] == 1) { + ($row, $col) = get_next_branch(0, 0); + } + } + else { + # modify the new cell wall if needed + $walls[$row]->[$col] |= $dir->[3]; + + $is_visited{$row, $col} = 1; + } + } + else { + ($row, $col) = get_next_branch($row, $col); + } +} + +print_maze(); + +sub input_dimensions { + # Print the banner and returns the dimensions as two integers > 1. + # The integers are parsed from the first line of standard input. + say ' ' x 28, 'AMAZING PROGRAM'; + say ' ' x 15, 'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY'; + print "\n" x 4; + + my ($w, $h) = (0, 0); + + while ($w <= 1 || $h <= 1) { + print 'WHAT ARE YOUR WIDTH AND LENGTH? '; + + ($w, $h) = =~ / \d+ /xg; + + if ($w < 1 || $h < 1) { + say "MEANINGLESS DIMENSIONS. TRY AGAIN." + } + } + + print "\n" x 4; + + return ($w, $h); +} + +sub get_possible_directions { + # Returns a list of all directions that are available to go to + # from the current coordinates. "Down" is available on the last line + # until we go there once and mark it as the path through the maze. + # + # Each returned direction element contains changes to the coordindates and to + # the wall masks of the previous and next cell after the move. + + my @rv; + # up + if ($row > 0 && !$is_visited{$row - 1, $col}) { + push @rv, [-1, 0, 0, 1]; + } + # left + if ($col > 0 && !$is_visited{$row, $col - 1}) { + push @rv, [0, -1, 0, 2]; + } + # right + if ($col < $width - 1 && !$is_visited{$row, $col + 1}) { + push @rv, [0, 1, 2, 0]; + } + # down + if ($row < $height - 1 && !$is_visited{$row + 1, $col} + || $row == $height - 1 && !$path_found + ) { + push @rv, [1, 0, 1, 0]; + } + + return @rv; +} + +sub get_next_branch { + # Returns the cell coordinates to start a new maze branch from. + # It looks for a visited cell starting from passed position and + # going down in the natural traversal order incrementing column and + # rows with a rollover to start at the bottom right corner. + my ($y, $x) = @_; + do { + if ($x < $width - 1) { + ++$x; + } elsif ($y < $height - 1) { + ($y, $x) = ($y + 1, 0); + } else { + ($y, $x) = (0, 0); + } + } while (!$is_visited{$y, $x}); + + return ($y, $x); +} + +sub print_maze { + # Print the full maze based on wall masks. + # For each cell, we mark the absense of the wall to the right with + # bit 2 and the absense of the wall down with bit 1. Full table: + # 0 -> both walls are present + # 1 -> wall down is absent + # 2 -> wall to the right is absent + # 3 -> both walls are absent + say join('.', '', map { $_ == $entry_col ? ' ' : '--' } 0 .. $width - 1), '.'; + + for my $row (@walls) { + say join(' ', map { $_ & 2 ? ' ' : 'I' } 0, @$row); + say join(':', '', map { $_ & 1 ? ' ' : '--' } @$row), '.'; + } + + return; +} From 6f599f12f64a51cfd2bc039a5ad48d5f9d8ef9d9 Mon Sep 17 00:00:00 2001 From: Alex Kapranoff Date: Tue, 4 Jan 2022 00:47:34 -0800 Subject: [PATCH 016/102] Fix the bug identified in #400 --- 02_Amazing/perl/amazing.pl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/02_Amazing/perl/amazing.pl b/02_Amazing/perl/amazing.pl index a474ba59..c7cb5f44 100644 --- a/02_Amazing/perl/amazing.pl +++ b/02_Amazing/perl/amazing.pl @@ -60,6 +60,10 @@ while (keys %is_visited < $width * $height) { } } +unless ($path_found) { + $walls[-1]->[rand $width] |= 1; +} + print_maze(); sub input_dimensions { From 5409fa3daf6d935d74543d8009d722d72cb0f6ba Mon Sep 17 00:00:00 2001 From: Alex Kapranoff Date: Tue, 4 Jan 2022 00:51:54 -0800 Subject: [PATCH 017/102] chmod +x on the Perl script, as is done in #307 --- 02_Amazing/perl/amazing.pl | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 02_Amazing/perl/amazing.pl diff --git a/02_Amazing/perl/amazing.pl b/02_Amazing/perl/amazing.pl old mode 100644 new mode 100755 From ec43a4fc9490c220e76b434c045b3c84198eeefd Mon Sep 17 00:00:00 2001 From: Bastiaan Veelo Date: Mon, 3 Jan 2022 00:19:19 +0100 Subject: [PATCH 018/102] D version of Acey-Ducey. --- 01_Acey_Ducey/d/.gitignore | 2 + 01_Acey_Ducey/d/README.md | 29 ++++++ 01_Acey_Ducey/d/aceyducey.d | 131 ++++++++++++++++++++++++++++ 01_Acey_Ducey/d/aceyducey_literal.d | 104 ++++++++++++++++++++++ 4 files changed, 266 insertions(+) create mode 100644 01_Acey_Ducey/d/.gitignore create mode 100644 01_Acey_Ducey/d/README.md create mode 100644 01_Acey_Ducey/d/aceyducey.d create mode 100644 01_Acey_Ducey/d/aceyducey_literal.d diff --git a/01_Acey_Ducey/d/.gitignore b/01_Acey_Ducey/d/.gitignore new file mode 100644 index 00000000..d969f6b2 --- /dev/null +++ b/01_Acey_Ducey/d/.gitignore @@ -0,0 +1,2 @@ +*.exe +*.obj diff --git a/01_Acey_Ducey/d/README.md b/01_Acey_Ducey/d/README.md new file mode 100644 index 00000000..a45fcb2c --- /dev/null +++ b/01_Acey_Ducey/d/README.md @@ -0,0 +1,29 @@ +Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html) + +Converted to [D](https://dlang.org/) by [Bastiaan Veelo](https://github.com/veelo). + +Two versions are supplied that are functionally equivalent, but differ in source layout: + +
+
aceyducey_literal.d
+
A largely literal transcription of the original Basic source. All unnecessary uglyness is preserved.
+
aceyducey.d
+
An idiomatic D refactoring of the original, with a focus on increasing the readability and robustness. + Memory-safety is ensured by the language, thanks to the + @safe annotation.
+
+ +## Running the code + +Assuming the reference [dmd](https://dlang.org/download.html#dmd) compiler: +```shell +dmd -run aceyducey.d +``` + +[Other compilers](https://dlang.org/download.html) also exist. + +Note that there are compiler switches related to memory-safety (`-preview=dip25` and `-preview=dip1000`) that are not +used here because they are unnecessary in this case. What these do is to make the analysis more thorough, so that with +them some code that needed to be `@system` can then be inferred to be in fact `@safe`. [Code that compiles without +these switches is just as safe as when compiled with them] +(https://forum.dlang.org/post/dftgjalswvwfjpyushgn@forum.dlang.org). diff --git a/01_Acey_Ducey/d/aceyducey.d b/01_Acey_Ducey/d/aceyducey.d new file mode 100644 index 00000000..036786c5 --- /dev/null +++ b/01_Acey_Ducey/d/aceyducey.d @@ -0,0 +1,131 @@ +@safe: // Make @safe the default for this file, enforcing memory-safety. + +void main() +{ + import std.stdio : write, writeln; + import std.string : center, toUpper, wrap; + import std.exception : ifThrown; + + enum width = 80; + writeln(center("Acey Ducey Card Game", width)); + writeln(center("(After Creative Computing Morristown, New Jersey)\n", width)); + writeln(wrap("Acey-Ducey is played in the following manner: The dealer (computer) deals two cards face up. " ~ + "You have an option to bet or not bet depending on whether or not you feel the third card will " ~ + "have a value between the first two. If you do not want to bet, input a 0.", width)); + + enum Hand {low, middle, high} + Card[Hand.max + 1] cards; // Three cards. + bool play = true; + + while (play) + { + int cash = 100; + while (cash > 0) + { + writeln("\nYou now have ", cash, " dollars."); + int bet = 0; + while (bet <= 0) + { + do // Draw new cards, until the first card has a smaller value than the last card. + { + foreach (ref card; cards) + card.drawNew; + } while (cards[Hand.low] >= cards[Hand.high]); + writeln("Here are your next two cards:\n", cards[Hand.low], "\n", cards[Hand.high]); + + int askBet() // A nested function. + { + import std.conv : to; + + write("\nWhat is your bet? "); + int answer = readString.to!int. + ifThrown!Exception(askBet); // Try again when answer does not convert to int. + if (answer <= cash) + return answer; + writeln("Sorry, my friend, but you bet too much.\nYou have only ", cash, " dollars to bet."); + return askBet; // Recurse: Ask again. + } + bet = askBet; + if (bet <= 0) // Negative bets are interpreted as 0. + writeln("CHICKEN!!"); + } // bet is now > 0. + + writeln(cards[Hand.middle]); + if (cards[Hand.low] < cards[Hand.middle] && cards[Hand.middle] < cards[Hand.high]) + { + writeln("YOU WIN!!!"); + cash += bet; + } + else + { + writeln("Sorry, you lose."); + cash -= bet; + if (cash <= 0) + { + writeln("\n\nSorry, friend, but you blew your wad."); + write("\n\nTry again (Yes or No)? "); + play = readString.toUpper == "YES"; + } + } + } + } + writeln("O.K., hope you had fun!"); +} + +struct Card +{ + int value = 2; + alias value this; // Enables Card to stand in as an int, so that cards can be compared as ints. + + invariant + { + assert(2 <= value && value <= 14); // Ensure cards always have a valid value. + } + + /// Adopt a new value. + void drawNew() + { + import std.random : uniform; + + value = uniform!("[]", int, int)(2, 14); // A random int between inclusive bounds. + } + + /// Called for implicit conversion to string. + string toString() const pure + { + import std.conv : text; + + switch (value) + { + case 11: return "Jack"; + case 12: return "Queen"; + case 13: return "King"; + case 14: return "Ace"; + default: return text(" ", value); // Basic prepends a space. + } + } +} + +/// Read a string from standard input, stripping newline and other enclosing whitespace. +string readString() nothrow +{ + import std.string : strip; + + try + return trustedReadln.strip; + catch (Exception) // readln throws on I/O and Unicode errors, which we handle here. + return ""; +} + +/** An @trusted wrapper around readln. + * + * This is the only function that formally requires manual review for memory-safety. + * [Arguably readln should be safe already](https://forum.dlang.org/post/rab398$1up$1@digitalmars.com) + * which would remove the need to have any @trusted code in this program. + */ +string trustedReadln() @trusted +{ + import std.stdio : readln; + + return readln; +} diff --git a/01_Acey_Ducey/d/aceyducey_literal.d b/01_Acey_Ducey/d/aceyducey_literal.d new file mode 100644 index 00000000..a51028de --- /dev/null +++ b/01_Acey_Ducey/d/aceyducey_literal.d @@ -0,0 +1,104 @@ +void main() +{ + import std; + + L10: writef("%26s", ' '); writeln("ACEY DUCEY CARD GAME"); + L20: writef("%15s", ' '); writeln("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + L21: writeln; + L22: writeln; + L30: writeln("ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER "); + L40: writeln("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP"); + L50: writeln("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING"); + L60: writeln("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE"); + L70: writeln("A VALUE BETWEEN THE FIRST TWO."); + L80: writeln("IF YOU DO NOT WANT TO BET, INPUT A 0"); + L100: int N=100; + L110: int Q=100, M; + L120: writeln("YOU NOW HAVE ",Q," DOLLARS."); + L130: writeln; + L140: goto L260; + L210: Q=Q+M; + L220: goto L120; + L240: Q=Q-M; + L250: goto L120; + L260: writeln("HERE ARE YOUR NEXT TWO CARDS: "); + L270: auto A=to!int(14*uniform01)+2; + L280: if (A<2) goto L270; + L290: if (A>14) goto L270; + L300: auto B=to!int(14*uniform01)+2; + L310: if (B<2) goto L300; + L320: if (B>14) goto L300; + L330: if (A>=B) goto L270; + L350: if (A<11) goto L400; + L360: if (A==11) goto L420; + L370: if (A==12) goto L440; + L380: if (A==13) goto L460; + L390: if (A==14) goto L480; + L400: writefln("%2d", A); + L410: goto L500; + L420: writeln("JACK"); + L430: goto L500; + L440: writeln("QUEEN"); + L450: goto L500; + L460: writeln("KING"); + L470: goto L500; + L480: writeln("ACE"); + L500: if (B<11) goto L550; + L510: if (B==11) goto L570; + L520: if (B==12) goto L590; + L530: if (B==13) goto L610; + L540: if (B==14) goto L630; + L550: writefln("%2d", B); + L560: goto L650; + L570: writeln("JACK"); + L580: goto L650; + L590: writeln("QUEEN"); + L600: goto L650; + L610: writeln("KING"); + L620: goto L650; + L630: writeln("ACE"); + L640: writeln; + L650: writeln; + L660: write("WHAT IS YOUR BET? "); M = stdin.readln.strip.to!int; + L670: if (M!=0) goto L680; + L675: writeln("CHICKEN!!"); + L676: writeln; + L677: goto L260; + L680: if (M<=Q) goto L730; + L690: writeln("SORRY, MY FRIEND, BUT YOU BET TOO MUCH."); + L700: writeln("YOU HAVE ONLY ",Q," DOLLARS TO BET."); + L710: goto L650; + L730: auto C=to!int(14*uniform01)+2; + L740: if (C<2) goto L730; + L750: if (C>14) goto L730; + L760: if (C<11) goto L810; + L770: if (C==11) goto L830; + L780: if (C==12) goto L850; + L790: if (C==13) goto L870; + L800: if (C==14) goto L890; + L810: writeln(C); + L820: goto L910; + L830: writeln("JACK"); + L840: goto L910; + L850: writeln("QUEEN"); + L860: goto L910; + L870: writeln("KING"); + L880: goto L910; + L890: writeln( "ACE"); + L900: writeln; + L910: if (C>A) goto L930; + L920: goto L970; + L930: if (C>=B) goto L970; + L950: writeln("YOU WIN!!!"); + L960: goto L210; + L970: writeln("SORRY, YOU LOSE"); + L980: if (M Date: Tue, 4 Jan 2022 08:36:37 -0500 Subject: [PATCH 019/102] cleanup --- 31_Depth_Charge/ruby/.gitignore | 57 +++++++++++++++++++++++++++++ 31_Depth_Charge/ruby/depthcharge.rb | 48 ++++-------------------- 2 files changed, 65 insertions(+), 40 deletions(-) create mode 100644 31_Depth_Charge/ruby/.gitignore diff --git a/31_Depth_Charge/ruby/.gitignore b/31_Depth_Charge/ruby/.gitignore new file mode 100644 index 00000000..d25ad7bc --- /dev/null +++ b/31_Depth_Charge/ruby/.gitignore @@ -0,0 +1,57 @@ +# Package Shell Specific Things + +## Build Process + +/build + +## Transient files + +/src/input +/src/output +/src/log +/drop + +# Programming Languages + +## Java +/src/java/**/*.class + +## Rakudo / Perl6 +/src/**/.precomp + +## PHP +/vendor/ + +## Python +*.swp +__pycache__/ +*.pyc +*.egg-info +/dist + +## Ruby +*.gem +.bundle + +# Editors + +## Dia +*.dia.autosave + +## Emacs +\#*\# +.\#* + + +## Vi / Vim +*.swp + +# Filesystem Artifacts + +## Mac + +.DS_Store + +## NFS + +.nfs* diff --git a/31_Depth_Charge/ruby/depthcharge.rb b/31_Depth_Charge/ruby/depthcharge.rb index 5ba36ba6..ba2a5d83 100755 --- a/31_Depth_Charge/ruby/depthcharge.rb +++ b/31_Depth_Charge/ruby/depthcharge.rb @@ -13,7 +13,6 @@ class DepthCharge break if ! get_input_another_game() end - # 420 PRINT "OK. HOPE YOU ENJOYED YOURSELF." : GOTO 600 printf("OK. HOPE YOU ENJOYED YOURSELF.\n") end @@ -51,7 +50,7 @@ class DepthCharge the_input = Integer(value) rescue nil - if the_input == nil || the_input < 0 + if the_input == nil || the_input < 1 printf("PLEASE ENTER A POSITIVE NUMBER\n\n") next @@ -61,25 +60,7 @@ class DepthCharge end end - def get_search_area_dimension - # 20 INPUT "DIMENSION OF SEARCH AREA";G: PRINT - @search_area_dimension = get_input_positive_integer("DIMENSION OF SEARCH AREA: ") - # 30 N=INT(LOG(G)/LOG(2))+1 - - @num_tries = Integer( - Math.log(@search_area_dimension)/Math.log(2) - ) - - end - def print_instructions - # 40 PRINT "YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER" - # 50 PRINT "AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE. YOUR" - # 60 PRINT "MISSION IS TO DESTROY IT. YOU HAVE";N;"SHOTS." - # 70 PRINT "SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A" - # 80 PRINT "TRIO OF NUMBERS -- THE FIRST TWO ARE THE" - # 90 PRINT "SURFACE COORDINATES; THE THIRD IS THE DEPTH." - # 100 PRINT : PRINT "GOOD LUCK !": PRINT printf( <<~INSTRUCTIONS YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE. YOUR @@ -110,19 +91,21 @@ GOOD LUCK ! end def setup_game - get_search_area_dimension() + @search_area_dimension = get_input_positive_integer("DIMENSION OF SEARCH AREA: ") + + @num_tries = Integer( + Math.log(@search_area_dimension)/Math.log(2) + 1 + ) setup_enemy() end def setup_enemy - # 110 A=INT(G*RND(1)) : B=INT(G*RND(1)) : C=INT(G*RND(1)) @enemy_x = rand(1..@search_area_dimension) @enemy_y = rand(1..@search_area_dimension) @enemy_z = rand(1..@search_area_dimension) - end + end def game_loop - # 120 FOR D=1 TO N : PRINT : PRINT "TRIAL #";D; : INPUT X,Y,Z for @trial in 1..@num_tries do output_game_status() @@ -130,7 +113,6 @@ GOOD LUCK ! @shot_y = get_input_positive_integer("Y: ") @shot_z = get_input_positive_integer("Z: ") - # 130 IF ABS(X-A)+ABS(Y-B)+ABS(Z-C)=0 THEN 300 if ( (@enemy_x - @shot_x).abs \ + (@enemy_y - @shot_y).abs \ @@ -140,7 +122,6 @@ GOOD LUCK ! you_win() return else - # 140 GOSUB 500 : PRINT : NEXT D missed_shot() end end @@ -156,54 +137,41 @@ GOOD LUCK ! printf("TRIAL \#%d\n", @trial) end def you_win - printf("B O O M ! ! YOU FOUND IT IN %d TRIES!\n\n", @trial ) + printf("\nB O O M ! ! YOU FOUND IT IN %d TRIES!\n\n", @trial ) end def missed_shot missed_directions = [] - # 530 IF X>A THEN PRINT "EAST"; - # 540 IF X @enemy_x missed_directions.push('TOO FAR EAST') elsif @shot_x < @enemy_x missed_directions.push('TOO FAR WEST') end - # 510 IF Y>B THEN PRINT "NORTH"; - # 520 IF Y @enemy_y missed_directions.push('TOO FAR NORTH') elsif @shot_y < @enemy_y missed_directions.push('TOO FAR SOUTH') end - # 560 IF Z>C THEN PRINT " TOO LOW." - # 570 IF Z @enemy_z missed_directions.push('TOO DEEP') elsif @shot_z < @enemy_z missed_directions.push('TOO SHALLOW') end - # 500 PRINT "SONAR REPORTS SHOT WAS "; printf("SONAR REPORTS SHOT WAS: \n") printf("%s\n", "\t" + missed_directions.join("\n\t")) - # 550 IF Y<>B OR X<>A THEN PRINT " AND"; - # 590 RETURN end def you_lose - # You took too long! printf("YOU HAVE BEEN TORPEDOED! ABANDON SHIP!\n") printf("THE SUBMARINE WAS AT %d %d %d\n", @enemy_x, @enemy_y, @enemy_z) end def get_input_another_game - # 400 PRINT : PRINT: INPUT "ANOTHER GAME (Y OR N)";A$ return get_input_y_or_n("ANOTHER GAME (Y OR N): ") - # 410 IF A$="Y" THEN 100 end end From a05a1fedf37285e5e087138f3a529a2879d7f888 Mon Sep 17 00:00:00 2001 From: "christopher.millward" Date: Tue, 4 Jan 2022 10:40:59 -0500 Subject: [PATCH 020/102] War refactor and cleanup --- 94_War/javascript/war.js | 228 ++++++++++++++++++++++----------------- 1 file changed, 128 insertions(+), 100 deletions(-) diff --git a/94_War/javascript/war.js b/94_War/javascript/war.js index eb74fb0c..bdc935bc 100644 --- a/94_War/javascript/war.js +++ b/94_War/javascript/war.js @@ -1,60 +1,95 @@ // WAR // -// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess) +// Original conversion from BASIC to Javascript by Oscar Toledo G. (nanochess) // -function print(str) -{ +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) +function tab(space) { + let 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"]; +function input() { + return new Promise(function (resolve) { + const input_element = document.createElement("INPUT"); -var l = []; + print("? "); + input_element.setAttribute("type", "text"); + input_element.setAttribute("length", "50"); + document.getElementById("output").appendChild(input_element); + input_element.focus(); + input_element.addEventListener("keydown", function (event) { + if (event.keyCode == 13) { + const input_str = input_element.value; + document.getElementById("output").removeChild(input_element); + print(input_str); + print("\n"); + resolve(input_str); + } + }); + }); +} -// Main control section -async function main() -{ +async function askYesOrNo(question) { + while (1) { + print(question); + const str = await input(); + if (str == "YES") { + return true; + } + else if (str == "NO") { + return false; + } + else { + print("YES OR NO, PLEASE. "); + } + } +} + +async function askAboutInstructions() { + const playerWantsInstructions = await askYesOrNo("DO YOU WANT DIRECTIONS"); + if (playerWantsInstructions) { + 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"); + } + print("\n"); + print("\n"); +} + +function createGameDeck(cards, gameSize) { + const deck = []; + const deckSize = cards.length; + for (let j = 0; j < gameSize; j++) { + let card; + + // Compute a new card index until we find one that isn't already in the new deck + do { + card = Math.floor(deckSize * Math.random()); + } while (deck.includes(card)); + deck[j] = card + } + return deck; +} + +function computeCardValue(cardIndex) { + return Math.floor(cardIndex / 4); +} + +function printGameOver(playerScore, computerScore) { + print("\n"); + print("\n"); + print(`WE HAVE RUN OUT OF CARDS. FINAL SCORE: YOU: ${playerScore} THE COMPUTER: ${computerScore}\n`); + print("\n"); +} + +function printTitle() { print(tab(33) + "WAR\n"); print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"); print("\n"); @@ -62,72 +97,65 @@ async function main() 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"); +} + +function printCards(playerCard, computerCard) { print("\n"); + print(`YOU: ${playerCard}\tCOMPUTER: ${computerCard}\n`); +} + +const 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" +]; + +// Main control section +async function main() { + printTitle(); + await askAboutInstructions(); - a1 = 0; - b1 = 0; - p = 0; + let computerScore = 0; + let playerScore = 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 + const gameSize = 4; + const deck = createGameDeck(cards, gameSize); + let shouldContinuePlaying = true; - 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"); + while (deck.length > 0 && shouldContinuePlaying) { + const m1 = deck.shift(); // Take a card + const m2 = deck.shift(); // Take a card + printCards(cards[m1], cards[m2]); + + const playerCardValue = computeCardValue(m1); + const computerCardValue = computeCardValue(m2); + if (playerCardValue < computerCardValue) { + computerScore++; + print("THE COMPUTER WINS!!! YOU HAVE " + playerScore + " AND THE COMPUTER HAS " + computerScore + "\n"); + } else if (playerCardValue > computerCardValue) { + playerScore++; + print("YOU WIN. YOU HAVE " + playerScore + " AND THE COMPUTER HAS " + computerScore + "\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; + + if (deck.length === 0) { + printGameOver(playerScore, computerScore); } - while (1) { - print("DO YOU WANT TO CONTINUE"); - str = await input(); - if (str == "YES") - break; - if (str == "NO") - break; - print("YES OR NO, PLEASE. "); + else { + shouldContinuePlaying = await askYesOrNo("DO YOU WANT TO CONTINUE"); } - if (str == "NO") - break; } print("THANKS FOR PLAYING. IT WAS FUN.\n"); print("\n"); From fe6ff50d2f5d18c32dc71548b2b969de67e3ada8 Mon Sep 17 00:00:00 2001 From: "christopher.millward" Date: Tue, 4 Jan 2022 10:44:48 -0500 Subject: [PATCH 021/102] Updated documentation and used push() --- 94_War/javascript/war.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/94_War/javascript/war.js b/94_War/javascript/war.js index bdc935bc..965294a6 100644 --- a/94_War/javascript/war.js +++ b/94_War/javascript/war.js @@ -73,7 +73,7 @@ function createGameDeck(cards, gameSize) { do { card = Math.floor(deckSize * Math.random()); } while (deck.includes(card)); - deck[j] = card + deck.push(card); } return deck; } @@ -129,7 +129,7 @@ async function main() { let playerScore = 0; // Generate a random deck - const gameSize = 4; + const gameSize = cards.length; // Number of cards to shuffle into the game deck. Can be <= cards.length. const deck = createGameDeck(cards, gameSize); let shouldContinuePlaying = true; From a6957caed0aba39c52d4d2e520aa7abf9926fdea Mon Sep 17 00:00:00 2001 From: "christopher.millward" Date: Tue, 4 Jan 2022 10:46:44 -0500 Subject: [PATCH 022/102] Removed last of the single-letter variables --- 94_War/javascript/war.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/94_War/javascript/war.js b/94_War/javascript/war.js index 965294a6..ededa1ed 100644 --- a/94_War/javascript/war.js +++ b/94_War/javascript/war.js @@ -134,12 +134,12 @@ async function main() { let shouldContinuePlaying = true; while (deck.length > 0 && shouldContinuePlaying) { - const m1 = deck.shift(); // Take a card - const m2 = deck.shift(); // Take a card - printCards(cards[m1], cards[m2]); + const playerCard = deck.shift(); // Take a card + const computerCard = deck.shift(); // Take a card + printCards(cards[playerCard], cards[computerCard]); - const playerCardValue = computeCardValue(m1); - const computerCardValue = computeCardValue(m2); + const playerCardValue = computeCardValue(playerCard); + const computerCardValue = computeCardValue(computerCard); if (playerCardValue < computerCardValue) { computerScore++; print("THE COMPUTER WINS!!! YOU HAVE " + playerScore + " AND THE COMPUTER HAS " + computerScore + "\n"); From 05f597b12c1518da66b104fca8875aaf6ad00bd9 Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Tue, 4 Jan 2022 14:37:22 -0300 Subject: [PATCH 023/102] Added Calendar first implementation it has some formatting problems --- 21_Calendar/python/calendar.py | 69 ++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 21_Calendar/python/calendar.py diff --git a/21_Calendar/python/calendar.py b/21_Calendar/python/calendar.py new file mode 100644 index 00000000..6f3cb191 --- /dev/null +++ b/21_Calendar/python/calendar.py @@ -0,0 +1,69 @@ + +def calendar(weekday, leap_year): + """ + function to print a year's calendar. + + input: + _weekday_: int - the initial day of the week (0=SUN, -1=MON, -2=TUES...) + _leap_year_: bool - indicates if the year is a leap year + """ + months_days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + days = ' S M T W T F S' + sep = "*" * 59 + years_day = 365 + d = weekday + + if leap_year: + months_days[2] = 29 + years_day = 366 + + months_names = [" JANUARY ", + " FEBRUARY", + " MARCH ", + " APRIL ", + " MAY ", + " JUNE ", + " JULY ", + " AUGUST ", + "SEPTEMBER", + " OCTOBER ", + " NOVEMBER", + " DECEMBER"] + + print(" "*32 + "CALENDAR") + print(" "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + + days_count = 0 # S in the original program + + # main loop + for n in range(1, 13): + days_count += months_days[n-1] + print("** {} ****************** {} ****************** {} **".format(days_count, + months_names[n-1], years_day-days_count)) + print(days) + print(sep) + print("\n") + + for w in range(1, 7): + print("\n") + for g in range(1, 8): + d += 1 + d2 = d - days_count + + if d2 > months_days[n]: + break + + if d2 > 0: + print("{}".format(d2),end=' ') + else: + print("{}".format(''),end=' ') + if d2 >= months_days[n]: + break + + if d2 > months_days[n]: + d -= g + + print("\n") + +if __name__ == "__main__": + calendar(-1, False) \ No newline at end of file From 1b81994c4a00ffc2b60e5d70813482bbd557fa47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Tue, 4 Jan 2022 17:59:28 +0000 Subject: [PATCH 024/102] Add Perl version of 25_Chief --- 25_Chief/perl/chief.pl | 69 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 25_Chief/perl/chief.pl diff --git a/25_Chief/perl/chief.pl b/25_Chief/perl/chief.pl new file mode 100644 index 00000000..d3462514 --- /dev/null +++ b/25_Chief/perl/chief.pl @@ -0,0 +1,69 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +print ' ' x 30 . "CHIEF\n"; +print ' ' x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; +print "\n\n\n"; + +print "I AM CHIEF NUMBERS FREEK, THE GREAT INDIAN MATH GOD.\n"; +print "ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR?\n"; + +chomp( my $A = uc ); +print "SHUT UP, PALE FACE WITH WISE TONGUE.\n" unless ( $A eq 'YES' ); + +print " TAKE A NUMBER AND ADD 3. DIVIDE THIS NUMBER BY 5 AND\n"; +print "MULTIPLY BY 8. DIVIDE BY 5 AND ADD THE SAME. SUBTRACT 1.\n"; +print " WHAT DO YOU HAVE?\n"; + +chomp( my $B = ); +my $C = ( $B + 1 - 5 ) * 5 / 8 * 5 - 3; + +print "I BET YOUR NUMBER WAS $C. AM I RIGHT?\n"; + +chomp( my $D = uc ); +if ( $D eq 'YES' ) { + print "BYE!!!\n"; + exit; +} + +print "WHAT WAS YOUR ORIGINAL NUMBER?\n"; + +chomp( my $K = ); +my $F = $K + 3; +my $G = $F / 5; +my $H = $G * 8; +my $I = $H / 5 + 5; +my $J = $I - 1; + +print "SO YOU THINK YOU'RE SO SMART, EH?\n"; +print "NOW WATCH.\n"; +print "$K PLUS 3 EQUALS $F. THIS DIVIDED BY 5 EQUALS $G;\n"; +print "THIS TIMES 8 EQUALS $H. IF WE DIVIDE BY 5 AND ADD 5,\n"; +print "WE GET $I , WHICH, MINUS 1, EQUALS $J.\n"; +print "NOW DO YOU BELIEVE ME?\n"; + +chomp( my $Z = uc ); +if ( $Z eq 'YES' ) { + print "BYE!!!\n"; + exit; +} + +print "YOU HAVE MADE ME MAD!!!\n"; +print "THERE MUST BE A GREAT LIGHTNING BOLT!\n\n\n"; + +for my $i ( reverse 22 .. 30 ) { + print ' ' x $i . "X X\n"; +} +print ' ' x 21 . "X XXX\n"; +print ' ' x 20 . "X X\n"; +print ' ' x 19 . "XX X\n"; +for my $i ( reverse 13 .. 20 ) { + print ' ' x $i . "X X\n"; +} +print ' ' x 12 . "XX\n"; +print ' ' x 11 . "X\n"; +print ' ' x 10 . "*\n"; +print "\n#########################\n\n"; +print "I HOPE YOU BELIEVE ME NOW, FOR YOUR SAKE!!\n"; From a8f0bb10c6fe8acfcfb5c5cb59fd35370292d566 Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Tue, 4 Jan 2022 15:10:08 -0300 Subject: [PATCH 025/102] formatting text updated --- 21_Calendar/python/calendar.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/21_Calendar/python/calendar.py b/21_Calendar/python/calendar.py index 6f3cb191..6c803771 100644 --- a/21_Calendar/python/calendar.py +++ b/21_Calendar/python/calendar.py @@ -8,7 +8,7 @@ def calendar(weekday, leap_year): _leap_year_: bool - indicates if the year is a leap year """ months_days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] - days = ' S M T W T F S' + days = 'S M T W T F S\n' sep = "*" * 59 years_day = 365 d = weekday @@ -32,17 +32,16 @@ def calendar(weekday, leap_year): print(" "*32 + "CALENDAR") print(" "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - + print("\n"*11) days_count = 0 # S in the original program # main loop for n in range(1, 13): days_count += months_days[n-1] - print("** {} ****************** {} ****************** {} **".format(days_count, + print("** {} ****************** {} ****************** {} **\n".format(days_count, months_names[n-1], years_day-days_count)) print(days) print(sep) - print("\n") for w in range(1, 7): print("\n") @@ -54,9 +53,13 @@ def calendar(weekday, leap_year): break if d2 > 0: - print("{}".format(d2),end=' ') + if d2 < 10: + print(" {}".format(d2), end=' ') + else: + print("{}".format(d2), end=' ') else: - print("{}".format(''),end=' ') + print("{}".format(' '), end=' ') + if d2 >= months_days[n]: break @@ -65,5 +68,6 @@ def calendar(weekday, leap_year): print("\n") + if __name__ == "__main__": - calendar(-1, False) \ No newline at end of file + calendar(-6, False) From 873ca419e1846ab5e49e350f181a408875eb51fb Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Tue, 4 Jan 2022 15:12:41 -0300 Subject: [PATCH 026/102] formatting logic updated --- 21_Calendar/python/calendar.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/21_Calendar/python/calendar.py b/21_Calendar/python/calendar.py index 6c803771..c90b1b62 100644 --- a/21_Calendar/python/calendar.py +++ b/21_Calendar/python/calendar.py @@ -39,7 +39,7 @@ def calendar(weekday, leap_year): for n in range(1, 13): days_count += months_days[n-1] print("** {} ****************** {} ****************** {} **\n".format(days_count, - months_names[n-1], years_day-days_count)) + months_names[n-1], years_day-days_count)) print(days) print(sep) @@ -52,13 +52,12 @@ def calendar(weekday, leap_year): if d2 > months_days[n]: break - if d2 > 0: - if d2 < 10: - print(" {}".format(d2), end=' ') - else: - print("{}".format(d2), end=' ') - else: + if d2 <= 0: print("{}".format(' '), end=' ') + elif d2 < 10: + print(" {}".format(d2), end=' ') + else: + print("{}".format(d2), end=' ') if d2 >= months_days[n]: break From 6517975e250a0fa4f3d84936498877a5dd6a0f24 Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Tue, 4 Jan 2022 15:15:02 -0300 Subject: [PATCH 027/102] Updated formatting to look like the original program --- 21_Calendar/python/calendar.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/21_Calendar/python/calendar.py b/21_Calendar/python/calendar.py index c90b1b62..b59d09f4 100644 --- a/21_Calendar/python/calendar.py +++ b/21_Calendar/python/calendar.py @@ -58,6 +58,7 @@ def calendar(weekday, leap_year): print(" {}".format(d2), end=' ') else: print("{}".format(d2), end=' ') + print() if d2 >= months_days[n]: break @@ -67,6 +68,8 @@ def calendar(weekday, leap_year): print("\n") + print("\n") + if __name__ == "__main__": calendar(-6, False) From 9b44692b8ccaa3fca3dee78781b006ce67b660ec Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Tue, 4 Jan 2022 15:31:16 -0300 Subject: [PATCH 028/102] Added parse function for starting day of the week of the year and boolean to check if it's a leap year structured code --- 21_Calendar/python/calendar.py | 56 +++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/21_Calendar/python/calendar.py b/21_Calendar/python/calendar.py index b59d09f4..63c2741f 100644 --- a/21_Calendar/python/calendar.py +++ b/21_Calendar/python/calendar.py @@ -1,4 +1,46 @@ +def parse_input(): + """ + function to parse input for weekday and leap year boolean + """ + + days_mapping = { + "sunday": 0, + "monday": -1, + "tuesday": -2, + "wednesday": -3, + "thursday": -4, + "friday": -5, + "saturday": -6 + } + + day = 0 + leap_day = False + + correct_day_input = False + while not correct_day_input: + weekday = input("INSERT THE STARTING DAY OF THE WEEK OF THE YEAR:") + + for day_k in days_mapping.keys(): + if weekday.lower() in day_k: + day = days_mapping[day_k] + correct_day_input = True + break + + while True: + leap = input("IS IT A LEAP YEAR?:") + + if 'y' in leap.lower(): + leap_day = True + break + + if 'n' in leap.lower(): + leap_day = False + break + + return day, leap_day + + def calendar(weekday, leap_year): """ function to print a year's calendar. @@ -30,9 +72,6 @@ def calendar(weekday, leap_year): " NOVEMBER", " DECEMBER"] - print(" "*32 + "CALENDAR") - print(" "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - print("\n"*11) days_count = 0 # S in the original program # main loop @@ -71,5 +110,14 @@ def calendar(weekday, leap_year): print("\n") +def main(): + print(" "*32 + "CALENDAR") + print(" "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + print("\n"*11) + + day, leap_year = parse_input() + calendar(day, leap_year) + + if __name__ == "__main__": - calendar(-6, False) + main() From f673a3740f0bac5552e9359f8a7072e759558c69 Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Tue, 4 Jan 2022 15:45:12 -0300 Subject: [PATCH 029/102] Added porting notes and original program commentary --- 21_Calendar/python/calendar.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/21_Calendar/python/calendar.py b/21_Calendar/python/calendar.py index 63c2741f..6f3f572b 100644 --- a/21_Calendar/python/calendar.py +++ b/21_Calendar/python/calendar.py @@ -1,3 +1,24 @@ +######################################################## +# Calendar +# +# From: BASIC Computer Games (1978) +# Edited by David Ahl# +# +# This program prints out a calendar +# for any year. You must specify the +# starting day of the week of the year in +# statement 130. (Sunday(0), Monday +# (-1), Tuesday(-2), etc.) You can determine +# this by using the program WEEKDAY. +# You must also make two changes +# for leap years in statement 360 and 620. +# The program listing describes the necessary +# changes. Running the program produces a +# nice 12-month calendar. +# The program was written by Geofrey +# Chase of the Abbey, Portsmouth, Rhode Island. +# +######################################################## def parse_input(): """ @@ -121,3 +142,15 @@ def main(): if __name__ == "__main__": main() + +######################################################## +# +######################################################## +# +# Porting notes: +# +# It has been added an input at the beginning of the +# program so the user can specify the first day of the +# week of the year and if the year is leap or not. +# +######################################################## From 89ffbe6c6d0070f91523618aecc9f5f128c69001 Mon Sep 17 00:00:00 2001 From: a2wd Date: Tue, 4 Jan 2022 19:51:10 +0100 Subject: [PATCH 030/102] Added instruction on how to run the games --- HOW_TO_RUN_THE_GAMES.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 HOW_TO_RUN_THE_GAMES.md diff --git a/HOW_TO_RUN_THE_GAMES.md b/HOW_TO_RUN_THE_GAMES.md new file mode 100644 index 00000000..e69de29b From 40935505006bea529956b5e17e8708b7f48c3e6e Mon Sep 17 00:00:00 2001 From: Alito Date: Tue, 4 Jan 2022 19:57:29 +0100 Subject: [PATCH 031/102] Updated HOW_TO_RUN_THE_GAMES.md Added a new line to improve formatting around the note on the python environments. --- HOW_TO_RUN_THE_GAMES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HOW_TO_RUN_THE_GAMES.md b/HOW_TO_RUN_THE_GAMES.md index 6de43c98..96533226 100644 --- a/HOW_TO_RUN_THE_GAMES.md +++ b/HOW_TO_RUN_THE_GAMES.md @@ -67,6 +67,7 @@ The python translations can be run from the command line by using the `py` inter * eg. `python aceyducey.py` **Note** + Some translations include multiple versions for python, such as `acey ducey` which features versions for Python 2 (`aceyducey.py`) and Python 3 (`acey_ducey.py`) as well as an extra object-oriented version (`acey_ducey_oo.py`). You can manage and use different versions of python with [pip](https://pypi.org/project/pip/). @@ -81,4 +82,4 @@ If you don't already have a ruby interpreter, you can download it from the [ruby ## vbnet -Follow the same steps as for the [csharp](#csharp) translations. This can be run with `dotnet` or `Visual Studio`. \ No newline at end of file +Follow the same steps as for the [csharp](#csharp) translations. This can be run with `dotnet` or `Visual Studio`. From 990eb9915cc2a09e2880b7c4a51138c537b6bc58 Mon Sep 17 00:00:00 2001 From: Alito Date: Tue, 4 Jan 2022 19:58:48 +0100 Subject: [PATCH 032/102] Updated HOW_TO_RUN_THE_GAMES.md Fixed a typo (missing 'c' in the ruby project link text). --- HOW_TO_RUN_THE_GAMES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HOW_TO_RUN_THE_GAMES.md b/HOW_TO_RUN_THE_GAMES.md index 96533226..44d82e98 100644 --- a/HOW_TO_RUN_THE_GAMES.md +++ b/HOW_TO_RUN_THE_GAMES.md @@ -74,7 +74,7 @@ You can manage and use different versions of python with [pip](https://pypi.org/ ## ruby -If you don't already have a ruby interpreter, you can download it from the [ruby projet site](https://www.ruby-lang.org/en/). +If you don't already have a ruby interpreter, you can download it from the [ruby project site](https://www.ruby-lang.org/en/). 1. From the command-line, navigate to the corresponding directory. 1. Invoke with the `ruby` tool. From 75cf4767f020f16c054ac680ccbc83db3be5b3e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Tue, 4 Jan 2022 20:20:00 +0000 Subject: [PATCH 033/102] Update aceyducey.pl --- 01_Acey_Ducey/perl/aceyducey.pl | 123 ++++++++++++++------------------ 1 file changed, 53 insertions(+), 70 deletions(-) diff --git a/01_Acey_Ducey/perl/aceyducey.pl b/01_Acey_Ducey/perl/aceyducey.pl index e2de13df..d4dfb2c2 100755 --- a/01_Acey_Ducey/perl/aceyducey.pl +++ b/01_Acey_Ducey/perl/aceyducey.pl @@ -28,17 +28,15 @@ If you do not want to bet, input a 0. If you want to quit, input a -1. END_INSTRUCTIONS -my @cards = (1 .. 13); # That is, Ace through King. +my @cards = ( 1 .. 13 ); # That is, Ace through King. my $keepPlaying = 1; GAME: -while ($keepPlaying) -{ - my $playerBalance = 100; # The player starts with $100 +while ($keepPlaying) { + my $playerBalance = 100; # The player starts with $100 - HAND: - while (1) - { + HAND: + while (1) { print "\nYou now have $playerBalance dollars.\n\n"; # We'll create a new array that is a shuffled version of the deck. @@ -48,19 +46,17 @@ while ($keepPlaying) # that those will be unique. This way we don't have to keep drawing # if we get, say, two queens. We sort them as we pull them to make # sure that the first card is lower than the second one. - my ($firstCard, $secondCard) = sort { $a <=> $b } @shuffledDeck[ 0 .. 1 ]; + my ( $firstCard, $secondCard ) = sort { $a <=> $b } @shuffledDeck[ 0 .. 1 ]; print "I drew ", nameOfCard($firstCard), " and ", nameOfCard($secondCard), ".\n"; my $bet = getValidBet($playerBalance); - if ($bet == 0) - { + if ( $bet == 0 ) { print "Chicken!\n\n"; next HAND; } - if ($bet < 0) - { + if ( $bet < 0 ) { last GAME; } @@ -72,19 +68,16 @@ while ($keepPlaying) print "I drew ", nameOfCard($thirdCard), "!\n"; - if (($firstCard < $thirdCard) && ($thirdCard < $secondCard)) - { + if ( ( $firstCard < $thirdCard ) && ( $thirdCard < $secondCard ) ) { print "You win!\n\n"; $playerBalance += $bet; } - else - { + else { print "You lose!\n\n"; $playerBalance -= $bet; } - if ($playerBalance <= 0) - { + if ( $playerBalance <= 0 ) { print "Sorry, buddy, you blew your wad!\n\n"; last HAND; } @@ -96,49 +89,43 @@ while ($keepPlaying) print "Thanks for playing!\n"; ############### -sub getValidBet -{ +sub getValidBet { my $maxBet = shift; - print "\nWhat's your bet? "; - - my $input = ; - chomp $input; - - # This regular expression will validate that the player entered an integer. - # The !~ match operate *negates* the match, so if the player did NOT enter - # an integer, they'll be given an error and prompted again. - if ($input !~ /^ # Match the beginning of the string - [+-]? # Optional plus or minus... - \d+ # followed by one more more digits... - $ # and then the end of the string - /x # The x modifier ignores whitespace in this regex... - ) + INPUT: { - print "Sorry, numbers only!\n"; - $input = getValidBet($maxBet); - } + print "\nWhat's your bet? "; - if ($input > $maxBet) - { - print "Sorry, my friend, you can't bet more money than you have.\n"; - print "You only have $maxBet dollars to spend!\n"; - $input = getValidBet($maxBet); - } + chomp( my $input = ); - if ($input != int($input)) - { - print "Sorry, you must bet in whole dollars. No change!\n"; - $input = getValidBet($maxBet); - } + # This regular expression will validate that the player entered an integer. + # The !~ match operate *negates* the match, so if the player did NOT enter + # an integer, they'll be given an error and prompted again. + if ( + $input !~ /^ # Match the beginning of the string + [+-]? # Optional plus or minus... + \d+ # followed by one more more digits... + $ # and then the end of the string + /x # The x modifier ignores whitespace in this regex... + ) + { + print "Sorry, numbers only!\n"; + redo INPUT; + } - return $input; + if ( $input > $maxBet ) { + print "Sorry, my friend, you can't bet more money than you have.\n"; + print "You only have $maxBet dollars to spend!\n"; + redo INPUT; + } + + return $input; + } } # Since arrays in Perl are 0-based, we need to convert the value that we drew from # the array to its proper position in the deck. -sub nameOfCard -{ +sub nameOfCard { my $value = shift; # Note that the Joker isn't used in this game, but since arrays in Perl are @@ -150,25 +137,21 @@ sub nameOfCard return $cardlist[$value]; } -sub promptUserToKeepPlaying -{ - print "Try again (Y/N)? "; - my $input = ; - chomp $input; +sub promptUserToKeepPlaying { + YESNO: + { + print "Try again (Y/N)? "; - my $keepGoing; - if (uc($input) eq 'Y') - { - $keepGoing = 1; - } - elsif (uc($input) eq 'N') - { - $keepGoing = 0; - } - else - { - $keepGoing = promptUserToKeepPlaying(); - } + chomp( my $input = uc ); - return $keepGoing; + if ( $input eq 'Y' ) { + return 1; + } + elsif ( $input eq 'N' ) { + return 0; + } + else { + redo YESNO; + } + } } From cf9c2328b3ca8b7b1ae05282f3a9ef1d7279e503 Mon Sep 17 00:00:00 2001 From: Eric S Weilnau Date: Tue, 4 Jan 2022 18:38:07 -0500 Subject: [PATCH 034/102] Format external links --- 01_Acey_Ducey/README.md | 3 ++- 24_Chemist/README.md | 3 ++- 43_Hammurabi/README.md | 6 +++--- 84_Super_Star_Trek/README.md | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/01_Acey_Ducey/README.md b/01_Acey_Ducey/README.md index 3434eb8e..77ff8621 100644 --- a/01_Acey_Ducey/README.md +++ b/01_Acey_Ducey/README.md @@ -15,4 +15,5 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html -A Common Lisp port is [here](https://github.com/koalahedron/lisp-computer-games/blob/master/01%20Acey%20Ducey/common-lisp/acey-deucy.lisp). +#### External Links + - Common Lisp: https://github.com/koalahedron/lisp-computer-games/blob/master/01%20Acey%20Ducey/common-lisp/acey-deucy.lisp diff --git a/24_Chemist/README.md b/24_Chemist/README.md index 95db3f66..b93c1431 100644 --- a/24_Chemist/README.md +++ b/24_Chemist/README.md @@ -13,4 +13,5 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html -[Conversion to C](https://github.com/ericfischer/basic-computer-games/blob/main/24%20Chemist/c/chemist.c) +#### External Links + - C: https://github.com/ericfischer/basic-computer-games/blob/main/24%20Chemist/c/chemist.c diff --git a/43_Hammurabi/README.md b/43_Hammurabi/README.md index c92b7ee3..c02219b1 100644 --- a/43_Hammurabi/README.md +++ b/43_Hammurabi/README.md @@ -21,6 +21,6 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html -[Port to C language](https://github.com/beyonddream/hamurabi) - -[Port to Rust language](https://github.com/beyonddream/hamurabi.rs) +#### External Links + - C: https://github.com/beyonddream/hamurabi + - Rust: https://github.com/beyonddream/hamurabi.rs diff --git a/84_Super_Star_Trek/README.md b/84_Super_Star_Trek/README.md index 4a96f528..77fae3d8 100644 --- a/84_Super_Star_Trek/README.md +++ b/84_Super_Star_Trek/README.md @@ -101,4 +101,4 @@ Instructions in this directory at instructions.txt #### External Links - - Super Star Trek in C++ : https://www.codeproject.com/Articles/28399/The-Object-Oriented-Text-Star-Trek-Game-in-C + - C++: https://www.codeproject.com/Articles/28399/The-Object-Oriented-Text-Star-Trek-Game-in-C From f7b4b999dddf1066d91844b1855e0b228213aefb Mon Sep 17 00:00:00 2001 From: Bastiaan Veelo Date: Wed, 5 Jan 2022 01:51:34 +0100 Subject: [PATCH 035/102] D version of the word game. --- 96_Word/d/.gitignore | 2 ++ 96_Word/d/README.md | 15 ++++++++ 96_Word/d/word.d | 85 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 96_Word/d/.gitignore create mode 100644 96_Word/d/README.md create mode 100644 96_Word/d/word.d diff --git a/96_Word/d/.gitignore b/96_Word/d/.gitignore new file mode 100644 index 00000000..d969f6b2 --- /dev/null +++ b/96_Word/d/.gitignore @@ -0,0 +1,2 @@ +*.exe +*.obj diff --git a/96_Word/d/README.md b/96_Word/d/README.md new file mode 100644 index 00000000..764cb141 --- /dev/null +++ b/96_Word/d/README.md @@ -0,0 +1,15 @@ +Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html) + +Converted to [D](https://dlang.org/) by [Bastiaan Veelo](https://github.com/veelo). + +The Basic original required words to be exactly five letters in length for the program to behave correctly. +This version does not replicate that limitation, and the test for that requirement is commented out. + +## Running the code + +Assuming the reference [dmd](https://dlang.org/download.html#dmd) compiler: +```shell +dmd -dip1000 -run word.d +``` + +[Other compilers](https://dlang.org/download.html) also exist. diff --git a/96_Word/d/word.d b/96_Word/d/word.d new file mode 100644 index 00000000..6f4d46d6 --- /dev/null +++ b/96_Word/d/word.d @@ -0,0 +1,85 @@ +@safe: // Make @safe the default for this file, enforcing memory-safety. +import std; + +void main() +{ + enum width = 80; + writeln(center("Word", width)); + writeln(center("(After Creative Computing Morristown, New Jersey)\n\n\n", width)); + writeln(wrap("I am thinking of a word -- you guess it. I will give you " ~ + "clues to help you get it. Good luck!!\n\n", width)); + + string[] words = ["dinky", "smoke", "water", "grass", "train", "might", "first", + "candy", "champ", "would", "clump", "dopey"]; + + playLoop: while (true) + { + writeln("\n\nYou are starting a new game..."); + + string word = words[uniform(0, $-1)]; // $ is a short-hand for words.length. + int guesses = 0; + string knownLetters = '-'.repeat(word.length).array; + + while (true) + { + writeln("Guess a ", word.length, " letter word"); + string guess = readString.toLower; + if (guess == "?") + { + writeln("The secret word is ", word, "\n"); + continue playLoop; // Start a new game. + } + /* Uncomment this for equivalence with Basic. + if (guess.length != 5) + { + writeln("You must guess a 5 letter word. Start again."); + continue; // Ask for new guess. + } + */ + guesses++; + if (guess == word) + break; // Done guessing + string commonLetters; + foreach (i, wordLetter; word) + foreach (j, guessLetter; guess) + if (guessLetter == wordLetter) + { + commonLetters ~= guessLetter; + if (i == j) + knownLetters.replaceInPlace(i, i + 1, [guessLetter]); + } + writeln("There were ", commonLetters.length, " matches and the common letters were... ", commonLetters); + writeln("From the exact letter matches, you know................ ", knownLetters); + if (knownLetters == word) + break; // Done guessing + if (commonLetters.length < 2) + writeln("If you give up, type '?' for your next guess."); + writeln; + } + + writeln("You have guessed the word. It took ", guesses, " guesses!"); + write("\n\nWant to play again? "); + if (readString.toLower != "yes") + break; // Terminate playLoop + } +} + +/// Read a string from standard input, stripping newline and other enclosing whitespace. +string readString() nothrow +{ + try + return trustedReadln.strip; + catch (Exception) // readln throws on I/O and Unicode errors, which we handle here. + return ""; +} + +/** An @trusted wrapper around readln. + * + * This is the only function that formally requires manual review for memory-safety. + * [Arguably readln should be safe already](https://forum.dlang.org/post/rab398$1up$1@digitalmars.com) + * which would remove the need to have any @trusted code in this program. + */ +string trustedReadln() @trusted +{ + return readln; +} From 5263ee6ba9eed38009724014098f9b9fe4baadc7 Mon Sep 17 00:00:00 2001 From: James Allenspach Date: Tue, 4 Jan 2022 22:12:28 -0600 Subject: [PATCH 036/102] Initial commit --- 44_Hangman/perl/hangman.pl | 223 +++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100755 44_Hangman/perl/hangman.pl diff --git a/44_Hangman/perl/hangman.pl b/44_Hangman/perl/hangman.pl new file mode 100755 index 00000000..e2aca815 --- /dev/null +++ b/44_Hangman/perl/hangman.pl @@ -0,0 +1,223 @@ +#!/usr/bin/perl + +use strict; +use warnings; + + +# global variables defined here + +my(@WORDS) = qw( + 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 +); +my(@PIC,@L,$board,@guessedLetters,$guesses,$hangCount); +my($guess,%GUESSED); + +# Subroutines defined here. + +# init_variables: initialize all of the variables needed +# (this covers lines 50-90 in the original BASIC program) + +sub init_variables { + @guessedLetters = (); + @PIC = ( + 'XXXXXXX ', + 'X X ', + 'X ', + 'X ', + 'X ', + 'X ', + 'X ', + 'X ', + 'X ', + 'X ', + 'X ', + 'X ', + ); + $guesses = 0; %GUESSED = (); + $hangCount = 0; +} + +# addchar: given a row & column, put the specified char in that place in @PIC +sub addchar { + my($row,$col, $c) = @_; + + substr($PIC[$row],$col,1) = $c; +} + + +# main code starts here + +print ' 'x31; print "Hangman\n"; +print ' 'x14; print "Creative Computing Morristown, New Jersey\n\n\n\n"; + +# an iteration of the PLAY block is one complete game. +# There is a continue block that will ask if the user +# wants to play another game. + +PLAY: while (1) { + + init_variables(); + # Any words left? + if (@WORDS == 0) { + print "You did all the words!\n"; + last PLAY; + } + # splice a random word out of the @WORDS array + my($thisWord) = splice(@WORDS, int(rand(scalar @WORDS)),1); + # $board is the "game board" of the filled-out word + # that the user is working on + $board = '.'x(length $thisWord); + + # GUESS loop is run for every time the user guesses a letter + GUESS: while(1) { + print "Here are the letters you used:\n"; + printf("%s\n", join(',',@guessedLetters)); + printf("\n\n%s\n", $board); + + print "What is your guess for a letter ? "; + chomp($guess = ); + # The %GUESSED hash allows us to quickly identify + # letters that have already been guessed + if ($GUESSED{lc $guess}) { + print "You guessed that letter before!\n\n"; + redo GUESS; + } + + # save the guessed letter + push @guessedLetters, $guess; + $GUESSED{lc $guess} = 1; + ++$guesses; + + # now look for the letter in the $thisWord var + # and put it into the $board var wherever it + # shows up. $foundLetter is a flag that indicates + # whether or not the letter is found. + my $foundLetter = 0; + for (my $i = 0; $i < length $thisWord; ++$i) { + if (lc substr($thisWord,$i,1) eq lc $guess) { + $foundLetter = 1; + substr($board, $i, 1) = substr($thisWord, $i, 1); + } + } + + # The user found a letter in the solution! + if ($foundLetter) { + + # Are there any '.' chars left in the board? + if (index($board, '.') < 0) { + print "You found the word!\n\n"; + } else { + printf("%s\n\n", $board); + print "What is your guess for the word ? "; + chomp(my $guessword = ); + if (lc $thisWord ne lc $guessword) { + print "Wrong. Try another letter.\n"; + # Go to the next iteration of the GUESS loop + next GUESS; + } + printf("Right! It took you %d %s!\n", $guesses, ($guesses == 1 ? 'guess' : 'guesses')); + } + # At this point the user has discovered the word and won. + # This "next" statement takes execution down to the + # continue block for the PLAY loop; + next PLAY; + + } else { # didn't find a letter + + ++$hangCount; + print "\n\n\nSorry, that letter isn't in the word.\n"; + + # The addchar() calls in the block below piece together the + # hangman graphic, depending on how many wrong letters + # the user has. + if ($hangCount == 1) { + print "First, we draw a head\n"; + addchar(2,5,"-");addchar(2,6,"-");addchar(2,7,"-"); + addchar(3,4,"("); addchar(3,5,"."); addchar(3,7,"."); addchar(3,8,")"); + addchar(4,5,"-");addchar(4,6,"-");addchar(4,7,"-"); + } + if ($hangCount == 2) { + print "Now we draw a body.\n"; + for (5 .. 8) { + addchar($_, 6, "X"); + } + } + if ($hangCount == 3) { + print "Next we draw an arm.\n"; + for (3 .. 6) { + addchar($_, $_-1, "\\"); + } + } + if ($hangCount == 4) { + print "This time it's the other arm.\n"; + addchar(3,10, "/"); + addchar(4, 9, "/"); + addchar(5, 8, "/"); + addchar(6, 7, "/"); + } + if ($hangCount == 5) { + print "Now, let's draw the right leg.\n"; + addchar( 9,5, "/"); + addchar(10,4, "/"); + } + if ($hangCount == 6) { + print "This time we draw the left leg.\n"; + addchar(9,7,"\\"); + addchar(10,8,"\\"); + } + if ($hangCount == 7) { + print "Now we put up a hand.\n"; + addchar(2,10,"\\"); + } + if ($hangCount == 8) { + print "Next the other hand.\n"; + addchar(2,2,"/"); + } + if ($hangCount == 9) { + print "Now we draw one foot\n"; + addchar(11,9,"\\"); + addchar(11,10, "-"); + } + if ($hangCount == 10) { + print "Here's the other foot -- you're hung!!\n"; + addchar(11,2,"-"); + addchar(11,3, "/"); + } + + printf("$_\n") for @PIC; + print "\n\n"; + + # Next guess if the user has not lost + if ($hangCount < 10) { + next GUESS; + } + + printf("Sorry, you lose. The word was %s\n", $thisWord); + next PLAY; + + } # didn't find a letter block + } # GUESS block +} # PLAY block + +# This block is reached either by the player winning (see the "next PLAY") +# statement) or by the user losing (as the PLAY block is complete and +# execution naturally comes to this continue block). +continue { + print "Want another word ? "; + chomp(my $in = ); + if ($in !~ m/^y/i) { + # Exit the PLAY loop + print "\nIt's been fun! Bye for now.\n\n"; + last PLAY; + } + # At this point execution goes to the start of the PLAY block, + # meaning a new game +} From 6e3da5b1a1c79b24bac5619ee9f3cd74edd7c6cc Mon Sep 17 00:00:00 2001 From: James Allenspach Date: Tue, 4 Jan 2022 22:14:49 -0600 Subject: [PATCH 037/102] Removal of unused var --- 44_Hangman/perl/hangman.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/44_Hangman/perl/hangman.pl b/44_Hangman/perl/hangman.pl index e2aca815..aadf631b 100755 --- a/44_Hangman/perl/hangman.pl +++ b/44_Hangman/perl/hangman.pl @@ -17,7 +17,7 @@ my(@WORDS) = qw( MAGISTRATE ERRONEOUSLY LOUDSPEAKER PHYTOTOXIC MATRIMONIAL PARASYMPATHOMIMETIC THIGMOTROPISM ); -my(@PIC,@L,$board,@guessedLetters,$guesses,$hangCount); +my(@PIC,$board,@guessedLetters,$guesses,$hangCount); my($guess,%GUESSED); # Subroutines defined here. From daab84dbd55d623c07059bc3f85fccc011174aad Mon Sep 17 00:00:00 2001 From: James Allenspach Date: Tue, 4 Jan 2022 22:18:09 -0600 Subject: [PATCH 038/102] Rename some vars to be more helpful --- 44_Hangman/perl/hangman.pl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/44_Hangman/perl/hangman.pl b/44_Hangman/perl/hangman.pl index aadf631b..45a6da9b 100755 --- a/44_Hangman/perl/hangman.pl +++ b/44_Hangman/perl/hangman.pl @@ -17,8 +17,8 @@ my(@WORDS) = qw( MAGISTRATE ERRONEOUSLY LOUDSPEAKER PHYTOTOXIC MATRIMONIAL PARASYMPATHOMIMETIC THIGMOTROPISM ); -my(@PIC,$board,@guessedLetters,$guesses,$hangCount); -my($guess,%GUESSED); +my(@PIC,$board,@guessedLetters,$guessCount,$hangCount); +my(%GUESSED); # Subroutines defined here. @@ -41,7 +41,7 @@ sub init_variables { 'X ', 'X ', ); - $guesses = 0; %GUESSED = (); + $guessCount = 0; %GUESSED = (); $hangCount = 0; } @@ -83,7 +83,7 @@ PLAY: while (1) { printf("\n\n%s\n", $board); print "What is your guess for a letter ? "; - chomp($guess = ); + chomp(my $guess = ); # The %GUESSED hash allows us to quickly identify # letters that have already been guessed if ($GUESSED{lc $guess}) { @@ -94,7 +94,7 @@ PLAY: while (1) { # save the guessed letter push @guessedLetters, $guess; $GUESSED{lc $guess} = 1; - ++$guesses; + ++$guessCount; # now look for the letter in the $thisWord var # and put it into the $board var wherever it @@ -123,7 +123,7 @@ PLAY: while (1) { # Go to the next iteration of the GUESS loop next GUESS; } - printf("Right! It took you %d %s!\n", $guesses, ($guesses == 1 ? 'guess' : 'guesses')); + printf("Right! It took you %d %s!\n", $guessCount, ($guessCount == 1 ? 'guess' : 'guesses')); } # At this point the user has discovered the word and won. # This "next" statement takes execution down to the From f2e7381878c198b467093eef1deac7c3bc3b6e88 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 20:44:47 -0800 Subject: [PATCH 039/102] first very ugly port. --- 81_Splat/java/src/Splat.java | 277 +++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 81_Splat/java/src/Splat.java diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java new file mode 100644 index 00000000..0930dcc2 --- /dev/null +++ b/81_Splat/java/src/Splat.java @@ -0,0 +1,277 @@ +import java.util.Arrays; +import java.util.Random; +import java.util.Scanner; + +public class Splat { + private final Random random = new Random(); + private final Scanner scanner = new Scanner(System.in); + + public static void main(String[] args) { + new Splat().run(); + } + + public void run() { + System.out.printf("%33s%s\n", " ", "SPLAT"); + System.out.printf("%15s%s\n", " ", "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.print("\n\n\n"); + System.out.println("WELCOME TO 'SPLAT' -- THE GAME THAT SIMULATES A PARACHUTE"); + System.out.println("JUMP. TRY TO OPEN YOUR CHUTE AT THE LAST POSSIBLE"); + System.out.println("MOMENT WITHOUT GOING SPLAT."); + + float[] Arr = new float[42]; + Arrays.fill(Arr, 0.0f); + int K = 0; + int K1 = 0; + while (true) { + + System.out.print("\n\n"); + float V = 0.0f; + float A = 0.0f; + int N = 0; + int M = 0; + int D1 = (int) (9001.0f * random.nextFloat() + 1000); + D1 = 2937; //debug fixme + + System.out.print("SELECT YOUR OWN TERMINAL VELOCITY (YES OR NO) "); + float V1; + while (true) { + String A1 = scanner.next(); + if (A1.equals("NO")) { + V1 = (int) (1000 * random.nextFloat()); + System.out.printf("OK. TERMINAL VELOCITY = %d MI/HR\n", (int) V1); + break; + } + if (!A1.equals("YES")) { + System.out.print("YES OR NO "); + continue; + } + System.out.print("WHAT TERMINAL VELOCITY (MI/HR) "); + V1 = scanner.nextInt(); + break; + } + V1 = V1 * (5280.0f / 3600.0f); + V = V1 + ((V1 * random.nextFloat()) / 20.0f) - ((V1 * random.nextFloat()) / 20.0f); + System.out.print("WANT TO SELECT ACCELERATION DUE TO GRAVITY (YES OR NO) "); + float A2; + while (true) { + String B1 = scanner.next(); + if (B1.equals("NO")) { + switch (random.nextInt(10)) { + case 0: + System.out.println("FINE. YOU'RE ON MERCURY. ACCELERATION=12.2 FT/SEC/SEC."); + A2 = 12.2f; + break; + case 1: + System.out.println("ALL RIGHT. YOU'RE ON VENUS. ACCELERATION=28.3 FT/SEC/SEC."); + A2 = 28.3f; + break; + case 2: + System.out.println("THEN YOU'RE ON EARTH. ACCELERATION=32.16 FT/SEC/SEC."); + A2 = 32.16f; + break; + case 3: + System.out.println("FINE. YOU'RE ON THE MOON. ACCELERATION=5.15 FT/SEC/SEC."); + A2 = 5.15f; + break; + case 4: + System.out.println("ALL RIGHT. YOU'RE ON MARS. ACCELERATION=12.5 FT/SEC/SEC."); + A2 = 12.5f; + break; + case 5: + System.out.println("THEN YOU'RE ON JUPITER. ACCELERATION=85.2 FT/SEC/SEC."); + A2 = 85.2f; + break; + case 6: + System.out.println("FINE. YOU'RE ON SATURN. ACCELERATION=37.6 FT/SEC/SEC."); + A2 = 37.6f; + break; + case 7: + System.out.println("ALL RIGHT. YOU'RE ON URANUS. ACCELERATION=33.8 FT/SEC/SEC."); + A2 = 33.8f; + break; + case 8: + System.out.println("THEN YOU'RE ON NEPTUNE. ACCELERATION=39.6 FT/SEC/SEC."); + A2 = 39.6f; + break; + case 9: + System.out.println("FINE. YOU'RE ON THE SUN. ACCELERATION=896 FT/SEC/SEC."); + A2 = 896.0f; + break; + default: + throw new RuntimeException("Impossible. Will fix stupid switch statement later."); + } + break; + } + if (!B1.equals("YES")) { + System.out.print("YES OR NO "); + continue; + } + System.out.print("WHAT ACCELERATION (FT/SEC/SEC) "); + A2 = scanner.nextFloat(); + break; + } + A = A2 + ((A2 * random.nextFloat()) / 20.0f) - ((A2 * random.nextFloat()) / 20.0f); + System.out.println(); + System.out.printf(" ALTITUDE = %d FT\n", D1); + System.out.printf(" TERM. VELOCITY = %.2f FT/SEC +/-5%%\n", V1); + System.out.printf(" ACCELERATION = %.2f FT/SEC/SEC +/-5%%\n", A2); + System.out.println("SET THE TIMER FOR YOUR FREEFALL."); + System.out.print("HOW MANY SECONDS "); + float T = scanner.nextFloat(); + System.out.println("HERE WE GO.\n"); + System.out.println("TIME (SEC) DIST TO FALL (FT)"); + System.out.println("========== ================="); + boolean splat = false; + boolean terminalReached = false; + float D = 0.0f; + for (float i = 0.0f; !splat && (i < T); i += T / 8) { + if (i > (V / A)) { + terminalReached = true; + System.out.printf("TERMINAL VELOCITY REACHED AT T PLUS %f SECONDS.\n", (V / A)); + for (i = i; i < T; i += T / 8) { + D = D1 - ((V * V / (2 * A)) + (V * (i - (V / A)))); +// System.out.printf(" ......................................tv %f\n", D); + if (D <= 0) { + splat = true; + break; + } + System.out.printf("%10.2f %f\n", i, D); + } + break; + } + D = D1 - ((A / 2) * i * i); +// System.out.printf(" ......................................debug %f\n", D); + if (D <= 0) { + splat = true; + break; + } + System.out.printf("%10.2f %f\n", i, D); + } + + if (!splat) { + + System.out.println("CHUTE OPEN"); + int J = 0; + for (J = 0; J < 42; J++) { + if (Arr[J] == 0) { + Arr[J] = D; + break; + } + K = K + 1; + if (D > Arr[J]) { + continue; + } + K1 = K1 + 1; + } + + if (J > 2) { + if (K - K1 <= 0.1 * K) { + System.out.printf("WOW! THAT'S SOME JUMPING. OF THE %d SUCCESSFUL JUMPS\n", K); + System.out.printf("BEFORE YOURS, ONLY %d OPENED THEIR CHUTES LOWER THAN\n", K - K1); + System.out.println("YOU DID."); + } else if (K - K1 <= 0.25 * K) { + System.out.printf("PRETTY GOOD! %d SUCCESSFUL JUMPS PRECEDED YOURS AND ONLY\n", K); + System.out.printf("%d OF THEM GOT LOWER THAN YOU DID BEFORE THEIR CHUTES\n", K - K1); + System.out.println("OPENED."); + } else if (K - K1 <= 0.5 * K) { + System.out.printf("NOT BAD. THERE HAVE BEEN %d SUCCESSFUL JUMPS BEFORE YOURS.\n", K); + System.out.printf("YOU WERE BEATEN OUT BY %d OF THEM.\n", K - K1); + } else if (K - K1 <= 0.75 * K) { + System.out.printf("CONSERVATIVE, AREN'T YOU? YOU RANKED ONLY %d IN THE\n", K - K1); + System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS.", K); + } else if (K - K1 <= -0.9 * K) { + System.out.println("HUMPH! DON'T YOU HAVE ANY SPORTING BLOOD? THERE WERE"); + System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS AND YOU CAME IN %d JUMPS\n", K, K1); + System.out.println("BETTER THAN THE WORST. SHAPE UP!!!\n"); + } else { + System.out.printf("HEY! YOU PULLED THE RIP CORD MUCH TOO SOON. %f SUCCESSFUL\n", K); + System.out.printf("JUMPS BEFORE YOURS AND YOU CAME IN NUMBER %d! GET WITH IT!\n", K - K1); + } + } else { + System.out.println("AMAZING!!! NOT BAD FOR YOUR "); + switch (J) { + case 0: + System.out.print("1ST "); + break; + case 1: + System.out.print("2ND "); + break; + case 2: + System.out.print("3RD "); + break; + } + System.out.println("SUCCESSFUL JUMP!!!"); + } + + + } else { + if (terminalReached) { + System.out.printf("%.2f SPLAT\n", (V / A) + ((D1 - (V * V / (2 * A))) / V)); + } else { + System.out.printf("%.2f SPLAT\n", Math.sqrt(2 * D1 / A)); + + } + switch (random.nextInt(10)) { + case 0: + System.out.println("REQUIESCAT IN PACE."); + break; + case 1: + System.out.println("MAY THE ANGEL OF HEAVEN LEAD YOU INTO PARADISE."); + break; + case 2: + System.out.println("REST IN PEACE."); + break; + case 3: + System.out.println("SON-OF-A-GUN."); + break; + case 4: + System.out.println("#$%&&%!$"); + break; + case 5: + System.out.println("A KICK IN THE PANTS IS A BOOST IF YOU'RE HEADED RIGHT."); + break; + case 6: + System.out.println("HMMM. SHOULD HAVE PICKED A SHORTER TIME."); + break; + case 7: + System.out.println("MUTTER. MUTTER. MUTTER."); + break; + case 8: + System.out.println("PUSHING UP DAISIES."); + break; + default: + System.out.println("EASY COME, EASY GO."); + + } + } + boolean chosen = false; + while (!chosen) { + System.out.print("DO YOU WANT TO PLAY AGAIN "); + String Z = scanner.next(); + if (Z.equals("YES")) { + break; + } + if (Z.equals("NO")) { + System.out.print("PLEASE "); + while (true) { + Z = scanner.next(); + if (Z.equals("YES")) { + chosen = true; + break; + } + if (Z.equals("NO")) { + System.out.println("SSSSSSSSSS."); + return; + } + System.out.print("YES OR NO "); + } + continue; + } else { + System.out.print("YES OR NO "); + } + } + + } + + } +} \ No newline at end of file From b899d6d5c508bfe9a746c64b9dbaad2496ac33dd Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 21:14:36 -0800 Subject: [PATCH 040/102] factor out planet enum --- 81_Splat/java/src/Splat.java | 86 +++++++++++++++++------------------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index 0930dcc2..c5c94a5d 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -30,7 +30,6 @@ public class Splat { int N = 0; int M = 0; int D1 = (int) (9001.0f * random.nextFloat() + 1000); - D1 = 2937; //debug fixme System.out.print("SELECT YOUR OWN TERMINAL VELOCITY (YES OR NO) "); float V1; @@ -56,50 +55,7 @@ public class Splat { while (true) { String B1 = scanner.next(); if (B1.equals("NO")) { - switch (random.nextInt(10)) { - case 0: - System.out.println("FINE. YOU'RE ON MERCURY. ACCELERATION=12.2 FT/SEC/SEC."); - A2 = 12.2f; - break; - case 1: - System.out.println("ALL RIGHT. YOU'RE ON VENUS. ACCELERATION=28.3 FT/SEC/SEC."); - A2 = 28.3f; - break; - case 2: - System.out.println("THEN YOU'RE ON EARTH. ACCELERATION=32.16 FT/SEC/SEC."); - A2 = 32.16f; - break; - case 3: - System.out.println("FINE. YOU'RE ON THE MOON. ACCELERATION=5.15 FT/SEC/SEC."); - A2 = 5.15f; - break; - case 4: - System.out.println("ALL RIGHT. YOU'RE ON MARS. ACCELERATION=12.5 FT/SEC/SEC."); - A2 = 12.5f; - break; - case 5: - System.out.println("THEN YOU'RE ON JUPITER. ACCELERATION=85.2 FT/SEC/SEC."); - A2 = 85.2f; - break; - case 6: - System.out.println("FINE. YOU'RE ON SATURN. ACCELERATION=37.6 FT/SEC/SEC."); - A2 = 37.6f; - break; - case 7: - System.out.println("ALL RIGHT. YOU'RE ON URANUS. ACCELERATION=33.8 FT/SEC/SEC."); - A2 = 33.8f; - break; - case 8: - System.out.println("THEN YOU'RE ON NEPTUNE. ACCELERATION=39.6 FT/SEC/SEC."); - A2 = 39.6f; - break; - case 9: - System.out.println("FINE. YOU'RE ON THE SUN. ACCELERATION=896 FT/SEC/SEC."); - A2 = 896.0f; - break; - default: - throw new RuntimeException("Impossible. Will fix stupid switch statement later."); - } + A2 = chooseRandomAcceleration(); break; } if (!B1.equals("YES")) { @@ -274,4 +230,44 @@ public class Splat { } } + + private float chooseRandomAcceleration() { + Planet planet = Planet.pickRandom(); + System.out.printf("%s. ACCELERATION=%.2f FT/SEC/SEC.\n", planet.getMessage(), planet.getAcceleration()); + return planet.getAcceleration(); + } + + enum Planet { + MERCURY("FINE. YOU'RE ON MERCURY", 12.2f), + VENUS("ALL RIGHT. YOU'RE ON VENUS", 28.3f), + EARTH("THEN YOU'RE ON EARTH", 32.16f), + MOON("FINE. YOU'RE ON THE MOON", 5.15f), + MARS("ALL RIGHT. YOU'RE ON MARS", 12.5f), + JUPITER("THEN YOU'RE ON JUPITER", 85.2f), + SATURN("FINE. YOU'RE ON SATURN", 37.6f), + URANUS("ALL RIGHT. YOU'RE ON URANUS", 33.8f), + NEPTUNE("THEN YOU'RE ON NEPTUNE", 39.6f), + SUN("FINE. YOU'RE ON THE SUN", 896.0f); + + static final Random random = new Random(); + private final String message; + private final float acceleration; + + Planet(String message, float acceleration) { + this.message = message; + this.acceleration = acceleration; + } + + static Planet pickRandom(){ + return values()[random.nextInt(Planet.values().length)]; + } + + public String getMessage() { + return message; + } + + public float getAcceleration() { + return acceleration; + } + } } \ No newline at end of file From 22213547fc81233c2645c7014e60a2537a9a50ef Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 21:22:11 -0800 Subject: [PATCH 041/102] factor out askYesNo --- 81_Splat/java/src/Splat.java | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index c5c94a5d..3f44af2f 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -27,27 +27,18 @@ public class Splat { System.out.print("\n\n"); float V = 0.0f; float A = 0.0f; - int N = 0; - int M = 0; int D1 = (int) (9001.0f * random.nextFloat() + 1000); - System.out.print("SELECT YOUR OWN TERMINAL VELOCITY (YES OR NO) "); float V1; - while (true) { - String A1 = scanner.next(); - if (A1.equals("NO")) { - V1 = (int) (1000 * random.nextFloat()); - System.out.printf("OK. TERMINAL VELOCITY = %d MI/HR\n", (int) V1); - break; - } - if (!A1.equals("YES")) { - System.out.print("YES OR NO "); - continue; - } + if(askYesNo("SELECT YOUR OWN TERMINAL VELOCITY")){ System.out.print("WHAT TERMINAL VELOCITY (MI/HR) "); V1 = scanner.nextInt(); - break; } + else { + V1 = (int) (1000 * random.nextFloat()); + System.out.printf("OK. TERMINAL VELOCITY = %d MI/HR\n", (int) V1); + } + V1 = V1 * (5280.0f / 3600.0f); V = V1 + ((V1 * random.nextFloat()) / 20.0f) - ((V1 * random.nextFloat()) / 20.0f); System.out.print("WANT TO SELECT ACCELERATION DUE TO GRAVITY (YES OR NO) "); @@ -231,6 +222,18 @@ public class Splat { } + private boolean askYesNo(String prompt){ + System.out.printf("%s (YES OR NO) ", prompt); + while (true) { + String answer = scanner.next(); + switch(answer){ + case "YES": return true; + case "NO": return false; + default: System.out.print("YES OR NO "); + } + } + } + private float chooseRandomAcceleration() { Planet planet = Planet.pickRandom(); System.out.printf("%s. ACCELERATION=%.2f FT/SEC/SEC.\n", planet.getMessage(), planet.getAcceleration()); From 9fba41771c254890d30b14cf343d4f6babc4b645 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 21:24:01 -0800 Subject: [PATCH 042/102] plug in yesno prompt for acceleration --- 81_Splat/java/src/Splat.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index 3f44af2f..ba1496ca 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -41,22 +41,16 @@ public class Splat { V1 = V1 * (5280.0f / 3600.0f); V = V1 + ((V1 * random.nextFloat()) / 20.0f) - ((V1 * random.nextFloat()) / 20.0f); - System.out.print("WANT TO SELECT ACCELERATION DUE TO GRAVITY (YES OR NO) "); + float A2; - while (true) { - String B1 = scanner.next(); - if (B1.equals("NO")) { - A2 = chooseRandomAcceleration(); - break; - } - if (!B1.equals("YES")) { - System.out.print("YES OR NO "); - continue; - } + if(askYesNo("WANT TO SELECT ACCELERATION DUE TO GRAVITY")){ System.out.print("WHAT ACCELERATION (FT/SEC/SEC) "); A2 = scanner.nextFloat(); - break; } + else { + A2 = chooseRandomAcceleration(); + } + A = A2 + ((A2 * random.nextFloat()) / 20.0f) - ((A2 * random.nextFloat()) / 20.0f); System.out.println(); System.out.printf(" ALTITUDE = %d FT\n", D1); From c3a1b621b917aaa71966c18cbe64004924d36dfd Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 21:32:56 -0800 Subject: [PATCH 043/102] factor out intro and prompt messages --- 81_Splat/java/src/Splat.java | 69 ++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index ba1496ca..e4614fa8 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -11,12 +11,7 @@ public class Splat { } public void run() { - System.out.printf("%33s%s\n", " ", "SPLAT"); - System.out.printf("%15s%s\n", " ", "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); - System.out.print("\n\n\n"); - System.out.println("WELCOME TO 'SPLAT' -- THE GAME THAT SIMULATES A PARACHUTE"); - System.out.println("JUMP. TRY TO OPEN YOUR CHUTE AT THE LAST POSSIBLE"); - System.out.println("MOMENT WITHOUT GOING SPLAT."); + showIntroduction(); float[] Arr = new float[42]; Arrays.fill(Arr, 0.0f); @@ -25,37 +20,18 @@ public class Splat { while (true) { System.out.print("\n\n"); - float V = 0.0f; - float A = 0.0f; int D1 = (int) (9001.0f * random.nextFloat() + 1000); - float V1; - if(askYesNo("SELECT YOUR OWN TERMINAL VELOCITY")){ - System.out.print("WHAT TERMINAL VELOCITY (MI/HR) "); - V1 = scanner.nextInt(); - } - else { - V1 = (int) (1000 * random.nextFloat()); - System.out.printf("OK. TERMINAL VELOCITY = %d MI/HR\n", (int) V1); - } + float terminalVelocity = promptTerminalVelocity(); + float V = terminalVelocity + ((terminalVelocity * random.nextFloat()) / 20.0f) - ((terminalVelocity * random.nextFloat()) / 20.0f); - V1 = V1 * (5280.0f / 3600.0f); - V = V1 + ((V1 * random.nextFloat()) / 20.0f) - ((V1 * random.nextFloat()) / 20.0f); + float gravitationalAcceleration = promptGravitationalAcceleration(); + float A = gravitationalAcceleration + ((gravitationalAcceleration * random.nextFloat()) / 20.0f) - ((gravitationalAcceleration * random.nextFloat()) / 20.0f); - float A2; - if(askYesNo("WANT TO SELECT ACCELERATION DUE TO GRAVITY")){ - System.out.print("WHAT ACCELERATION (FT/SEC/SEC) "); - A2 = scanner.nextFloat(); - } - else { - A2 = chooseRandomAcceleration(); - } - - A = A2 + ((A2 * random.nextFloat()) / 20.0f) - ((A2 * random.nextFloat()) / 20.0f); System.out.println(); System.out.printf(" ALTITUDE = %d FT\n", D1); - System.out.printf(" TERM. VELOCITY = %.2f FT/SEC +/-5%%\n", V1); - System.out.printf(" ACCELERATION = %.2f FT/SEC/SEC +/-5%%\n", A2); + System.out.printf(" TERM. VELOCITY = %.2f FT/SEC +/-5%%\n", terminalVelocity); + System.out.printf(" ACCELERATION = %.2f FT/SEC/SEC +/-5%%\n", gravitationalAcceleration); System.out.println("SET THE TIMER FOR YOUR FREEFALL."); System.out.print("HOW MANY SECONDS "); float T = scanner.nextFloat(); @@ -216,6 +192,37 @@ public class Splat { } + private void showIntroduction() { + System.out.printf("%33s%s\n", " ", "SPLAT"); + System.out.printf("%15s%s\n", " ", "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.print("\n\n\n"); + System.out.println("WELCOME TO 'SPLAT' -- THE GAME THAT SIMULATES A PARACHUTE"); + System.out.println("JUMP. TRY TO OPEN YOUR CHUTE AT THE LAST POSSIBLE"); + System.out.println("MOMENT WITHOUT GOING SPLAT."); + } + + private float promptTerminalVelocity() { + if(askYesNo("SELECT YOUR OWN TERMINAL VELOCITY")){ + System.out.print("WHAT TERMINAL VELOCITY (MI/HR) "); + return mphToFeetPerSec(scanner.nextFloat()); + } + float terminalVelocity = (int) (1000 * random.nextFloat()); + System.out.printf("OK. TERMINAL VELOCITY = %.2f MI/HR\n", terminalVelocity); + return mphToFeetPerSec(terminalVelocity); + } + + private float promptGravitationalAcceleration() { + if(askYesNo("WANT TO SELECT ACCELERATION DUE TO GRAVITY")){ + System.out.print("WHAT ACCELERATION (FT/SEC/SEC) "); + return scanner.nextFloat(); + } + return chooseRandomAcceleration(); + } + + private float mphToFeetPerSec(float speed){ + return speed * (5280.0f / 3600.0f); + } + private boolean askYesNo(String prompt){ System.out.printf("%s (YES OR NO) ", prompt); while (true) { From eba6c07fd03cd2f08ec0b711a3289397ba3b4cf9 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 22:05:24 -0800 Subject: [PATCH 044/102] factor out initial jump conditions --- 81_Splat/java/src/Splat.java | 94 ++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 20 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index e4614fa8..67e278f8 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -3,7 +3,7 @@ import java.util.Random; import java.util.Scanner; public class Splat { - private final Random random = new Random(); + private static final Random random = new Random(); private final Scanner scanner = new Scanner(System.in); public static void main(String[] args) { @@ -19,19 +19,15 @@ public class Splat { int K1 = 0; while (true) { - System.out.print("\n\n"); - int D1 = (int) (9001.0f * random.nextFloat() + 1000); - - float terminalVelocity = promptTerminalVelocity(); - float V = terminalVelocity + ((terminalVelocity * random.nextFloat()) / 20.0f) - ((terminalVelocity * random.nextFloat()) / 20.0f); - - float gravitationalAcceleration = promptGravitationalAcceleration(); - float A = gravitationalAcceleration + ((gravitationalAcceleration * random.nextFloat()) / 20.0f) - ((gravitationalAcceleration * random.nextFloat()) / 20.0f); + InitialJumpConditions jump = buildInitialConditions(); + final float V = jump.getTerminalVelocity(); + final float A = jump.getGravitationalAcceleration(); System.out.println(); - System.out.printf(" ALTITUDE = %d FT\n", D1); - System.out.printf(" TERM. VELOCITY = %.2f FT/SEC +/-5%%\n", terminalVelocity); - System.out.printf(" ACCELERATION = %.2f FT/SEC/SEC +/-5%%\n", gravitationalAcceleration); + System.out.printf(" ALTITUDE = %d FT\n", jump.getAltitude()); + System.out.printf(" TERM. VELOCITY = %.2f FT/SEC +/-5%%\n", jump.getOriginalTerminalVelocity()); + System.out.printf(" ACCELERATION = %.2f FT/SEC/SEC +/-5%%\n", jump.getOriginalGravitationalAcceleration()); + System.out.println("SET THE TIMER FOR YOUR FREEFALL."); System.out.print("HOW MANY SECONDS "); float T = scanner.nextFloat(); @@ -42,12 +38,11 @@ public class Splat { boolean terminalReached = false; float D = 0.0f; for (float i = 0.0f; !splat && (i < T); i += T / 8) { - if (i > (V / A)) { + if (i > jump.getTimeOfTerminalAccelerationReached()) { terminalReached = true; - System.out.printf("TERMINAL VELOCITY REACHED AT T PLUS %f SECONDS.\n", (V / A)); + System.out.printf("TERMINAL VELOCITY REACHED AT T PLUS %f SECONDS.\n", jump.getTimeOfTerminalAccelerationReached()); for (i = i; i < T; i += T / 8) { - D = D1 - ((V * V / (2 * A)) + (V * (i - (V / A)))); -// System.out.printf(" ......................................tv %f\n", D); + D = jump.getAltitude() - ((V * V / (2 * A)) + (V * (i - (V / A)))); if (D <= 0) { splat = true; break; @@ -56,8 +51,7 @@ public class Splat { } break; } - D = D1 - ((A / 2) * i * i); -// System.out.printf(" ......................................debug %f\n", D); + D = jump.getAltitude() - ((A / 2) * i * i); if (D <= 0) { splat = true; break; @@ -123,9 +117,9 @@ public class Splat { } else { if (terminalReached) { - System.out.printf("%.2f SPLAT\n", (V / A) + ((D1 - (V * V / (2 * A))) / V)); + System.out.printf("%.2f SPLAT\n", (V / A) + ((jump.getAltitude() - (V * V / (2 * A))) / V)); } else { - System.out.printf("%.2f SPLAT\n", Math.sqrt(2 * D1 / A)); + System.out.printf("%.2f SPLAT\n", Math.sqrt(2 * jump.getAltitude() / A)); } switch (random.nextInt(10)) { @@ -192,6 +186,13 @@ public class Splat { } + private InitialJumpConditions buildInitialConditions() { + System.out.print("\n\n"); + float terminalVelocity = promptTerminalVelocity(); + float gravitationalAcceleration = promptGravitationalAcceleration(); + return InitialJumpConditions.create(terminalVelocity, gravitationalAcceleration); + } + private void showIntroduction() { System.out.printf("%33s%s\n", " ", "SPLAT"); System.out.printf("%15s%s\n", " ", "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); @@ -241,6 +242,59 @@ public class Splat { return planet.getAcceleration(); } + + static class InitialJumpConditions { + private final float originalTerminalVelocity; + private final float originalGravitationalAcceleration; + private final float terminalVelocity; + private final float gravitationalAcceleration; + private final int altitude; + + private InitialJumpConditions(float originalTerminalVelocity, float originalGravitationalAcceleration, + float terminalVelocity, float gravitationalAcceleration, int altitude) { + this.originalTerminalVelocity = originalTerminalVelocity; + this.originalGravitationalAcceleration = originalGravitationalAcceleration; + this.terminalVelocity = terminalVelocity; + this.gravitationalAcceleration = gravitationalAcceleration; + this.altitude = altitude; + } + + // Create initial jump conditions with adjusted velocity/acceleration and a random initial altitude + private static InitialJumpConditions create(float terminalVelocity, float gravitationalAcceleration) { + final int altitude = (int) (9001.0f * random.nextFloat() + 1000); + return new InitialJumpConditions(terminalVelocity, gravitationalAcceleration, + plusMinus5Percent(terminalVelocity), plusMinus5Percent(gravitationalAcceleration), altitude); + } + + private static float plusMinus5Percent(float value) { + return value + ((value * random.nextFloat()) / 20.0f) - ((value * random.nextFloat()) / 20.0f); + } + + public float getOriginalTerminalVelocity() { + return originalTerminalVelocity; + } + + public float getOriginalGravitationalAcceleration() { + return originalGravitationalAcceleration; + } + + public float getTerminalVelocity() { + return terminalVelocity; + } + + public float getGravitationalAcceleration() { + return gravitationalAcceleration; + } + + public int getAltitude() { + return altitude; + } + + public float getTimeOfTerminalAccelerationReached(){ + return terminalVelocity / gravitationalAcceleration; + } + } + enum Planet { MERCURY("FINE. YOU'RE ON MERCURY", 12.2f), VENUS("ALL RIGHT. YOU'RE ON VENUS", 28.3f), From 8a992b6ba44b38beb827a66d6e5f551dbbbec786 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 22:07:32 -0800 Subject: [PATCH 045/102] invert if and factor out splat message --- 81_Splat/java/src/Splat.java | 85 +++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index 67e278f8..65be1d77 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -59,7 +59,15 @@ public class Splat { System.out.printf("%10.2f %f\n", i, D); } - if (!splat) { + if (splat) { + if (terminalReached) { + System.out.printf("%.2f SPLAT\n", (V / A) + ((jump.getAltitude() - (V * V / (2 * A))) / V)); + } else { + System.out.printf("%.2f SPLAT\n", Math.sqrt(2 * jump.getAltitude() / A)); + + } + showRandomSplatMessage(); + } else { System.out.println("CHUTE OPEN"); int J = 0; @@ -115,45 +123,6 @@ public class Splat { } - } else { - if (terminalReached) { - System.out.printf("%.2f SPLAT\n", (V / A) + ((jump.getAltitude() - (V * V / (2 * A))) / V)); - } else { - System.out.printf("%.2f SPLAT\n", Math.sqrt(2 * jump.getAltitude() / A)); - - } - switch (random.nextInt(10)) { - case 0: - System.out.println("REQUIESCAT IN PACE."); - break; - case 1: - System.out.println("MAY THE ANGEL OF HEAVEN LEAD YOU INTO PARADISE."); - break; - case 2: - System.out.println("REST IN PEACE."); - break; - case 3: - System.out.println("SON-OF-A-GUN."); - break; - case 4: - System.out.println("#$%&&%!$"); - break; - case 5: - System.out.println("A KICK IN THE PANTS IS A BOOST IF YOU'RE HEADED RIGHT."); - break; - case 6: - System.out.println("HMMM. SHOULD HAVE PICKED A SHORTER TIME."); - break; - case 7: - System.out.println("MUTTER. MUTTER. MUTTER."); - break; - case 8: - System.out.println("PUSHING UP DAISIES."); - break; - default: - System.out.println("EASY COME, EASY GO."); - - } } boolean chosen = false; while (!chosen) { @@ -186,6 +155,41 @@ public class Splat { } + private void showRandomSplatMessage() { + switch (random.nextInt(10)) { + case 0: + System.out.println("REQUIESCAT IN PACE."); + break; + case 1: + System.out.println("MAY THE ANGEL OF HEAVEN LEAD YOU INTO PARADISE."); + break; + case 2: + System.out.println("REST IN PEACE."); + break; + case 3: + System.out.println("SON-OF-A-GUN."); + break; + case 4: + System.out.println("#$%&&%!$"); + break; + case 5: + System.out.println("A KICK IN THE PANTS IS A BOOST IF YOU'RE HEADED RIGHT."); + break; + case 6: + System.out.println("HMMM. SHOULD HAVE PICKED A SHORTER TIME."); + break; + case 7: + System.out.println("MUTTER. MUTTER. MUTTER."); + break; + case 8: + System.out.println("PUSHING UP DAISIES."); + break; + default: + System.out.println("EASY COME, EASY GO."); + + } + } + private InitialJumpConditions buildInitialConditions() { System.out.print("\n\n"); float terminalVelocity = promptTerminalVelocity(); @@ -243,6 +247,7 @@ public class Splat { } + // Immutable static class InitialJumpConditions { private final float originalTerminalVelocity; private final float originalGravitationalAcceleration; From dd0dbf648037ba072c4df2bba66b9ed2d62bccc7 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 22:10:44 -0800 Subject: [PATCH 046/102] simplify splat message --- 81_Splat/java/src/Splat.java | 48 +++++++++++------------------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index 65be1d77..3e2f2f83 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -1,4 +1,5 @@ import java.util.Arrays; +import java.util.List; import java.util.Random; import java.util.Scanner; @@ -121,8 +122,6 @@ public class Splat { } System.out.println("SUCCESSFUL JUMP!!!"); } - - } boolean chosen = false; while (!chosen) { @@ -156,38 +155,19 @@ public class Splat { } private void showRandomSplatMessage() { - switch (random.nextInt(10)) { - case 0: - System.out.println("REQUIESCAT IN PACE."); - break; - case 1: - System.out.println("MAY THE ANGEL OF HEAVEN LEAD YOU INTO PARADISE."); - break; - case 2: - System.out.println("REST IN PEACE."); - break; - case 3: - System.out.println("SON-OF-A-GUN."); - break; - case 4: - System.out.println("#$%&&%!$"); - break; - case 5: - System.out.println("A KICK IN THE PANTS IS A BOOST IF YOU'RE HEADED RIGHT."); - break; - case 6: - System.out.println("HMMM. SHOULD HAVE PICKED A SHORTER TIME."); - break; - case 7: - System.out.println("MUTTER. MUTTER. MUTTER."); - break; - case 8: - System.out.println("PUSHING UP DAISIES."); - break; - default: - System.out.println("EASY COME, EASY GO."); - - } + List messages = Arrays.asList( + "REQUIESCAT IN PACE.", + "MAY THE ANGEL OF HEAVEN LEAD YOU INTO PARADISE.", + "REST IN PEACE.", + "SON-OF-A-GUN.", + "#$%&&%!$", + "A KICK IN THE PANTS IS A BOOST IF YOU'RE HEADED RIGHT.", + "HMMM. SHOULD HAVE PICKED A SHORTER TIME.", + "MUTTER. MUTTER. MUTTER.", + "PUSHING UP DAISIES.", + "EASY COME, EASY GO." + ); + System.out.println(messages.get(random.nextInt(10))); } private InitialJumpConditions buildInitialConditions() { From 42f57024fe971b10c0399eb81decc776e04ce04d Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 22:31:51 -0800 Subject: [PATCH 047/102] factor out silly play again prompt --- 81_Splat/java/src/Splat.java | 72 +++++++++++++++--------------------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index 3e2f2f83..73d91021 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -21,13 +21,11 @@ public class Splat { while (true) { InitialJumpConditions jump = buildInitialConditions(); - final float V = jump.getTerminalVelocity(); - final float A = jump.getGravitationalAcceleration(); System.out.println(); System.out.printf(" ALTITUDE = %d FT\n", jump.getAltitude()); System.out.printf(" TERM. VELOCITY = %.2f FT/SEC +/-5%%\n", jump.getOriginalTerminalVelocity()); - System.out.printf(" ACCELERATION = %.2f FT/SEC/SEC +/-5%%\n", jump.getOriginalGravitationalAcceleration()); + System.out.printf(" ACCELERATION = %.2f FT/SEC/SEC +/-5%%\n", jump.getOriginalAcceleration()); System.out.println("SET THE TIMER FOR YOUR FREEFALL."); System.out.print("HOW MANY SECONDS "); @@ -35,6 +33,8 @@ public class Splat { System.out.println("HERE WE GO.\n"); System.out.println("TIME (SEC) DIST TO FALL (FT)"); System.out.println("========== ================="); + final float V = jump.getTerminalVelocity(); + final float A = jump.getAcceleration(); boolean splat = false; boolean terminalReached = false; float D = 0.0f; @@ -123,37 +123,24 @@ public class Splat { System.out.println("SUCCESSFUL JUMP!!!"); } } - boolean chosen = false; - while (!chosen) { - System.out.print("DO YOU WANT TO PLAY AGAIN "); - String Z = scanner.next(); - if (Z.equals("YES")) { - break; - } - if (Z.equals("NO")) { - System.out.print("PLEASE "); - while (true) { - Z = scanner.next(); - if (Z.equals("YES")) { - chosen = true; - break; - } - if (Z.equals("NO")) { - System.out.println("SSSSSSSSSS."); - return; - } - System.out.print("YES OR NO "); - } - continue; - } else { - System.out.print("YES OR NO "); - } + if(!playAgain()){ + return; } - } } + private boolean playAgain() { + if (askYesNo("DO YOU WANT TO PLAY AGAIN ")) { + return true; + } + if (askYesNo("PLEASE")) { + return true; + } + System.out.println("SSSSSSSSSS."); + return false; + } + private void showRandomSplatMessage() { List messages = Arrays.asList( "REQUIESCAT IN PACE.", @@ -173,8 +160,8 @@ public class Splat { private InitialJumpConditions buildInitialConditions() { System.out.print("\n\n"); float terminalVelocity = promptTerminalVelocity(); - float gravitationalAcceleration = promptGravitationalAcceleration(); - return InitialJumpConditions.create(terminalVelocity, gravitationalAcceleration); + float acceleration = promptGravitationalAcceleration(); + return InitialJumpConditions.create(terminalVelocity, acceleration); } private void showIntroduction() { @@ -226,21 +213,20 @@ public class Splat { return planet.getAcceleration(); } - // Immutable static class InitialJumpConditions { private final float originalTerminalVelocity; - private final float originalGravitationalAcceleration; + private final float originalAcceleration; private final float terminalVelocity; - private final float gravitationalAcceleration; + private final float acceleration; private final int altitude; - private InitialJumpConditions(float originalTerminalVelocity, float originalGravitationalAcceleration, - float terminalVelocity, float gravitationalAcceleration, int altitude) { + private InitialJumpConditions(float originalTerminalVelocity, float originalAcceleration, + float terminalVelocity, float acceleration, int altitude) { this.originalTerminalVelocity = originalTerminalVelocity; - this.originalGravitationalAcceleration = originalGravitationalAcceleration; + this.originalAcceleration = originalAcceleration; this.terminalVelocity = terminalVelocity; - this.gravitationalAcceleration = gravitationalAcceleration; + this.acceleration = acceleration; this.altitude = altitude; } @@ -259,16 +245,16 @@ public class Splat { return originalTerminalVelocity; } - public float getOriginalGravitationalAcceleration() { - return originalGravitationalAcceleration; + public float getOriginalAcceleration() { + return originalAcceleration; } public float getTerminalVelocity() { return terminalVelocity; } - public float getGravitationalAcceleration() { - return gravitationalAcceleration; + public float getAcceleration() { + return acceleration; } public int getAltitude() { @@ -276,7 +262,7 @@ public class Splat { } public float getTimeOfTerminalAccelerationReached(){ - return terminalVelocity / gravitationalAcceleration; + return terminalVelocity / acceleration; } } From 347558b966a041a6bf221cfeb8d655aeedd28441 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 22:53:32 -0800 Subject: [PATCH 048/102] factor out JumpResult and executeJump() --- 81_Splat/java/src/Splat.java | 111 +++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 39 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index 73d91021..ad15d84e 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -20,65 +20,41 @@ public class Splat { int K1 = 0; while (true) { - InitialJumpConditions jump = buildInitialConditions(); + InitialJumpConditions initial = buildInitialConditions(); System.out.println(); - System.out.printf(" ALTITUDE = %d FT\n", jump.getAltitude()); - System.out.printf(" TERM. VELOCITY = %.2f FT/SEC +/-5%%\n", jump.getOriginalTerminalVelocity()); - System.out.printf(" ACCELERATION = %.2f FT/SEC/SEC +/-5%%\n", jump.getOriginalAcceleration()); + System.out.printf(" ALTITUDE = %d FT\n", initial.getAltitude()); + System.out.printf(" TERM. VELOCITY = %.2f FT/SEC +/-5%%\n", initial.getOriginalTerminalVelocity()); + System.out.printf(" ACCELERATION = %.2f FT/SEC/SEC +/-5%%\n", initial.getOriginalAcceleration()); System.out.println("SET THE TIMER FOR YOUR FREEFALL."); System.out.print("HOW MANY SECONDS "); - float T = scanner.nextFloat(); + float freefallTime = scanner.nextFloat(); System.out.println("HERE WE GO.\n"); System.out.println("TIME (SEC) DIST TO FALL (FT)"); System.out.println("========== ================="); - final float V = jump.getTerminalVelocity(); - final float A = jump.getAcceleration(); - boolean splat = false; - boolean terminalReached = false; - float D = 0.0f; - for (float i = 0.0f; !splat && (i < T); i += T / 8) { - if (i > jump.getTimeOfTerminalAccelerationReached()) { - terminalReached = true; - System.out.printf("TERMINAL VELOCITY REACHED AT T PLUS %f SECONDS.\n", jump.getTimeOfTerminalAccelerationReached()); - for (i = i; i < T; i += T / 8) { - D = jump.getAltitude() - ((V * V / (2 * A)) + (V * (i - (V / A)))); - if (D <= 0) { - splat = true; - break; - } - System.out.printf("%10.2f %f\n", i, D); - } - break; - } - D = jump.getAltitude() - ((A / 2) * i * i); - if (D <= 0) { - splat = true; - break; - } - System.out.printf("%10.2f %f\n", i, D); - } + final float V = initial.getTerminalVelocity(); + final float A = initial.getAcceleration(); + JumpResult jump = executeJump(initial, freefallTime); - if (splat) { - if (terminalReached) { - System.out.printf("%.2f SPLAT\n", (V / A) + ((jump.getAltitude() - (V * V / (2 * A))) / V)); + if (jump.isSplat()) { + if (jump.hasReachedTerminalVelocity()) { + System.out.printf("%.2f SPLAT\n", (V / A) + ((initial.getAltitude() - (V * V / (2 * A))) / V)); } else { - System.out.printf("%.2f SPLAT\n", Math.sqrt(2 * jump.getAltitude() / A)); + System.out.printf("%.2f SPLAT\n", Math.sqrt(2 * initial.getAltitude() / A)); } showRandomSplatMessage(); } else { - System.out.println("CHUTE OPEN"); int J = 0; for (J = 0; J < 42; J++) { if (Arr[J] == 0) { - Arr[J] = D; + Arr[J] = jump.getDistance(); break; } K = K + 1; - if (D > Arr[J]) { + if (jump.getDistance() > Arr[J]) { continue; } K1 = K1 + 1; @@ -98,7 +74,7 @@ public class Splat { System.out.printf("YOU WERE BEATEN OUT BY %d OF THEM.\n", K - K1); } else if (K - K1 <= 0.75 * K) { System.out.printf("CONSERVATIVE, AREN'T YOU? YOU RANKED ONLY %d IN THE\n", K - K1); - System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS.", K); + System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS.\n", K); } else if (K - K1 <= -0.9 * K) { System.out.println("HUMPH! DON'T YOU HAVE ANY SPORTING BLOOD? THERE WERE"); System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS AND YOU CAME IN %d JUMPS\n", K, K1); @@ -130,6 +106,33 @@ public class Splat { } + private JumpResult executeJump(InitialJumpConditions initial, float T) { + final float V = initial.getTerminalVelocity(); + final float A = initial.getAcceleration(); + + JumpResult jump = new JumpResult(initial.getAltitude()); + for (float i = 0.0f; !jump.isSplat() && (i < T); i += T / 8) { + if (i > initial.getTimeOfTerminalAccelerationReached()) { + jump.setReachedTerminalVelocity(); + System.out.printf("TERMINAL VELOCITY REACHED AT T PLUS %f SECONDS.\n", initial.getTimeOfTerminalAccelerationReached()); + for (i = i; i < T; i += T / 8) { + jump.setDistance(initial.getAltitude() - ((V * V / (2 * A)) + (V * (i - (V / A))))); + if (jump.isSplat()) { + break; + } + System.out.printf("%10.2f %f\n", i, jump.getDistance()); + } + break; + } + jump.setDistance( initial.getAltitude() - ((A / 2) * i * i)); + if (jump.isSplat()) { + break; + } + System.out.printf("%10.2f %f\n", i, jump.getDistance()); + } + return jump; + } + private boolean playAgain() { if (askYesNo("DO YOU WANT TO PLAY AGAIN ")) { return true; @@ -213,6 +216,36 @@ public class Splat { return planet.getAcceleration(); } + // Mutable + static class JumpResult { + private boolean reachedTerminalVelocity = false; + private float distance; // from the ground + + public JumpResult(float distance) { + this.distance = distance; + } + + public boolean isSplat() { + return distance <= 0; + } + + public boolean hasReachedTerminalVelocity() { + return reachedTerminalVelocity; + } + + public float getDistance() { + return distance; + } + + public void setDistance(float distance){ + this.distance = distance; + } + + public void setReachedTerminalVelocity(){ + reachedTerminalVelocity = true; + } + } + // Immutable static class InitialJumpConditions { private final float originalTerminalVelocity; From 98b4e94719d08fbcc05cf6fba07eca8df7aaa66f Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 23:14:58 -0800 Subject: [PATCH 049/102] factor out result message display and clean up ordinal switch --- 81_Splat/java/src/Splat.java | 159 +++++++++++++++++------------------ 1 file changed, 76 insertions(+), 83 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index ad15d84e..a0193507 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -6,6 +6,9 @@ import java.util.Scanner; public class Splat { private static final Random random = new Random(); private final Scanner scanner = new Scanner(System.in); + private final float[] Arr = new float[42]; + private int K = 0; + private int K1 = 0; public static void main(String[] args) { new Splat().run(); @@ -14,10 +17,7 @@ public class Splat { public void run() { showIntroduction(); - float[] Arr = new float[42]; Arrays.fill(Arr, 0.0f); - int K = 0; - int K1 = 0; while (true) { InitialJumpConditions initial = buildInitialConditions(); @@ -33,106 +33,100 @@ public class Splat { System.out.println("HERE WE GO.\n"); System.out.println("TIME (SEC) DIST TO FALL (FT)"); System.out.println("========== ================="); - final float V = initial.getTerminalVelocity(); - final float A = initial.getAcceleration(); + JumpResult jump = executeJump(initial, freefallTime); + showJumpResults(initial, jump); - if (jump.isSplat()) { - if (jump.hasReachedTerminalVelocity()) { - System.out.printf("%.2f SPLAT\n", (V / A) + ((initial.getAltitude() - (V * V / (2 * A))) / V)); - } else { - System.out.printf("%.2f SPLAT\n", Math.sqrt(2 * initial.getAltitude() / A)); - - } - showRandomSplatMessage(); - } else { - System.out.println("CHUTE OPEN"); - int J = 0; - for (J = 0; J < 42; J++) { - if (Arr[J] == 0) { - Arr[J] = jump.getDistance(); - break; - } - K = K + 1; - if (jump.getDistance() > Arr[J]) { - continue; - } - K1 = K1 + 1; - } - - if (J > 2) { - if (K - K1 <= 0.1 * K) { - System.out.printf("WOW! THAT'S SOME JUMPING. OF THE %d SUCCESSFUL JUMPS\n", K); - System.out.printf("BEFORE YOURS, ONLY %d OPENED THEIR CHUTES LOWER THAN\n", K - K1); - System.out.println("YOU DID."); - } else if (K - K1 <= 0.25 * K) { - System.out.printf("PRETTY GOOD! %d SUCCESSFUL JUMPS PRECEDED YOURS AND ONLY\n", K); - System.out.printf("%d OF THEM GOT LOWER THAN YOU DID BEFORE THEIR CHUTES\n", K - K1); - System.out.println("OPENED."); - } else if (K - K1 <= 0.5 * K) { - System.out.printf("NOT BAD. THERE HAVE BEEN %d SUCCESSFUL JUMPS BEFORE YOURS.\n", K); - System.out.printf("YOU WERE BEATEN OUT BY %d OF THEM.\n", K - K1); - } else if (K - K1 <= 0.75 * K) { - System.out.printf("CONSERVATIVE, AREN'T YOU? YOU RANKED ONLY %d IN THE\n", K - K1); - System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS.\n", K); - } else if (K - K1 <= -0.9 * K) { - System.out.println("HUMPH! DON'T YOU HAVE ANY SPORTING BLOOD? THERE WERE"); - System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS AND YOU CAME IN %d JUMPS\n", K, K1); - System.out.println("BETTER THAN THE WORST. SHAPE UP!!!\n"); - } else { - System.out.printf("HEY! YOU PULLED THE RIP CORD MUCH TOO SOON. %f SUCCESSFUL\n", K); - System.out.printf("JUMPS BEFORE YOURS AND YOU CAME IN NUMBER %d! GET WITH IT!\n", K - K1); - } - } else { - System.out.println("AMAZING!!! NOT BAD FOR YOUR "); - switch (J) { - case 0: - System.out.print("1ST "); - break; - case 1: - System.out.print("2ND "); - break; - case 2: - System.out.print("3RD "); - break; - } - System.out.println("SUCCESSFUL JUMP!!!"); - } - } if(!playAgain()){ + System.out.println("SSSSSSSSSS."); return; } } - } - private JumpResult executeJump(InitialJumpConditions initial, float T) { + private void showJumpResults(InitialJumpConditions initial, JumpResult jump) { final float V = initial.getTerminalVelocity(); final float A = initial.getAcceleration(); + if (jump.isSplat()) { + if (jump.hasReachedTerminalVelocity()) { + System.out.printf("%.2f SPLAT\n", (V / A) + ((initial.getAltitude() - (V * V / (2 * A))) / V)); + } else { + System.out.printf("%.2f SPLAT\n", Math.sqrt(2 * initial.getAltitude() / A)); + } + showRandomSplatMessage(); + } else { + System.out.println("CHUTE OPEN"); + int J = 0; + for (J = 0; J < 42; J++) { + if (Arr[J] == 0) { + Arr[J] = jump.getDistance(); + break; + } + K = K + 1; + if (jump.getDistance() > Arr[J]) { + continue; + } + K1 = K1 + 1; + } + + if (J > 2) { + if (K - K1 <= 0.1 * K) { + System.out.printf("WOW! THAT'S SOME JUMPING. OF THE %d SUCCESSFUL JUMPS\n", K); + System.out.printf("BEFORE YOURS, ONLY %d OPENED THEIR CHUTES LOWER THAN\n", K - K1); + System.out.println("YOU DID."); + } else if (K - K1 <= 0.25 * K) { + System.out.printf("PRETTY GOOD! %d SUCCESSFUL JUMPS PRECEDED YOURS AND ONLY\n", K); + System.out.printf("%d OF THEM GOT LOWER THAN YOU DID BEFORE THEIR CHUTES\n", K - K1); + System.out.println("OPENED."); + } else if (K - K1 <= 0.5 * K) { + System.out.printf("NOT BAD. THERE HAVE BEEN %d SUCCESSFUL JUMPS BEFORE YOURS.\n", K); + System.out.printf("YOU WERE BEATEN OUT BY %d OF THEM.\n", K - K1); + } else if (K - K1 <= 0.75 * K) { + System.out.printf("CONSERVATIVE, AREN'T YOU? YOU RANKED ONLY %d IN THE\n", K - K1); + System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS.\n", K); + } else if (K - K1 <= -0.9 * K) { + System.out.println("HUMPH! DON'T YOU HAVE ANY SPORTING BLOOD? THERE WERE"); + System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS AND YOU CAME IN %d JUMPS\n", K, K1); + System.out.println("BETTER THAN THE WORST. SHAPE UP!!!\n"); + } else { + System.out.printf("HEY! YOU PULLED THE RIP CORD MUCH TOO SOON. %f SUCCESSFUL\n", K); + System.out.printf("JUMPS BEFORE YOURS AND YOU CAME IN NUMBER %d! GET WITH IT!\n", K - K1); + } + } else { + String[] nums = new String[]{ "1ST", "2ND", "3RD"}; + System.out.printf("AMAZING!!! NOT BAD FOR YOUR %s SUCCESSFUL JUMP!!!\n", nums[J]); + } + } + } + + private JumpResult executeJump(InitialJumpConditions initial, float chuteOpenTime) { JumpResult jump = new JumpResult(initial.getAltitude()); - for (float i = 0.0f; !jump.isSplat() && (i < T); i += T / 8) { - if (i > initial.getTimeOfTerminalAccelerationReached()) { + for (float time = 0.0f; !jump.isSplat() && (time < chuteOpenTime); time += chuteOpenTime / 8) { + if (!jump.hasReachedTerminalVelocity() && time > initial.getTimeOfTerminalAccelerationReached()) { jump.setReachedTerminalVelocity(); System.out.printf("TERMINAL VELOCITY REACHED AT T PLUS %f SECONDS.\n", initial.getTimeOfTerminalAccelerationReached()); - for (i = i; i < T; i += T / 8) { - jump.setDistance(initial.getAltitude() - ((V * V / (2 * A)) + (V * (i - (V / A))))); - if (jump.isSplat()) { - break; - } - System.out.printf("%10.2f %f\n", i, jump.getDistance()); - } - break; } - jump.setDistance( initial.getAltitude() - ((A / 2) * i * i)); + float newDistance = computeDistance(initial, time, jump.hasReachedTerminalVelocity()); + jump.setDistance(newDistance); + if (jump.isSplat()) { - break; + return jump; } - System.out.printf("%10.2f %f\n", i, jump.getDistance()); + System.out.printf("%10.2f %f\n", time, jump.getDistance()); } return jump; } + private float computeDistance(InitialJumpConditions initial, float i, boolean hasReachedTerminalVelocity) { + final float V = initial.getTerminalVelocity(); + final float A = initial.getAcceleration(); + if(hasReachedTerminalVelocity) { + return initial.getAltitude() - ((V * V / (2 * A)) + (V * (i - (V / A)))); + } + return initial.getAltitude() - ((A / 2) * i * i); + } + private boolean playAgain() { if (askYesNo("DO YOU WANT TO PLAY AGAIN ")) { return true; @@ -140,7 +134,6 @@ public class Splat { if (askYesNo("PLEASE")) { return true; } - System.out.println("SSSSSSSSSS."); return false; } From 8e98439f35e93e95379ef652fd283a10d919baeb Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 23:49:31 -0800 Subject: [PATCH 050/102] simplify handling of past successes --- 81_Splat/java/src/Splat.java | 146 +++++++++++++++++------------------ 1 file changed, 72 insertions(+), 74 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index a0193507..2586ecab 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -1,14 +1,9 @@ -import java.util.Arrays; -import java.util.List; -import java.util.Random; -import java.util.Scanner; +import java.util.*; public class Splat { private static final Random random = new Random(); private final Scanner scanner = new Scanner(System.in); - private final float[] Arr = new float[42]; - private int K = 0; - private int K1 = 0; + private final List pastSuccessfulJumpDistances = new ArrayList<>(); public static void main(String[] args) { new Splat().run(); @@ -17,7 +12,6 @@ public class Splat { public void run() { showIntroduction(); - Arrays.fill(Arr, 0.0f); while (true) { InitialJumpConditions initial = buildInitialConditions(); @@ -45,59 +39,66 @@ public class Splat { } private void showJumpResults(InitialJumpConditions initial, JumpResult jump) { + if (jump.isSplat()) { + showSplatMessage(initial, jump); + showCleverSplatMessage(); + return; + } + System.out.println("CHUTE OPEN"); + int worseJumpCount = countWorseHistoricalJumps(jump); + pastSuccessfulJumpDistances.add(jump.getDistance()); + int successfulJumpCt = pastSuccessfulJumpDistances.size(); + + if (pastSuccessfulJumpDistances.size() <= 2) { + List ordinals = Arrays.asList("1ST", "2ND", "3RD"); + System.out.printf("AMAZING!!! NOT BAD FOR YOUR %s SUCCESSFUL JUMP!!!\n", ordinals.get(successfulJumpCt)); + return; + } + + int betterThanCount = successfulJumpCt - worseJumpCount; + if (betterThanCount <= 0.1 * successfulJumpCt) { + System.out.printf("WOW! THAT'S SOME JUMPING. OF THE %d SUCCESSFUL JUMPS\n", successfulJumpCt); + System.out.printf("BEFORE YOURS, ONLY %d OPENED THEIR CHUTES LOWER THAN\n", betterThanCount); + System.out.println("YOU DID."); + } else if (betterThanCount <= 0.25 * successfulJumpCt) { + System.out.printf("PRETTY GOOD! %d SUCCESSFUL JUMPS PRECEDED YOURS AND ONLY\n", successfulJumpCt); + System.out.printf("%d OF THEM GOT LOWER THAN YOU DID BEFORE THEIR CHUTES\n", betterThanCount); + System.out.println("OPENED."); + } else if (betterThanCount <= 0.5 * successfulJumpCt) { + System.out.printf("NOT BAD. THERE HAVE BEEN %d SUCCESSFUL JUMPS BEFORE YOURS.\n", successfulJumpCt); + System.out.printf("YOU WERE BEATEN OUT BY %d OF THEM.\n", betterThanCount); + } else if (betterThanCount <= 0.75 * successfulJumpCt) { + System.out.printf("CONSERVATIVE, AREN'T YOU? YOU RANKED ONLY %d IN THE\n", betterThanCount); + System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS.\n", successfulJumpCt); + } else if (betterThanCount <= -0.9 * successfulJumpCt) { + System.out.println("HUMPH! DON'T YOU HAVE ANY SPORTING BLOOD? THERE WERE"); + System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS AND YOU CAME IN %d JUMPS\n", successfulJumpCt, worseJumpCount); + System.out.println("BETTER THAN THE WORST. SHAPE UP!!!\n"); + } else { + System.out.printf("HEY! YOU PULLED THE RIP CORD MUCH TOO SOON. %d SUCCESSFUL\n", successfulJumpCt); + System.out.printf("JUMPS BEFORE YOURS AND YOU CAME IN NUMBER %d! GET WITH IT!\n", betterThanCount); + } + } + + private void showSplatMessage(InitialJumpConditions initial, JumpResult jump) { + double timeOfSplat = computeTimeOfSplat(initial, jump); + System.out.printf("%10.2f SPLAT\n", timeOfSplat); + } + + private double computeTimeOfSplat(InitialJumpConditions initial, JumpResult jump) { final float V = initial.getTerminalVelocity(); final float A = initial.getAcceleration(); - - if (jump.isSplat()) { - if (jump.hasReachedTerminalVelocity()) { - System.out.printf("%.2f SPLAT\n", (V / A) + ((initial.getAltitude() - (V * V / (2 * A))) / V)); - } else { - System.out.printf("%.2f SPLAT\n", Math.sqrt(2 * initial.getAltitude() / A)); - } - showRandomSplatMessage(); - } else { - System.out.println("CHUTE OPEN"); - int J = 0; - for (J = 0; J < 42; J++) { - if (Arr[J] == 0) { - Arr[J] = jump.getDistance(); - break; - } - K = K + 1; - if (jump.getDistance() > Arr[J]) { - continue; - } - K1 = K1 + 1; - } - - if (J > 2) { - if (K - K1 <= 0.1 * K) { - System.out.printf("WOW! THAT'S SOME JUMPING. OF THE %d SUCCESSFUL JUMPS\n", K); - System.out.printf("BEFORE YOURS, ONLY %d OPENED THEIR CHUTES LOWER THAN\n", K - K1); - System.out.println("YOU DID."); - } else if (K - K1 <= 0.25 * K) { - System.out.printf("PRETTY GOOD! %d SUCCESSFUL JUMPS PRECEDED YOURS AND ONLY\n", K); - System.out.printf("%d OF THEM GOT LOWER THAN YOU DID BEFORE THEIR CHUTES\n", K - K1); - System.out.println("OPENED."); - } else if (K - K1 <= 0.5 * K) { - System.out.printf("NOT BAD. THERE HAVE BEEN %d SUCCESSFUL JUMPS BEFORE YOURS.\n", K); - System.out.printf("YOU WERE BEATEN OUT BY %d OF THEM.\n", K - K1); - } else if (K - K1 <= 0.75 * K) { - System.out.printf("CONSERVATIVE, AREN'T YOU? YOU RANKED ONLY %d IN THE\n", K - K1); - System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS.\n", K); - } else if (K - K1 <= -0.9 * K) { - System.out.println("HUMPH! DON'T YOU HAVE ANY SPORTING BLOOD? THERE WERE"); - System.out.printf("%d SUCCESSFUL JUMPS BEFORE YOURS AND YOU CAME IN %d JUMPS\n", K, K1); - System.out.println("BETTER THAN THE WORST. SHAPE UP!!!\n"); - } else { - System.out.printf("HEY! YOU PULLED THE RIP CORD MUCH TOO SOON. %f SUCCESSFUL\n", K); - System.out.printf("JUMPS BEFORE YOURS AND YOU CAME IN NUMBER %d! GET WITH IT!\n", K - K1); - } - } else { - String[] nums = new String[]{ "1ST", "2ND", "3RD"}; - System.out.printf("AMAZING!!! NOT BAD FOR YOUR %s SUCCESSFUL JUMP!!!\n", nums[J]); - } + if (jump.hasReachedTerminalVelocity()) { + return (V / A) + ((initial.getAltitude() - (V * V / (2 * A))) / V); } + return Math.sqrt(2 * initial.getAltitude() / A); + } + + // Returns the number of jumps that this jump was better than + private int countWorseHistoricalJumps(JumpResult jump) { + return (int) pastSuccessfulJumpDistances.stream() + .filter(distance -> jump.getDistance() < distance) + .count(); } private JumpResult executeJump(InitialJumpConditions initial, float chuteOpenTime) { @@ -131,13 +132,10 @@ public class Splat { if (askYesNo("DO YOU WANT TO PLAY AGAIN ")) { return true; } - if (askYesNo("PLEASE")) { - return true; - } - return false; + return askYesNo("PLEASE"); } - private void showRandomSplatMessage() { + private void showCleverSplatMessage() { List messages = Arrays.asList( "REQUIESCAT IN PACE.", "MAY THE ANGEL OF HEAVEN LEAD YOU INTO PARADISE.", @@ -205,7 +203,7 @@ public class Splat { private float chooseRandomAcceleration() { Planet planet = Planet.pickRandom(); - System.out.printf("%s. ACCELERATION=%.2f FT/SEC/SEC.\n", planet.getMessage(), planet.getAcceleration()); + System.out.printf("%s %s. ACCELERATION=%.2f FT/SEC/SEC.\n", planet.getMessage(), planet.name(), planet.getAcceleration()); return planet.getAcceleration(); } @@ -293,16 +291,16 @@ public class Splat { } enum Planet { - MERCURY("FINE. YOU'RE ON MERCURY", 12.2f), - VENUS("ALL RIGHT. YOU'RE ON VENUS", 28.3f), - EARTH("THEN YOU'RE ON EARTH", 32.16f), - MOON("FINE. YOU'RE ON THE MOON", 5.15f), - MARS("ALL RIGHT. YOU'RE ON MARS", 12.5f), - JUPITER("THEN YOU'RE ON JUPITER", 85.2f), - SATURN("FINE. YOU'RE ON SATURN", 37.6f), - URANUS("ALL RIGHT. YOU'RE ON URANUS", 33.8f), - NEPTUNE("THEN YOU'RE ON NEPTUNE", 39.6f), - SUN("FINE. YOU'RE ON THE SUN", 896.0f); + MERCURY("FINE. YOU'RE ON", 12.2f), + VENUS("ALL RIGHT. YOU'RE ON", 28.3f), + EARTH("THEN YOU'RE ON", 32.16f), + MOON("FINE. YOU'RE ON THE", 5.15f), + MARS("ALL RIGHT. YOU'RE ON", 12.5f), + JUPITER("THEN YOU'RE ON", 85.2f), + SATURN("FINE. YOU'RE ON", 37.6f), + URANUS("ALL RIGHT. YOU'RE ON", 33.8f), + NEPTUNE("THEN YOU'RE ON", 39.6f), + SUN("FINE. YOU'RE ON THE", 896.0f); static final Random random = new Random(); private final String message; From 522975485110ed58784438945e21e575e14bc5ef Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 4 Jan 2022 23:59:26 -0800 Subject: [PATCH 051/102] fix problem with holding count after add and fix up some visiblity for simplicity --- 81_Splat/java/src/Splat.java | 92 ++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index 2586ecab..6b89dde2 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -46,8 +46,8 @@ public class Splat { } System.out.println("CHUTE OPEN"); int worseJumpCount = countWorseHistoricalJumps(jump); - pastSuccessfulJumpDistances.add(jump.getDistance()); int successfulJumpCt = pastSuccessfulJumpDistances.size(); + pastSuccessfulJumpDistances.add(jump.getDistance()); if (pastSuccessfulJumpDistances.size() <= 2) { List ordinals = Arrays.asList("1ST", "2ND", "3RD"); @@ -207,6 +207,40 @@ public class Splat { return planet.getAcceleration(); } + enum Planet { + MERCURY("FINE. YOU'RE ON", 12.2f), + VENUS("ALL RIGHT. YOU'RE ON", 28.3f), + EARTH("THEN YOU'RE ON", 32.16f), + MOON("FINE. YOU'RE ON THE", 5.15f), + MARS("ALL RIGHT. YOU'RE ON", 12.5f), + JUPITER("THEN YOU'RE ON", 85.2f), + SATURN("FINE. YOU'RE ON", 37.6f), + URANUS("ALL RIGHT. YOU'RE ON", 33.8f), + NEPTUNE("THEN YOU'RE ON", 39.6f), + SUN("FINE. YOU'RE ON THE", 896.0f); + + private static final Random random = new Random(); + private final String message; + private final float acceleration; + + Planet(String message, float acceleration) { + this.message = message; + this.acceleration = acceleration; + } + + static Planet pickRandom(){ + return values()[random.nextInt(Planet.values().length)]; + } + + String getMessage() { + return message; + } + + float getAcceleration() { + return acceleration; + } + } + // Mutable static class JumpResult { private boolean reachedTerminalVelocity = false; @@ -216,23 +250,23 @@ public class Splat { this.distance = distance; } - public boolean isSplat() { + boolean isSplat() { return distance <= 0; } - public boolean hasReachedTerminalVelocity() { + boolean hasReachedTerminalVelocity() { return reachedTerminalVelocity; } - public float getDistance() { + float getDistance() { return distance; } - public void setDistance(float distance){ + void setDistance(float distance){ this.distance = distance; } - public void setReachedTerminalVelocity(){ + void setReachedTerminalVelocity(){ reachedTerminalVelocity = true; } } @@ -265,62 +299,28 @@ public class Splat { return value + ((value * random.nextFloat()) / 20.0f) - ((value * random.nextFloat()) / 20.0f); } - public float getOriginalTerminalVelocity() { + float getOriginalTerminalVelocity() { return originalTerminalVelocity; } - public float getOriginalAcceleration() { + float getOriginalAcceleration() { return originalAcceleration; } - public float getTerminalVelocity() { + float getTerminalVelocity() { return terminalVelocity; } - public float getAcceleration() { + float getAcceleration() { return acceleration; } - public int getAltitude() { + int getAltitude() { return altitude; } - public float getTimeOfTerminalAccelerationReached(){ + float getTimeOfTerminalAccelerationReached(){ return terminalVelocity / acceleration; } } - - enum Planet { - MERCURY("FINE. YOU'RE ON", 12.2f), - VENUS("ALL RIGHT. YOU'RE ON", 28.3f), - EARTH("THEN YOU'RE ON", 32.16f), - MOON("FINE. YOU'RE ON THE", 5.15f), - MARS("ALL RIGHT. YOU'RE ON", 12.5f), - JUPITER("THEN YOU'RE ON", 85.2f), - SATURN("FINE. YOU'RE ON", 37.6f), - URANUS("ALL RIGHT. YOU'RE ON", 33.8f), - NEPTUNE("THEN YOU'RE ON", 39.6f), - SUN("FINE. YOU'RE ON THE", 896.0f); - - static final Random random = new Random(); - private final String message; - private final float acceleration; - - Planet(String message, float acceleration) { - this.message = message; - this.acceleration = acceleration; - } - - static Planet pickRandom(){ - return values()[random.nextInt(Planet.values().length)]; - } - - public String getMessage() { - return message; - } - - public float getAcceleration() { - return acceleration; - } - } } \ No newline at end of file From 9cc332f568189fa7bc028e662de6a5e08e3a88a7 Mon Sep 17 00:00:00 2001 From: jason Date: Wed, 5 Jan 2022 00:00:03 -0800 Subject: [PATCH 052/102] grammar nit --- 81_Splat/java/src/Splat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index 6b89dde2..4c0e2fdf 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -94,7 +94,7 @@ public class Splat { return Math.sqrt(2 * initial.getAltitude() / A); } - // Returns the number of jumps that this jump was better than + // Returns the number of jumps for which this jump was better private int countWorseHistoricalJumps(JumpResult jump) { return (int) pastSuccessfulJumpDistances.stream() .filter(distance -> jump.getDistance() < distance) From 11dba9dd92cef1a0d26c2300129be460072a6fd7 Mon Sep 17 00:00:00 2001 From: jason Date: Wed, 5 Jan 2022 00:04:24 -0800 Subject: [PATCH 053/102] debrand --- 81_Splat/java/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/81_Splat/java/README.md b/81_Splat/java/README.md index 51edd8d4..b8998fa6 100644 --- a/81_Splat/java/README.md +++ b/81_Splat/java/README.md @@ -1,3 +1,3 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) -Conversion to [Oracle Java](https://openjdk.java.net/) +Conversion to [Java](https://openjdk.java.net/) From 18b37bda81c1504cc6c062de84787a6403953630 Mon Sep 17 00:00:00 2001 From: jason Date: Wed, 5 Jan 2022 00:12:43 -0800 Subject: [PATCH 054/102] add top comment copied from readme (includes attribution) and reorganize methods for readability. --- 81_Splat/java/src/Splat.java | 196 +++++++++++++++++++---------------- 1 file changed, 109 insertions(+), 87 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index 4c0e2fdf..3c4cd817 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -1,5 +1,22 @@ import java.util.*; +/** + * SPLAT simulates a parachute jump in which you try to open your parachute at the last possible moment without going + * splat! You may select your own terminal velocity or let the computer do it for you. You many also select the + * acceleration due to gravity or, again, let the computer do it in which case you might wind up on any of eight + * planets (out to Neptune), the moon, or the sun. + *

+ * The computer then tells you the height you’re jumping from and asks for the seconds of free fall. It then divides + * your free fall time into eight intervals and gives you progress reports on your way down. The computer also keeps + * track of all prior jumps in the array A and lets you know how you compared with previous successful jumps. If you + * want to recall information from previous runs, then you should store array A in a disk or take file and read it + * before each run. + *

+ * John Yegge created this program while at the Oak Ridge Associated Universities. + *

+ * Ported from BASIC by jason plumb (@breedx2) + *

+ */ public class Splat { private static final Random random = new Random(); private final Scanner scanner = new Scanner(System.in); @@ -31,13 +48,74 @@ public class Splat { JumpResult jump = executeJump(initial, freefallTime); showJumpResults(initial, jump); - if(!playAgain()){ + if (!playAgain()) { System.out.println("SSSSSSSSSS."); return; } } } + private void showIntroduction() { + System.out.printf("%33s%s\n", " ", "SPLAT"); + System.out.printf("%15s%s\n", " ", "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.print("\n\n\n"); + System.out.println("WELCOME TO 'SPLAT' -- THE GAME THAT SIMULATES A PARACHUTE"); + System.out.println("JUMP. TRY TO OPEN YOUR CHUTE AT THE LAST POSSIBLE"); + System.out.println("MOMENT WITHOUT GOING SPLAT."); + } + + private InitialJumpConditions buildInitialConditions() { + System.out.print("\n\n"); + float terminalVelocity = promptTerminalVelocity(); + float acceleration = promptGravitationalAcceleration(); + return InitialJumpConditions.create(terminalVelocity, acceleration); + } + + private float promptTerminalVelocity() { + if (askYesNo("SELECT YOUR OWN TERMINAL VELOCITY")) { + System.out.print("WHAT TERMINAL VELOCITY (MI/HR) "); + return mphToFeetPerSec(scanner.nextFloat()); + } + float terminalVelocity = (int) (1000 * random.nextFloat()); + System.out.printf("OK. TERMINAL VELOCITY = %.2f MI/HR\n", terminalVelocity); + return mphToFeetPerSec(terminalVelocity); + } + + private float promptGravitationalAcceleration() { + if (askYesNo("WANT TO SELECT ACCELERATION DUE TO GRAVITY")) { + System.out.print("WHAT ACCELERATION (FT/SEC/SEC) "); + return scanner.nextFloat(); + } + return chooseRandomAcceleration(); + } + + private JumpResult executeJump(InitialJumpConditions initial, float chuteOpenTime) { + JumpResult jump = new JumpResult(initial.getAltitude()); + for (float time = 0.0f; !jump.isSplat() && (time < chuteOpenTime); time += chuteOpenTime / 8) { + if (!jump.hasReachedTerminalVelocity() && time > initial.getTimeOfTerminalAccelerationReached()) { + jump.setReachedTerminalVelocity(); + System.out.printf("TERMINAL VELOCITY REACHED AT T PLUS %f SECONDS.\n", initial.getTimeOfTerminalAccelerationReached()); + } + float newDistance = computeDistance(initial, time, jump.hasReachedTerminalVelocity()); + jump.setDistance(newDistance); + + if (jump.isSplat()) { + return jump; + } + System.out.printf("%10.2f %f\n", time, jump.getDistance()); + } + return jump; + } + + private float computeDistance(InitialJumpConditions initial, float i, boolean hasReachedTerminalVelocity) { + final float V = initial.getTerminalVelocity(); + final float A = initial.getAcceleration(); + if (hasReachedTerminalVelocity) { + return initial.getAltitude() - ((V * V / (2 * A)) + (V * (i - (V / A)))); + } + return initial.getAltitude() - ((A / 2) * i * i); + } + private void showJumpResults(InitialJumpConditions initial, JumpResult jump) { if (jump.isSplat()) { showSplatMessage(initial, jump); @@ -85,6 +163,9 @@ public class Splat { System.out.printf("%10.2f SPLAT\n", timeOfSplat); } + /** + * Returns the number of jumps for which this jump was better + */ private double computeTimeOfSplat(InitialJumpConditions initial, JumpResult jump) { final float V = initial.getTerminalVelocity(); final float A = initial.getAcceleration(); @@ -94,38 +175,26 @@ public class Splat { return Math.sqrt(2 * initial.getAltitude() / A); } - // Returns the number of jumps for which this jump was better private int countWorseHistoricalJumps(JumpResult jump) { return (int) pastSuccessfulJumpDistances.stream() .filter(distance -> jump.getDistance() < distance) .count(); } - private JumpResult executeJump(InitialJumpConditions initial, float chuteOpenTime) { - JumpResult jump = new JumpResult(initial.getAltitude()); - for (float time = 0.0f; !jump.isSplat() && (time < chuteOpenTime); time += chuteOpenTime / 8) { - if (!jump.hasReachedTerminalVelocity() && time > initial.getTimeOfTerminalAccelerationReached()) { - jump.setReachedTerminalVelocity(); - System.out.printf("TERMINAL VELOCITY REACHED AT T PLUS %f SECONDS.\n", initial.getTimeOfTerminalAccelerationReached()); - } - float newDistance = computeDistance(initial, time, jump.hasReachedTerminalVelocity()); - jump.setDistance(newDistance); - - if (jump.isSplat()) { - return jump; - } - System.out.printf("%10.2f %f\n", time, jump.getDistance()); - } - return jump; - } - - private float computeDistance(InitialJumpConditions initial, float i, boolean hasReachedTerminalVelocity) { - final float V = initial.getTerminalVelocity(); - final float A = initial.getAcceleration(); - if(hasReachedTerminalVelocity) { - return initial.getAltitude() - ((V * V / (2 * A)) + (V * (i - (V / A)))); - } - return initial.getAltitude() - ((A / 2) * i * i); + private void showCleverSplatMessage() { + List messages = Arrays.asList( + "REQUIESCAT IN PACE.", + "MAY THE ANGEL OF HEAVEN LEAD YOU INTO PARADISE.", + "REST IN PEACE.", + "SON-OF-A-GUN.", + "#$%&&%!$", + "A KICK IN THE PANTS IS A BOOST IF YOU'RE HEADED RIGHT.", + "HMMM. SHOULD HAVE PICKED A SHORTER TIME.", + "MUTTER. MUTTER. MUTTER.", + "PUSHING UP DAISIES.", + "EASY COME, EASY GO." + ); + System.out.println(messages.get(random.nextInt(10))); } private boolean playAgain() { @@ -135,68 +204,21 @@ public class Splat { return askYesNo("PLEASE"); } - private void showCleverSplatMessage() { - List messages = Arrays.asList( - "REQUIESCAT IN PACE.", - "MAY THE ANGEL OF HEAVEN LEAD YOU INTO PARADISE.", - "REST IN PEACE.", - "SON-OF-A-GUN.", - "#$%&&%!$", - "A KICK IN THE PANTS IS A BOOST IF YOU'RE HEADED RIGHT.", - "HMMM. SHOULD HAVE PICKED A SHORTER TIME.", - "MUTTER. MUTTER. MUTTER.", - "PUSHING UP DAISIES.", - "EASY COME, EASY GO." - ); - System.out.println(messages.get(random.nextInt(10))); - } - - private InitialJumpConditions buildInitialConditions() { - System.out.print("\n\n"); - float terminalVelocity = promptTerminalVelocity(); - float acceleration = promptGravitationalAcceleration(); - return InitialJumpConditions.create(terminalVelocity, acceleration); - } - - private void showIntroduction() { - System.out.printf("%33s%s\n", " ", "SPLAT"); - System.out.printf("%15s%s\n", " ", "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); - System.out.print("\n\n\n"); - System.out.println("WELCOME TO 'SPLAT' -- THE GAME THAT SIMULATES A PARACHUTE"); - System.out.println("JUMP. TRY TO OPEN YOUR CHUTE AT THE LAST POSSIBLE"); - System.out.println("MOMENT WITHOUT GOING SPLAT."); - } - - private float promptTerminalVelocity() { - if(askYesNo("SELECT YOUR OWN TERMINAL VELOCITY")){ - System.out.print("WHAT TERMINAL VELOCITY (MI/HR) "); - return mphToFeetPerSec(scanner.nextFloat()); - } - float terminalVelocity = (int) (1000 * random.nextFloat()); - System.out.printf("OK. TERMINAL VELOCITY = %.2f MI/HR\n", terminalVelocity); - return mphToFeetPerSec(terminalVelocity); - } - - private float promptGravitationalAcceleration() { - if(askYesNo("WANT TO SELECT ACCELERATION DUE TO GRAVITY")){ - System.out.print("WHAT ACCELERATION (FT/SEC/SEC) "); - return scanner.nextFloat(); - } - return chooseRandomAcceleration(); - } - - private float mphToFeetPerSec(float speed){ + private float mphToFeetPerSec(float speed) { return speed * (5280.0f / 3600.0f); } - private boolean askYesNo(String prompt){ + private boolean askYesNo(String prompt) { System.out.printf("%s (YES OR NO) ", prompt); while (true) { String answer = scanner.next(); - switch(answer){ - case "YES": return true; - case "NO": return false; - default: System.out.print("YES OR NO "); + switch (answer) { + case "YES": + return true; + case "NO": + return false; + default: + System.out.print("YES OR NO "); } } } @@ -228,7 +250,7 @@ public class Splat { this.acceleration = acceleration; } - static Planet pickRandom(){ + static Planet pickRandom() { return values()[random.nextInt(Planet.values().length)]; } @@ -262,11 +284,11 @@ public class Splat { return distance; } - void setDistance(float distance){ + void setDistance(float distance) { this.distance = distance; } - void setReachedTerminalVelocity(){ + void setReachedTerminalVelocity() { reachedTerminalVelocity = true; } } @@ -319,7 +341,7 @@ public class Splat { return altitude; } - float getTimeOfTerminalAccelerationReached(){ + float getTimeOfTerminalAccelerationReached() { return terminalVelocity / acceleration; } } From 3c185d1c8c2c3c7eed2995b04aed9861699294dc Mon Sep 17 00:00:00 2001 From: jason Date: Wed, 5 Jan 2022 00:15:05 -0800 Subject: [PATCH 055/102] remove unnecessary leftover check --- 81_Splat/java/src/Splat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index 3c4cd817..b76c82ff 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -91,7 +91,7 @@ public class Splat { private JumpResult executeJump(InitialJumpConditions initial, float chuteOpenTime) { JumpResult jump = new JumpResult(initial.getAltitude()); - for (float time = 0.0f; !jump.isSplat() && (time < chuteOpenTime); time += chuteOpenTime / 8) { + for (float time = 0.0f; time < chuteOpenTime; time += chuteOpenTime / 8) { if (!jump.hasReachedTerminalVelocity() && time > initial.getTimeOfTerminalAccelerationReached()) { jump.setReachedTerminalVelocity(); System.out.printf("TERMINAL VELOCITY REACHED AT T PLUS %f SECONDS.\n", initial.getTimeOfTerminalAccelerationReached()); From 3bdb7be6d171f0f7dd461af0a72e1e8f0f3c27ab Mon Sep 17 00:00:00 2001 From: Minas Date: Wed, 5 Jan 2022 14:08:37 +0000 Subject: [PATCH 056/102] Fixed the A to be : to make more sense in the first game in java --- 01_Acey_Ducey/java/src/AceyDucey.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/01_Acey_Ducey/java/src/AceyDucey.java b/01_Acey_Ducey/java/src/AceyDucey.java index 43fc9950..d53c0d05 100644 --- a/01_Acey_Ducey/java/src/AceyDucey.java +++ b/01_Acey_Ducey/java/src/AceyDucey.java @@ -167,6 +167,6 @@ public class AceyDucey { System.out.println("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING"); System.out.println("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE"); System.out.println("A VALUE BETWEEN THE FIRST TWO."); - System.out.println("IF YOU DO NOT WANT TO BET, INPUT A 0"); + System.out.println("IF YOU DO NOT WANT TO BET, INPUT: 0"); } } \ No newline at end of file From a98662a4f0521d3fd7537b79849f26140d171e9f Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Wed, 5 Jan 2022 11:35:09 -0500 Subject: [PATCH 057/102] Create HighIQ.java --- 48_High_IQ/java/HighIQ.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 48_High_IQ/java/HighIQ.java diff --git a/48_High_IQ/java/HighIQ.java b/48_High_IQ/java/HighIQ.java new file mode 100644 index 00000000..58f3203a --- /dev/null +++ b/48_High_IQ/java/HighIQ.java @@ -0,0 +1,4 @@ +public class HighIQ { + + +} From c9d26373b597ea8e2983f02dbca7d6426dc3ce10 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Wed, 5 Jan 2022 11:36:38 -0500 Subject: [PATCH 058/102] Move java to src folder --- 48_High_IQ/java/{ => src}/HighIQ.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename 48_High_IQ/java/{ => src}/HighIQ.java (100%) diff --git a/48_High_IQ/java/HighIQ.java b/48_High_IQ/java/src/HighIQ.java similarity index 100% rename from 48_High_IQ/java/HighIQ.java rename to 48_High_IQ/java/src/HighIQ.java From 9b47c69be55bb6b24ff8bdf4a71c735a7d14aae0 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Wed, 5 Jan 2022 11:37:24 -0500 Subject: [PATCH 059/102] Create HighIQGame.java --- 48_High_IQ/java/src/HighIQGame.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 48_High_IQ/java/src/HighIQGame.java diff --git a/48_High_IQ/java/src/HighIQGame.java b/48_High_IQ/java/src/HighIQGame.java new file mode 100644 index 00000000..c7d4df9b --- /dev/null +++ b/48_High_IQ/java/src/HighIQGame.java @@ -0,0 +1,5 @@ +public class HighIQGame { + public static void main(String[] args) { + + } +} From 917915048e22d329c521ff8a214c132beae651a2 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Wed, 5 Jan 2022 11:41:21 -0500 Subject: [PATCH 060/102] Create Board.java --- 48_High_IQ/java/src/Board.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 48_High_IQ/java/src/Board.java diff --git a/48_High_IQ/java/src/Board.java b/48_High_IQ/java/src/Board.java new file mode 100644 index 00000000..18b17cf5 --- /dev/null +++ b/48_High_IQ/java/src/Board.java @@ -0,0 +1,10 @@ +public class Board { + + public Board() { + + } + + public String toString() { + return ""; + } +} From 4ea34f845644d89cdc009c7c33a6937201b3fb1e Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Wed, 5 Jan 2022 11:49:07 -0500 Subject: [PATCH 061/102] Add method signatures to HighIQ.java --- 48_High_IQ/java/src/HighIQ.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index 58f3203a..2516bb1b 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -1,4 +1,10 @@ public class HighIQ { + public HighIQ() { + + } + public void play() { + + } } From fb8a87bade402b7ddd225f8554bfe5a3af4d2682 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Wed, 5 Jan 2022 11:59:12 -0500 Subject: [PATCH 062/102] Added the board matrix --- 48_High_IQ/java/src/Board.java | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/48_High_IQ/java/src/Board.java b/48_High_IQ/java/src/Board.java index 18b17cf5..6a320bd1 100644 --- a/48_High_IQ/java/src/Board.java +++ b/48_High_IQ/java/src/Board.java @@ -1,10 +1,28 @@ public class Board { - public Board() { - - } + private int[][] board; - public String toString() { - return ""; - } + public Board() { + board = new int[7][7]; + + //Set all of the corners to -1, and place pegs in proper spaces + for(int i = 0; i < 7; i++) { + for(int j = 0; j < 7; j++) { + if((i < 3 || i > 5) && (j < 3 || j > 5)) { + //If both i and j are either less than 3 or greater than 5, then the index is a corner + board[i][j] = -1; + } else if(i == 4 && j == 4) { + //Do not place a peg in the center + board[i][j] = 0; + } else { + //Place a peg everywhere else + board[i][j] = 1; + } + } + } + } + + public String toString() { + return ""; + } } From 64f854171814659ed7968b8fb24445737ad5dbfd Mon Sep 17 00:00:00 2001 From: Bastiaan Veelo Date: Wed, 5 Jan 2022 15:02:47 +0100 Subject: [PATCH 063/102] D version of 3D-plot. With bonus. --- 87_3-D_Plot/d/.gitignore | 2 + 87_3-D_Plot/d/README.md | 182 ++++++++++++++++++++++++++++ 87_3-D_Plot/d/threedeeplot.d | 35 ++++++ 87_3-D_Plot/d/threedeeplot_random.d | 50 ++++++++ 4 files changed, 269 insertions(+) create mode 100644 87_3-D_Plot/d/.gitignore create mode 100644 87_3-D_Plot/d/README.md create mode 100644 87_3-D_Plot/d/threedeeplot.d create mode 100644 87_3-D_Plot/d/threedeeplot_random.d diff --git a/87_3-D_Plot/d/.gitignore b/87_3-D_Plot/d/.gitignore new file mode 100644 index 00000000..d969f6b2 --- /dev/null +++ b/87_3-D_Plot/d/.gitignore @@ -0,0 +1,2 @@ +*.exe +*.obj diff --git a/87_3-D_Plot/d/README.md b/87_3-D_Plot/d/README.md new file mode 100644 index 00000000..8a01faf3 --- /dev/null +++ b/87_3-D_Plot/d/README.md @@ -0,0 +1,182 @@ +Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html) + +Converted to [D](https://dlang.org/) by [Bastiaan Veelo](https://github.com/veelo). + +## Running the code + +Assuming the reference [dmd](https://dlang.org/download.html#dmd) compiler: +```shell +dmd -dip1000 -run threedeeplot.d +``` + +[Other compilers](https://dlang.org/download.html) also exist. + +## On rounding floating point values to integer values + +The D equivalent of Basic `INT` is [`floor`](https://dlang.org/phobos/std_math_rounding.html#.floor), +which rounds towards negative infinity. If you change occurrences of `floor` to +[`lrint`](https://dlang.org/phobos/std_math_rounding.html#.lrint), you'll see that the plots show a bit more detail, +as is done in the bonus below. + +## Bonus: Self-writing programs + +With a small modification to the source, the program can be extended to **plot a random function**, and **print its formula**. + +```shell +rdmd -dip1000 threedeeplot_random.d +``` +(`rdmd` caches the executable, which results in speedy execution when the source does not change.) + +### Example output +``` + 3D Plot + (After Creative Computing Morristown, New Jersey) + + + f(z) = 30 * sin(z / 10.0) + + * + * * * * + * * * * * + * * * * * + * * * * * * + * * * * * * + * * * * * ** + * * * * * * * + * * * * * * ** + * * * * * * * * + * * * * * * * * + * * * * * * * ** + * * * * * * * * * + * * * * ** * * * * + * * * * ** * * * + * * * * * * * * + * * * * * * * * + * * * ** * * ** + * * * ** * ** + * * * * * ** + * * * * * ** + * * * * * ** + * * * ** * ** + * * * ** * * ** + * * * * * * * * + * * * * * * * * + * * * * ** * * * + * * * * ** * * * * + * * * * * * * * * + * * * * * * * ** + * * * * * * * * + * * * * * * * * + * * * * * * ** + * * * * * * * + * * * * * ** + * * * * * * + * * * * * * + * * * * * + * * * * * + * * * * + * +``` + +### Breakdown of differences + +Have a look at the relevant differences between `threedeeplot.d` and `threedeeplot_random.d`. +This is the original function with the single expression that is evaluated for the plot: +```d + static float fna(float z) + { + return 30.0 * exp(-z * z / 100.0); + } +``` +Here `static` means that the nested function does not need acces to its enclosing scope. + +Now, by inserting the following: +```d + enum functions = ["30.0 * exp(-z * z / 100.0)", + "sqrt(900.01 - z * z) * .9 - 2", + "30 * (cos(z / 16.0) + .5)", + "30 - 30 * sin(z / 18.0)", + "30 * exp(-cos(z / 16.0)) - 30", + "30 * sin(z / 10.0)"]; + + size_t index = uniform(0, functions.length); + writeln(center("f(z) = " ~ functions[index], width), "\n"); +``` +and changing the implementation of `fna` to +```d + float fna(float z) + { + final switch (index) + { + static foreach (i, f; functions) + case i: + mixin("return " ~ f ~ ";"); + } + } +``` +we unlock some very special abilities of D. Let's break it down: + +```d + enum functions = ["30.0 * exp(-z * z / 100.0)", /*...*/]; +``` +This defines an array of strings, each containing a mathematical expression. Due to the `enum` keyword, this is an +array that really only exists at compile-time. + +```d + size_t index = uniform(0, functions.length); +``` +This defines a random index into the array. `functions.length` is evaluated at compile-time, due to D's compile-time +function evaluation (CTFE). + +```d + writeln(center("f(z) = " ~ functions[index], width), "\n"); +``` +Unmistakenly, this prints the formula centered on a line. What happens behind the scenes is that `functions` (which +only existed at compile-time before now) is pasted in, so that an instance of that array actually exists at run-time +at this spot, and is instantly indexed. + +```d + float fna(float z) + { + final switch (index) + { + // ... + } + } +``` +`static` has been dropped from the nested function because we want to evaluate `index` inside it. The function contains +an ordinary `switch`, with `final` providing some extra robustness. It disallows a `default` case and produces an error +when the switch doesn't handle all cases. The `switch` body is where the magic happens and consists of these three +lines: +```d + static foreach (i, f; functions) + case i: + mixin("return " ~ f ~ ";"); +``` +The `static foreach` iterates over `functions` at compile-time, producing one `case` for every element in `functions`. +`mixin` takes a string, which is constructed at compile-time, and pastes it right into the source. + +In effect, the implementation of `float fna(float z)` unrolls itself into +```d + float fna(float z) + { + final switch (index) + { + case 0: + return 30.0 * exp(-z * z / 100.0); + case 1: + return sqrt(900.01 - z * z) * .9 - 2; + case 2: + return 30 * (cos(z / 16.0) + .5); + case 3: + return 30 - 30 * sin(z / 18.0); + case 4: + return 30 * exp(-cos(z / 16.0)) - 30; + case 5: + return 30 * sin(z / 10.0)"; + } + } +``` + +So if you feel like adding another function, all you need to do is append it to the `functions` array, and the rest of +the program *rewrites itself...* diff --git a/87_3-D_Plot/d/threedeeplot.d b/87_3-D_Plot/d/threedeeplot.d new file mode 100644 index 00000000..a3660321 --- /dev/null +++ b/87_3-D_Plot/d/threedeeplot.d @@ -0,0 +1,35 @@ +@safe: // Make @safe the default for this file, enforcing memory-safety. +import std.stdio, std.string, std.math, std.range, std.conv, std.algorithm; + +void main() +{ + enum width = 80; + writeln(center("3D Plot", width)); + writeln(center("(After Creative Computing Morristown, New Jersey)\n\n\n", width)); + + static float fna(float z) + { + return 30.0 * exp(-z * z / 100.0); + } + + char[] row; + + for (float x = -30.0; x <= 30.0; x += 1.5) + { + size_t max_z = 0L; + auto y1 = 5 * floor((sqrt(900 - x * x)) / 5.0); + for (float y = y1; y >= -y1; y -= 5) + { + auto z = to!size_t(max(0, floor(25 + fna(sqrt(x * x + y * y)) - .7 * y))); + if (z > max_z) // Visible + { + max_z = z; + if (z + 1 > row.length) // row needs to grow + row ~= ' '.repeat(z + 1 - row.length).array; + row[z] = '*'; + } + } + writeln(row); + row = null; + } +} diff --git a/87_3-D_Plot/d/threedeeplot_random.d b/87_3-D_Plot/d/threedeeplot_random.d new file mode 100644 index 00000000..3db1a2cd --- /dev/null +++ b/87_3-D_Plot/d/threedeeplot_random.d @@ -0,0 +1,50 @@ +@safe: // Make @safe the default for this file, enforcing memory-safety. +import std.stdio, std.string, std.math, std.range, std.conv, std.random, std.algorithm; + +void main() +{ + enum width = 80; + writeln(center("3D Plot", width)); + writeln(center("(After Creative Computing Morristown, New Jersey)\n\n", width)); + + enum functions = ["30.0 * exp(-z * z / 100.0)", + "sqrt(900.01 - z * z) * .9 - 2", + "30 * (cos(z / 16.0) + .5)", + "30 - 30 * sin(z / 18.0)", + "30 * exp(-cos(z / 16.0)) - 30", + "30 * sin(z / 10.0)"]; + + size_t index = uniform(0, functions.length); + writeln(center("f(z) = " ~ functions[index], width), "\n"); + + float fna(float z) + { + final switch (index) + { + static foreach (i, f; functions) + case i: + mixin("return " ~ f ~ ";"); + } + } + + char[] row; + + for (float x = -30.0; x <= 30.0; x += 1.5) + { + size_t max_z = 0L; + auto y1 = 5 * lrint((sqrt(900 - x * x)) / 5.0); + for (float y = y1; y >= -y1; y -= 5) + { + auto z = to!size_t(max(0, lrint(25 + fna(sqrt(x * x + y * y)) - .7 * y))); + if (z > max_z) // Visible + { + max_z = z; + if (z + 1 > row.length) // row needs to grow + row ~= ' '.repeat(z + 1 - row.length).array; + row[z] = '*'; + } + } + writeln(row); + row = null; + } +} From b250689f378aff08202fa72e735f233c2f45f109 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Wed, 5 Jan 2022 12:20:07 -0500 Subject: [PATCH 064/102] Use Map instead of 2d array --- 48_High_IQ/java/src/Board.java | 36 ++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/48_High_IQ/java/src/Board.java b/48_High_IQ/java/src/Board.java index 6a320bd1..8d183675 100644 --- a/48_High_IQ/java/src/Board.java +++ b/48_High_IQ/java/src/Board.java @@ -1,25 +1,27 @@ +import java.util.Map; +import java.util.HashMap; + public class Board { - private int[][] board; + private final Map board; public Board() { - board = new int[7][7]; - - //Set all of the corners to -1, and place pegs in proper spaces - for(int i = 0; i < 7; i++) { - for(int j = 0; j < 7; j++) { - if((i < 3 || i > 5) && (j < 3 || j > 5)) { - //If both i and j are either less than 3 or greater than 5, then the index is a corner - board[i][j] = -1; - } else if(i == 4 && j == 4) { - //Do not place a peg in the center - board[i][j] = 0; - } else { - //Place a peg everywhere else - board[i][j] = 1; - } - } + board = new HashMap<>(); + + int[] locations = new int[] {13,14,15, + 22,23,24, + 29,30,31,32,33,34,35, + 38,39,40,42,43,44, + 47,48,49,50,51,52,53, + 58,59,60, + 67,68,69}; + + for(int i : locations) { + //put board(i) in } + + //set the center position as 0 + } public String toString() { From 4a44f5097a1b97dde887f2b1348a84b5db41869a Mon Sep 17 00:00:00 2001 From: Yash Chauhan <68198489+ITrustNumbers@users.noreply.github.com> Date: Thu, 6 Jan 2022 00:19:34 +0530 Subject: [PATCH 065/102] Ported the Traditional NIM Game into python 3 I just completed the NIM(Traditional Version) game in python. Hope it works as expected --- 65_Nim/python/Traditional_NIM.py | 126 +++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 65_Nim/python/Traditional_NIM.py diff --git a/65_Nim/python/Traditional_NIM.py b/65_Nim/python/Traditional_NIM.py new file mode 100644 index 00000000..5c01ee2e --- /dev/null +++ b/65_Nim/python/Traditional_NIM.py @@ -0,0 +1,126 @@ +import random + +#Class of the Game +class NIM: + + def __init__(self): + + self.Piles = { + 1 : 7, + 2 : 5, + 3 : 3, + 4 : 1 + } + + def Remove_pegs(self, command): + + try: + + pile, num = command.split(',') + num = int(num) + pile = int(pile) + + except Exception as e: + + if 'not enough values' in str(e): + print('\nNot a valid command. Your command should be in the form of "1,3", Try Again\n') + + else: + print('\nError, Try again\n') + return None + + if self._command_integrity(num, pile) == True: + self.Piles[pile] -= num + else: + print('\nInvalid value of either Peg or Pile\n') + + def get_AI_move(self): + + possible_pile = [] + for k,v in self.Piles.items(): + if v != 0: + possible_pile.append(k) + + pile = random.choice(possible_pile) + + num = random.randint(1,self.Piles[pile]) + + return pile, num + + def _command_integrity(self, num, pile): + + if pile <= 4 and pile >= 1: + if num <= self.Piles[pile]: + return True + + return False + + def print_pegs(self): + + for pile, peg in self.Piles.items(): + print('Pile {} : {}'.format(pile, 'O '*peg)) + + def Help(self): + + print('-'*10) + print('\nThe Game is player with a number of Piles of Objects("O" == one peg)') + print('\nThe Piles are arranged as given below(Tradional NIM)\n') + self.print_pegs() + print('\nAny Number of of Objects are removed one pile by "YOU" and the machine alternatively') + print('\nOn your turn, you may take all the objects that remain in any pile') + print('but you must take ATLEAST one object') + print('\nAnd you may take objects from only one pile on a single turn.') + print('\nThe winner is defined as the one that picks the last remaning object') + print('-'*10) + + def Checkforwin(self): + + sum = 0 + for k,v in self.Piles.items(): + sum += v + + if sum == 0: + return True + + else: + return False + +#main program +if __name__ == "__main__": + + #Game initialization + game = NIM() + + print('Hello, This is a game of NIM') + help = input('Do You Need Instruction (YES or NO): ') + + if help == 'yes' or help == 'YES' or help == 'Yes': + + #Printing Game Instruction + game.Help() + + #Start game loop + input('\nPress Enter to start the Game:\n') + End = False + while True: + + game.print_pegs() + + #Players Move + command = input('\nYOUR MOVE - Number of PILE, Number of Object? ') + game.Remove_pegs(command) + End = game.Checkforwin() + if End == True: + print('Player Wins the Game, Congratulations!!') + input('Press any key to exit') + break + + #Computers Move + command = game.get_AI_move() + print('\nA.I MOVE - A.I Removed {} pegs from Pile {}'.format(command[1],command[0])) + game.Remove_pegs(str(command[0]) +',' + str(command[1])) + End = game.Checkforwin() + if End == True: + print('\nComputer Wins the Game, Better Luck Next Time\n') + input('Press any key to exit') + break From df70eca658dc62f31ac5897ae5ab206a16582875 Mon Sep 17 00:00:00 2001 From: Yash Chauhan <68198489+ITrustNumbers@users.noreply.github.com> Date: Thu, 6 Jan 2022 00:36:48 +0530 Subject: [PATCH 066/102] Minor Changes to the Traditional NIM --- 65_Nim/python/Traditional_NIM.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/65_Nim/python/Traditional_NIM.py b/65_Nim/python/Traditional_NIM.py index 5c01ee2e..3507ecc2 100644 --- a/65_Nim/python/Traditional_NIM.py +++ b/65_Nim/python/Traditional_NIM.py @@ -111,8 +111,8 @@ if __name__ == "__main__": game.Remove_pegs(command) End = game.Checkforwin() if End == True: - print('Player Wins the Game, Congratulations!!') - input('Press any key to exit') + print('\nPlayer Wins the Game, Congratulations!!') + input('\nPress any key to exit') break #Computers Move From f34bf73563db35671a930fad7d8d6a08f54e3703 Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Wed, 5 Jan 2022 16:07:54 -0300 Subject: [PATCH 067/102] Aded synonym ruby port --- 85_Synonym/ruby/synonim.rb | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 85_Synonym/ruby/synonim.rb diff --git a/85_Synonym/ruby/synonim.rb b/85_Synonym/ruby/synonim.rb new file mode 100644 index 00000000..f4dcb558 --- /dev/null +++ b/85_Synonym/ruby/synonim.rb @@ -0,0 +1,59 @@ + + +puts <<~INSTRUCTIONS + SYNONYM + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + +A SYNONYM OF A WORD MEANS ANOTHER WORD IN THE ENGLISH +LANGUAGE WHICH HAS THE SAME OR VERY NEARLY THE SAME MEANING. +I CHOOSE A WORD -- YOU TYPE A SYNONYM. +IF YOU CAN'T THINK OF A SYNONYM, TYPE THE WORD 'HELP' +AND I WILL TELL YOU A SYNONYM. + + +INSTRUCTIONS + +right_words = ["RIGHT", "CORRECT", "FINE", "GOOD!", "CHECK"] + +synonym_words = [ + ["FIRST", "START", "BEGINNING", "ONSET", "INITIAL"], + ["SIMILAR", "ALIKE", "SAME", "LIKE", "RESEMBLING"], + ["MODEL", "PATTERN", "PROTOTYPE", "STANDARD", "CRITERION"], + ["SMALL", "INSIGNIFICANT", "LITTLE", "TINY", "MINUTE"], + ["STOP", "HALT", "STAY", "ARREST", "CHECK", "STANDSTILL"], + ["HOUSE", "DWELLING", "RESIDENCE", "DOMICILE", "LODGING", "HABITATION"], + ["PIT", "HOLE", "HOLLOW", "WELL", "GULF", "CHASM", "ABYSS"], + ["PUSH", "SHOVE", "THRUST", "PROD", "POKE", "BUTT", "PRESS"], + ["RED", "ROUGE", "SCARLET", "CRIMSON", "FLAME", "RUBY"], + ["PAIN", "SUFFERING", "HURT", "MISERY", "DISTRESS", "ACHE", "DISCOMFORT"], +] + +synonym_words.shuffle.each {|words_ar| + +} + + +synonym_words.each {|words_ar| + answer = false + keyword = words_ar.shift + + while not answer and words_ar.length != 0 + puts " WHAT IS A SYNONYM OF #{keyword}? " + inp = gets.chomp.upcase + + if inp == "HELP" + clue = words_ar.sample + puts "**** A SYNONYM OF #{keyword} IS #{clue}." + words_ar.delete(clue) + elsif words_ar.include? inp + puts right_words.sample + answer = true + else + puts "TRY AGAIN." + end + + end + +} + +puts "SYNONYM DRILL COMPLETED" \ No newline at end of file From fd489bf3da56b950c1ca12f68af9eb5f94c357f2 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Wed, 5 Jan 2022 14:30:02 -0500 Subject: [PATCH 068/102] Using single class --- 48_High_IQ/java/src/Board.java | 30 ------------ 48_High_IQ/java/src/HighIQ.java | 82 +++++++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 38 deletions(-) delete mode 100644 48_High_IQ/java/src/Board.java diff --git a/48_High_IQ/java/src/Board.java b/48_High_IQ/java/src/Board.java deleted file mode 100644 index 8d183675..00000000 --- a/48_High_IQ/java/src/Board.java +++ /dev/null @@ -1,30 +0,0 @@ -import java.util.Map; -import java.util.HashMap; - -public class Board { - - private final Map board; - - public Board() { - board = new HashMap<>(); - - int[] locations = new int[] {13,14,15, - 22,23,24, - 29,30,31,32,33,34,35, - 38,39,40,42,43,44, - 47,48,49,50,51,52,53, - 58,59,60, - 67,68,69}; - - for(int i : locations) { - //put board(i) in - } - - //set the center position as 0 - - } - - public String toString() { - return ""; - } -} diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index 2516bb1b..cf0c05ab 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -1,10 +1,76 @@ +import java.io.PrintStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; + public class HighIQ { - - public HighIQ() { - - } - - public void play() { - - } + + private Map board; + private PrintStream out; + private Scanner scanner; + + public HighIQ() { + out = System.out; + scanner = new Scanner(System.in); + board = new HashMap<>(); + + //Set of all locations to put initial pegs on + int[] locations = new int[]{ + 13, 14, 15, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 38, 39, 40, 42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 58, 59, 60, 67, 68, 69 + }; + + for (int i : locations) { + board.put(i, true); + } + + board.put(41, false); + } + + public boolean move() { + System.out.println("MOVE WHICH PIECE"); + int from = scanner.nextInt(); + + //using the getOrDefault, which will make the statement false if it is an invalid position + if(!board.getOrDefault(from,false)) { + return false; + } + + System.out.println("TO WHERE"); + int to = scanner.nextInt(); + + if(board.getOrDefault(to,true)) { + return false; + } + + //Do nothing if they are the same + if(from == to) { + return true; + } + + //using the difference to check if the relative locations are valid + int difference = Math.abs(to - from); + if(difference != 2 && difference != 18) { + return false; + } + + //check if there is a peg between from and to + if(!board.getOrDefault((to + from) / 2,false)) { + return false; + } + + return true; + } + + public void play() { + while(true) { + while(!move()) { + System.out.println("ILLEGAL MOVE, TRY AGAIN..."); + + } + } + } + + public void printBoard() { + + } } From 6a43be82295eb141b729e282b3b07fd469155e40 Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Wed, 5 Jan 2022 16:42:43 -0300 Subject: [PATCH 069/102] Added history and porting comments --- 85_Synonym/ruby/synonim.rb | 39 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/85_Synonym/ruby/synonim.rb b/85_Synonym/ruby/synonim.rb index f4dcb558..6334104a 100644 --- a/85_Synonym/ruby/synonim.rb +++ b/85_Synonym/ruby/synonim.rb @@ -1,4 +1,25 @@ - +######################################################## +# +# Synonym +# +# From Basic Computer Games (1978) +# +#A synonym of a word is another word (in the English language) which has the same, +#or very nearly the same, meaning. This program tests your knowledge of synonyms +#of a few common words. +# +#The computer chooses a word and asks you for a synonym. The computer then tells +#you whether you’re right or wrong. If you can’t think of a synonym, type “HELP” +#which causes a synonym to be printed. +#You may put in words of your choice in the data statements. +#The number following DATA in Statement 500 is the total number of data statements. +#In each data statement, the first number is the number of words in that statement. +# +#Can you think of a way to make this into a more general kind of CAI program for any subject? +#Walt Koetke of Lexington High School, Massachusetts created this program. +# +# +######################################################## puts <<~INSTRUCTIONS SYNONYM @@ -56,4 +77,18 @@ synonym_words.each {|words_ar| } -puts "SYNONYM DRILL COMPLETED" \ No newline at end of file +puts "SYNONYM DRILL COMPLETED" + + +###################################################################### +# +# Porting notes +# +# There is a bug in the original program where if you keep asking for +# synoyms of a given word it ends up running out of synonyms +# in the array and the program crashes. +# The bug has been fixed in this version and now when +# it runs out of words it continues with the next +# array. +# +###################################################################### From f85645fceec41fd2f7786a2b9ecffa3c8c856711 Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Wed, 5 Jan 2022 16:45:12 -0300 Subject: [PATCH 070/102] Formatting comments --- 85_Synonym/ruby/synonim.rb | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/85_Synonym/ruby/synonim.rb b/85_Synonym/ruby/synonim.rb index 6334104a..92d2e8c7 100644 --- a/85_Synonym/ruby/synonim.rb +++ b/85_Synonym/ruby/synonim.rb @@ -4,19 +4,19 @@ # # From Basic Computer Games (1978) # -#A synonym of a word is another word (in the English language) which has the same, -#or very nearly the same, meaning. This program tests your knowledge of synonyms -#of a few common words. +# A synonym of a word is another word (in the English language) which has the same, +# or very nearly the same, meaning. This program tests your knowledge of synonyms +# of a few common words. # -#The computer chooses a word and asks you for a synonym. The computer then tells -#you whether you’re right or wrong. If you can’t think of a synonym, type “HELP” -#which causes a synonym to be printed. -#You may put in words of your choice in the data statements. -#The number following DATA in Statement 500 is the total number of data statements. -#In each data statement, the first number is the number of words in that statement. +# The computer chooses a word and asks you for a synonym. The computer then tells +# you whether you’re right or wrong. If you can’t think of a synonym, type “HELP” +# which causes a synonym to be printed. +# You may put in words of your choice in the data statements. +# The number following DATA in Statement 500 is the total number of data statements. +# In each data statement, the first number is the number of words in that statement. # -#Can you think of a way to make this into a more general kind of CAI program for any subject? -#Walt Koetke of Lexington High School, Massachusetts created this program. +# Can you think of a way to make this into a more general kind of CAI program for any subject? +# Walt Koetke of Lexington High School, Massachusetts created this program. # # ######################################################## From f74537329b88473a1061061f2d877857bf454cff Mon Sep 17 00:00:00 2001 From: Yash Chauhan <68198489+ITrustNumbers@users.noreply.github.com> Date: Thu, 6 Jan 2022 03:03:02 +0530 Subject: [PATCH 071/102] Ported Chief game to Python --- 25_Chief/python/Chief.py | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 25_Chief/python/Chief.py diff --git a/25_Chief/python/Chief.py b/25_Chief/python/Chief.py new file mode 100644 index 00000000..67b4eab8 --- /dev/null +++ b/25_Chief/python/Chief.py @@ -0,0 +1,77 @@ +def print_lightning_bolt(): + + print('*'*36) + n = 24 + while n > 16: + print(' '*n + 'x x') + n -=1 + print(' '*16 + 'x xxx') + print(' '*15 + 'x x') + print(' '*14+ 'xxx x') + n -=1 + while n > 8: + print(' '*n + 'x x') + n -=1 + print(' '*8 + 'xx') + print(' '*7 +'x') + print('*'*36) + + +def print_solution(n): + + print('\n{} plus 3 gives {}. This Divided by 5 equals {}'.format(n, n+3, (n+3)/5)) + print('This times 8 gives {}. If we divide 5 and add 5.'.format(( (n+3)/5 )*8 )) + print('We get {}, which, minus 1 equals {}'.format(( ((n+3)/5)*8)/5+5, ((((n+3)/5)*8)/5+5)-1 )) + +def Game(): + print('\nTake a Number and ADD 3. Now, Divide this number by 5 and') + print('multiply by 8. Now, Divide by 5 and add the same. Subtract 1') + + resp = float(input('\nWhat do you have? ')) + comp_guess = (((resp - 4)*5)/8)*5 -3 + resp2 = input('\nI bet your number was {} was i right(Yes or No)? '.format(comp_guess)) + + if resp2 == 'Yes' or resp2 == 'YES' or resp2 == 'yes': + print('\nHuh, I Knew I was unbeatable') + print('And here is how i did it') + print_solution(comp_guess) + input('') + + else: + resp3 = float(input('\nHUH!! what was you original number? ')) + + if resp3 == comp_guess: + print('\nThat was my guess, AHA i was right') + print("Shamed to accept defeat i guess, don't worry you can master mathematics too") + print('Here is how i did it') + print_solution(comp_guess) + input('') + + else: + print('\nSo you think you\'re so smart, EH?') + print('Now, Watch') + print_solution(resp3) + + resp4 = input('\nNow do you believe me? ') + + if resp4 == 'Yes' or resp4 == 'YES' or resp4 == 'yes': + print('\nOk, Lets play again sometime bye!!!!') + input('') + + else: + print('\nYOU HAVE MADE ME VERY MAD!!!!!') + print("BY THE WRATH OF THE MATHEMATICS AND THE RAGE OF THE GODS") + print("THERE SHALL BE LIGHTNING!!!!!!!") + print_lightning_bolt() + print('\nI Hope you believe me now, for your own sake') + input('') + +if __name__ == '__main__': + + print('I am CHIEF NUMBERS FREEK, The GREAT INDIAN MATH GOD.') + play = input('\nAre you ready to take the test you called me out for(Yes or No)? ') + if play == 'Yes' or play == 'YES' or play == 'yes': + Game() + else: + print('Ok, Nevermind. Let me go back to my great slumber, Bye') + input('') From 56ccff2d55d16b71f16956f893ec17bfee4cae6e Mon Sep 17 00:00:00 2001 From: jason Date: Wed, 5 Jan 2022 19:48:19 -0800 Subject: [PATCH 072/102] improve input handling of numeric values --- 81_Splat/java/src/Splat.java | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/81_Splat/java/src/Splat.java b/81_Splat/java/src/Splat.java index b76c82ff..e042c326 100644 --- a/81_Splat/java/src/Splat.java +++ b/81_Splat/java/src/Splat.java @@ -39,8 +39,7 @@ public class Splat { System.out.printf(" ACCELERATION = %.2f FT/SEC/SEC +/-5%%\n", initial.getOriginalAcceleration()); System.out.println("SET THE TIMER FOR YOUR FREEFALL."); - System.out.print("HOW MANY SECONDS "); - float freefallTime = scanner.nextFloat(); + float freefallTime = promptFloat("HOW MANY SECONDS "); System.out.println("HERE WE GO.\n"); System.out.println("TIME (SEC) DIST TO FALL (FT)"); System.out.println("========== ================="); @@ -73,18 +72,28 @@ public class Splat { private float promptTerminalVelocity() { if (askYesNo("SELECT YOUR OWN TERMINAL VELOCITY")) { - System.out.print("WHAT TERMINAL VELOCITY (MI/HR) "); - return mphToFeetPerSec(scanner.nextFloat()); + float terminalVelocity = promptFloat("WHAT TERMINAL VELOCITY (MI/HR) "); + return mphToFeetPerSec(terminalVelocity); } float terminalVelocity = (int) (1000 * random.nextFloat()); System.out.printf("OK. TERMINAL VELOCITY = %.2f MI/HR\n", terminalVelocity); return mphToFeetPerSec(terminalVelocity); } + private float promptFloat(String prompt){ + while(true){ + System.out.print(prompt); + try { + return scanner.nextFloat(); + } catch (Exception e) { + scanner.next(); // clear current input + } + } + } + private float promptGravitationalAcceleration() { if (askYesNo("WANT TO SELECT ACCELERATION DUE TO GRAVITY")) { - System.out.print("WHAT ACCELERATION (FT/SEC/SEC) "); - return scanner.nextFloat(); + return promptFloat("WHAT ACCELERATION (FT/SEC/SEC) "); } return chooseRandomAcceleration(); } From e6586027238a750768fd6cc75b226eec87086bd2 Mon Sep 17 00:00:00 2001 From: Adam Coffman Date: Wed, 5 Jan 2022 20:17:52 -0600 Subject: [PATCH 073/102] initial implementation of FlipFlop in Ruby --- 36_Flip_Flop/ruby/flipflop.rb | 162 ++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 36_Flip_Flop/ruby/flipflop.rb diff --git a/36_Flip_Flop/ruby/flipflop.rb b/36_Flip_Flop/ruby/flipflop.rb new file mode 100644 index 00000000..3a65a4c2 --- /dev/null +++ b/36_Flip_Flop/ruby/flipflop.rb @@ -0,0 +1,162 @@ +#A class representing the internal state of a single game of flip flop +# state represents the list of X's (A in the original code) +# guesses represents the number of guesses the user has made (C in the original code) +# seed represents the random seed for an instance of the game (Q in the original code) +Game = Struct.new(:state, :guesses, :seed) do + + #The original BASIC program used 1 indexed arrays while Ruby has 0-indexed arrays. + #We can't use 0 indexed arrays for the flip functions or we'll get divide by zero errors. + #These convenience functions allow us to modify and access internal game state in a 1-indexed fashion + def flip_letter(letter_number) + index = letter_number -1 + if self.state[index] == 'X' + self.state[index] = 'O' + else + self.state[index] = 'X' + end + end + + def letter_at(letter_number) + self.state[letter_number - 1] + end +end + +def print_welcome + puts 'FLIPFLOP'.center(72) + puts 'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY'.center(72) + puts <<~EOS + + THE OBJECT OF THIS PUZZLE IS TO CHANGE THIS: + + X X X X X X X X X X + + TO THIS: + + O O O O O O O O O O + + BY TYPING THE NUMBER CORRESPONDING TO THE POSITION OF THE + LETTER ON SOME NUMBERS, ONE POSITION WILL CHANGE, ON + OTHERS, TWO WILL CHANGE. TO RESET LINE TO ALL X'S, TYPE 0 + (ZERO) AND TO START OVER IN THE MIDDLE OF A GAME, TYPE + 11 (ELEVEN). + EOS +end + +def print_starting_message + puts <<~EOS + + HERE IS THE STARTING LINE OF X'S. + + 1 2 3 4 5 6 7 8 9 10 + X X X X X X X X X X + + EOS +end + +#Create a new game with [X,X,X,X,X,X,X,X,X,X] as the state +#0 as the number of guesses and a random seed between 0 and 1 +def generate_new_game + Game.new(Array.new(10, 'X'), 0, rand()) +end + +#Given a game, an index, and a shuffle function, flip one or more letters +def shuffle_board(game, index, shuffle_function) + n = method(shuffle_function).call(game, index) + + if game.letter_at(n) == "O" + game.flip_letter(n) + if index == n + n = shuffle_board(game, index, shuffle_function) + end + else + game.flip_letter(n) + end + return n +end + +#Shuffle logic copied from original BASIC code +def shuffle_function1(game, index) + r = Math.tan(game.seed + index / game.seed - index) - Math.sin(game.seed / index) + 336 * Math.sin(8 * index) + n = r - r.floor + (10 * n).floor +end + +def shuffle_function2(game, index) + r = 0.592 * (1/ Math.tan(game.seed / index + game.seed)) / Math.sin(index * 2 + game.seed) - Math.cos(index) + n = r - r.floor + (10 * n) +end + +def play_game + print_starting_message + game = generate_new_game + working_index = nil + + loop do + puts "INPUT THE NUMBER" + input = gets.chomp.downcase + + #See if the user input a valid integer, fail otherwise + if numeric_input = Integer(input, exception: false) + + #If 11 is entered, we're done with this version of the game + if numeric_input == 11 + return :restart + end + + if numeric_input > 11 + puts 'ILLEGAL ENTRY--TRY AGAIN.' + next #illegal entries don't count towards your guesses + end + + if working_index == numeric_input + game.flip_letter(numeric_input) + working_index = shuffle_board(game, numeric_input, :shuffle_function2) + #If 0 is entered, we want to reset the state, but not the random seed or number of guesses and keep playing + elsif numeric_input == 0 + game.state = Array.new(10, 'X') + elsif game.letter_at(numeric_input) == "O" + game.flip_letter(numeric_input) + if numeric_input == working_index + working_index = shuffle_board(game, numeric_input, :shuffle_function1) + end + else + game.flip_letter(numeric_input) + working_index = shuffle_board(game, numeric_input, :shuffle_function1) + end + else + puts 'ILLEGAL ENTRY--TRY AGAIN.' + next #illegal entries don't count towards your guesses + end + + game.guesses += 1 + puts '1 2 3 4 5 6 7 8 9 10' + puts game.state.join(' ') + + if game.state.all? { |x| x == 'O' } + if game.guesses > 12 + puts "TRY HARDER NEXT TIME. IT TOOK YOU #{game.guesses} GUESSES." + else + puts "VERY GOOD. YOU GUESSED IT IN ONLY #{game.guesses} GUESSES." + end + #game is complete + return + end + end +end + + + +#Execution starts +print_welcome +loop do + result = play_game + if result == :restart + next + end + + puts 'DO YOU WANT TO TRY ANOTHER PUZZLE' + if gets.chomp.downcase[0] == 'n' + break + end +end From aed1f65c761348a046a39bfe8e3e097b8661972a Mon Sep 17 00:00:00 2001 From: RibTips <36372030+ribtips@users.noreply.github.com> Date: Thu, 6 Jan 2022 01:24:44 -0500 Subject: [PATCH 074/102] 11_Bombardment in Perl A version of bombardment written in perl --- 11_Bombardment/perl/bombardment.pl | 129 +++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 11_Bombardment/perl/bombardment.pl diff --git a/11_Bombardment/perl/bombardment.pl b/11_Bombardment/perl/bombardment.pl new file mode 100644 index 00000000..593bd9fa --- /dev/null +++ b/11_Bombardment/perl/bombardment.pl @@ -0,0 +1,129 @@ +#!/usr/bin/perl + +use strict; +use warnings; + + +#GLOBAL +my %player_bases; +my %computer_bases; +my %player_choices; +my %computer_choices; + +&main; + +sub main { + &print_intro; + &display_field; + &populate_computer_bases; + &populate_player_bases; + &game_play; +} + +sub game_play { + until (keys %computer_bases == 0 || keys %player_bases == 0) { + &player_turn; + if (keys %computer_bases == 0) { + exit; + } + &computer_turn; + } + exit; +} + +sub computer_turn { + # There is logic in here to ensure that the computer doesn't try to pick a target it has already picked + my $valid_choice = 0; + until ($valid_choice == 1) { + my $target = int(rand(25)+1); + if (exists $computer_choices{$target}) { + $valid_choice = 0; + } + else { + $valid_choice = 1; + $computer_choices{$target}=1; + if (exists $player_bases{$target}) { + delete($player_bases{$target}); + my $size = keys %player_bases; + if ($size > 0) { + print "I GOT YOU. IT WON'T BE LONG NOW. POST $target WAS HIT.\n"; + if ($size == 3) { print "YOU HAVE ONLY THREE OUTPOSTS LEFT.\n"}; + if ($size == 2) { print "YOU HAVE ONLY TWO OUTPOSTS LEFT.\n"}; + if ($size == 1) { print "YOU HAVE ONLY ONE OUTPOSTS LEFT.\n"}; + } + else { + print "YOU'RE DEAD. YOUR LAST OUTPOST WAS AT $target. HA, HA, HA.\nBETTER LUCK NEXT TIME\n"; + } + + } + else { + print "I MISSED YOU, YOU DIRTY RAT. I PICKED $target. YOUR TURN:\n"; + } + } + } +} + +sub player_turn { + print "WHERE DO YOU WISH TO FIRE YOUR MISSILE\n"; + chomp(my $target=); + if (exists $computer_bases{$target}) { + print "YOU GOT ONE OF MY OUTPOSTS!\n"; + delete($computer_bases{$target}); + my $size = keys %computer_bases; + if ($size == 3) { print "ONE DOWN, THREE TO GO.\n"}; + if ($size == 2) { print "TWO DOWN, TWO TO GO.\n"}; + if ($size == 1) { print "THREE DOWN, ONE TO GO.\n"}; + if ($size == 0) { print "YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN\nMY TRANSISTO&S RECUP%RA*E!\n"}; + } + else { + print "HA, HA YOU MISSED. MY TURN NOW:\n"; + } +} + +sub populate_player_bases { + print "WHAT ARE YOUR FOUR POSITIONS\n"; + my $positions=; + chomp($positions); + my @positions = split/ /,$positions; + foreach my $base (@positions) { + $player_bases{$base}=0; + } +} + +sub display_field { + for my $num (1..25) { + if (length($num) < 2) { + $num = " $num"; + } + print "$num "; + if ($num % 5 == 0) { + print "\n"; + } + } +} + +sub populate_computer_bases { + my $size = 0; + until ($size == 4) { + my $base = int(rand(25)+1); + $computer_bases{$base}=0; + $size = keys %computer_bases; + } +} + +sub print_intro { + print "" * 33 + "BOMBARDMENT\n"; + print "" * 15 + " CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; + print "\n\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\n"; + print "THE OBJECT OF THE GAME IS TO FIRE MISSLES 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 "GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!\n"; + print "TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS.\n"; + print "\n\n\n\n"; +} From 71c754190550fbebb0ac8ae92d4bef3cd8b7c94b Mon Sep 17 00:00:00 2001 From: John Long Date: Wed, 5 Jan 2022 23:22:46 -0800 Subject: [PATCH 075/102] Switch to readln readln throws an exception when a file hits EOF, wheras readLine returns null. That puts us in an infinite loop if we hit EOF. --- 03_Animal/kotlin/Animal.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/03_Animal/kotlin/Animal.kt b/03_Animal/kotlin/Animal.kt index bac9af08..90fc9f20 100644 --- a/03_Animal/kotlin/Animal.kt +++ b/03_Animal/kotlin/Animal.kt @@ -37,14 +37,14 @@ fun main() { // an answer or a blank string fun ask(question: String): String { print("$question? ") - return readLine()?.uppercase() ?: "" + return readln().uppercase() ?: "" } // Special case for a "yes or no" question, returns true of yes fun askYesOrNo(question: String): Boolean { return generateSequence { print("$question? ") - readLine() + readln() }.firstNotNullOf { yesOrNo(it) } } From f8cc93aaeab6f7a73ebc15e1a91957b75e794e5a Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 08:50:17 -0500 Subject: [PATCH 076/102] added getChar method --- 48_High_IQ/java/src/HighIQ.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index cf0c05ab..75426197 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -71,6 +71,17 @@ public class HighIQ { } public void printBoard() { - + + } + + private char getChar(int position) { + Boolean value = board.get(position); + if(value == null) { + return ' '; + } else if(value) { + return '!'; + } else { + return 'O'; + } } } From 918b42149e0f4abe2512eaf69343fb1cbe7baef5 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 08:52:12 -0500 Subject: [PATCH 077/102] Implemented Possible printBoard Doing this through web browser, so unsure if this will work or compile.. Will check later --- 48_High_IQ/java/src/HighIQ.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index 75426197..93340556 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -71,7 +71,12 @@ public class HighIQ { } public void printBoard() { - + for(int i = 0; i < 7; i++) { + for(int j = 11; j < 18; j++) { + out.print(getChar(j + 9 * i)); + } + out.println(); + } } private char getChar(int position) { From 056c8cd4d971174bd68aed81708a2de1b39e59a2 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 09:06:15 -0500 Subject: [PATCH 078/102] Update HighIQ.java --- 48_High_IQ/java/src/HighIQ.java | 36 ++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index 93340556..77e0e5ae 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -62,12 +62,38 @@ public class HighIQ { } public void play() { - while(true) { - while(!move()) { - System.out.println("ILLEGAL MOVE, TRY AGAIN..."); - + do { + do { + while(!move()) { + System.out.println("ILLEGAL MOVE, TRY AGAIN..."); + } + } while(!isGameFinished()); + + int pegCount = 0; + for(Integer key : board.getKeySet()) { + if(board.getOrDefault(key,false)) { + pegCount++; + } } - } + + out.println("YOU HAD " + pegCount + " PEGS REMAINING"); + + if(pegCount == 1) { + out.println("BRAVO! YOU MADE A PERFECT SCORE!"); + out.println("SAVE THIS PAPER AS A RECORD OF YOUR ACCOMPLISHMENT!"); + } + + } while(playAgain()); + } + + private boolean playAgain() { + out.println("PLAY AGAIN (YES OR NO)"); + return scanner.nextLine().toLowerCase().equals("yes"); + } + + + public boolean isGameFinished() { + return false; } public void printBoard() { From aaa8d6186061983dc6af1f8b7b9ec09c0b926353 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 09:34:20 -0500 Subject: [PATCH 079/102] Implemented GameFinished does it work? Unsure... --- 48_High_IQ/java/src/HighIQ.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index 77e0e5ae..99d046fe 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -93,7 +93,26 @@ public class HighIQ { public boolean isGameFinished() { - return false; + for(Integer key : board.getKeySet()) { + if(board.get(key)) { + //Spacing is either 1 or 9 + for(int space = 1; space <= 9; space += 8) { + //Next val is the next spot, prev and next after are the two spots where the peg would go if a move was possible + Boolean nextVal = board.get(key + space); + Boolean prevAfter = board.get(key - space); + Boolean nextAfter = board.get(key + space * 2); + + if(nextVal != null && nextVal) { + if((prevAfter != null && !prevAfter) || (nextAfter != null && !nextAfter)) { + return false; + } + } + + } + } + + } + return true; } public void printBoard() { From 31dec710639d360536207692634a24b3e2bf108e Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 09:45:04 -0500 Subject: [PATCH 080/102] Simplified isGameFinished Unsure if I should simplify further --- 48_High_IQ/java/src/HighIQ.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index 99d046fe..83cff254 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -96,18 +96,13 @@ public class HighIQ { for(Integer key : board.getKeySet()) { if(board.get(key)) { //Spacing is either 1 or 9 - for(int space = 1; space <= 9; space += 8) { - //Next val is the next spot, prev and next after are the two spots where the peg would go if a move was possible - Boolean nextVal = board.get(key + space); - Boolean prevAfter = board.get(key - space); - Boolean nextAfter = board.get(key + space * 2); - - if(nextVal != null && nextVal) { - if((prevAfter != null && !prevAfter) || (nextAfter != null && !nextAfter)) { - return false; - } + //Looking to the right and down from every point, checking for both directions of movement + for(int space : new int[] {1,9}) { + Boolean nextToPeg = board.getOrDefault(key + space,false); + Boolean hasMovableSpace = !board.getOrDefault(key - space,true) || !board.getOrDefault(key + space * 2, true); + if(nextToPeg && hasMovableSpace) { + return false; } - } } From e19a4aef19457cdb6256899c062b88e2580679fd Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 09:46:58 -0500 Subject: [PATCH 081/102] Added leaving comment --- 48_High_IQ/java/src/HighIQ.java | 1 + 1 file changed, 1 insertion(+) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index 83cff254..b1a40831 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -84,6 +84,7 @@ public class HighIQ { } } while(playAgain()); + out.println("SO LONG FOR NOW."); } private boolean playAgain() { From 821ae4befe7bb7845e7fcea6f1f28a0308bd778a Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 10:02:44 -0500 Subject: [PATCH 082/102] Moving re-playability to other script --- 48_High_IQ/java/src/HighIQ.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index b1a40831..37fd6aa2 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -9,9 +9,9 @@ public class HighIQ { private PrintStream out; private Scanner scanner; - public HighIQ() { + public HighIQ(Scanner sccanner) { out = System.out; - scanner = new Scanner(System.in); + this.scanner = scanner; board = new HashMap<>(); //Set of all locations to put initial pegs on @@ -25,6 +25,7 @@ public class HighIQ { board.put(41, false); } + public boolean move() { System.out.println("MOVE WHICH PIECE"); @@ -63,7 +64,6 @@ public class HighIQ { public void play() { do { - do { while(!move()) { System.out.println("ILLEGAL MOVE, TRY AGAIN..."); } @@ -83,14 +83,12 @@ public class HighIQ { out.println("SAVE THIS PAPER AS A RECORD OF YOUR ACCOMPLISHMENT!"); } - } while(playAgain()); - out.println("SO LONG FOR NOW."); } - private boolean playAgain() { - out.println("PLAY AGAIN (YES OR NO)"); - return scanner.nextLine().toLowerCase().equals("yes"); - } +// private boolean playAgain() { +// out.println("PLAY AGAIN (YES OR NO)"); +// return scanner.nextLine().toLowerCase().equals("yes"); +// } public boolean isGameFinished() { From f5997021970a2ac6b278a5321430cf74553d0caf Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Thu, 6 Jan 2022 13:03:31 -0300 Subject: [PATCH 083/102] Added script to write a markdown TODO list of implementations for games --- 00_Utilities/markdown_todo.py | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 00_Utilities/markdown_todo.py diff --git a/00_Utilities/markdown_todo.py b/00_Utilities/markdown_todo.py new file mode 100644 index 00000000..accf1ac2 --- /dev/null +++ b/00_Utilities/markdown_todo.py @@ -0,0 +1,43 @@ +import os + + +lang_pos = { + "csharp": 1, "java": 2, "javascript": 3, + "pascal": 4, "perl": 5, "python": 6, "ruby": 7, "vbnet": 8 +} + +write_string = "# TODO list \n game | csharp | java | javascript | pascal | perl | python | ruby | vbnet \n --- | --- | --- | --- | --- | --- | --- | --- | --- \n" +# Set the directory you want to start from +rootDir = '..' + +checklist = ["game", "csharp", "java", "javascript", + "pascal", "perl", "python", "ruby", "vbnet"] + +prev_game = "" + +for dirName, subdirList, fileList in os.walk(rootDir): + split_dir = dirName.split("/") + + if len(split_dir) == 2 and not split_dir[1] in ['.git', '00_Utilities']: + if prev_game == "": + prev_game = split_dir[1] + checklist[0] = split_dir[1] + + if prev_game != split_dir[1]: + # it's a new dir + write_string += " | ".join(checklist) + "\n" + checklist = [split_dir[1], "csharp", "java", "javascript", + "pascal", "perl", "python", "ruby", "vbnet"] + prev_game = split_dir[1] + + elif len(split_dir) == 3 and split_dir[1] != '.git': + if split_dir[2] in lang_pos.keys(): + if len(fileList) > 1 or len(subdirList) > 0: + # there is more files than the readme + checklist[lang_pos[split_dir[2]]] = "✅" + else: + checklist[lang_pos[split_dir[2]]] = "⬜️" + + +with open("README.md", "w") as f: + f.write(write_string) From 08b299b3bb23a22f03dec849d460660a004ce946 Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Thu, 6 Jan 2022 13:13:04 -0300 Subject: [PATCH 084/102] Sorted table --- 00_Utilities/markdown_todo.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/00_Utilities/markdown_todo.py b/00_Utilities/markdown_todo.py index accf1ac2..74e358c0 100644 --- a/00_Utilities/markdown_todo.py +++ b/00_Utilities/markdown_todo.py @@ -10,6 +10,8 @@ write_string = "# TODO list \n game | csharp | java | javascript | pascal | perl # Set the directory you want to start from rootDir = '..' +strings_done = [] + checklist = ["game", "csharp", "java", "javascript", "pascal", "perl", "python", "ruby", "vbnet"] @@ -25,7 +27,7 @@ for dirName, subdirList, fileList in os.walk(rootDir): if prev_game != split_dir[1]: # it's a new dir - write_string += " | ".join(checklist) + "\n" + strings_done.append(checklist) checklist = [split_dir[1], "csharp", "java", "javascript", "pascal", "perl", "python", "ruby", "vbnet"] prev_game = split_dir[1] @@ -39,5 +41,10 @@ for dirName, subdirList, fileList in os.walk(rootDir): checklist[lang_pos[split_dir[2]]] = "⬜️" +sorted_strings = list(map(lambda l: " | ".join(l) + "\n", + sorted(strings_done, key=lambda x: x[0]))) +write_string += ''.join(sorted_strings) + + with open("README.md", "w") as f: f.write(write_string) From 048b9c31a283b6b40bafd3480cd7cc5667f1eab6 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 11:38:17 -0500 Subject: [PATCH 085/102] Added re-playability --- 48_High_IQ/java/src/HighIQGame.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/48_High_IQ/java/src/HighIQGame.java b/48_High_IQ/java/src/HighIQGame.java index c7d4df9b..efbd09ec 100644 --- a/48_High_IQ/java/src/HighIQGame.java +++ b/48_High_IQ/java/src/HighIQGame.java @@ -1,5 +1,11 @@ +import java.util.Scanner; + public class HighIQGame { public static void main(String[] args) { - + Scanner scanner = new Scanner(System.in); + do { + new HighIQ(scanner).play(); + System.out.println("PLAY AGAIN (YES OR NO)"); + } while(scanner.nextLine().toLowerCase().equals("yes")); } } From 18016b59ed7f647cef92213243cb20ba8b689983 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 13:15:48 -0500 Subject: [PATCH 086/102] Typo Fixes --- 48_High_IQ/java/src/HighIQ.java | 6 +++--- 48_High_IQ/java/src/HighIQGame.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index 37fd6aa2..37528748 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -9,7 +9,7 @@ public class HighIQ { private PrintStream out; private Scanner scanner; - public HighIQ(Scanner sccanner) { + public HighIQ(Scanner scanner) { out = System.out; this.scanner = scanner; board = new HashMap<>(); @@ -70,7 +70,7 @@ public class HighIQ { } while(!isGameFinished()); int pegCount = 0; - for(Integer key : board.getKeySet()) { + for(Integer key : board.keySet()) { if(board.getOrDefault(key,false)) { pegCount++; } @@ -92,7 +92,7 @@ public class HighIQ { public boolean isGameFinished() { - for(Integer key : board.getKeySet()) { + for(Integer key : board.keySet()) { if(board.get(key)) { //Spacing is either 1 or 9 //Looking to the right and down from every point, checking for both directions of movement diff --git a/48_High_IQ/java/src/HighIQGame.java b/48_High_IQ/java/src/HighIQGame.java index efbd09ec..4df22853 100644 --- a/48_High_IQ/java/src/HighIQGame.java +++ b/48_High_IQ/java/src/HighIQGame.java @@ -6,6 +6,6 @@ public class HighIQGame { do { new HighIQ(scanner).play(); System.out.println("PLAY AGAIN (YES OR NO)"); - } while(scanner.nextLine().toLowerCase().equals("yes")); + } while(scanner.nextLine().equalsIgnoreCase("yes")); } } From 45345d593d136668e36d63668eed61e124435f63 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 13:16:55 -0500 Subject: [PATCH 087/102] Reformatted Code --- 48_High_IQ/java/src/HighIQ.java | 84 ++++++++++++++++----------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index 37528748..5c3f31aa 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -5,7 +5,7 @@ import java.util.Scanner; public class HighIQ { - private Map board; + private Map board; private PrintStream out; private Scanner scanner; @@ -25,104 +25,100 @@ public class HighIQ { board.put(41, false); } - + + public void play() { + do { + while (!move()) { + System.out.println("ILLEGAL MOVE, TRY AGAIN..."); + } + } while (!isGameFinished()); + + int pegCount = 0; + for (Integer key : board.keySet()) { + if (board.getOrDefault(key, false)) { + pegCount++; + } + } + + out.println("YOU HAD " + pegCount + " PEGS REMAINING"); + + if (pegCount == 1) { + out.println("BRAVO! YOU MADE A PERFECT SCORE!"); + out.println("SAVE THIS PAPER AS A RECORD OF YOUR ACCOMPLISHMENT!"); + } + } public boolean move() { System.out.println("MOVE WHICH PIECE"); int from = scanner.nextInt(); //using the getOrDefault, which will make the statement false if it is an invalid position - if(!board.getOrDefault(from,false)) { + if (!board.getOrDefault(from, false)) { return false; } System.out.println("TO WHERE"); int to = scanner.nextInt(); - if(board.getOrDefault(to,true)) { + if (board.getOrDefault(to, true)) { return false; } //Do nothing if they are the same - if(from == to) { + if (from == to) { return true; } //using the difference to check if the relative locations are valid int difference = Math.abs(to - from); - if(difference != 2 && difference != 18) { + if (difference != 2 && difference != 18) { return false; } //check if there is a peg between from and to - if(!board.getOrDefault((to + from) / 2,false)) { + if (!board.getOrDefault((to + from) / 2, false)) { return false; } return true; } - public void play() { - do { - while(!move()) { - System.out.println("ILLEGAL MOVE, TRY AGAIN..."); - } - } while(!isGameFinished()); - - int pegCount = 0; - for(Integer key : board.keySet()) { - if(board.getOrDefault(key,false)) { - pegCount++; - } - } - - out.println("YOU HAD " + pegCount + " PEGS REMAINING"); - - if(pegCount == 1) { - out.println("BRAVO! YOU MADE A PERFECT SCORE!"); - out.println("SAVE THIS PAPER AS A RECORD OF YOUR ACCOMPLISHMENT!"); - } - - } - // private boolean playAgain() { // out.println("PLAY AGAIN (YES OR NO)"); // return scanner.nextLine().toLowerCase().equals("yes"); // } - - + public boolean isGameFinished() { - for(Integer key : board.keySet()) { - if(board.get(key)) { + for (Integer key : board.keySet()) { + if (board.get(key)) { //Spacing is either 1 or 9 //Looking to the right and down from every point, checking for both directions of movement - for(int space : new int[] {1,9}) { - Boolean nextToPeg = board.getOrDefault(key + space,false); - Boolean hasMovableSpace = !board.getOrDefault(key - space,true) || !board.getOrDefault(key + space * 2, true); - if(nextToPeg && hasMovableSpace) { + for (int space : new int[]{1, 9}) { + Boolean nextToPeg = board.getOrDefault(key + space, false); + Boolean hasMovableSpace = !board.getOrDefault(key - space, true) || !board.getOrDefault(key + space * 2, true); + if (nextToPeg && hasMovableSpace) { return false; } } } - } return true; } public void printBoard() { - for(int i = 0; i < 7; i++) { - for(int j = 11; j < 18; j++) { + for (int i = 0; i < 7; i++) { + for (int j = 11; j < 18; j++) { out.print(getChar(j + 9 * i)); } out.println(); } } - + private char getChar(int position) { Boolean value = board.get(position); - if(value == null) { + if (value == null) { return ' '; - } else if(value) { + } else if (value) { return '!'; } else { return 'O'; From 3d4f5c685adbb4865e707490474cf039efacd9c7 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 13:22:56 -0500 Subject: [PATCH 088/102] Added Instructions --- 48_High_IQ/java/src/HighIQ.java | 3 +++ 48_High_IQ/java/src/HighIQGame.java | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index 5c3f31aa..a0278771 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -27,7 +27,10 @@ public class HighIQ { } public void play() { + + do { + printBoard(); while (!move()) { System.out.println("ILLEGAL MOVE, TRY AGAIN..."); } diff --git a/48_High_IQ/java/src/HighIQGame.java b/48_High_IQ/java/src/HighIQGame.java index 4df22853..e74e5783 100644 --- a/48_High_IQ/java/src/HighIQGame.java +++ b/48_High_IQ/java/src/HighIQGame.java @@ -2,10 +2,34 @@ import java.util.Scanner; public class HighIQGame { public static void main(String[] args) { + + printInstructions(); + Scanner scanner = new Scanner(System.in); do { new HighIQ(scanner).play(); System.out.println("PLAY AGAIN (YES OR NO)"); } while(scanner.nextLine().equalsIgnoreCase("yes")); } + + public static void printInstructions() { + System.out.println("HERE IS THE BOARD:"); + System.out.println(" ! ! !"); + System.out.println(" 13 14 15\n"); + System.out.println(" ! ! !"); + System.out.println(" 22 23 24\n"); + System.out.println("! ! ! ! ! ! !"); + System.out.println("29 30 31 32 33 34 35\n"); + System.out.println("! ! ! ! ! ! !"); + System.out.println("38 39 40 41 42 43 44\n"); + System.out.println("! ! ! ! ! ! !"); + System.out.println("47 48 49 50 51 52 53\n"); + System.out.println(" ! ! !"); + System.out.println(" 58 59 60\n"); + System.out.println(" ! ! !"); + System.out.println(" 67 68 69"); + System.out.println("TO SAVE TYPING TIME, A COMPRESSED VERSION OF THE GAME BOARD"); + System.out.println("WILL BE USED DURING PLAY. REFER TO THE ABOVE ONE FOR PEG"); + System.out.println("NUMBERS. OK, LET'S BEGIN."); + } } From 110b77fccd5d8cbc956abae1c1538964ab9a8e27 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 13:35:37 -0500 Subject: [PATCH 089/102] Cleanup --- 48_High_IQ/java/src/HighIQ.java | 49 ++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/48_High_IQ/java/src/HighIQ.java b/48_High_IQ/java/src/HighIQ.java index a0278771..d77a2ec2 100644 --- a/48_High_IQ/java/src/HighIQ.java +++ b/48_High_IQ/java/src/HighIQ.java @@ -3,11 +3,25 @@ import java.util.HashMap; import java.util.Map; import java.util.Scanner; +/** + * Game of HighIQ + *

+ * Based on the Basic Game of HighIQ Here: + * https://github.com/coding-horror/basic-computer-games/blob/main/48_High_IQ/highiq.bas + * + * No additional functionality has been added + */ public class HighIQ { - private Map board; - private PrintStream out; - private Scanner scanner; + //Game board, as a map of position numbers to their values + private final Map board; + + //Output stream + private final PrintStream out; + + //Input scanner to use + private final Scanner scanner; + public HighIQ(Scanner scanner) { out = System.out; @@ -26,13 +40,14 @@ public class HighIQ { board.put(41, false); } + /** + * Plays the actual game, from start to finish. + */ public void play() { - - do { printBoard(); while (!move()) { - System.out.println("ILLEGAL MOVE, TRY AGAIN..."); + out.println("ILLEGAL MOVE, TRY AGAIN..."); } } while (!isGameFinished()); @@ -51,8 +66,12 @@ public class HighIQ { } } + /** + * Makes an individual move + * @return True if the move was valid, false if the user made an error and the move is invalid + */ public boolean move() { - System.out.println("MOVE WHICH PIECE"); + out.println("MOVE WHICH PIECE"); int from = scanner.nextInt(); //using the getOrDefault, which will make the statement false if it is an invalid position @@ -60,7 +79,7 @@ public class HighIQ { return false; } - System.out.println("TO WHERE"); + out.println("TO WHERE"); int to = scanner.nextInt(); if (board.getOrDefault(to, true)) { @@ -83,14 +102,18 @@ public class HighIQ { return false; } + //Actually move + board.put(from,false); + board.put(to,true); + board.put((from + to) / 2, false); + return true; } -// private boolean playAgain() { -// out.println("PLAY AGAIN (YES OR NO)"); -// return scanner.nextLine().toLowerCase().equals("yes"); -// } - + /** + * Checks if the game is finished + * @return True if there are no more moves, False otherwise + */ public boolean isGameFinished() { for (Integer key : board.keySet()) { if (board.get(key)) { From 60b84070c99624f8fa5d7db18c9d26d854b90686 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 13:40:28 -0500 Subject: [PATCH 090/102] Added Header --- 48_High_IQ/java/src/HighIQGame.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/48_High_IQ/java/src/HighIQGame.java b/48_High_IQ/java/src/HighIQGame.java index e74e5783..43400fb3 100644 --- a/48_High_IQ/java/src/HighIQGame.java +++ b/48_High_IQ/java/src/HighIQGame.java @@ -13,6 +13,8 @@ public class HighIQGame { } public static void printInstructions() { + System.out.println("\t\t\t H-I-Q"); + System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("HERE IS THE BOARD:"); System.out.println(" ! ! !"); System.out.println(" 13 14 15\n"); From 6ae9fbcd3676ad929d44c89b07d90dd415d83a4b Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 14:22:28 -0500 Subject: [PATCH 091/102] Initial Commit Added Instructions, Random mine placement, and the general layout --- 30_Cube/java/src/Cube.java | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 30_Cube/java/src/Cube.java diff --git a/30_Cube/java/src/Cube.java b/30_Cube/java/src/Cube.java new file mode 100644 index 00000000..2e19a691 --- /dev/null +++ b/30_Cube/java/src/Cube.java @@ -0,0 +1,80 @@ +import java.io.PrintStream; +import java.util.Random; + +public class Cube { + + private Location playerLocation; + private Location[] mines; + private PrintStream out; + + + public static void main(String[] args) { + new Cube().play(); + } + + public Cube() { + out = System.out; + } + + private void placeMines() { + mines = new Location[5]; + Random random = new Random(); + for(int i = 0; i < mines.length; i++) { + int x = random.nextInt(1,4); + int y = random.nextInt(1,4); + int z = random.nextInt(1,4); + mines[i] = new Location(x,y,z); + } + } + + public void play() { + + } + + public void printInstructions() { + out.println("THIS IS A GAME IN WHICH YOU WILL BE PLAYING AGAINST THE"); + out.println("RANDOM DECISION OF THE COMPUTER. THE FIELD OF PLAY IS A"); + out.println("CUBE OF SIDE 3. ANY OF THE 27 LOCATIONS CAN BE DESIGNATED"); + out.println("CUBE OF SIDE 3. ANY OF THE 27 LOCATIONS CAN BE DESIGNATED"); + out.println("BY INPUTTING THREE NUMBERS SUCH AS 2,3,1. AT THE START"); + out.println("YOU ARE AUTOMATICALLY AT LOCATION 1,1,1. THE OBJECT OF"); + out.println("THE GAME IS TO GET TO LOCATION 3,3,3. ONE MINOR DETAIL:"); + out.println("THE COMPUTER WILL PICK, AT RANDOM, 5 LOCATIONS AT WHICH"); + out.println("IT WILL PLANT LAND MINES. IF YOU HIT ONE OF THESE LOCATIONS"); + out.println("YOU LOSE. ONE OTHER DETAIL: YOU MAY MOVE ONLY ONE SPACE"); + out.println("IN ONE DIRECTION EACH MOVE. FOR EXAMPLE: FROM 1,1,2 YOU"); + out.println("MAY MOVE TO 2,1,2 OR 1,1,3. YOU MAY NOT CHANGE"); + out.println("TWO OF THE NUMBERS ON THE SAME MOVE. IF YOU MAKE AN ILLEGAL"); + out.println("MOVE, YOU LOSE AND THE COMPUTER TAKES THE MONEY YOU MAY"); + } + + public class Location { + int x,y,z; + + public Location(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Location location = (Location) o; + + if (x != location.x) return false; + if (y != location.y) return false; + return z == location.z; + } + + @Override + public int hashCode() { + int result = x; + result = 31 * result + y; + result = 31 * result + z; + return result; + } + } +} From 4d88281a17750b7dd00735c41b52d2f361114e8e Mon Sep 17 00:00:00 2001 From: Flavio Poletti Date: Thu, 6 Jan 2022 20:09:19 +0100 Subject: [PATCH 092/102] Add Perl for 04_Awari --- 04_Awari/perl/awari.pl | 267 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 04_Awari/perl/awari.pl diff --git a/04_Awari/perl/awari.pl b/04_Awari/perl/awari.pl new file mode 100644 index 00000000..3d70452c --- /dev/null +++ b/04_Awari/perl/awari.pl @@ -0,0 +1,267 @@ +#!/usr/bin/env perl +use v5.24; +use warnings; +use experimental 'signatures'; +no warnings 'experimental::signatures'; +use List::Util 'none'; + +# our board will be represented with an array of 14 slots, from 0 to 13. +# Positions 6 and 13 represent the "home pit" for the human and the +# computer, respectively. +use constant PLAYER_HOME => 6; +use constant COMPUTER_HOME => 13; + +use constant FIRST => 0; +use constant AGAIN => 1; + +exit main(@ARGV); + +sub main { + $|++; # disable buffering on standard output, every print will be + # done immediately + + welcome(); # startup message + + # this array will keep track of computer-side failures, defined as + # "the computer did not win". Whenever the computer loses or draws, the + # specific sequence of moves will be saved and then used to drive + # the search for a (hopefully) optimal move. + my $failures = []; + while ('enjoying') { + + # a new game starts, let's reset the board to the initial condition + my $board = [ (3) x 6, 0, (3) x 6, 0 ]; + + # this string will keep track of all moves performed + my $moves = '/'; + + # the human player starts + my $turn = 'player'; + + say "\n"; + print_board($board); + + while (not is_game_over($board)) { + + my $move; # this will collect the move in this turn + + if ($turn eq 'player') { # "first" move for player + + # player_move(...) does the move selected by the player, + # returning both the selected move as well as the pit id + # where the last seed landed + ($move, my $landing) = player_move($board); + + # if we landed on the Player's Home Pit we get another move + $turn = $landing == PLAYER_HOME ? 'player-again' : 'computer'; + } + elsif ($turn eq 'player-again') { # "second" move for player + + # here we call player_move making it clear that it's the + # second move, to get the right prompt eventually. We only + # care for the $move as the result, so we ignore the other. + ($move) = player_move($board, AGAIN); + $turn = 'computer'; + } + else { + + # the computer_move(...) function analyzes the $board as well + # as adapting the strategy based on past "failures" (i.e. + # matches where the computer did not win). For this it's + # important to pass the log of these failures, as well as the + # full record of moves in this specific match. + ($move, my $landing) = computer_move($board, $failures, $moves); + print "\nMY MOVE IS ", $move - 6; + + # do the second move in the turn if conditions apply + if ($landing == COMPUTER_HOME && ! is_game_over($board)) { + + # save the first move before doing the second one! + $moves .= "$move/"; + + my ($move) = computer_move($board, $failures, $moves); + print ',', $move - 6; + } + $turn = 'player'; + } + + # append the last selected move by either party, to track this + # specific match (useful for computer's AI and ML) + $moves .= "$move/"; + print_board($board); + } + + # assess_victory() returns the difference between player's and + # computer's seeds, so a negative value is a win for the computer. + my $computer_won = assess_victory($board) < 0; + + # if this last match was a "failure" (read: not a win for the + # computer), then record it for future memory. + push $failures->@*, $moves unless $computer_won; + } + + return 0; +} + +# calculate the difference between the two home pits. Negative values mean +# that the computer won, 0 is a draw, positive values is a player's win. +# The difference is also returned back, in case of need. +sub assess_victory ($board) { + say "\nGAME OVER"; + my $difference = $board->[PLAYER_HOME] - $board->[COMPUTER_HOME]; + if ($difference < 0) { + say 'I WIN BY ', -$difference, ' POINTS'; + } + else { + say $difference ? "YOU WIN BY $difference POINTS" : 'DRAWN GAME'; + } + return $difference; +} + +# move the seeds from $pit and take into account possible bonuses +sub move_seeds ($board, $pit) { + + # get the seeds from the selected pit $pit + my $seeds = $board->[$pit]; + $board->[$pit] = 0; + + # $landing will be our "moving cursor" to place seeds around + my $landing = $pit; + while ($seeds > 0) { + $landing = ($landing + 1) % 14; # 12 --> 13 -[wrap]-> 0 --> 1 + --$seeds; + ++$board->[$landing]; + } + + # check for "stealing seeds" condition. This cannot happen in home pits + if ($landing != PLAYER_HOME && $landing != COMPUTER_HOME + && $board->[$landing] == 1 && $board->[12 - $landing] > 0) { + my $home = $pit < 7 ? PLAYER_HOME : COMPUTER_HOME; + $board->[$home] += 1 + $board->[12 - $landing]; + $board->@[$landing, 12 - $landing] = (0, 0); + } + + return ($pit, $landing); +} + +sub get_player_move ($board, $prompt) { + print "\n$prompt? "; + while (defined(my $move = )) { + chomp($move); # remove newline + return $move - 1 if $move =~ m{\A[1-6]\z}mxs && $board->[$move - 1]; + print 'ILLEGAL MOVE\nAGAIN? '; + } + die "goodbye\n"; +} + +sub player_move ($board, $stage = FIRST) { + my $prompt = $stage == FIRST ? 'YOUR MOVE' : 'AGAIN'; + my $selected_move = get_player_move($board, $prompt); + return move_seeds($board, $selected_move); +} + +sub computer_move ($board, $failures, $moves) { + + # we will go through all possible moves for the computer and all + # possible responses by the player, collecting the "best" move in terms + # of reasonable outcome (assuming that each side wants to maximize their + # outcome. $best_move will eventually contain the best move for the + # computer, and $best_difference the best difference in scoring (as + # seen from the computer). + my ($best_move, $best_difference); + for my $c_move (7 .. 12) { + next unless $board->[$c_move]; # only consider pits with seeds inside + + # we work on a copy of the board to do all our trial-and-errors + my $copy = [ $board->@* ]; + move_seeds($copy, $c_move); + + # it's time to "think like a player" and see what's the "best" move + # for the player in this situation. This heuristic is "not perfect" + # but it seems OK anyway. + my $best_player_score = 0; + for my $p_move (0 .. 5) { + next unless $copy->[$p_move]; # only pits with seeds inside + my $landing = $copy->[$p_move] + $p_move; + + # the player's score for this move, calculated as additional seeds + # placed in the player's pit. The original algorithm sets this to + # 1 only if the $landing position is greater than 13, which can + # be obtained by setting the ORIGINAL environment variable to a + # "true" value (in Perl terms). Otherwise it is calculated + # according to the real rules for the game. + my $p_score = $ENV{ORIGINAL} ? $landing > 13 : int(($landing - 5) / 14); + + # whatever, the landing position must be within the bounds + $landing %= 14; + + # if the conditions apply, the player's move might win additional + # seeds, which we have to to take into account. + $p_score += $copy->[12 - $landing] + if $copy->[$landing] == 0 + && $landing != PLAYER_HOME && $landing != COMPUTER_HOME; + + # let's compare this move's score against the best collected + # so far (as a response to a specific computer's move). + $best_player_score = $p_score if $p_score > $best_player_score; + } + + # the overall score for the player is the additional seeds we just + # calculated into $best_player_score plus the seeds that were already + # in the player's pit + $best_player_score += $copy->[PLAYER_HOME]; + + # the best difference we can aim for with this computer's move must + # assume that the player will try its best + my $difference = $copy->[COMPUTER_HOME] - $best_player_score; + + # now it's time to check this computer's move against the history + # of failed matches. $candidate_moves will be the "candidate" list + # of moves if we accept this one. + my $candidate_moves = $moves . $c_move . '/'; + for my $failure ($failures->@*) { + + # index(.) returns 0 if and only if $candidate_moves appears at + # the very beginning of $failure, i.e. it matches a previous + # behaviour. + next if index($failure, $candidate_moves) != 0; + + # same sequence of moves as before... assign a penalty + $difference -= 2; + } + + # update $best_move and $best_difference if they need to + ($best_move, $best_difference) = ($c_move, $difference) + if (! defined $best_move) || ($best_difference < $difference); + } + + # apply the selected move and return + return move_seeds($board, $best_move); +} + +sub welcome { + say ' ' x 34, 'AWARI'; + say ' ' x 15, 'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY'; +} + +sub print_board ($board) { + my $template = ' + %2d %2d %2d %2d %2d %2d + %2d %d + %2d %2d %2d %2d %2d %2d +'; + printf $template, $board->@[12, 11, 10, 9, 8 , 7, 13, 6, 0 .. 5]; + return; +} + +sub is_game_over ($board) { + + # game over if the player's side is empty + return 1 if none { $_ } $board->@[0 .. 5]; + + # game over if the computers' side is empty + return 1 if none { $_ } $board->@[7 .. 12]; + + # not game over + return 0; +} From 33dbe7e92d14980b17ddfb3afa56868c95013287 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 15:35:24 -0500 Subject: [PATCH 093/102] Started work on the play cycle --- 30_Cube/java/src/Cube.java | 90 +++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 5 deletions(-) diff --git a/30_Cube/java/src/Cube.java b/30_Cube/java/src/Cube.java index 2e19a691..7fbe39ee 100644 --- a/30_Cube/java/src/Cube.java +++ b/30_Cube/java/src/Cube.java @@ -1,11 +1,17 @@ import java.io.PrintStream; +import java.util.HashSet; import java.util.Random; +import java.util.Scanner; +import java.util.Set; public class Cube { private Location playerLocation; - private Location[] mines; + private Set mines; private PrintStream out; + private Scanner scanner; + + private int money; public static void main(String[] args) { @@ -14,28 +20,84 @@ public class Cube { public Cube() { out = System.out; + scanner = new Scanner(System.in); + money = 500; + mines = new HashSet<>(); } private void placeMines() { - mines = new Location[5]; + mines.clear(); Random random = new Random(); - for(int i = 0; i < mines.length; i++) { + for(int i = 0; i < 5; i++) { int x = random.nextInt(1,4); int y = random.nextInt(1,4); int z = random.nextInt(1,4); - mines[i] = new Location(x,y,z); + mines.add(new Location(x,y,z)); } } public void play() { + out.println("DO YOU WANT TO SEE INSTRUCTIONS? (YES--1,NO--0)"); + if(readParsedBoolean()) { + printInstructions(); + } + do { + placeMines(); + out.println("WANT TO MAKE A WAGER?"); + int wager = 0 ; + if(readParsedBoolean()) { + out.println("HOW MUCH?"); + do { + wager = scanner.nextInt(); + if(wager > money) { + out.println("TRIED TO FOOL ME; BET AGAIN"); + } + } while(wager > money); + } + + + while(playerLocation.x + playerLocation.y + playerLocation.z != 9) { + out.println("\nNEXT MOVE"); + String input = scanner.nextLine(); + + String[] stringValues = input.split(","); + + int x = Integer.parseInt(stringValues[0]); + int y = Integer.parseInt(stringValues[1]); + int z = Integer.parseInt(stringValues[2]); + + Location location = new Location(x,y,z); + + if(x < 1 || x > 3 || y < 1 || y > 3 || z < 1 || z > 3 || isMoveValid(playerLocation,location)) { + out.println("ILLEGAL MOVE, YOU LOSE."); + return; + } + + playerLocation = location; + + if(mines.contains(location)) { + out.println("******BANG******"); + out.println("YOU LOSE!\n\n"); + money -= wager; + } + } + } while(money > 0 && !doAnotherRound()); + } + + private boolean doAnotherRound() { + if(money > 0) { + out.println("DO YOU WANT TO TRY AGAIN?"); + return readParsedBoolean(); + } else { + return false; + } } public void printInstructions() { out.println("THIS IS A GAME IN WHICH YOU WILL BE PLAYING AGAINST THE"); out.println("RANDOM DECISION OF THE COMPUTER. THE FIELD OF PLAY IS A"); out.println("CUBE OF SIDE 3. ANY OF THE 27 LOCATIONS CAN BE DESIGNATED"); - out.println("CUBE OF SIDE 3. ANY OF THE 27 LOCATIONS CAN BE DESIGNATED"); out.println("BY INPUTTING THREE NUMBERS SUCH AS 2,3,1. AT THE START"); out.println("YOU ARE AUTOMATICALLY AT LOCATION 1,1,1. THE OBJECT OF"); out.println("THE GAME IS TO GET TO LOCATION 3,3,3. ONE MINOR DETAIL:"); @@ -46,6 +108,24 @@ public class Cube { out.println("MAY MOVE TO 2,1,2 OR 1,1,3. YOU MAY NOT CHANGE"); out.println("TWO OF THE NUMBERS ON THE SAME MOVE. IF YOU MAKE AN ILLEGAL"); out.println("MOVE, YOU LOSE AND THE COMPUTER TAKES THE MONEY YOU MAY"); + out.println("\n"); + out.println("ALL YES OR NO QUESTIONS WILL BE ANSWERED BY A 1 FOR YES"); + out.println("OR A 0 (ZERO) FOR NO."); + out.println(); + out.println("WHEN STATING THE AMOUNT OF A WAGER, PRINT ONLY THE NUMBER"); + out.println("OF DOLLARS (EXAMPLE: 250) YOU ARE AUTOMATICALLY STARTED WITH"); + out.println("500 DOLLARS IN YOUR ACCOUNT."); + out.println(); + out.println("GOOD LUCK!"); + } + + private boolean readParsedBoolean() { + String in = scanner.nextLine(); + return in.toLowerCase().charAt(0) == 'y' || Boolean.parseBoolean(in); + } + + private boolean isMoveValid(Location from, Location to) { + return Math.abs(from.x - to.x) + Math.abs(from.y - to.y) + Math.abs(from.z - to.z) <= 1; } public class Location { From 28b94b55679a7b1472367b23684707e00f9b6fa6 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 16:04:03 -0500 Subject: [PATCH 094/102] Game now works --- 30_Cube/java/src/Cube.java | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/30_Cube/java/src/Cube.java b/30_Cube/java/src/Cube.java index 7fbe39ee..1b68a285 100644 --- a/30_Cube/java/src/Cube.java +++ b/30_Cube/java/src/Cube.java @@ -49,27 +49,32 @@ public class Cube { if(readParsedBoolean()) { out.println("HOW MUCH?"); do { - wager = scanner.nextInt(); + wager = Integer.parseInt(scanner.nextLine()); if(wager > money) { out.println("TRIED TO FOOL ME; BET AGAIN"); } } while(wager > money); } - + playerLocation = new Location(1,1,1); while(playerLocation.x + playerLocation.y + playerLocation.z != 9) { out.println("\nNEXT MOVE"); String input = scanner.nextLine(); String[] stringValues = input.split(","); + if(stringValues.length < 3) { + out.println("ILLEGAL MOVE, YOU LOSE."); + return; + } + int x = Integer.parseInt(stringValues[0]); int y = Integer.parseInt(stringValues[1]); int z = Integer.parseInt(stringValues[2]); Location location = new Location(x,y,z); - if(x < 1 || x > 3 || y < 1 || y > 3 || z < 1 || z > 3 || isMoveValid(playerLocation,location)) { + if(x < 1 || x > 3 || y < 1 || y > 3 || z < 1 || z > 3 || !isMoveValid(playerLocation,location)) { out.println("ILLEGAL MOVE, YOU LOSE."); return; } @@ -80,9 +85,18 @@ public class Cube { out.println("******BANG******"); out.println("YOU LOSE!\n\n"); money -= wager; + break; } } - } while(money > 0 && !doAnotherRound()); + + if(wager > 0) { + out.printf("YOU NOW HAVE %d DOLLARS\n",money); + } + + } while(money > 0 && doAnotherRound()); + + out.println("TOUGH LUCK!"); + out.println("\nGOODBYE."); } private boolean doAnotherRound() { @@ -121,7 +135,11 @@ public class Cube { private boolean readParsedBoolean() { String in = scanner.nextLine(); - return in.toLowerCase().charAt(0) == 'y' || Boolean.parseBoolean(in); + try { + return in.toLowerCase().charAt(0) == 'y' || Boolean.parseBoolean(in) || Integer.parseInt(in) == 1; + } catch(NumberFormatException exception) { + return false; + } } private boolean isMoveValid(Location from, Location to) { From fe6cb06d6f660916fe08a8d02d58f760685ac438 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 16:11:12 -0500 Subject: [PATCH 095/102] Added Comments --- 30_Cube/java/src/Cube.java | 46 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/30_Cube/java/src/Cube.java b/30_Cube/java/src/Cube.java index 1b68a285..1237a49d 100644 --- a/30_Cube/java/src/Cube.java +++ b/30_Cube/java/src/Cube.java @@ -4,16 +4,33 @@ import java.util.Random; import java.util.Scanner; import java.util.Set; +/** + * Game of Cube + *

+ * Based on game of Cube at: + * https://github.com/coding-horror/basic-computer-games/blob/main/30_Cube/cube.bas + * + * + */ public class Cube { + //Current player location private Location playerLocation; + + //Current list of mines private Set mines; + + //System input / output objects private PrintStream out; private Scanner scanner; + //Player's current money private int money; - + /** + * Entry point, creates a new Cube object and calls the play method + * @param args Java execution arguments, not used in application + */ public static void main(String[] args) { new Cube().play(); } @@ -22,9 +39,12 @@ public class Cube { out = System.out; scanner = new Scanner(System.in); money = 500; - mines = new HashSet<>(); + mines = new HashSet<>(5); } + /** + * Clears mines and places 5 new mines on the board + */ private void placeMines() { mines.clear(); Random random = new Random(); @@ -36,6 +56,9 @@ public class Cube { } } + /** + * Runs the entire game until the player runs out of money or chooses to stop + */ public void play() { out.println("DO YOU WANT TO SEE INSTRUCTIONS? (YES--1,NO--0)"); if(readParsedBoolean()) { @@ -99,6 +122,11 @@ public class Cube { out.println("\nGOODBYE."); } + /** + * Queries the user whether they want to play another round + * @return True if the player decides to play another round, + * False if the player would not like to play again + */ private boolean doAnotherRound() { if(money > 0) { out.println("DO YOU WANT TO TRY AGAIN?"); @@ -108,6 +136,9 @@ public class Cube { } } + /** + * Prints the instructions to the game, copied from the original code. + */ public void printInstructions() { out.println("THIS IS A GAME IN WHICH YOU WILL BE PLAYING AGAINST THE"); out.println("RANDOM DECISION OF THE COMPUTER. THE FIELD OF PLAY IS A"); @@ -133,6 +164,11 @@ public class Cube { out.println("GOOD LUCK!"); } + /** + * Waits for the user to input a boolean value. This could either be (true,false), (1,0), (y,n), (yes,no), etc. + * By default, it will return false + * @return Parsed boolean value of the user input + */ private boolean readParsedBoolean() { String in = scanner.nextLine(); try { @@ -155,6 +191,9 @@ public class Cube { this.z = z; } + /* + For use in HashSet and checking if two Locations are the same + */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -167,6 +206,9 @@ public class Cube { return z == location.z; } + /* + For use in the HashSet to accordingly index the set + */ @Override public int hashCode() { int result = x; From d2495a55aad12e1cad51b0497bf2eac74c5ab9c0 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 16:12:04 -0500 Subject: [PATCH 096/102] Added Comments --- 30_Cube/java/src/Cube.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/30_Cube/java/src/Cube.java b/30_Cube/java/src/Cube.java index 1237a49d..0100682a 100644 --- a/30_Cube/java/src/Cube.java +++ b/30_Cube/java/src/Cube.java @@ -178,6 +178,12 @@ public class Cube { } } + /** + * Checks if a move is valid + * @param from The point that the player is at + * @param to The point that the player wishes to move to + * @return True if the player is only moving, at most, 1 location in any direction, False if the move is invalid + */ private boolean isMoveValid(Location from, Location to) { return Math.abs(from.x - to.x) + Math.abs(from.y - to.y) + Math.abs(from.z - to.z) <= 1; } From d2bf2e2e3b476d1c200cecc7f2d523bc4a92393d Mon Sep 17 00:00:00 2001 From: Pat Ludwig Date: Thu, 6 Jan 2022 17:17:39 -0600 Subject: [PATCH 097/102] Fix issues with spacing in intro section And bug with justification of the first two lines --- 11_Bombardment/perl/bombardment.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/11_Bombardment/perl/bombardment.pl b/11_Bombardment/perl/bombardment.pl index 593bd9fa..0641102e 100644 --- a/11_Bombardment/perl/bombardment.pl +++ b/11_Bombardment/perl/bombardment.pl @@ -112,8 +112,8 @@ sub populate_computer_bases { } sub print_intro { - print "" * 33 + "BOMBARDMENT\n"; - print "" * 15 + " CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; + print " " x 33, "BOMBARDMENT\n"; + print " " x 15, " CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; print "\n\n"; print "YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU\n"; print "HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.\n"; @@ -122,8 +122,8 @@ sub print_intro { print "THE OBJECT OF THE GAME IS TO FIRE MISSLES 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 "GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!\n"; + print "FIRST IS THE WINNER.\n\n"; + print "GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!\n\n"; print "TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS.\n"; print "\n\n\n\n"; } From dd7def55f3c637cd25629c1b810935a9ade97303 Mon Sep 17 00:00:00 2001 From: Flavio Poletti Date: Fri, 7 Jan 2022 03:11:52 +0100 Subject: [PATCH 098/102] Add 12_Bombs_Away in Perl --- 12_Bombs_Away/perl/bombsaway.pl | 140 ++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 12_Bombs_Away/perl/bombsaway.pl diff --git a/12_Bombs_Away/perl/bombsaway.pl b/12_Bombs_Away/perl/bombsaway.pl new file mode 100644 index 00000000..dd4c4674 --- /dev/null +++ b/12_Bombs_Away/perl/bombsaway.pl @@ -0,0 +1,140 @@ +#!/usr/bin/env perl +use v5.24; +use warnings; +use experimental 'signatures'; +no warnings 'experimental::signatures'; + +exit main(@ARGV); + +sub main { + $|++; + my $mission = 'y'; + + my @choices = ( + { # 1 - Italy + ask => 'YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3)', + comments => [ + q{SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE.}, + 'BE CAREFUL!!!', + q{YOU'RE GOING FOR THE OIL, EH?}, + ], + }, + { # 2 - Allies + ask => 'AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4)', + comments => [ + q{YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI.}, + q{YOU'RE DUMPING THE A-BOMB ON HIROSHIMA.}, + q{YOU'RE CHASING THE BISMARK IN THE NORTH SEA.}, + q{YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR.}, + ], + }, + \&japan, + { # 4 - Germany + ask => "A NAZI, EH? OH WELL. ARE YOU GOING FOR RUSSIA(1),\n" + . 'ENGLAND(2), OR FRANCE(3)', + comments => [ + q{YOU'RE NEARING STALINGRAD.}, + q{NEARING LONDON. BE CAREFUL, THEY'VE GOT RADAR.}, + q{NEARING VERSAILLES. DUCK SOUP. THEY'RE NEARLY DEFENSELESS.}, + ], + }, + ); + + while (fc($mission // 'n') eq fc('y')) { + say 'YOU ARE A PILOT IN A WORLD WAR II BOMBER.'; + + my $side = choose( + 'WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4)? ', 4); + my $choice = $choices[$side - 1]; + ref($choice) eq 'HASH' ? multiple($choice) : $choice->(); + + print "\n\n\nANOTHER MISSION (Y OR N)? "; + chomp($mission = ); + } + say "CHICKEN !!!\n"; + return 0; +} + +sub choose ($prompt, $n_max) { + while ('necessary') { + print "$prompt? "; + chomp(my $side = ); + return $side if $side =~ m{\A [1-9]\d* \z}mxs && $side <= $n_max; + say 'TRY AGAIN...'; + } +} + +sub multiple ($spec) { + my $target = choose("$spec->{ask}? ", scalar $spec->{comments}->@*); + say $spec->{comments}->[$target - 1]; + say ''; + + my $missions; + while ('necessary') { + print 'HOW MANY MISSIONS HAVE YOU FLOWN? '; + chomp($missions = ); + last if $missions < 160; + print 'MISSIONS, NOT MILES... +150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS. +NOW THEN, '; + } + if ($missions < 25) { say 'FRESH OUT OF TRANING, EH?' } + elsif ($missions >= 100) { say q{THAT'S PUSHING THE ODDS!} } + + return direct_hit() if $missions >= rand(160); + + my $miss = 2 + int rand(30); + say "MISSED TARGET BY $miss MILES!"; + say "NOW YOU'RE REALLY IN FOR IT !!\n"; + our $double_fire = 0; + my $response = choose( + 'DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3)', 3); + if ($response < 2) { + print q{WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? }; + chomp (our $hit_rate = ); + if ($hit_rate < 10) { + say q{YOU LIE, BUT YOU'LL PAY...}; + return endgame('fail'); # sure failure + } + say ''; + } + else { + $double_fire = 35; + } + return endgame(); +} + +sub direct_hit { + my $killed = int rand(100); + say "DIRECT HIT!!!! $killed KILLED.\nMISSION SUCCESSFUL"; + return; +} + +sub endgame ($fail = 0) { + our $double_fire //= 0; + our $hit_rate //= 0; + $fail ||= ($double_fire + $hit_rate) > rand(100); + if ($fail) { + say '* * * * BOOM * * * * +YOU HAVE BEEN SHOT DOWN..... +DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR +LAST TRIBUTE...'; + } + else { + say 'YOU MADE IT THROUGH TREMENDOUS FLAK!!'; + } + return; +} + +sub japan { + say q{YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.}; + print q{YOUR FIRST KAMIKAZE MISSION(Y OR N)? }; + chomp(my $is_first_kamikaze = ); + if (fc($is_first_kamikaze) eq fc('n')) { + our $hit_rate = 0; + say ''; + return endgame(); + } + return direct_hit() if rand(1) > 0.65; + return endgame('fail'); +} From 5b0d5e1221490818c433e4a19d97f450f2a61e58 Mon Sep 17 00:00:00 2001 From: Pat Ludwig Date: Thu, 6 Jan 2022 19:49:26 -0600 Subject: [PATCH 099/102] Fix misspelling General code cleanup, including * Address code indendation * Condense print statments * Add spaces before = signs * Add spaces around operators * Simplify a few things * Use full variable names instead of single letters --- 54_Letter/perl/letter.pl | 41 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/54_Letter/perl/letter.pl b/54_Letter/perl/letter.pl index 54fb5fe0..56acf533 100755 --- a/54_Letter/perl/letter.pl +++ b/54_Letter/perl/letter.pl @@ -5,40 +5,37 @@ print ' 'x33 . "LETTER\n"; print ' 'x15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; print "\n\n\n"; -print "LETTER GUESSING GAME\n"; print "\n"; +print "LETTER GUESSING GAME\n\n"; print "I'LL THINK OF A LETTER OF THE ALPHABET, A TO Z.\n"; print "TRY TO GUESS MY LETTER AND I'LL GIVE YOU CLUES\n"; print "AS TO HOW CLOSE YOU'RE GETTING TO MY LETTER.\n"; -my $A; while (1) { - my $L= 65+int(rand(1)*26); - my $G= 0; - print "\n"; print "O.K., I HAVE A LETTER. START GUESSING.\n"; + my $letter = 65 + int(rand(26)); + my $guesses = 0; + print "\nO.K., I HAVE A LETTER. START GUESSING.\n"; + my $answer; do { - print "\n"; print "WHAT IS YOUR GUESS? "; - $G=$G+1; - chomp($A= ); - $A= ord($A); + print "\nWHAT IS YOUR GUESS? "; + $guesses++; + chomp($answer = ); + $answer = ord($answer); print "\n"; - if ($A<$L) { print "TOO LOW. TRY A HIGHER LETTER.\n"; } - if ($A>$L) { print "TOO HIGH. TRY A LOWER LETTER.\n"; } - } until($A eq $L); + print "TOO LOW. TRY A HIGHER LETTER.\n" if $answer < $letter; + print "TOO HIGH. TRY A LOWER LETTER.\n" if $answer > $letter; + } until($answer eq $letter); - print "\n"; print "YOU GOT IT IN $G GUESSES!!\n"; + print "\nYOU GOT IT IN $guesses GUESSES!!\n"; - if ($G<=5) { + if ($guesses <= 5) { print "GOOD JOB !!!!!\n"; - for (my $N=1; $N<=15; $N++) { print chr(7); } #ASCII Bell. - } else { + print chr(7) x 15; # ASCII Bell + } else { print "BUT IT SHOULDN'T TAKE MORE THAN 5 GUESSES!\n"; - } - - print "\n"; - print "LET'S PLAN AGAIN.....\n"; } + print "\nLET'S PLAY AGAIN.....\n"; +} + exit; - - From c2358069574050e33ee4fbb101594d246828099f Mon Sep 17 00:00:00 2001 From: James Allenspach Date: Thu, 6 Jan 2022 20:23:53 -0600 Subject: [PATCH 100/102] Initial commit --- 62_Mugwump/perl/mugwump.pl | 96 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100755 62_Mugwump/perl/mugwump.pl diff --git a/62_Mugwump/perl/mugwump.pl b/62_Mugwump/perl/mugwump.pl new file mode 100755 index 00000000..356c9983 --- /dev/null +++ b/62_Mugwump/perl/mugwump.pl @@ -0,0 +1,96 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +# global variables defined here +my(@MUGWUMP) = (); + +# subroutines defined here + +# init_mugwump: pick the random places for the Mugwumps +sub init_mugwump() { + @MUGWUMP = (); + for (1 .. 4) { + push @MUGWUMP, [ int(rand 10), int(rand 10) ]; + } +} + + +# main code starts here + +# print introductory text +print <); + my($M,$N) = split(/,/,$in); + $M = int($M); + $N = int($N); + + for my $i (0 .. $#MUGWUMP) { + # -1 indicates a Mugwump that was already found + next if $MUGWUMP[$i]->[0] == -1; + + if ($MUGWUMP[$i]->[0] == $M && $MUGWUMP[$i]->[1] == $N) { + $MUGWUMP[$i]->[0] = -1; + printf("You have found Mugwump %d\n", $i+1); + } else { + my $d = sqrt(($MUGWUMP[$i]->[0] - $M) ** 2 + ($MUGWUMP[$i]->[1] - $N) ** 2); + printf("You are %.1f units away from Mugwump %d\n", $d, $i+1); + } + } + + # If a Mugwump still has not been found, + # go to the next turn + for my $j (0 .. $#MUGWUMP) { + if ($MUGWUMP[$j]->[0] != -1) { + next TURN; + } + } + # You win! + printf("You got all of them in %d %s!\n\n", $turn, ($turn == 1 ? 'turn' : 'turns')); + # Pass execution down to the continue block + next PLAY; + + } # end of TURN loop + + print "\nSorry, that's 10 tries. Here's where they're hiding:\n"; + for my $i (0 .. $#MUGWUMP) { + printf("Mugwump %d is at (%d, %d)\n", $i+1, $MUGWUMP[$i]->[0], $MUGWUMP[$i]->[1]) + if $MUGWUMP[$i]->[0] != -1; + } +} +continue { + print "\nThat was fun! Let's play again.......\n"; + print "Four more Mugwumps are now in hiding.\n\n"; +} + From dbc02ecf611f001fe434a7b343be61d8d76e19ae Mon Sep 17 00:00:00 2001 From: James Allenspach Date: Thu, 6 Jan 2022 20:25:06 -0600 Subject: [PATCH 101/102] typo --- 62_Mugwump/perl/mugwump.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/62_Mugwump/perl/mugwump.pl b/62_Mugwump/perl/mugwump.pl index 356c9983..d02a9036 100755 --- a/62_Mugwump/perl/mugwump.pl +++ b/62_Mugwump/perl/mugwump.pl @@ -33,7 +33,7 @@ number between 0 and 9, inclusive. First number is distance to right of homebase and second number is distance above homebase. -You get 10 tries. After each try, i will tell +You get 10 tries. After each try, I will tell you how far you are from each Mugwump. HERE From 03a18e473ab64753262d9099569534edf64775f3 Mon Sep 17 00:00:00 2001 From: Pat Ludwig Date: Thu, 6 Jan 2022 22:09:04 -0600 Subject: [PATCH 102/102] Fix enemy fire Choice 3, both should apply both $double_fire and $hit_rate --- 12_Bombs_Away/perl/bombsaway.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/12_Bombs_Away/perl/bombsaway.pl b/12_Bombs_Away/perl/bombsaway.pl index dd4c4674..478d01a7 100644 --- a/12_Bombs_Away/perl/bombsaway.pl +++ b/12_Bombs_Away/perl/bombsaway.pl @@ -89,7 +89,7 @@ NOW THEN, '; our $double_fire = 0; my $response = choose( 'DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3)', 3); - if ($response < 2) { + if ($response != 2) { print q{WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? }; chomp (our $hit_rate = ); if ($hit_rate < 10) { @@ -98,7 +98,7 @@ NOW THEN, '; } say ''; } - else { + if ($response > 1) { $double_fire = 35; } return endgame();