diff --git a/.gitignore b/.gitignore index fc50f7f2..a186b7a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ */.vs -*/csharp/bin -*/csharp/obj +bin/ +obj/ .idea *.iws diff --git a/04 Awari/python/awari.py b/04 Awari/python/awari.py index de97ee97..c04cce26 100644 --- a/04 Awari/python/awari.py +++ b/04 Awari/python/awari.py @@ -90,6 +90,7 @@ One could go many directions with this game: game_number = 0 move_count = 0 losing_book = [] +n = 0 MAX_HISTORY = 9 LOSING_BOOK_SIZE = 50 diff --git a/06 Banner/java/Banner.java b/06 Banner/java/Banner.java new file mode 100644 index 00000000..8c4e1c61 --- /dev/null +++ b/06 Banner/java/Banner.java @@ -0,0 +1,224 @@ +import java.util.Scanner; +import java.util.HashMap; +import java.util.Map; +import java.lang.Math; + +/** + * Game of Banner + *

+ * Based on the BASIC game of Banner here + * https://github.com/coding-horror/basic-computer-games/blob/main/06%20Banner/banner.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. + * + * Converted from BASIC to Java by Darren Cardenas. + */ + +public class Banner { + + private final Scanner scan; // For user input + + public Banner() { + + scan = new Scanner(System.in); + + } // End of constructor Banner + + public void play() { + + int bitIndex = 0; + int centerFlag = 0; + int dataIndex = 0; + int hIndex = 0; + int horizontal = 0; + int index = 0; + int letterIndex = 0; + int tempVal = 0; + int vertical = 0; + int vIndex = 0; + int writeIndex = 0; + + int[] writerMap = new int[10]; + int[] writeLimit = new int[10]; + + String centerResponse = ""; + String characters = ""; + String letter = ""; + String lineContent = ""; + String setPage = ""; + String statement = ""; + String token = ""; // Print token + + Map symbolData = new HashMap(); + symbolData.put(" ", new int[]{0,0,0,0,0,0,0,0 }); + symbolData.put("A", new int[]{0,505,37,35,34,35,37,505 }); + symbolData.put("G", new int[]{0,125,131,258,258,290,163,101}); + symbolData.put("E", new int[]{0,512,274,274,274,274,258,258}); + symbolData.put("T", new int[]{0,2,2,2,512,2,2,2 }); + symbolData.put("W", new int[]{0,256,257,129,65,129,257,256 }); + symbolData.put("L", new int[]{0,512,257,257,257,257,257,257}); + symbolData.put("S", new int[]{0,69,139,274,274,274,163,69 }); + symbolData.put("O", new int[]{0,125,131,258,258,258,131,125}); + symbolData.put("N", new int[]{0,512,7,9,17,33,193,512 }); + symbolData.put("F", new int[]{0,512,18,18,18,18,2,2 }); + symbolData.put("K", new int[]{0,512,17,17,41,69,131,258 }); + symbolData.put("B", new int[]{0,512,274,274,274,274,274,239}); + symbolData.put("D", new int[]{0,512,258,258,258,258,131,125}); + symbolData.put("H", new int[]{0,512,17,17,17,17,17,512 }); + symbolData.put("M", new int[]{0,512,7,13,25,13,7,512 }); + symbolData.put("?", new int[]{0,5,3,2,354,18,11,5 }); + symbolData.put("U", new int[]{0,128,129,257,257,257,129,128}); + symbolData.put("R", new int[]{0,512,18,18,50,82,146,271 }); + symbolData.put("P", new int[]{0,512,18,18,18,18,18,15 }); + symbolData.put("Q", new int[]{0,125,131,258,258,322,131,381}); + symbolData.put("Y", new int[]{0,8,9,17,481,17,9,8 }); + symbolData.put("V", new int[]{0,64,65,129,257,129,65,64 }); + symbolData.put("X", new int[]{0,388,69,41,17,41,69,388 }); + symbolData.put("Z", new int[]{0,386,322,290,274,266,262,260}); + symbolData.put("I", new int[]{0,258,258,258,512,258,258,258}); + symbolData.put("C", new int[]{0,125,131,258,258,258,131,69 }); + symbolData.put("J", new int[]{0,65,129,257,257,257,129,128 }); + symbolData.put("1", new int[]{0,0,0,261,259,512,257,257 }); + symbolData.put("2", new int[]{0,261,387,322,290,274,267,261}); + symbolData.put("*", new int[]{0,69,41,17,512,17,41,69 }); + symbolData.put("3", new int[]{0,66,130,258,274,266,150,100 }); + symbolData.put("4", new int[]{0,33,49,41,37,35,512,33 }); + symbolData.put("5", new int[]{0,160,274,274,274,274,274,226}); + symbolData.put("6", new int[]{0,194,291,293,297,305,289,193}); + symbolData.put("7", new int[]{0,258,130,66,34,18,10,8 }); + symbolData.put("8", new int[]{0,69,171,274,274,274,171,69 }); + symbolData.put("9", new int[]{0,263,138,74,42,26,10,7 }); + symbolData.put("=", new int[]{0,41,41,41,41,41,41,41 }); + symbolData.put("!", new int[]{0,1,1,1,384,1,1,1 }); + symbolData.put("0", new int[]{0,57,69,131,258,131,69,57 }); + symbolData.put(".", new int[]{0,1,1,129,449,129,1,1 }); + + System.out.print("HORIZONTAL? "); + horizontal = Integer.parseInt(scan.nextLine()); + + System.out.print("VERTICAL? "); + vertical = Integer.parseInt(scan.nextLine()); + + System.out.print("CENTERED? "); + centerResponse = scan.nextLine().toUpperCase(); + + centerFlag = 0; + + // Lexicographical comparison + if (centerResponse.compareTo("P") > 0) { + centerFlag = 1; + } + + System.out.print("CHARACTER (TYPE 'ALL' IF YOU WANT CHARACTER BEING PRINTED)? "); + characters = scan.nextLine().toUpperCase(); + + System.out.print("STATEMENT? "); + statement = scan.nextLine().toUpperCase(); + + // Initiates the print + System.out.print("SET PAGE? "); + setPage = scan.nextLine(); + + // Begin loop through statement letters + for (letterIndex = 1; letterIndex <= statement.length(); letterIndex++) { + + // Extract a letter + letter = String.valueOf(statement.charAt(letterIndex - 1)); + + // Begin loop through all symbol data + for (String symbolString: symbolData.keySet()) { + + // Begin letter handling + if (letter.equals(" ")) { + for (index = 1; index <= (7 * horizontal); index++) { + System.out.println(""); + } + break; + + } else if (letter.equals(symbolString)) { + token = characters; + + if (characters.equals("ALL")) { + token = symbolString; + } + + for (dataIndex = 1; dataIndex <= 7; dataIndex++) { + + // Avoid overwriting symbol data + tempVal = symbolData.get(symbolString)[dataIndex]; + + for (bitIndex = 8; bitIndex >= 0; bitIndex--) { + + if (Math.pow(2, bitIndex) < tempVal) { + writerMap[9 - bitIndex] = 1; + tempVal -= Math.pow(2, bitIndex); + + if (tempVal == 1) { + writeLimit[dataIndex] = 9 - bitIndex; + break; + } + + } else { + + writerMap[9 - bitIndex] = 0; + } + } // End of bitIndex loop + + for (hIndex = 1; hIndex <= horizontal; hIndex++) { + + // Add whitespace for centering + lineContent = " ".repeat((int)((63 - 4.5 * vertical) * centerFlag / token.length())); + + for (writeIndex = 1; writeIndex <= writeLimit[dataIndex]; writeIndex++) { + + if (writerMap[writeIndex] == 0) { + + for (vIndex = 1; vIndex <= vertical; vIndex++) { + + for (index = 1; index <= token.length(); index++) { + lineContent += " "; + } + } + + } else { + + for (vIndex = 1; vIndex <= vertical; vIndex++) { + lineContent += token; + } + } + + } // End of writeIndex loop + + System.out.println(lineContent); + + } // End of hIndex loop + + } // End of dataIndex loop + + // Add padding between letters + for (index = 1; index <= 2 * horizontal; index++) { + System.out.println(""); + } + + } // End letter handling + + } // End loop through all symbol data + + } // End loop through statement letters + + // Add extra length to the banner + for (index = 1; index <= 75; index++) { + System.out.println(""); + } + + } // End of method play + + public static void main(String[] args) { + + Banner game = new Banner(); + game.play(); + + } // End of method main + +} // End of class Banner diff --git a/11 Bombardment/ruby/bombardment.rb b/11 Bombardment/ruby/bombardment.rb new file mode 100644 index 00000000..9a89f9f6 --- /dev/null +++ b/11 Bombardment/ruby/bombardment.rb @@ -0,0 +1,167 @@ +require "set" + +class Battlefield + TOTAL_OUTPOSTS = 25 + TOTAL_PLATOONS = 4 + + class << self + def with_random_platoon_placements + new((1..TOTAL_OUTPOSTS).to_a.sample(4)) + end + + def valid_platoon_placement?(i) + i.between?(1, TOTAL_OUTPOSTS) + end + end + + def initialize(platoon_placements) + @platoon_placements = Set.new(platoon_placements) + end + + # Fires a missile at the specified outpost. Returns true if it hits a + # platoon, false otherwise. + def fire_missile_at(outpost) + !@platoon_placements.delete?(outpost).nil? + end + + def remaining_platoons_count + @platoon_placements.size + end +end + +class Game + def initialize(player_battlefield:, computer_battlefield:) + @player_battlefield = player_battlefield + @computer_battlefield = computer_battlefield + end + + def play + player_choice = get_integer_answer_to("WHERE DO YOU WISH TO FIRE") + + if @computer_battlefield.fire_missile_at(player_choice) + print_player_success_message + return if @computer_battlefield.remaining_platoons_count == 0 + else + puts "HA, HA YOU MISSED. MY TURN NOW:" + end + puts + + computer_choice = rand(1..Battlefield::TOTAL_OUTPOSTS) + + if @player_battlefield.fire_missile_at(computer_choice) + print_computer_success_message(computer_choice) + else + puts "I MISSED YOU, YOU DIRTY RAT. I PICKED #{computer_choice}. YOUR TURN:" + end + puts + end + + def finished? + @player_battlefield.remaining_platoons_count == 0 || + @computer_battlefield.remaining_platoons_count == 0 + end + + private + + def get_integer_answer_to(question) + puts question + $stdin.gets.strip.to_i + end + + def print_computer_success_message(computer_choice) + if @player_battlefield.remaining_platoons_count == 0 + puts "YOU'RE DEAD. YOUR LAST OUTPOST WAS AT #{computer_choice}. HA, HA, HA." + puts "BETTER LUCK NEXT TIME." + return + end + + puts "I GOT YOU. IT WON'T BE LONG NOW. POST #{computer_choice} WAS HIT." + + case @player_battlefield.remaining_platoons_count + when 1 + puts "YOU HAVE ONLY ONE OUTPOST LEFT" + when 2 + puts "YOU HAVE ONLY TWO OUTPOSTS LEFT" + when 3 + puts "YOU HAVE ONLY THREE OUTPOSTS LEFT" + end + end + + def print_player_success_message + if @computer_battlefield.remaining_platoons_count == 0 + puts "YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN" + puts "MY TRANSISTO&S RECUP%RA*E!" + return + end + + puts "YOU GOT ONE OF MY OUTPOSTS!" + + case @computer_battlefield.remaining_platoons_count + when 1 + puts "THREE DOWN, ONE TO GO." + when 2 + puts "TWO DOWN, TWO TO GO." + when 3 + puts "ONE DOWN, THREE TO GO." + end + end +end + +INTRODUCTION = <<~TEXT + BOMBARDMENT + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + + + YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU + HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED. + YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST. + THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS. + + THE OBJECT OF THE GAME IS TO FIRE MISSLES AT THE + OUTPOSTS OF THE COMPUTER. IT WILL DO THE SAME TO YOU. + THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS + FIRST IS THE WINNER. + + GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT! + + TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS. +TEXT + +def print_matrix + (1..25).each do |i| + print i + print i % 5 == 0 ? "\n" : "\t" + end +end + +def ask_for_platoon_placements + puts "WAHT ARE YOUR FOUR POSITIONS?" + platoon_placements = $stdin.gets.strip.split(",").map(&:to_i) + + if platoon_placements.size == 4 && + platoon_placements.all? { |i| Battlefield.valid_platoon_placement?(i) } + platoon_placements + else + puts "POSITIONS SHOULD BE BETWEEN 1 TO 25, DELIMITED BY COMMA." + ask_for_platoon_placements + end +end + +def start_game + puts INTRODUCTION + puts + print_matrix + puts + platoon_placements = ask_for_platoon_placements + puts + + game = Game.new( + player_battlefield: Battlefield.new(platoon_placements), + computer_battlefield: Battlefield.with_random_platoon_placements + ) + + game.play until game.finished? +end + +start_game diff --git a/19 Bunny/perl/bunny.pl b/19 Bunny/perl/bunny.pl new file mode 100644 index 00000000..21b65f2e --- /dev/null +++ b/19 Bunny/perl/bunny.pl @@ -0,0 +1,55 @@ +#!/usr/bin/perl +use strict; + +print ' 'x 33 . "BUNNY\n"; +print ' 'x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; +print "\n"; print "\n"; print "\n"; +#REM "BUNNY" FROM AHL'$S 'BASIC COMPUTER GAMES'; + +# This data contains the letter Bunny A=1, B=2, C=3... +my @A= (2,21,14,14,25); + +# This data structure contains the pair of start and finish absolute position to show letters. +# -1 means next line, whatever more than 128 will stop the data read. +my @B= ( + 1,2,-1,0,2,45,50,-1,0,5,43,52,-1,0,7,41,52,-1, + 1,9,37,50,-1,2,11,36,50,-1,3,13,34,49,-1,4,14,32,48,-1, + 5,15,31,47,-1,6,16,30,45,-1,7,17,29,44,-1,8,19,28,43,-1, + 9,20,27,41,-1,10,21,26,40,-1,11,22,25,38,-1,12,22,24,36,-1, + 13,34,-1,14,33,-1,15,31,-1,17,29,-1,18,27,-1, + 19,26,-1,16,28,-1,13,30,-1,11,31,-1,10,32,-1, + 8,33,-1,7,34,-1,6,13,16,34,-1,5,12,16,35,-1, + 4,12,16,35,-1,3,12,15,35,-1,2,35,-1,1,35,-1, + 2,34,-1,3,34,-1,4,33,-1,6,33,-1,10,32,34,34,-1, + 14,17,19,25,28,31,35,35,-1,15,19,23,30,36,36,-1, + 14,18,21,21,24,30,37,37,-1,13,18,23,29,33,38,-1, + 12,29,31,33,-1,11,13,17,17,19,19,22,22,24,31,-1, + 10,11,17,18,22,22,24,24,29,29,-1, + 22,23,26,29,-1,27,29,-1,28,29,-1,4096 + ); + + +&ENTERS(); +my $L= 64; #REM ASCII LETTER CODE... +print "\n"; + +my $P=0; #Position read iterator +my $Line= ' 'x 60; +while (1) { + my $X= $B[$P]; $P++; #Read start position. + if ($X<0) { print "$Line\n";; $Line= ' 'x 60; next; } + if ($X>128) { last; } + my $Y= $B[$P]; $P++; #Read end position. + + for (my $I=$X; $I<=$Y; $I++) { my $J=$I-5*int($I/5); + substr($Line, $I, 1, chr($L+$A[$J])); #You can change $I for $X to get a nice bunny shadow. + } + } + +&ENTERS(); +exit; + + +sub ENTERS { #GOSUB 260 + for (my $I=1; $I<=6; $I++) { print chr(10); } + } diff --git a/21 Calendar/java/Calendar.java b/21 Calendar/java/Calendar.java new file mode 100644 index 00000000..4202a4dc --- /dev/null +++ b/21 Calendar/java/Calendar.java @@ -0,0 +1,175 @@ +/** + * Game of Calendar + *

+ * Based on the BASIC game of Calendar here + * https://github.com/coding-horror/basic-computer-games/blob/main/21%20Calendar/calendar.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. + * + * Converted from BASIC to Java by Darren Cardenas. + */ + +public class Calendar { + + private static final int NUM_WEEK_ROWS = 6; + private static final int NUM_DAYS_PER_WEEK = 7; + private static final int NUM_MONTHS_PER_YEAR = 12; + private static final int[] daysPerMonth = { 0, 31, 28, 31, 30, 31, 30, + 31, 31, 30, 31, 30, 31 }; + + public void play() { + + showIntro(); + startGame(); + + } // End of method play + + private static void showIntro() { + + System.out.println(" ".repeat(31) + "CALENDAR"); + System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println("\n\n"); + + } // End of method showIntro + + private void startGame() { + + int dayOfMonth = 0; + int dayOfWeek = 0; + int dayOfYear = 0; + int daysTotal = 0; + int index = 0; + int month = 0; + int row = 0; + + String lineContent = ""; + + for (index = 1; index <= 6; index++) { + System.out.println(""); + } + + daysTotal = -1; + dayOfYear = 0; + + System.out.println(""); + + // Begin loop through all months + for (month = 1; month <= NUM_MONTHS_PER_YEAR; month++) { + + System.out.println(""); + + dayOfYear = dayOfYear + daysPerMonth[month - 1]; + + lineContent = String.format("** %-3d" + "*".repeat(18), dayOfYear); + + switch (month) { + case 1: + lineContent += " JANUARY "; + break; + case 2: + lineContent += " FEBRUARY"; + break; + case 3: + lineContent += " MARCH "; + break; + case 4: + lineContent += " APRIL "; + break; + case 5: + lineContent += " MAY "; + break; + case 6: + lineContent += " JUNE "; + break; + case 7: + lineContent += " JULY "; + break; + case 8: + lineContent += " AUGUST "; + break; + case 9: + lineContent += "SEPTEMBER"; + break; + case 10: + lineContent += " OCTOBER "; + break; + case 11: + lineContent += " NOVEMBER"; + break; + case 12: + lineContent += " DECEMBER"; + break; + default: + break; + } + + lineContent += "*".repeat(18) + " " + (365 - dayOfYear) + "**"; + + System.out.println(lineContent); + System.out.println(""); + + System.out.print(" S M T W"); + System.out.println(" T F S"); + System.out.println(""); + + System.out.println("*".repeat(59)); + + // Begin loop through each week row + for (row = 1; row <= NUM_WEEK_ROWS; row++) { + + System.out.println(""); + + lineContent = " "; + + // Begin loop through days of the week + for (dayOfWeek = 1; dayOfWeek <= NUM_DAYS_PER_WEEK; dayOfWeek++) { + + daysTotal++; + + dayOfMonth = daysTotal - dayOfYear; + + if (dayOfMonth > daysPerMonth[month]) { + row = 6; + break; + } + + if (dayOfMonth > 0) { + lineContent += dayOfMonth; + } + + while (lineContent.length() < (4 + 8 * dayOfWeek)) { + lineContent += " "; + } + + } // End loop through days of the week + + if (dayOfMonth == daysPerMonth[month]) { + row = 6; + daysTotal += dayOfWeek; + System.out.println(lineContent); + break; + } + + System.out.println(lineContent); + + } // End loop through each week row + + daysTotal -= dayOfWeek; + + } // End loop through all months + + for (index = 1; index <= 6; index++) { + System.out.println(""); + } + + } // End of method startGame + + public static void main(String[] args) { + + Calendar game = new Calendar(); + game.play(); + + } // End of method main + +} // End of class Calendar diff --git a/29 Craps/csharp/Craps/.gitignore b/29 Craps/csharp/Craps/.gitignore new file mode 100644 index 00000000..c1cb0dce --- /dev/null +++ b/29 Craps/csharp/Craps/.gitignore @@ -0,0 +1,5 @@ +.vs +TestResults +bin +obj + diff --git a/29 Craps/csharp/Craps/Craps.sln b/29 Craps/csharp/Craps/Craps.sln new file mode 100644 index 00000000..f6ab76ec --- /dev/null +++ b/29 Craps/csharp/Craps/Craps.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31112.23 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Craps", "Craps\Craps.csproj", "{783A49D7-DADE-477A-9973-D9457258573B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrapsTester", "CrapsTester\CrapsTester.csproj", "{44DFE8DB-715F-428E-992D-A97C34D47B98}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {783A49D7-DADE-477A-9973-D9457258573B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {783A49D7-DADE-477A-9973-D9457258573B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {783A49D7-DADE-477A-9973-D9457258573B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {783A49D7-DADE-477A-9973-D9457258573B}.Release|Any CPU.Build.0 = Release|Any CPU + {44DFE8DB-715F-428E-992D-A97C34D47B98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {44DFE8DB-715F-428E-992D-A97C34D47B98}.Debug|Any CPU.Build.0 = Debug|Any CPU + {44DFE8DB-715F-428E-992D-A97C34D47B98}.Release|Any CPU.ActiveCfg = Release|Any CPU + {44DFE8DB-715F-428E-992D-A97C34D47B98}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {871679FF-B86C-468B-960E-DFC625CDB5D0} + EndGlobalSection +EndGlobal diff --git a/29 Craps/csharp/Craps/Craps/Craps.csproj b/29 Craps/csharp/Craps/Craps/Craps.csproj new file mode 100644 index 00000000..c73e0d16 --- /dev/null +++ b/29 Craps/csharp/Craps/Craps/Craps.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp3.1 + + + diff --git a/29 Craps/csharp/Craps/Craps/CrapsGame.cs b/29 Craps/csharp/Craps/Craps/CrapsGame.cs new file mode 100644 index 00000000..71a3931f --- /dev/null +++ b/29 Craps/csharp/Craps/Craps/CrapsGame.cs @@ -0,0 +1,73 @@ +namespace Craps +{ + public enum Result + { + // It's not used in this program but it's often a good idea to include a "none" + // value in an enum so that you can set an instance of the enum to "invalid" or + // initialise it to "none of the valid values". + noResult, + naturalWin, + snakeEyesLoss, + naturalLoss, + pointLoss, + pointWin, + }; + + class CrapsGame + { + private readonly UserInterface ui; + private Dice dice1 = new Dice(); + private Dice dice2 = new Dice(); + + public CrapsGame(ref UserInterface ui) + { + this.ui = ui; + } + + public Result Play(out int diceRoll) + { + diceRoll = dice1.Roll() + dice2.Roll(); + + if (Win(diceRoll)) + { + return Result.naturalWin; + } + else if (Lose(diceRoll)) + { + return (diceRoll == 2) ? Result.snakeEyesLoss : Result.naturalLoss; + } + else + { + var point = diceRoll; + ui.Point(point); + + while (true) + { + var newRoll = dice1.Roll() + dice2.Roll(); + if (newRoll == point) + { + diceRoll = newRoll; + return Result.pointWin; + } + else if (newRoll == 7) + { + diceRoll = newRoll; + return Result.pointLoss; + } + + ui.NoPoint(newRoll); + } + } + } + + private bool Lose(int diceRoll) + { + return diceRoll == 2 || diceRoll == 3 || diceRoll == 12; + } + + private bool Win(int diceRoll) + { + return diceRoll == 7 || diceRoll == 11; + } + } +} diff --git a/29 Craps/csharp/Craps/Craps/Dice.cs b/29 Craps/csharp/Craps/Craps/Dice.cs new file mode 100644 index 00000000..43186026 --- /dev/null +++ b/29 Craps/csharp/Craps/Craps/Dice.cs @@ -0,0 +1,23 @@ +using System; + + +namespace Craps +{ + public class Dice + { + private Random rand = new Random(); + public readonly int sides; + + public Dice() + { + sides = 6; + } + + public Dice(int sides) + { + this.sides = sides; + } + + public int Roll() => rand.Next(1, sides + 1); + } +} diff --git a/29 Craps/csharp/Craps/Craps/Program.cs b/29 Craps/csharp/Craps/Craps/Program.cs new file mode 100644 index 00000000..d0aa5961 --- /dev/null +++ b/29 Craps/csharp/Craps/Craps/Program.cs @@ -0,0 +1,51 @@ +using System.Diagnostics; + + + +namespace Craps +{ + class Program + { + static void Main(string[] args) + { + var ui = new UserInterface(); + var game = new CrapsGame(ref ui); + int winnings = 0; + + ui.Intro(); + + do + { + var bet = ui.PlaceBet(); + var result = game.Play(out int diceRoll); + + switch (result) + { + case Result.naturalWin: + winnings += bet; + break; + + case Result.naturalLoss: + case Result.snakeEyesLoss: + case Result.pointLoss: + winnings -= bet; + break; + + case Result.pointWin: + winnings += (2 * bet); + break; + + // Include a default so that we will be warned if the values of the enum + // ever change and we forget to add code to handle the new value. + default: + Debug.Assert(false); // We should never get here. + break; + } + + ui.ShowResult(result, diceRoll, bet); + } while (ui.PlayAgain(winnings)); + + ui.GoodBye(winnings); + } + } +} diff --git a/29 Craps/csharp/Craps/Craps/UserInterface.cs b/29 Craps/csharp/Craps/Craps/UserInterface.cs new file mode 100644 index 00000000..149a3ecc --- /dev/null +++ b/29 Craps/csharp/Craps/Craps/UserInterface.cs @@ -0,0 +1,143 @@ +using System; +using System.Diagnostics; + + + +namespace Craps +{ + public class UserInterface + { + public void Intro() + { + Console.WriteLine(" CRAPS"); + Console.WriteLine(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n"); + Console.WriteLine("2,3,12 ARE LOSERS; 4,5,6,8,9,10 ARE POINTS; 7,11 ARE NATURAL WINNERS."); + + // In the original game a random number would be generated and then thrown away for as many + // times as the number the user entered. This is presumably something to do with ensuring + // that different random numbers will be generated each time the program is run. + // + // This is not necessary in C#; the random number generator uses the current time as a seed + // so the results will always be different every time it is run. + // + // So that the game exactly matches the original game we ask the question but then ignore + // the answer. + Console.Write("PICK A NUMBER AND INPUT TO ROLL DICE "); + GetInt(); + } + + public int PlaceBet() + { + Console.Write("INPUT THE AMOUNT OF YOUR WAGER. "); + int n = GetInt(); + Console.WriteLine("I WILL NOW THROW THE DICE"); + + return n; + } + + public bool PlayAgain(int winnings) + { + // Goodness knows why we have to enter 5 to play + // again but that's what the original game asked. + Console.Write("IF YOU WANT TO PLAY AGAIN PRINT 5 IF NOT PRINT 2 "); + + bool playAgain = (GetInt() == 5); + + if (winnings < 0) + { + Console.WriteLine($"YOU ARE NOW UNDER ${-winnings}"); + } + else if (winnings > 0) + { + Console.WriteLine($"YOU ARE NOW OVER ${winnings}"); + } + else + { + Console.WriteLine($"YOU ARE NOW EVEN AT ${winnings}"); + } + + return playAgain; + } + + public void GoodBye(int winnings) + { + if (winnings < 0) + { + Console.WriteLine("TOO BAD, YOU ARE IN THE HOLE. COME AGAIN."); + } + else if (winnings > 0) + { + Console.WriteLine("CONGRATULATIONS---YOU CAME OUT A WINNER. COME AGAIN!"); + } + else + { + Console.WriteLine("CONGRATULATIONS---YOU CAME OUT EVEN, NOT BAD FOR AN AMATEUR"); + } + } + + public void NoPoint(int diceRoll) + { + Console.WriteLine($"{diceRoll} - NO POINT. I WILL ROLL AGAIN "); + } + + public void Point(int point) + { + Console.WriteLine($"{point} IS THE POINT. I WILL ROLL AGAIN"); + } + + public void ShowResult(Result result, int diceRoll, int bet) + { + switch (result) + { + case Result.naturalWin: + Console.WriteLine($"{diceRoll} - NATURAL....A WINNER!!!!"); + Console.WriteLine($"{diceRoll} PAYS EVEN MONEY, YOU WIN {bet} DOLLARS"); + break; + + case Result.naturalLoss: + Console.WriteLine($"{diceRoll} - CRAPS...YOU LOSE."); + Console.WriteLine($"YOU LOSE {bet} DOLLARS."); + break; + + case Result.snakeEyesLoss: + Console.WriteLine($"{diceRoll} - SNAKE EYES....YOU LOSE."); + Console.WriteLine($"YOU LOSE {bet} DOLLARS."); + break; + + case Result.pointLoss: + Console.WriteLine($"{diceRoll} - CRAPS. YOU LOSE."); + Console.WriteLine($"YOU LOSE ${bet}"); + break; + + case Result.pointWin: + Console.WriteLine($"{diceRoll} - A WINNER.........CONGRATS!!!!!!!!"); + Console.WriteLine($"AT 2 TO 1 ODDS PAYS YOU...LET ME SEE... {2 * bet} DOLLARS"); + break; + + // Include a default so that we will be warned if the values of the enum + // ever change and we forget to add code to handle the new value. + default: + Debug.Assert(false); // We should never get here. + break; + } + } + + private int GetInt() + { + while (true) + { + string input = Console.ReadLine(); + if (int.TryParse(input, out int n)) + { + return n; + } + else + { + Console.Write("ENTER AN INTEGER "); + } + } + } + } +} + + diff --git a/29 Craps/csharp/Craps/CrapsTester/CrapsTester.csproj b/29 Craps/csharp/Craps/CrapsTester/CrapsTester.csproj new file mode 100644 index 00000000..748e7da4 --- /dev/null +++ b/29 Craps/csharp/Craps/CrapsTester/CrapsTester.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + + + diff --git a/29 Craps/csharp/Craps/CrapsTester/CrapsTests.cs b/29 Craps/csharp/Craps/CrapsTester/CrapsTests.cs new file mode 100644 index 00000000..576c2b82 --- /dev/null +++ b/29 Craps/csharp/Craps/CrapsTester/CrapsTests.cs @@ -0,0 +1,96 @@ +using Craps; +using Microsoft.VisualStudio.TestTools.UnitTesting; + + + +namespace CrapsTester +{ + [TestClass] + public class DiceTests + { + [TestMethod] + public void SixSidedDiceReturnsValidRolls() + { + var dice = new Dice(); + for (int i = 0; i < 100000; i++) + { + var roll = dice.Roll(); + Assert.IsTrue(roll >= 1 && roll <= dice.sides); + } + } + + [TestMethod] + public void TwentySidedDiceReturnsValidRolls() + { + var dice = new Dice(20); + for (int i = 0; i < 100000; i++) + { + var roll = dice.Roll(); + Assert.IsTrue(roll >= 1 && roll <= dice.sides); + } + } + + [TestMethod] + public void DiceRollsAreRandom() + { + // Roll 600,000 dice and count how many rolls there are for each side. + + var dice = new Dice(); + + int numOnes = 0; + int numTwos = 0; + int numThrees = 0; + int numFours = 0; + int numFives = 0; + int numSixes = 0; + int numErrors = 0; + + for (int i = 0; i < 600000; i++) + { + switch (dice.Roll()) + { + case 1: + numOnes++; + break; + + case 2: + numTwos++; + break; + + case 3: + numThrees++; + break; + + case 4: + numFours++; + break; + + case 5: + numFives++; + break; + + case 6: + numSixes++; + break; + + default: + numErrors++; + break; + } + } + + // We'll assume that a variation of 10% in rolls for the different numbers is random enough. + // Perfectly random rolling would produce 100000 rolls per side, +/- 5% of this gives the + // range 90000..110000. + const int minRolls = 95000; + const int maxRolls = 105000; + Assert.IsTrue(numOnes >= minRolls && numOnes <= maxRolls); + Assert.IsTrue(numTwos >= minRolls && numTwos <= maxRolls); + Assert.IsTrue(numThrees >= minRolls && numThrees <= maxRolls); + Assert.IsTrue(numFours >= minRolls && numFours <= maxRolls); + Assert.IsTrue(numFives >= minRolls && numFives <= maxRolls); + Assert.IsTrue(numSixes >= minRolls && numSixes <= maxRolls); + Assert.AreEqual(numErrors, 0); + } + } +} diff --git a/31 Depth Charge/java/DepthCharge.java b/31 Depth Charge/java/DepthCharge.java new file mode 100644 index 00000000..bf17accc --- /dev/null +++ b/31 Depth Charge/java/DepthCharge.java @@ -0,0 +1,186 @@ +import java.util.Scanner; +import java.lang.Math; + +/** + * Game of Depth Charge + *

+ * Based on the BASIC game of Depth Charge here + * https://github.com/coding-horror/basic-computer-games/blob/main/31%20Depth%20Charge/depthcharge.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. + * + * Converted from BASIC to Java by Darren Cardenas. + */ + +public class DepthCharge { + + private final Scanner scan; // For user input + + public DepthCharge() { + + scan = new Scanner(System.in); + + } // End of constructor DepthCharge + + public void play() { + + showIntro(); + startGame(); + + } // End of method play + + private static void showIntro() { + + System.out.println(" ".repeat(29) + "DEPTH CHARGE"); + System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println("\n\n"); + + } // End of method showIntro + + private void startGame() { + + int searchArea = 0; + int shotNum = 0; + int shotTotal = 0; + int shotX = 0; + int shotY = 0; + int shotZ = 0; + int targetX = 0; + int targetY = 0; + int targetZ = 0; + int tries = 0; + String[] userCoordinates; + String userResponse = ""; + + System.out.print("DIMENSION OF SEARCH AREA? "); + searchArea = Integer.parseInt(scan.nextLine()); + System.out.println(""); + + shotTotal = (int) (Math.log10(searchArea) / Math.log10(2)) + 1; + + System.out.println("YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER"); + System.out.println("AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE. YOUR"); + System.out.println("MISSION IS TO DESTROY IT. YOU HAVE " + shotTotal + " SHOTS."); + System.out.println("SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A"); + System.out.println("TRIO OF NUMBERS -- THE FIRST TWO ARE THE"); + System.out.println("SURFACE COORDINATES; THE THIRD IS THE DEPTH."); + + // Begin outer while loop + while (true) { + + System.out.println(""); + System.out.println("GOOD LUCK !"); + System.out.println(""); + + targetX = (int) ((searchArea + 1) * Math.random()); + targetY = (int) ((searchArea + 1) * Math.random()); + targetZ = (int) ((searchArea + 1) * Math.random()); + + // Begin loop through all shots + for (shotNum = 1; shotNum <= shotTotal; shotNum++) { + + // Get user input + System.out.println(""); + System.out.print("TRIAL # " + shotNum + "? "); + userResponse = scan.nextLine(); + + // Split on commas + userCoordinates = userResponse.split(","); + + // Assign to integer variables + shotX = Integer.parseInt(userCoordinates[0].trim()); + shotY = Integer.parseInt(userCoordinates[1].trim()); + shotZ = Integer.parseInt(userCoordinates[2].trim()); + + // Win condition + if (Math.abs(shotX - targetX) + Math.abs(shotY - targetY) + + Math.abs(shotZ - targetZ) == 0) { + + System.out.println("B O O M ! ! YOU FOUND IT IN" + shotNum + " TRIES!"); + break; + + } + + this.getReport(targetX, targetY, targetZ, shotX, shotY, shotZ); + + System.out.println(""); + + } // End loop through all shots + + if (shotNum > shotTotal) { + + System.out.println(""); + System.out.println("YOU HAVE BEEN TORPEDOED! ABANDON SHIP!"); + System.out.println("THE SUBMARINE WAS AT " + targetX + "," + targetY + "," + targetZ); + } + + System.out.println(""); + System.out.println(""); + System.out.print("ANOTHER GAME (Y OR N)? "); + userResponse = scan.nextLine(); + + if (!userResponse.toUpperCase().equals("Y")) { + System.out.print("OK. HOPE YOU ENJOYED YOURSELF."); + return; + } + + } // End outer while loop + + } // End of method startGame + + public void getReport(int a, int b, int c, int x, int y, int z) { + + System.out.print("SONAR REPORTS SHOT WAS "); + + // Handle y coordinate + if (y > b) { + + System.out.print("NORTH"); + + } else if (y < b) { + + System.out.print("SOUTH"); + } + + // Handle x coordinate + if (x > a) { + + System.out.print("EAST"); + + } else if (x < a) { + + System.out.print("WEST"); + } + + if ((y != b) || (x != a)) { + + System.out.print(" AND"); + } + + // Handle depth + if (z > c) { + + System.out.println(" TOO LOW."); + + } else if (z < c) { + + System.out.println(" TOO HIGH."); + + } else { + + System.out.println(" DEPTH OK."); + } + + return; + + } // End of method getReport + + public static void main(String[] args) { + + DepthCharge game = new DepthCharge(); + game.play(); + + } // End of method main + +} // End of class DepthCharge diff --git a/41 Guess/perl/guess.pl b/41 Guess/perl/guess.pl new file mode 100644 index 00000000..f16a3e84 --- /dev/null +++ b/41 Guess/perl/guess.pl @@ -0,0 +1,52 @@ +#!/usr/bin/perl +use strict; + +my $L1; +while (1) { + print ' 'x 33 . "GUESS\n"; + print ' 'x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; + print "\n"; print "\n"; print "\n"; + print "THIS IS A NUMBER GUESSING GAME. I'LL THINK\n"; + print "OF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT.\n"; + print "THEN YOU HAVE TO GUESS WHAT IT IS.\n"; + print "\n"; + print "WHAT LIMIT DO YOU WANT"; + print "? "; chomp(my $L = ); + print "\n"; + $L1= int(log($L)/log(2))+1; + + while (1) { + print "I'M THINKING OF A NUMBER BETWEEN 1 AND $L\n"; + my $G=0; + print "NOW YOU TRY TO GUESS WHAT IT IS.\n"; + my $M=int($L*rand(1)+1); + my $N=0; + while (1) { + while (1) { + print "? "; chomp($N = ); + if ($N>0) { last; } + } + $G=$G+1; + if ($N==$M) { last; } + if ($N>$M) { print "TOO HIGH. TRY A SMALLER ANSWER.\n"; } + else { print "TOO LOW. TRY A BIGGER ANSWER.\n"; } + } + print "THAT'S IT! YOU GOT IT IN $G TRIES.\n"; + if ($G<$L1) { print "VERY "; } + if ($G<=$L1) { print "GOOD.\n"; } + if ($G>$L1) { print "YOU SHOULD HAVE BEEN ABLE TO GET IT IN ONLY $L1\n"; } + &ENTERS(); + } + } + +exit; + + +sub ENTERS { #GOSUB 70 + for (my $H=1; $H<=5; $H++) { + print "\n"; + } + return; + } + + diff --git a/44 Hangman/java/Hangman.java b/44 Hangman/java/Hangman.java new file mode 100644 index 00000000..56567bb2 --- /dev/null +++ b/44 Hangman/java/Hangman.java @@ -0,0 +1,245 @@ +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Scanner; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * HANGMAN + * + * Converted from BASIC to Java by Aldrin Misquitta (@aldrinm) + */ +public class Hangman { + + //50 word list + private final static List words = List.of( + "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"); + + public static void main(String[] args) { + Scanner scan = new Scanner(System.in); + + printIntro(); + + int[] usedWords = new int[50]; + int roundNumber = 1; + int totalWords = words.size(); + boolean continueGame; + + do { + if (roundNumber > totalWords) { + System.out.println("\nYOU DID ALL THE WORDS!!"); + break; + } + + int randomWordIndex; + do { + randomWordIndex = ((int) (totalWords * Math.random())) + 1; + } while (usedWords[randomWordIndex] == 1); + usedWords[randomWordIndex] = 1; + + boolean youWon = playRound(scan, words.get(randomWordIndex - 1)); + if (!youWon) { + System.out.print("\nYOU MISSED THAT ONE. DO YOU WANT ANOTHER WORD? "); + } else { + System.out.print("\nWANT ANOTHER WORD? "); + } + final String anotherWordChoice = scan.next(); + continueGame = "YES".equals(anotherWordChoice); + roundNumber++; + } while (continueGame); + + System.out.println("\nIT'S BEEN FUN! BYE FOR NOW."); + } + + private static boolean playRound(Scanner scan, String word) { + char[] letters; + char[] discoveredLetters; + int misses = 0; + Set lettersUsed = new LinkedHashSet<>();//LinkedHashSet maintains the order of characters inserted + + String[][] hangmanPicture = new String[12][12]; + //initialize the hangman picture + for (int i = 0; i < hangmanPicture.length; i++) { + for (int j = 0; j < hangmanPicture[i].length; j++) { + hangmanPicture[i][j] = " "; + } + } + for (int i = 0; i < hangmanPicture.length; i++) { + hangmanPicture[i][0] = "X"; + } + for (int i = 0; i < 7; i++) { + hangmanPicture[0][i] = "X"; + } + hangmanPicture[1][6] = "X"; + + int totalWordGuesses = 0; //guesses + + int len = word.length(); + letters = word.toCharArray(); + + discoveredLetters = new char[len]; + Arrays.fill(discoveredLetters, '-'); + + boolean validNextGuess = false; + char guessLetter = ' '; + + while (misses < 10) { + while (!validNextGuess) { + printLettersUsed(lettersUsed); + printDiscoveredLetters(discoveredLetters); + + System.out.print("WHAT IS YOUR GUESS? "); + var tmpRead = scan.next(); + guessLetter = tmpRead.charAt(0); + if (lettersUsed.contains(guessLetter)) { + System.out.println("YOU GUESSED THAT LETTER BEFORE!"); + } else { + lettersUsed.add(guessLetter); + totalWordGuesses++; + validNextGuess = true; + } + } + + if (word.indexOf(guessLetter) >= 0) { + //replace all occurrences in D$ with G$ + for (int i = 0; i < letters.length; i++) { + if (letters[i] == guessLetter) { + discoveredLetters[i] = guessLetter; + } + } + //check if the word is fully discovered + boolean isWordDiscovered = true; + for (char discoveredLetter : discoveredLetters) { + if (discoveredLetter == '-') { + isWordDiscovered = false; + break; + } + } + if (isWordDiscovered) { + System.out.println("YOU FOUND THE WORD!"); + return true; + } + + printDiscoveredLetters(discoveredLetters); + System.out.print("WHAT IS YOUR GUESS FOR THE WORD? "); + final String wordGuess = scan.next(); + if (wordGuess.equals(word)) { + System.out.printf("RIGHT!! IT TOOK YOU %s GUESSES!", totalWordGuesses); + return true; + } else { + System.out.println("WRONG. TRY ANOTHER LETTER."); + } + } else { + misses = misses + 1; + System.out.println("\n\nSORRY, THAT LETTER ISN'T IN THE WORD."); + drawHangman(misses, hangmanPicture); + } + validNextGuess = false; + } + + System.out.printf("SORRY, YOU LOSE. THE WORD WAS %s", word); + return false; + } + + private static void drawHangman(int m, String[][] hangmanPicture) { + switch (m) { + case 1: + System.out.println("FIRST, WE DRAW A HEAD"); + hangmanPicture[2][5] = "-"; + hangmanPicture[2][6] = "-"; + hangmanPicture[2][7] = "-"; + hangmanPicture[3][4] = "("; + hangmanPicture[3][5] = "."; + hangmanPicture[3][7] = "."; + hangmanPicture[3][8] = ")"; + hangmanPicture[4][5] = "-"; + hangmanPicture[4][6] = "-"; + hangmanPicture[4][7] = "-"; + break; + case 2: + System.out.println("NOW WE DRAW A BODY."); + for (var i = 5; i <= 8; i++) { + hangmanPicture[i][6] = "X"; + } + break; + case 3: + System.out.println("NEXT WE DRAW AN ARM."); + for (int i = 3; i <= 6; i++) { + hangmanPicture[i][i - 1] = "\\"; + } + break; + case 4: + System.out.println("THIS TIME IT'S THE OTHER ARM."); + hangmanPicture[3][10] = "/"; + hangmanPicture[4][9] = "/"; + hangmanPicture[5][8] = "/"; + hangmanPicture[6][7] = "/"; + break; + case 5: + System.out.println("NOW, LET'S DRAW THE RIGHT LEG."); + hangmanPicture[9][5] = "/"; + hangmanPicture[10][4] = "/"; + break; + case 6: + System.out.println("THIS TIME WE DRAW THE LEFT LEG."); + hangmanPicture[9][7] = "\\"; + hangmanPicture[10][8] = "\\"; + break; + case 7: + System.out.println("NOW WE PUT UP A HAND."); + hangmanPicture[2][10] = "\\"; + break; + case 8: + System.out.println("NEXT THE OTHER HAND."); + hangmanPicture[2][2] = "/"; + break; + case 9: + System.out.println("NOW WE DRAW ONE FOOT"); + hangmanPicture[11][9] = "\\"; + hangmanPicture[11][10] = "-"; + break; + case 10: + System.out.println("HERE'S THE OTHER FOOT -- YOU'RE HUNG!!"); + hangmanPicture[11][2] = "-"; + hangmanPicture[11][3] = "/"; + break; + } + for (int i = 0; i <= 11; i++) { + for (int j = 0; j <= 11; j++) { + System.out.print(hangmanPicture[i][j]); + } + System.out.print("\n"); + } + + } + + private static void printDiscoveredLetters(char[] D$) { + System.out.println(new String(D$)); + System.out.println("\n"); + } + + private static void printLettersUsed(Set lettersUsed) { + System.out.println("\nHERE ARE THE LETTERS YOU USED:"); + System.out.println(lettersUsed.stream() + .map(Object::toString).collect(Collectors.joining(","))); + System.out.println("\n"); + } + + private static void printIntro() { + System.out.println(" HANGMAN"); + System.out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println("\n\n\n"); + } + +} + + diff --git a/70 Poetry/java/Poetry.java b/70 Poetry/java/Poetry.java new file mode 100644 index 00000000..80be8f21 --- /dev/null +++ b/70 Poetry/java/Poetry.java @@ -0,0 +1,266 @@ +/** + * Game of Poetry + *

+ * Based on the BASIC game of Poetry here + * https://github.com/coding-horror/basic-computer-games/blob/main/70%20Poetry/poetry.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. + * + * Converted from BASIC to Java by Darren Cardenas. + */ + +public class Poetry { + + private final static double COMMA_RATE = 0.19; + private final static double SPACE_RATE = 0.65; + private final static int PARAGRAPH_RATE = 20; + + private enum Step { + WORD_GROUP1, WORD_GROUP2, WORD_GROUP3, WORD_GROUP4, RANDOMIZE_COMMA, + RANDOMIZE_WHITESPACE, RANDOMIZE_COUNTERS + } + + public void play() { + + showIntro(); + startGame(); + + } // End of method play + + private void showIntro() { + + System.out.println(" ".repeat(29) + "POETRY"); + System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println("\n\n"); + + } // End of method showIntro + + private void startGame() { + + int groupIndex = 0; + int paragraphIndex = 0; + int punctuationIndex = 0; + int wordIndex = 1; + + Step nextStep = Step.WORD_GROUP1; + + // Begin outer while loop + while (true) { + + switch (nextStep) { + + case WORD_GROUP1: + + if (wordIndex == 1) { + + System.out.print("MIDNIGHT DREARY"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 2) { + + System.out.print("FIERY EYES"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 3) { + + System.out.print("BIRD OR FIEND"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 4) { + + System.out.print("THING OF EVIL"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 5) { + + System.out.print("PROPHET"); + nextStep = Step.RANDOMIZE_COMMA; + } + break; + + case WORD_GROUP2: + + if (wordIndex == 1) { + + System.out.print("BEGUILING ME"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 2) { + + System.out.print("THRILLED ME"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 3) { + + System.out.print("STILL SITTING...."); + nextStep = Step.RANDOMIZE_WHITESPACE; + + } else if (wordIndex == 4) { + + System.out.print("NEVER FLITTING"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 5) { + + System.out.print("BURNED"); + nextStep = Step.RANDOMIZE_COMMA; + } + break; + + case WORD_GROUP3: + + if (wordIndex == 1) { + + System.out.print("AND MY SOUL"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 2) { + + System.out.print("DARKNESS THERE"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 3) { + + System.out.print("SHALL BE LIFTED"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 4) { + + System.out.print("QUOTH THE RAVEN"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 5) { + + if (punctuationIndex != 0) { + + System.out.print("SIGN OF PARTING"); + } + + nextStep = Step.RANDOMIZE_COMMA; + } + break; + + case WORD_GROUP4: + + if (wordIndex == 1) { + + System.out.print("NOTHING MORE"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 2) { + + System.out.print("YET AGAIN"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 3) { + + System.out.print("SLOWLY CREEPING"); + nextStep = Step.RANDOMIZE_WHITESPACE; + + } else if (wordIndex == 4) { + + System.out.print("...EVERMORE"); + nextStep = Step.RANDOMIZE_COMMA; + + } else if (wordIndex == 5) { + + System.out.print("NEVERMORE"); + nextStep = Step.RANDOMIZE_COMMA; + } + break; + + case RANDOMIZE_COMMA: + + // Insert commas + if ((punctuationIndex != 0) && (Math.random() <= COMMA_RATE)) { + + System.out.print(","); + punctuationIndex = 2; + } + nextStep = Step.RANDOMIZE_WHITESPACE; + break; + + + case RANDOMIZE_WHITESPACE: + + // Insert spaces + if (Math.random() <= SPACE_RATE) { + + System.out.print(" "); + punctuationIndex++; + + } + // Insert newlines + else { + + System.out.println(""); + punctuationIndex = 0; + } + nextStep = Step.RANDOMIZE_COUNTERS; + break; + + case RANDOMIZE_COUNTERS: + + wordIndex = (int)((int)(10 * Math.random()) / 2) + 1; + + groupIndex++; + paragraphIndex++; + + if ((punctuationIndex == 0) && (groupIndex % 2 == 0)) { + + System.out.print(" "); + } + + if (groupIndex == 1) { + + nextStep = Step.WORD_GROUP1; + + } else if (groupIndex == 2) { + + nextStep = Step.WORD_GROUP2; + + } else if (groupIndex == 3) { + + nextStep = Step.WORD_GROUP3; + + } else if (groupIndex == 4) { + + nextStep = Step.WORD_GROUP4; + + } else if (groupIndex == 5) { + + groupIndex = 0; + System.out.println(""); + + if (paragraphIndex > PARAGRAPH_RATE) { + + System.out.println(""); + punctuationIndex = 0; + paragraphIndex = 0; + nextStep = Step.WORD_GROUP2; + + } else { + + nextStep = Step.RANDOMIZE_COUNTERS; + } + } + break; + + default: + System.out.println("INVALID STEP"); + break; + } + + } // End outer while loop + + } // End of method startGame + + public static void main(String[] args) { + + Poetry poetry = new Poetry(); + poetry.play(); + + } // End of method main + +} // End of class Poetry diff --git a/70 Poetry/perl/poetry.pl b/70 Poetry/perl/poetry.pl new file mode 100644 index 00000000..610938b6 --- /dev/null +++ b/70 Poetry/perl/poetry.pl @@ -0,0 +1,81 @@ +#!/usr/bin/perl +#use strict; +# Automatic converted by bas2perl.pl +# Too much spaguetti code to be properly converted. + + +print ' 'x 30 . "POETRY\n"; +print ' 'x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; +print "\n"; print "\n"; print "\n"; +Line90: +if ($I==1) { goto Line100; } elsif ($I==2) { goto Line101; } elsif ($I==3) { goto Line102; } elsif ($I==4) { goto Line103; } elsif ($I==5) { goto Line104; } ; +Line100: +print "MIDNIGHT DREARY"; goto Line210; +Line101: +print "FIERY EYES"; goto Line210; +Line102: +print "BIRD OR FIEND"; goto Line210; +Line103: +print "THING OF EVIL"; goto Line210; +Line104: +print "PROPHET"; goto Line210; +Line110: +if ($I==1) { goto Line111; } elsif ($I==2) { goto Line112; } elsif ($I==3) { goto Line113; } elsif ($I==4) { goto Line114; } elsif ($I==5) { goto Line115; } ; +Line111: +print "BEGUILING ME"; $U=2; goto Line210; +Line112: +print "THRILLED ME"; goto Line210; +Line113: +print "STILL SITTING...."; goto Line212; +Line114: +print "NEVER FLITTING"; $U=2; goto Line210; +Line115: +print "BURNED"; goto Line210; +Line120: +if ($I==1) { goto Line121; } elsif ($I==2) { goto Line122; } elsif ($I==3) { goto Line123; } elsif ($I==4) { goto Line124; } elsif ($I==5) { goto Line125; } ; +Line121: +print "AND MY SOUL"; goto Line210; +Line122: +print "DARKNESS THERE"; goto Line210; +Line123: +print "SHALL BE LIFTED"; goto Line210; +Line124: +print "QUOTH THE RAVEN"; goto Line210; +Line125: +if ($U==0) { goto Line210; } +print "SIGN OF PARTING"; goto Line210; +Line130: +if ($I==1) { goto Line131; } elsif ($I==2) { goto Line132; } elsif ($I==3) { goto Line133; } elsif ($I==4) { goto Line134; } elsif ($I==5) { goto Line135; } ; +Line131: +print "NOTHING MORE"; goto Line210; +Line132: +print "YET AGAIN"; goto Line210; +Line133: +print "SLOWLY CREEPING"; goto Line210; +Line134: +print "...EVERMORE"; goto Line210; +Line135: +print "NEVERMORE"; +Line210: +if ($U==0 || rand(1)>.19) { goto Line212; } +print ","; $U=2; +Line212: +if (rand(1)>.65) { goto Line214; } +print " "; $U=$U+1; goto Line215; +Line214: +print "\n"; $U=0; +Line215: +$I=int(int(10*rand(1))/2)+1; +$J=$J+1; $K=$K+1; +if ($U>0 || int($J/2)!=$J/2) { goto Line240; } +print " "; +Line240: +if ($J==1) { goto Line90; } elsif ($J==2) { goto Line110; } elsif ($J==3) { goto Line120; } elsif ($J==4) { goto Line130; } elsif ($J==5) { goto Line250; } ; +Line250: +$J=0; print "\n"; if ($K>20) { goto Line270; } +goto Line215; +Line270: +print "\n"; $U=0; $K=0; goto Line110; +exit; + + diff --git a/70 Poetry/poetry.pl b/70 Poetry/poetry.pl new file mode 100644 index 00000000..610938b6 --- /dev/null +++ b/70 Poetry/poetry.pl @@ -0,0 +1,81 @@ +#!/usr/bin/perl +#use strict; +# Automatic converted by bas2perl.pl +# Too much spaguetti code to be properly converted. + + +print ' 'x 30 . "POETRY\n"; +print ' 'x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; +print "\n"; print "\n"; print "\n"; +Line90: +if ($I==1) { goto Line100; } elsif ($I==2) { goto Line101; } elsif ($I==3) { goto Line102; } elsif ($I==4) { goto Line103; } elsif ($I==5) { goto Line104; } ; +Line100: +print "MIDNIGHT DREARY"; goto Line210; +Line101: +print "FIERY EYES"; goto Line210; +Line102: +print "BIRD OR FIEND"; goto Line210; +Line103: +print "THING OF EVIL"; goto Line210; +Line104: +print "PROPHET"; goto Line210; +Line110: +if ($I==1) { goto Line111; } elsif ($I==2) { goto Line112; } elsif ($I==3) { goto Line113; } elsif ($I==4) { goto Line114; } elsif ($I==5) { goto Line115; } ; +Line111: +print "BEGUILING ME"; $U=2; goto Line210; +Line112: +print "THRILLED ME"; goto Line210; +Line113: +print "STILL SITTING...."; goto Line212; +Line114: +print "NEVER FLITTING"; $U=2; goto Line210; +Line115: +print "BURNED"; goto Line210; +Line120: +if ($I==1) { goto Line121; } elsif ($I==2) { goto Line122; } elsif ($I==3) { goto Line123; } elsif ($I==4) { goto Line124; } elsif ($I==5) { goto Line125; } ; +Line121: +print "AND MY SOUL"; goto Line210; +Line122: +print "DARKNESS THERE"; goto Line210; +Line123: +print "SHALL BE LIFTED"; goto Line210; +Line124: +print "QUOTH THE RAVEN"; goto Line210; +Line125: +if ($U==0) { goto Line210; } +print "SIGN OF PARTING"; goto Line210; +Line130: +if ($I==1) { goto Line131; } elsif ($I==2) { goto Line132; } elsif ($I==3) { goto Line133; } elsif ($I==4) { goto Line134; } elsif ($I==5) { goto Line135; } ; +Line131: +print "NOTHING MORE"; goto Line210; +Line132: +print "YET AGAIN"; goto Line210; +Line133: +print "SLOWLY CREEPING"; goto Line210; +Line134: +print "...EVERMORE"; goto Line210; +Line135: +print "NEVERMORE"; +Line210: +if ($U==0 || rand(1)>.19) { goto Line212; } +print ","; $U=2; +Line212: +if (rand(1)>.65) { goto Line214; } +print " "; $U=$U+1; goto Line215; +Line214: +print "\n"; $U=0; +Line215: +$I=int(int(10*rand(1))/2)+1; +$J=$J+1; $K=$K+1; +if ($U>0 || int($J/2)!=$J/2) { goto Line240; } +print " "; +Line240: +if ($J==1) { goto Line90; } elsif ($J==2) { goto Line110; } elsif ($J==3) { goto Line120; } elsif ($J==4) { goto Line130; } elsif ($J==5) { goto Line250; } ; +Line250: +$J=0; print "\n"; if ($K>20) { goto Line270; } +goto Line215; +Line270: +print "\n"; $U=0; $K=0; goto Line110; +exit; + + diff --git a/73 Reverse/java/Reverse.java b/73 Reverse/java/Reverse.java new file mode 100644 index 00000000..22c1d073 --- /dev/null +++ b/73 Reverse/java/Reverse.java @@ -0,0 +1,242 @@ +import java.util.Scanner; +import java.lang.Math; + +/** + * Game of Reverse + *

+ * Based on the BASIC game of Reverse here + * https://github.com/coding-horror/basic-computer-games/blob/main/73%20Reverse/reverse.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. + * + * Converted from BASIC to Java by Darren Cardenas. + */ + +public class Reverse { + + private final int NUMBER_COUNT = 9; + + private final Scanner scan; // For user input + + private enum Step { + INITIALIZE, PERFORM_REVERSE, TRY_AGAIN, END_GAME + } + + public Reverse() { + + scan = new Scanner(System.in); + + } // End of constructor Reverse + + public void play() { + + showIntro(); + startGame(); + + } // End of method play + + private static void showIntro() { + + System.out.println(" ".repeat(31) + "REVERSE"); + System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println("\n\n"); + System.out.println("REVERSE -- A GAME OF SKILL"); + System.out.println(""); + + } // End of method showIntro + + private void startGame() { + + int index = 0; + int numMoves = 0; + int numReverse = 0; + int tempVal = 0; + int[] numList = new int[NUMBER_COUNT + 1]; + + Step nextStep = Step.INITIALIZE; + + String userResponse = ""; + + System.out.print("DO YOU WANT THE RULES? "); + userResponse = scan.nextLine(); + + if (!userResponse.toUpperCase().equals("NO")) { + + this.printRules(); + } + + // Begin outer while loop + while (true) { + + // Begin outer switch + switch (nextStep) { + + case INITIALIZE: + + // Make a random list of numbers + numList[1] = (int)((NUMBER_COUNT - 1) * Math.random() + 2); + + for (index = 2; index <= NUMBER_COUNT; index++) { + + // Keep generating lists if there are duplicates + while (true) { + + numList[index] = (int)(NUMBER_COUNT * Math.random() + 1); + + // Search for duplicates + if (!this.findDuplicates(numList, index)) { + break; + } + } + } + + System.out.println(""); + System.out.println("HERE WE GO ... THE LIST IS:"); + + numMoves = 0; + + this.printBoard(numList); + + nextStep = Step.PERFORM_REVERSE; + break; + + case PERFORM_REVERSE: + + System.out.print("HOW MANY SHALL I REVERSE? "); + numReverse = Integer.parseInt(scan.nextLine()); + + if (numReverse == 0) { + + nextStep = Step.TRY_AGAIN; + + } else if (numReverse > NUMBER_COUNT) { + + System.out.println("OOPS! TOO MANY! I CAN REVERSE AT MOST " + NUMBER_COUNT); + nextStep = Step.PERFORM_REVERSE; + + } else { + + numMoves++; + + for (index = 1; index <= (int)(numReverse / 2.0); index++) { + + tempVal = numList[index]; + numList[index] = numList[numReverse - index + 1]; + numList[numReverse - index + 1] = tempVal; + } + + this.printBoard(numList); + + nextStep = Step.TRY_AGAIN; + + // Check for a win + for (index = 1; index <= NUMBER_COUNT; index++) { + + if (numList[index] != index) { + nextStep = Step.PERFORM_REVERSE; + } + } + + if (nextStep == Step.TRY_AGAIN) { + System.out.println("YOU WON IT IN " + numMoves + " MOVES!!!"); + System.out.println(""); + } + } + break; + + case TRY_AGAIN: + + System.out.println(""); + System.out.print("TRY AGAIN (YES OR NO)? "); + userResponse = scan.nextLine(); + + if (userResponse.toUpperCase().equals("YES")) { + nextStep = Step.INITIALIZE; + } else { + nextStep = Step.END_GAME; + } + break; + + case END_GAME: + + System.out.println(""); + System.out.println("O.K. HOPE YOU HAD FUN!!"); + return; + + default: + + System.out.println("INVALID STEP"); + break; + + } // End outer switch + + } // End outer while loop + + } // End of method startGame + + public boolean findDuplicates(int[] board, int length) { + + int index = 0; + + for (index = 1; index <= length - 1; index++) { + + // Identify duplicates + if (board[length] == board[index]) { + + return true; // Found a duplicate + } + } + + return false; // No duplicates found + + } // End of method findDuplicates + + public void printBoard(int[] board) { + + int index = 0; + + System.out.println(""); + + for (index = 1; index <= NUMBER_COUNT; index++) { + + System.out.format("%2d", board[index]); + } + + System.out.println("\n"); + + } // End of method printBoard + + public void printRules() { + + System.out.println(""); + System.out.println("THIS IS THE GAME OF 'REVERSE'. TO WIN, ALL YOU HAVE"); + System.out.println("TO DO IS ARRANGE A LIST OF NUMBERS (1 THROUGH " + NUMBER_COUNT + ")"); + System.out.println("IN NUMERICAL ORDER FROM LEFT TO RIGHT. TO MOVE, YOU"); + System.out.println("TELL ME HOW MANY NUMBERS (COUNTING FROM THE LEFT) TO"); + System.out.println("REVERSE. FOR EXAMPLE, IF THE CURRENT LIST IS:"); + System.out.println(""); + System.out.println("2 3 4 5 1 6 7 8 9"); + System.out.println(""); + System.out.println("AND YOU REVERSE 4, THE RESULT WILL BE:"); + System.out.println(""); + System.out.println("5 4 3 2 1 6 7 8 9"); + System.out.println(""); + System.out.println("NOW IF YOU REVERSE 5, YOU WIN!"); + System.out.println(""); + System.out.println("1 2 3 4 5 6 7 8 9"); + System.out.println(""); + System.out.println("NO DOUBT YOU WILL LIKE THIS GAME, BUT"); + System.out.println("IF YOU WANT TO QUIT, REVERSE 0 (ZERO)."); + System.out.println(""); + + } // End of method printRules + + public static void main(String[] args) { + + Reverse game = new Reverse(); + game.play(); + + } // End of method main + +} // End of class Reverse diff --git a/82 Stars/csharp/Stars.sln b/82 Stars/csharp/Stars.sln new file mode 100644 index 00000000..5f85e6b7 --- /dev/null +++ b/82 Stars/csharp/Stars.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stars", "Stars\Stars.csproj", "{5832C21C-4DE5-475E-893D-745DA15F1AAC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|x64.ActiveCfg = Debug|Any CPU + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|x64.Build.0 = Debug|Any CPU + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|x86.ActiveCfg = Debug|Any CPU + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|x86.Build.0 = Debug|Any CPU + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|Any CPU.Build.0 = Release|Any CPU + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|x64.ActiveCfg = Release|Any CPU + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|x64.Build.0 = Release|Any CPU + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|x86.ActiveCfg = Release|Any CPU + {5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/82 Stars/csharp/Stars/Game.cs b/82 Stars/csharp/Stars/Game.cs new file mode 100644 index 00000000..7045fe4b --- /dev/null +++ b/82 Stars/csharp/Stars/Game.cs @@ -0,0 +1,94 @@ +using System; + +namespace Stars +{ + internal class Game + { + private readonly int _maxNumber; + private readonly int _maxGuessCount; + private readonly Random _random; + + public Game(int maxNumber, int maxGuessCount) + { + _maxNumber = maxNumber; + _maxGuessCount = maxGuessCount; + _random = new Random(); + } + + internal void DisplayInstructions() + { + if (Input.GetString("Do you want instructions? ").Equals("N", StringComparison.InvariantCultureIgnoreCase)) + { + return; + } + + Console.WriteLine($"I am thinking of a number between 1 and {_maxNumber}."); + Console.WriteLine("Try to guess my number. After you guess, I"); + Console.WriteLine("will type one or more stars (*). The more"); + Console.WriteLine("stars I type, the close you are to my number."); + Console.WriteLine("One star (*) means far away, seven stars (*******)"); + Console.WriteLine($"means really close! You get {_maxGuessCount} guesses."); + } + + internal void Play() + { + Console.WriteLine(); + Console.WriteLine(); + + var target = _random.Next(_maxNumber) + 1; + + Console.WriteLine("Ok, I am thinking of a number. Start guessing."); + + AcceptGuesses(target); + } + + private void AcceptGuesses(int target) + { + for (int guessCount = 1; guessCount <= _maxGuessCount; guessCount++) + { + Console.WriteLine(); + var guess = Input.GetNumber("Your guess? "); + + if (guess == target) + { + DisplayWin(guessCount); + return; + } + + DisplayStars(target, guess); + } + + DisplayLoss(target); + } + + private static void DisplayStars(int target, float guess) + { + var stars = Math.Abs(guess - target) switch + { + >= 64 => "*", + >= 32 => "**", + >= 16 => "***", + >= 8 => "****", + >= 4 => "*****", + >= 2 => "******", + _ => "*******" + }; + + Console.WriteLine(stars); + } + + private static void DisplayWin(int guessCount) + { + Console.WriteLine(); + Console.WriteLine(new string('*', 79)); + Console.WriteLine(); + Console.WriteLine($"You got it in {guessCount} guesses!!! Let's play again..."); + } + + private void DisplayLoss(int target) + { + Console.WriteLine(); + Console.WriteLine($"Sorry, that's {_maxGuessCount} guesses. The number was {target}."); + } + } +} \ No newline at end of file diff --git a/82 Stars/csharp/Stars/Input.cs b/82 Stars/csharp/Stars/Input.cs new file mode 100644 index 00000000..6ba6e3a1 --- /dev/null +++ b/82 Stars/csharp/Stars/Input.cs @@ -0,0 +1,31 @@ +using System; + +namespace Stars +{ + internal static class Input + { + // Float, because that's what the BASIC input operation returns + internal static float GetNumber(string prompt) + { + Console.Write(prompt); + + while (true) + { + var response = Console.ReadLine(); + if (float.TryParse(response, out var value)) + { + return value; + } + + Console.WriteLine("!Number expected - retry input line"); + Console.Write("? "); + } + } + + internal static string GetString(string prompt) + { + Console.Write(prompt); + return Console.ReadLine(); + } + } +} diff --git a/82 Stars/csharp/Stars/Program.cs b/82 Stars/csharp/Stars/Program.cs new file mode 100644 index 00000000..b072595c --- /dev/null +++ b/82 Stars/csharp/Stars/Program.cs @@ -0,0 +1,30 @@ +using System; + +namespace Stars +{ + class Program + { + static void Main(string[] args) + { + DisplayTitle(); + + var game = new Game(maxNumber: 100, maxGuessCount: 7); + + game.DisplayInstructions(); + + while (true) + { + game.Play(); + } + } + + private static void DisplayTitle() + { + Console.WriteLine(" Stars"); + Console.WriteLine(" Creative Computing Morristown, New Jersey"); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine(); + } + } +} diff --git a/82 Stars/csharp/Stars/Stars.csproj b/82 Stars/csharp/Stars/Stars.csproj new file mode 100644 index 00000000..20827042 --- /dev/null +++ b/82 Stars/csharp/Stars/Stars.csproj @@ -0,0 +1,8 @@ + + + + Exe + net5.0 + + + diff --git a/84 Super Star Trek/csharp/Game.cs b/84 Super Star Trek/csharp/Game.cs index f2e1c819..274e2948 100644 --- a/84 Super Star Trek/csharp/Game.cs +++ b/84 Super Star Trek/csharp/Game.cs @@ -4,7 +4,6 @@ using SuperStarTrek.Resources; using SuperStarTrek.Space; using SuperStarTrek.Systems; using SuperStarTrek.Systems.ComputerFunctions; -using static System.StringComparison; namespace SuperStarTrek { @@ -22,17 +21,18 @@ namespace SuperStarTrek private int _initialKlingonCount; private Enterprise _enterprise; - public Game() + internal Game(Output output, Input input, Random random) { - _output = new Output(); - _input = new Input(_output); - _random = new Random(); + _output = output; + _input = input; + _random = random; } - public float Stardate => _currentStardate; - public float StardatesRemaining => _finalStarDate - _currentStardate; + internal float Stardate => _currentStardate; - public void DoIntroduction() + internal float StardatesRemaining => _finalStarDate - _currentStardate; + + internal void DoIntroduction() { _output.Write(Strings.Title); @@ -44,16 +44,13 @@ namespace SuperStarTrek } } - public void Play() + internal void Play() { Initialise(); var gameOver = false; - var newQuadrantText = Strings.StartText; while (!gameOver) { - _enterprise.Quadrant.Display(Strings.NowEntering); - var command = _input.GetCommand(); var result = _enterprise.Execute(command); @@ -120,7 +117,7 @@ namespace SuperStarTrek private Quadrant BuildCurrentQuadrant() => new Quadrant(_galaxy[_currentQuadrant], _enterprise, _random, _galaxy, _input, _output); - public bool Replay() => _galaxy.StarbaseCount > 0 && _input.GetString(Strings.ReplayPrompt, "Aye"); + internal bool Replay() => _galaxy.StarbaseCount > 0 && _input.GetString(Strings.ReplayPrompt, "Aye"); private bool CheckIfStranded() { diff --git a/84 Super Star Trek/csharp/Input.cs b/84 Super Star Trek/csharp/Input.cs index 3011738b..2b37b2ba 100644 --- a/84 Super Star Trek/csharp/Input.cs +++ b/84 Super Star Trek/csharp/Input.cs @@ -10,24 +10,24 @@ namespace SuperStarTrek { private readonly Output _output; - public Input(Output output) + internal Input(Output output) { _output = output; } - public void WaitForAnyKeyButEnter(string prompt) + internal void WaitForAnyKeyButEnter(string prompt) { _output.Write($"Hit any key but Enter {prompt} "); while (Console.ReadKey(intercept: true).Key == ConsoleKey.Enter); } - public string GetString(string prompt) + internal string GetString(string prompt) { _output.Prompt(prompt); return Console.ReadLine(); } - public float GetNumber(string prompt) + internal float GetNumber(string prompt) { _output.Prompt(prompt); @@ -44,24 +44,24 @@ namespace SuperStarTrek } } - public (float X, float Y) GetCoordinates(string prompt) + internal (float X, float Y) GetCoordinates(string prompt) { _output.Prompt($"{prompt} (X,Y)"); var responses = ReadNumbers(2); return (responses[0], responses[1]); } - public bool TryGetNumber(string prompt, float minValue, float maxValue, out float value) + internal bool TryGetNumber(string prompt, float minValue, float maxValue, out float value) { value = GetNumber($"{prompt} ({minValue}-{maxValue})"); return value >= minValue && value <= maxValue; } - internal bool GetString(string replayPrompt, string trueValue) - => GetString(replayPrompt).Equals(trueValue, InvariantCultureIgnoreCase); + internal bool GetString(string replayPrompt, string trueValue) => + GetString(replayPrompt).Equals(trueValue, InvariantCultureIgnoreCase); - public Command GetCommand() + internal Command GetCommand() { while(true) { @@ -82,7 +82,7 @@ namespace SuperStarTrek } } - public bool TryGetCourse(string prompt, string officer, out Course course) + internal bool TryGetCourse(string prompt, string officer, out Course course) { if (!TryGetNumber(prompt, 1, 9, out var direction)) { @@ -95,7 +95,7 @@ namespace SuperStarTrek return true; } - public bool GetYesNo(string prompt, YesNoMode mode) + internal bool GetYesNo(string prompt, YesNoMode mode) { _output.Prompt($"{prompt} (Y/N)"); var response = Console.ReadLine().ToUpperInvariant(); @@ -150,7 +150,7 @@ namespace SuperStarTrek return numbers; } - public enum YesNoMode + internal enum YesNoMode { TrueOnY, FalseOnN diff --git a/84 Super Star Trek/csharp/Objects/Enterprise.cs b/84 Super Star Trek/csharp/Objects/Enterprise.cs index 4adf81df..ac9e8112 100644 --- a/84 Super Star Trek/csharp/Objects/Enterprise.cs +++ b/84 Super Star Trek/csharp/Objects/Enterprise.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using SuperStarTrek.Commands; using SuperStarTrek.Resources; using SuperStarTrek.Space; @@ -31,22 +30,33 @@ namespace SuperStarTrek.Objects _input = input; } - public Quadrant Quadrant => _quadrant; - public Coordinates QuadrantCoordinates => _quadrant.Coordinates; - public Coordinates SectorCoordinates { get; private set; } + internal Quadrant Quadrant => _quadrant; - public string Condition => GetCondition(); - public LibraryComputer Computer => (LibraryComputer)_commandExecutors[Command.COM]; - public ShieldControl ShieldControl => (ShieldControl)_commandExecutors[Command.SHE]; - public float Energy => TotalEnergy - ShieldControl.ShieldEnergy; - public float TotalEnergy { get; private set; } - public int DamagedSystemCount => _systems.Count(s => s.IsDamaged); - public IEnumerable Systems => _systems; - public PhotonTubes PhotonTubes => (PhotonTubes)_commandExecutors[Command.TOR]; - public bool IsDocked => _quadrant.EnterpriseIsNextToStarbase; - public bool IsStranded => TotalEnergy < 10 || Energy < 10 && ShieldControl.IsDamaged; + internal Coordinates QuadrantCoordinates => _quadrant.Coordinates; - public Enterprise Add(Subsystem system) + internal Coordinates SectorCoordinates { get; private set; } + + internal string Condition => GetCondition(); + + internal LibraryComputer Computer => (LibraryComputer)_commandExecutors[Command.COM]; + + internal ShieldControl ShieldControl => (ShieldControl)_commandExecutors[Command.SHE]; + + internal float Energy => TotalEnergy - ShieldControl.ShieldEnergy; + + internal float TotalEnergy { get; private set; } + + internal int DamagedSystemCount => _systems.Count(s => s.IsDamaged); + + internal IEnumerable Systems => _systems; + + internal PhotonTubes PhotonTubes => (PhotonTubes)_commandExecutors[Command.TOR]; + + internal bool IsDocked => _quadrant.EnterpriseIsNextToStarbase; + + internal bool IsStranded => TotalEnergy < 10 || Energy < 10 && ShieldControl.IsDamaged; + + internal Enterprise Add(Subsystem system) { _systems.Add(system); _commandExecutors[system.Command] = system; @@ -54,38 +64,29 @@ namespace SuperStarTrek.Objects return this; } - public void StartIn(Quadrant quadrant) + internal void StartIn(Quadrant quadrant) { _quadrant = quadrant; quadrant.Display(Strings.StartText); } private string GetCondition() => - (_quadrant.HasKlingons, Energy / _maxEnergy) switch + IsDocked switch { - (true, _) => "*Red*", - (_, < 0.1f) => "Yellow", - _ => "Green" + true => "Docked", + false when _quadrant.HasKlingons => "*Red*", + false when Energy / _maxEnergy < 0.1f => "Yellow", + false => "Green" }; - public CommandResult Execute(Command command) + internal CommandResult Execute(Command command) { if (command == Command.XXX) { return CommandResult.GameOver; } return _commandExecutors[command].ExecuteCommand(_quadrant); } - public void Refuel() => TotalEnergy = _maxEnergy; - - internal bool Recognises(string command) - { - throw new NotImplementedException(); - } - - internal string GetCommandList() - { - throw new NotImplementedException(); - } + internal void Refuel() => TotalEnergy = _maxEnergy; public override string ToString() => "<*>"; diff --git a/84 Super Star Trek/csharp/Objects/Klingon.cs b/84 Super Star Trek/csharp/Objects/Klingon.cs index 4e277b07..1b55940a 100644 --- a/84 Super Star Trek/csharp/Objects/Klingon.cs +++ b/84 Super Star Trek/csharp/Objects/Klingon.cs @@ -7,19 +7,20 @@ namespace SuperStarTrek.Objects { private readonly Random _random; - public Klingon(Coordinates sector, Random random) + internal Klingon(Coordinates sector, Random random) { Sector = sector; _random = random; Energy = _random.GetFloat(100, 300); } - public float Energy { get; private set; } - public Coordinates Sector { get; private set; } + internal float Energy { get; private set; } + + internal Coordinates Sector { get; private set; } public override string ToString() => "+K+"; - public CommandResult FireOn(Enterprise enterprise) + internal CommandResult FireOn(Enterprise enterprise) { var attackStrength = _random.GetFloat(); var distanceToEnterprise = Sector.GetDistanceTo(enterprise.SectorCoordinates); diff --git a/84 Super Star Trek/csharp/Objects/Starbase.cs b/84 Super Star Trek/csharp/Objects/Starbase.cs index 4befa73a..c9abb870 100644 --- a/84 Super Star Trek/csharp/Objects/Starbase.cs +++ b/84 Super Star Trek/csharp/Objects/Starbase.cs @@ -9,7 +9,7 @@ namespace SuperStarTrek.Objects private readonly Output _output; private readonly float _repairDelay; - public Starbase(Coordinates sector, Random random, Input input, Output output) + internal Starbase(Coordinates sector, Random random, Input input, Output output) { Sector = sector; _repairDelay = random.GetFloat() * 0.5f; @@ -18,6 +18,7 @@ namespace SuperStarTrek.Objects } internal Coordinates Sector { get; } + public override string ToString() => ">!<"; internal bool TryRepair(Enterprise enterprise, out float repairTime) diff --git a/84 Super Star Trek/csharp/Output.cs b/84 Super Star Trek/csharp/Output.cs index ed960eea..6a377bce 100644 --- a/84 Super Star Trek/csharp/Output.cs +++ b/84 Super Star Trek/csharp/Output.cs @@ -4,33 +4,33 @@ namespace SuperStarTrek { internal class Output { - public Output Write(string text) + internal Output Write(string text) { Console.Write(text); return this; } - public Output Write(string format, params object[] args) + internal Output Write(string format, params object[] args) { Console.Write(format, args); return this; } - public Output WriteLine(string text = "") + internal Output WriteLine(string text = "") { Console.WriteLine(text); return this; } - public Output NextLine() + internal Output NextLine() { Console.WriteLine(); return this; } - public Output Prompt(string text = "") + internal Output Prompt(string text = "") { Console.Write($"{text}? "); return this; diff --git a/84 Super Star Trek/csharp/Program.cs b/84 Super Star Trek/csharp/Program.cs index 7f8395a6..7080df29 100644 --- a/84 Super Star Trek/csharp/Program.cs +++ b/84 Super Star Trek/csharp/Program.cs @@ -29,8 +29,11 @@ namespace SuperStarTrek { static void Main() { - var foo = Utils.DirectionAndDistance.From(1,1).To(4,5); - var game = new Game(); + var output = new Output(); + var input = new Input(output); + var random = new Random(); + + var game = new Game(output, input, random); game.DoIntroduction(); diff --git a/84 Super Star Trek/csharp/Random.cs b/84 Super Star Trek/csharp/Random.cs index 5ed47805..cd0ef230 100644 --- a/84 Super Star Trek/csharp/Random.cs +++ b/84 Super Star Trek/csharp/Random.cs @@ -4,22 +4,22 @@ namespace SuperStarTrek { internal class Random { - private static readonly System.Random _random = new(); + private readonly System.Random _random = new(); - public Coordinates GetCoordinate() => new Coordinates(Get1To8Inclusive() - 1, Get1To8Inclusive() - 1); + internal Coordinates GetCoordinate() => new Coordinates(Get1To8Inclusive() - 1, Get1To8Inclusive() - 1); // Duplicates the algorithm used in the original code to get an integer value from 1 to 8, inclusive: // 475 DEF FNR(R)=INT(RND(R)*7.98+1.01) // Returns a value from 1 to 8, inclusive. // Note there's a slight bias away from the extreme values, 1 and 8. - public int Get1To8Inclusive() => (int)(GetFloat() * 7.98 + 1.01); + internal int Get1To8Inclusive() => (int)(GetFloat() * 7.98 + 1.01); - public int GetInt(int inclusiveMinValue, int exclusiveMaxValue) => + internal int GetInt(int inclusiveMinValue, int exclusiveMaxValue) => _random.Next(inclusiveMinValue, exclusiveMaxValue); - public float GetFloat() => (float)_random.NextDouble(); + internal float GetFloat() => (float)_random.NextDouble(); - public float GetFloat(float inclusiveMinValue, float exclusiveMaxValue) + internal float GetFloat(float inclusiveMinValue, float exclusiveMaxValue) => GetFloat() * (exclusiveMaxValue - inclusiveMinValue) + inclusiveMinValue; } } diff --git a/84 Super Star Trek/csharp/Resources/ComputerFunctions.txt b/84 Super Star Trek/csharp/Resources/ComputerFunctions.txt deleted file mode 100644 index 4827b0fe..00000000 --- a/84 Super Star Trek/csharp/Resources/ComputerFunctions.txt +++ /dev/null @@ -1,9 +0,0 @@ - -Functions available from Library-Computer: - 0 = Cumulative galactic record - 1 = Status report - 2 = Photon torpedo data - 3 = Starbase nav data - 4 = Direction/distance calculator - 5 = Galaxy 'region name' map - diff --git a/84 Super Star Trek/csharp/Resources/NowEntering.txt b/84 Super Star Trek/csharp/Resources/NowEntering.txt index 915b526f..6545f9c4 100644 --- a/84 Super Star Trek/csharp/Resources/NowEntering.txt +++ b/84 Super Star Trek/csharp/Resources/NowEntering.txt @@ -1,2 +1,3 @@ + Now entering {0} quadrant . . . diff --git a/84 Super Star Trek/csharp/Resources/ShieldsDropped.txt b/84 Super Star Trek/csharp/Resources/ShieldsDropped.txt index acc87f59..9135e8b4 100644 --- a/84 Super Star Trek/csharp/Resources/ShieldsDropped.txt +++ b/84 Super Star Trek/csharp/Resources/ShieldsDropped.txt @@ -1 +1 @@ -Shields dropped for docking purposes +Shields dropped for docking purposes \ No newline at end of file diff --git a/84 Super Star Trek/csharp/Resources/ShieldsSet.txt b/84 Super Star Trek/csharp/Resources/ShieldsSet.txt new file mode 100644 index 00000000..e3d7efda --- /dev/null +++ b/84 Super Star Trek/csharp/Resources/ShieldsSet.txt @@ -0,0 +1,2 @@ +Deflector control room report: + 'Shields now at {0} units per your command.' diff --git a/84 Super Star Trek/csharp/Resources/Strings.cs b/84 Super Star Trek/csharp/Resources/Strings.cs index ddb768ca..b6cd5486 100644 --- a/84 Super Star Trek/csharp/Resources/Strings.cs +++ b/84 Super Star Trek/csharp/Resources/Strings.cs @@ -6,38 +6,60 @@ namespace SuperStarTrek.Resources { internal static class Strings { - public static string CombatArea => GetResource(); - public static string ComputerFunctions => GetResource(); - public static string Congratulations => GetResource(); - public static string CourtMartial => GetResource(); - public static string Destroyed => GetResource(); - public static string EndOfMission => GetResource(); - public static string Enterprise => GetResource(); - public static string Instructions => GetResource(); - public static string LowShields => GetResource(); - public static string NoEnemyShips => GetResource(); - public static string NoStarbase => GetResource(); - public static string NowEntering => GetResource(); - public static string Orders => GetResource(); - public static string PermissionDenied => GetResource(); - public static string Protected => GetResource(); - public static string RegionNames => GetResource(); - public static string RelievedOfCommand => GetResource(); - public static string RepairEstimate => GetResource(); - public static string RepairPrompt => GetResource(); - public static string ReplayPrompt => GetResource(); - public static string ShieldsDropped => GetResource(); - public static string ShortRangeSensorsOut => GetResource(); - public static string StartText => GetResource(); - public static string Stranded => GetResource(); - public static string Title => GetResource(); + internal static string CombatArea => GetResource(); + + internal static string Congratulations => GetResource(); + + internal static string CourtMartial => GetResource(); + + internal static string Destroyed => GetResource(); + + internal static string EndOfMission => GetResource(); + + internal static string Enterprise => GetResource(); + + internal static string Instructions => GetResource(); + + internal static string LowShields => GetResource(); + + internal static string NoEnemyShips => GetResource(); + + internal static string NoStarbase => GetResource(); + + internal static string NowEntering => GetResource(); + + internal static string Orders => GetResource(); + + internal static string PermissionDenied => GetResource(); + + internal static string Protected => GetResource(); + + internal static string RegionNames => GetResource(); + + internal static string RelievedOfCommand => GetResource(); + + internal static string RepairEstimate => GetResource(); + + internal static string RepairPrompt => GetResource(); + + internal static string ReplayPrompt => GetResource(); + + internal static string ShieldsDropped => GetResource(); + + internal static string ShieldsSet => GetResource(); + + internal static string ShortRangeSensorsOut => GetResource(); + + internal static string StartText => GetResource(); + + internal static string Stranded => GetResource(); + + internal static string Title => GetResource(); private static string GetResource([CallerMemberName] string name = "") { var streamName = $"SuperStarTrek.Resources.{name}.txt"; - using var stream = Assembly - .GetExecutingAssembly() - .GetManifestResourceStream(streamName); + using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(streamName); using var reader = new StreamReader(stream); return reader.ReadToEnd(); diff --git a/84 Super Star Trek/csharp/Space/Coordinates.cs b/84 Super Star Trek/csharp/Space/Coordinates.cs index 1619d387..7aec927f 100644 --- a/84 Super Star Trek/csharp/Space/Coordinates.cs +++ b/84 Super Star Trek/csharp/Space/Coordinates.cs @@ -7,7 +7,7 @@ namespace SuperStarTrek.Space // Note that the origin is top-left, x increase downwards, and y increases to the right. internal record Coordinates { - public Coordinates(int x, int y) + internal Coordinates(int x, int y) { X = Validated(x, nameof(x)); Y = Validated(y, nameof(y)); @@ -16,12 +16,15 @@ namespace SuperStarTrek.Space SubRegionIndex = Y % 4; } - public int X { get; } - public int Y { get; } - public int RegionIndex { get; } - public int SubRegionIndex { get; } + internal int X { get; } + + internal int Y { get; } + + internal int RegionIndex { get; } + + internal int SubRegionIndex { get; } - private int Validated(int value, string argumentName) + private static int Validated(int value, string argumentName) { if (value >= 0 && value <= 7) { return value; } diff --git a/84 Super Star Trek/csharp/Space/Course.cs b/84 Super Star Trek/csharp/Space/Course.cs index a46385c3..b316e4b3 100644 --- a/84 Super Star Trek/csharp/Space/Course.cs +++ b/84 Super Star Trek/csharp/Space/Course.cs @@ -46,6 +46,7 @@ namespace SuperStarTrek.Space } internal float DeltaX { get; } + internal float DeltaY { get; } internal IEnumerable GetSectorsFrom(Coordinates start) @@ -74,16 +75,16 @@ namespace SuperStarTrek.Space return (xComplete && yComplete, new Coordinates(quadrantX, quadrantY), new Coordinates(sectorX, sectorY)); } - private (bool, int, int) GetNewCoordinate(int quadrant, int sector, float sectorsTravelled) + private static (bool, int, int) GetNewCoordinate(int quadrant, int sector, float sectorsTravelled) { var galacticCoordinate = quadrant * 8 + sector + sectorsTravelled; var newQuadrant = (int)(galacticCoordinate / 8); var newSector = (int)(galacticCoordinate - newQuadrant * 8); - if (newSector == -1) + if (newSector < 0) { newQuadrant -= 1; - newSector = 7; + newSector += 8; } return newQuadrant switch diff --git a/84 Super Star Trek/csharp/Space/Galaxy.cs b/84 Super Star Trek/csharp/Space/Galaxy.cs index 63838567..0b348b06 100644 --- a/84 Super Star Trek/csharp/Space/Galaxy.cs +++ b/84 Super Star Trek/csharp/Space/Galaxy.cs @@ -1,7 +1,5 @@ -using System.Collections; using System.Collections.Generic; using System.Linq; -using SuperStarTrek.Objects; using SuperStarTrek.Resources; using static System.StringSplitOptions; @@ -13,7 +11,6 @@ namespace SuperStarTrek.Space private static readonly string[] _regionNames; private static readonly string[] _subRegionIdentifiers; private readonly QuadrantInfo[][] _quadrants; - private readonly Random _random; static Galaxy() { @@ -21,16 +18,14 @@ namespace SuperStarTrek.Space _subRegionIdentifiers = new[] { "I", "II", "III", "IV" }; } - public Galaxy(Random random) + internal Galaxy(Random random) { - _random = random; - _quadrants = Enumerable .Range(0, 8) .Select(x => Enumerable .Range(0, 8) .Select(y => new Coordinates(x, y)) - .Select(c => QuadrantInfo.Create(c, GetQuadrantName(c))) + .Select(c => QuadrantInfo.Create(c, GetQuadrantName(c), random)) .ToArray()) .ToArray(); @@ -46,16 +41,18 @@ namespace SuperStarTrek.Space } } - public QuadrantInfo this[Coordinates coordinate] => _quadrants[coordinate.X][coordinate.Y]; + internal QuadrantInfo this[Coordinates coordinate] => _quadrants[coordinate.X][coordinate.Y]; - public int KlingonCount => _quadrants.SelectMany(q => q).Sum(q => q.KlingonCount); - public int StarbaseCount => _quadrants.SelectMany(q => q).Count(q => q.HasStarbase); - public IEnumerable> Quadrants => _quadrants; + internal int KlingonCount => _quadrants.SelectMany(q => q).Sum(q => q.KlingonCount); + + internal int StarbaseCount => _quadrants.SelectMany(q => q).Count(q => q.HasStarbase); + + internal IEnumerable> Quadrants => _quadrants; private static string GetQuadrantName(Coordinates coordinates) => $"{_regionNames[coordinates.RegionIndex]} {_subRegionIdentifiers[coordinates.SubRegionIndex]}"; - public IEnumerable> GetNeighborhood(Quadrant quadrant) => + internal IEnumerable> GetNeighborhood(Quadrant quadrant) => Enumerable.Range(-1, 3) .Select(dx => dx + quadrant.Coordinates.X) .Select(x => GetNeighborhoodRow(quadrant, x)); diff --git a/84 Super Star Trek/csharp/Space/Quadrant.cs b/84 Super Star Trek/csharp/Space/Quadrant.cs index b333cb7e..694f7fc8 100644 --- a/84 Super Star Trek/csharp/Space/Quadrant.cs +++ b/84 Super Star Trek/csharp/Space/Quadrant.cs @@ -14,9 +14,9 @@ namespace SuperStarTrek.Space private readonly Dictionary _sectors; private readonly Enterprise _enterprise; private readonly Output _output; - private bool _displayed = false; + private bool _entered = false; - public Quadrant( + internal Quadrant( QuadrantInfo info, Enterprise enterprise, Random random, @@ -39,13 +39,19 @@ namespace SuperStarTrek.Space PositionObject(_ => new Star(), _info.StarCount); } - public Coordinates Coordinates => _info.Coordinates; - public bool HasKlingons => _info.KlingonCount > 0; - public int KlingonCount => _info.KlingonCount; - public bool HasStarbase => _info.HasStarbase; - public Starbase Starbase { get; } + internal Coordinates Coordinates => _info.Coordinates; + + internal bool HasKlingons => _info.KlingonCount > 0; + + internal int KlingonCount => _info.KlingonCount; + + internal bool HasStarbase => _info.HasStarbase; + + internal Starbase Starbase { get; } + internal Galaxy Galaxy { get; } - public bool EnterpriseIsNextToStarbase => + + internal bool EnterpriseIsNextToStarbase => _info.HasStarbase && Math.Abs(_enterprise.SectorCoordinates.X - Starbase.Sector.X) <= 1 && Math.Abs(_enterprise.SectorCoordinates.Y - Starbase.Sector.Y) <= 1; @@ -71,9 +77,11 @@ namespace SuperStarTrek.Space internal void Display(string textFormat) { - if (_displayed) { return; } - - _output.Write(textFormat, this); + if (!_entered) + { + _output.Write(textFormat, this); + _entered = true; + } if (_info.KlingonCount > 0) { @@ -82,8 +90,6 @@ namespace SuperStarTrek.Space } _enterprise.Execute(Command.SRS); - - _displayed = true; } internal bool HasObjectAt(Coordinates coordinates) => _sectors.ContainsKey(coordinates); @@ -166,10 +172,10 @@ namespace SuperStarTrek.Space } } - public IEnumerable GetDisplayLines() => Enumerable.Range(0, 8).Select(x => GetDisplayLine(x)); + internal IEnumerable GetDisplayLines() => Enumerable.Range(0, 8).Select(x => GetDisplayLine(x)); - private string GetDisplayLine(int x) - => string.Join( + private string GetDisplayLine(int x) => + string.Join( " ", Enumerable .Range(0, 8) diff --git a/84 Super Star Trek/csharp/Space/QuadrantInfo.cs b/84 Super Star Trek/csharp/Space/QuadrantInfo.cs index 70447250..6a403c2e 100644 --- a/84 Super Star Trek/csharp/Space/QuadrantInfo.cs +++ b/84 Super Star Trek/csharp/Space/QuadrantInfo.cs @@ -1,5 +1,3 @@ -using SuperStarTrek.Objects; - namespace SuperStarTrek.Space { internal class QuadrantInfo @@ -15,15 +13,18 @@ namespace SuperStarTrek.Space HasStarbase = hasStarbase; } - public Coordinates Coordinates { get; } - public string Name { get; } - public int KlingonCount { get; private set; } - public bool HasStarbase { get; private set; } - public int StarCount { get; } + internal Coordinates Coordinates { get; } - public static QuadrantInfo Create(Coordinates coordinates, string name) + internal string Name { get; } + + internal int KlingonCount { get; private set; } + + internal bool HasStarbase { get; private set; } + + internal int StarCount { get; } + + internal static QuadrantInfo Create(Coordinates coordinates, string name, Random random) { - var random = new Random(); var klingonCount = random.GetFloat() switch { > 0.98f => 3, diff --git a/84 Super Star Trek/csharp/Systems/ComputerFunctions/ComputerFunction.cs b/84 Super Star Trek/csharp/Systems/ComputerFunctions/ComputerFunction.cs index 400c1f62..36d9127b 100644 --- a/84 Super Star Trek/csharp/Systems/ComputerFunctions/ComputerFunction.cs +++ b/84 Super Star Trek/csharp/Systems/ComputerFunctions/ComputerFunction.cs @@ -11,6 +11,7 @@ namespace SuperStarTrek.Systems.ComputerFunctions } internal string Description { get; } + protected Output Output { get; } internal abstract void Execute(Quadrant quadrant); diff --git a/84 Super Star Trek/csharp/Systems/ComputerFunctions/DirectionDistanceCalculator.cs b/84 Super Star Trek/csharp/Systems/ComputerFunctions/DirectionDistanceCalculator.cs index ff6239ed..a3679ada 100644 --- a/84 Super Star Trek/csharp/Systems/ComputerFunctions/DirectionDistanceCalculator.cs +++ b/84 Super Star Trek/csharp/Systems/ComputerFunctions/DirectionDistanceCalculator.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; using SuperStarTrek.Objects; using SuperStarTrek.Space; @@ -11,8 +8,8 @@ namespace SuperStarTrek.Systems.ComputerFunctions private readonly Enterprise _enterprise; private readonly Input _input; - public DirectionDistanceCalculator(Enterprise enterprise, Output output, Input input) - : base("Starbase nav data", output) + internal DirectionDistanceCalculator(Enterprise enterprise, Output output, Input input) + : base("Direction/distance calculator", output) { _enterprise = enterprise; _input = input; diff --git a/84 Super Star Trek/csharp/Systems/ComputerFunctions/GalacticReport.cs b/84 Super Star Trek/csharp/Systems/ComputerFunctions/GalacticReport.cs index 8b26cc2e..8be29baf 100644 --- a/84 Super Star Trek/csharp/Systems/ComputerFunctions/GalacticReport.cs +++ b/84 Super Star Trek/csharp/Systems/ComputerFunctions/GalacticReport.cs @@ -6,7 +6,7 @@ namespace SuperStarTrek.Systems.ComputerFunctions { internal abstract class GalacticReport : ComputerFunction { - public GalacticReport(string description, Output output, Galaxy galaxy) + internal GalacticReport(string description, Output output, Galaxy galaxy) : base(description, output) { Galaxy = galaxy; diff --git a/84 Super Star Trek/csharp/Systems/ComputerFunctions/StarbaseDataCalculator.cs b/84 Super Star Trek/csharp/Systems/ComputerFunctions/StarbaseDataCalculator.cs index 0d2c5b50..7a87f970 100644 --- a/84 Super Star Trek/csharp/Systems/ComputerFunctions/StarbaseDataCalculator.cs +++ b/84 Super Star Trek/csharp/Systems/ComputerFunctions/StarbaseDataCalculator.cs @@ -8,7 +8,7 @@ namespace SuperStarTrek.Systems.ComputerFunctions { private readonly Enterprise _enterprise; - public StarbaseDataCalculator(Enterprise enterprise, Output output) + internal StarbaseDataCalculator(Enterprise enterprise, Output output) : base("Starbase nav data", output) { _enterprise = enterprise; diff --git a/84 Super Star Trek/csharp/Systems/ComputerFunctions/StatusReport.cs b/84 Super Star Trek/csharp/Systems/ComputerFunctions/StatusReport.cs index f80ba7bb..26a299a8 100644 --- a/84 Super Star Trek/csharp/Systems/ComputerFunctions/StatusReport.cs +++ b/84 Super Star Trek/csharp/Systems/ComputerFunctions/StatusReport.cs @@ -10,7 +10,7 @@ namespace SuperStarTrek.Systems.ComputerFunctions private readonly Galaxy _galaxy; private readonly Enterprise _enterprise; - public StatusReport(Game game, Galaxy galaxy, Enterprise enterprise, Output output) + internal StatusReport(Game game, Galaxy galaxy, Enterprise enterprise, Output output) : base("Status report", output) { _game = game; diff --git a/84 Super Star Trek/csharp/Systems/ComputerFunctions/TorpedoDataCalculator.cs b/84 Super Star Trek/csharp/Systems/ComputerFunctions/TorpedoDataCalculator.cs index 09c71859..ec837fc4 100644 --- a/84 Super Star Trek/csharp/Systems/ComputerFunctions/TorpedoDataCalculator.cs +++ b/84 Super Star Trek/csharp/Systems/ComputerFunctions/TorpedoDataCalculator.cs @@ -8,7 +8,7 @@ namespace SuperStarTrek.Systems.ComputerFunctions { private readonly Enterprise _enterprise; - public TorpedoDataCalculator(Enterprise enterprise, Output output) + internal TorpedoDataCalculator(Enterprise enterprise, Output output) : base("Photon torpedo data", output) { _enterprise = enterprise; diff --git a/84 Super Star Trek/csharp/Systems/DamageControl.cs b/84 Super Star Trek/csharp/Systems/DamageControl.cs index 6ce41bbe..8fbf21d3 100644 --- a/84 Super Star Trek/csharp/Systems/DamageControl.cs +++ b/84 Super Star Trek/csharp/Systems/DamageControl.cs @@ -9,7 +9,7 @@ namespace SuperStarTrek.Systems private readonly Enterprise _enterprise; private readonly Output _output; - public DamageControl(Enterprise enterprise, Output output) + internal DamageControl(Enterprise enterprise, Output output) : base("Damage Control", Command.DAM, output) { _enterprise = enterprise; @@ -40,7 +40,7 @@ namespace SuperStarTrek.Systems return CommandResult.Ok; } - public void WriteDamageReport() + internal void WriteDamageReport() { _output.NextLine().WriteLine("Device State of Repair"); foreach (var system in _enterprise.Systems) diff --git a/84 Super Star Trek/csharp/Systems/LibraryComputer.cs b/84 Super Star Trek/csharp/Systems/LibraryComputer.cs index b2e47d2a..df5c6868 100644 --- a/84 Super Star Trek/csharp/Systems/LibraryComputer.cs +++ b/84 Super Star Trek/csharp/Systems/LibraryComputer.cs @@ -10,7 +10,7 @@ namespace SuperStarTrek.Systems private readonly Input _input; private readonly ComputerFunction[] _functions; - public LibraryComputer(Output output, Input input, params ComputerFunction[] functions) + internal LibraryComputer(Output output, Input input, params ComputerFunction[] functions) : base("Library-Computer", Command.COM, output) { _output = output; diff --git a/84 Super Star Trek/csharp/Systems/LongRangeSensors.cs b/84 Super Star Trek/csharp/Systems/LongRangeSensors.cs index 84ed7a87..a873eeba 100644 --- a/84 Super Star Trek/csharp/Systems/LongRangeSensors.cs +++ b/84 Super Star Trek/csharp/Systems/LongRangeSensors.cs @@ -1,10 +1,5 @@ - -using System; -using System.Collections.Generic; using System.Linq; using SuperStarTrek.Commands; -using SuperStarTrek.Objects; -using SuperStarTrek.Resources; using SuperStarTrek.Space; namespace SuperStarTrek.Systems @@ -14,7 +9,7 @@ namespace SuperStarTrek.Systems private readonly Galaxy _galaxy; private readonly Output _output; - public LongRangeSensors(Galaxy galaxy, Output output) + internal LongRangeSensors(Galaxy galaxy, Output output) : base("Long Range Sensors", Command.LRS, output) { _galaxy = galaxy; diff --git a/84 Super Star Trek/csharp/Systems/PhaserControl.cs b/84 Super Star Trek/csharp/Systems/PhaserControl.cs index 18566294..9207ad94 100644 --- a/84 Super Star Trek/csharp/Systems/PhaserControl.cs +++ b/84 Super Star Trek/csharp/Systems/PhaserControl.cs @@ -13,7 +13,7 @@ namespace SuperStarTrek.Systems private readonly Input _input; private readonly Random _random; - public PhaserControl(Enterprise enterprise, Output output, Input input, Random random) + internal PhaserControl(Enterprise enterprise, Output output, Input input, Random random) : base("Phaser Control", Command.PHA, output) { _enterprise = enterprise; diff --git a/84 Super Star Trek/csharp/Systems/PhotonTubes.cs b/84 Super Star Trek/csharp/Systems/PhotonTubes.cs index a807d16c..37613037 100644 --- a/84 Super Star Trek/csharp/Systems/PhotonTubes.cs +++ b/84 Super Star Trek/csharp/Systems/PhotonTubes.cs @@ -11,7 +11,7 @@ namespace SuperStarTrek.Systems private readonly Output _output; private readonly Input _input; - public PhotonTubes(int tubeCount, Enterprise enterprise, Output output, Input input) + internal PhotonTubes(int tubeCount, Enterprise enterprise, Output output, Input input) : base("Photon Tubes", Command.TOR, output) { TorpedoCount = _tubeCount = tubeCount; @@ -20,7 +20,7 @@ namespace SuperStarTrek.Systems _input = input; } - public int TorpedoCount { get; private set; } + internal int TorpedoCount { get; private set; } protected override bool CanExecuteCommand() => HasTorpedoes() && IsOperational("{name} are not operational"); diff --git a/84 Super Star Trek/csharp/Systems/ShieldControl.cs b/84 Super Star Trek/csharp/Systems/ShieldControl.cs index a7518359..de4f44d9 100644 --- a/84 Super Star Trek/csharp/Systems/ShieldControl.cs +++ b/84 Super Star Trek/csharp/Systems/ShieldControl.cs @@ -1,5 +1,6 @@ using SuperStarTrek.Commands; using SuperStarTrek.Objects; +using SuperStarTrek.Resources; using SuperStarTrek.Space; namespace SuperStarTrek.Systems @@ -10,7 +11,7 @@ namespace SuperStarTrek.Systems private readonly Output _output; private readonly Input _input; - public ShieldControl(Enterprise enterprise, Output output, Input input) + internal ShieldControl(Enterprise enterprise, Output output, Input input) : base("Shield Control", Command.SHE, output) { _enterprise = enterprise; @@ -18,7 +19,7 @@ namespace SuperStarTrek.Systems _input = input; } - public float ShieldEnergy { get; set; } + internal float ShieldEnergy { get; set; } protected override bool CanExecuteCommand() => IsOperational("{name} inoperable"); @@ -30,6 +31,7 @@ namespace SuperStarTrek.Systems if (Validate(requested)) { ShieldEnergy = requested; + _output.Write(Strings.ShieldsSet, requested); } else { diff --git a/84 Super Star Trek/csharp/Systems/ShortRangeSensors.cs b/84 Super Star Trek/csharp/Systems/ShortRangeSensors.cs index ad3929d1..c37028cb 100644 --- a/84 Super Star Trek/csharp/Systems/ShortRangeSensors.cs +++ b/84 Super Star Trek/csharp/Systems/ShortRangeSensors.cs @@ -16,7 +16,7 @@ namespace SuperStarTrek.Systems private readonly Game _game; private readonly Output _output; - public ShortRangeSensors(Enterprise enterprise, Galaxy galaxy, Game game, Output output) + internal ShortRangeSensors(Enterprise enterprise, Galaxy galaxy, Game game, Output output) : base("Short Range Sensors", Command.SRS, output) { _enterprise = enterprise; @@ -47,7 +47,7 @@ namespace SuperStarTrek.Systems return CommandResult.Ok; } - public IEnumerable GetStatusLines() + internal IEnumerable GetStatusLines() { yield return $"Stardate {_game.Stardate}"; yield return $"Condition {_enterprise.Condition}"; diff --git a/84 Super Star Trek/csharp/Systems/Subsystem.cs b/84 Super Star Trek/csharp/Systems/Subsystem.cs index 9e5f3570..5c11e656 100644 --- a/84 Super Star Trek/csharp/Systems/Subsystem.cs +++ b/84 Super Star Trek/csharp/Systems/Subsystem.cs @@ -1,4 +1,3 @@ -using System; using SuperStarTrek.Commands; using SuperStarTrek.Space; @@ -16,10 +15,13 @@ namespace SuperStarTrek.Systems _output = output; } - public string Name { get; } - public float Condition { get; private set; } - public bool IsDamaged => Condition < 0; - public Command Command { get; } + internal string Name { get; } + + internal float Condition { get; private set; } + + internal bool IsDamaged => Condition < 0; + + internal Command Command { get; } protected virtual bool CanExecuteCommand() => true; @@ -34,12 +36,12 @@ namespace SuperStarTrek.Systems return true; } - public CommandResult ExecuteCommand(Quadrant quadrant) + internal CommandResult ExecuteCommand(Quadrant quadrant) => CanExecuteCommand() ? ExecuteCommandCore(quadrant) : CommandResult.Ok; protected abstract CommandResult ExecuteCommandCore(Quadrant quadrant); - public virtual void Repair() + internal virtual void Repair() { if (IsDamaged) { @@ -47,7 +49,7 @@ namespace SuperStarTrek.Systems } } - public virtual bool Repair(float repairWorkDone) + internal virtual bool Repair(float repairWorkDone) { if (IsDamaged) { diff --git a/84 Super Star Trek/csharp/Systems/WarpEngines.cs b/84 Super Star Trek/csharp/Systems/WarpEngines.cs index 0dcf396c..096d0e43 100644 --- a/84 Super Star Trek/csharp/Systems/WarpEngines.cs +++ b/84 Super Star Trek/csharp/Systems/WarpEngines.cs @@ -1,6 +1,7 @@ using System; using SuperStarTrek.Commands; using SuperStarTrek.Objects; +using SuperStarTrek.Resources; using SuperStarTrek.Space; namespace SuperStarTrek.Systems @@ -11,7 +12,7 @@ namespace SuperStarTrek.Systems private readonly Output _output; private readonly Input _input; - public WarpEngines(Enterprise enterprise, Output output, Input input) + internal WarpEngines(Enterprise enterprise, Output output, Input input) : base("Warp Engines", Command.NAV, output) { _enterprise = enterprise; @@ -39,6 +40,8 @@ namespace SuperStarTrek.Systems _enterprise.PhotonTubes.ReplenishTorpedoes(); } + _enterprise.Quadrant.Display(Strings.NowEntering); + return CommandResult.Elapsed(timeElapsed); } diff --git a/84 Super Star Trek/csharp/Utils/DirectionAndDistance.cs b/84 Super Star Trek/csharp/Utils/DirectionAndDistance.cs index 3fa9f4b8..e4b1a2fa 100644 --- a/84 Super Star Trek/csharp/Utils/DirectionAndDistance.cs +++ b/84 Super Star Trek/csharp/Utils/DirectionAndDistance.cs @@ -14,13 +14,13 @@ namespace SuperStarTrek.Utils _fromY = fromY; } - public static DirectionAndDistance From(Coordinates coordinates) => From(coordinates.X, coordinates.Y); + internal static DirectionAndDistance From(Coordinates coordinates) => From(coordinates.X, coordinates.Y); - public static DirectionAndDistance From(float x, float y) => new DirectionAndDistance(x, y); + internal static DirectionAndDistance From(float x, float y) => new DirectionAndDistance(x, y); - public (float Direction, float Distance) To(Coordinates coordinates) => To(coordinates.X, coordinates.Y); + internal (float Direction, float Distance) To(Coordinates coordinates) => To(coordinates.X, coordinates.Y); - public (float Direction, float Distance) To(float x, float y) + internal (float Direction, float Distance) To(float x, float y) { var deltaX = x - _fromX; var deltaY = y - _fromY; @@ -45,7 +45,7 @@ namespace SuperStarTrek.Utils // 8430 PRINT"DIRECTION =";C1+(((ABS(X)-ABS(A))+ABS(X))/ABS(X)):GOTO8460 // 8450 PRINT"DIRECTION =";C1+(ABS(X)/ABS(A)) // 8460 PRINT"DISTANCE =";SQR(X^2+A^2):IFH8=1THEN1990 - private float GetDirection(float deltaX, float deltaY) + private static float GetDirection(float deltaX, float deltaY) { var deltaXDominant = Math.Abs(deltaX) > Math.Abs(deltaY); var fractionalPart = deltaXDominant ? deltaY / deltaX : -deltaX / deltaY; @@ -59,7 +59,7 @@ namespace SuperStarTrek.Utils return direction < 1 ? direction + 8 : direction; } - private float GetDistance(float deltaX, float deltaY) => + private static float GetDistance(float deltaX, float deltaY) => (float)Math.Sqrt(Math.Pow(deltaX, 2) + Math.Pow(deltaY, 2)); } } \ No newline at end of file