From 5ac95df4184a7effc39255d9736d59b8c09c8d1d Mon Sep 17 00:00:00 2001 From: NezumiRonin Date: Tue, 9 Mar 2021 21:59:33 -0600 Subject: [PATCH 001/337] Create russianroulette.pl Horrible use of gotos in PERL (or any language), but it was converted automatically with a Perl Script. --- 76 Russian Roulette/perl/russianroulette.pl | 39 +++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 76 Russian Roulette/perl/russianroulette.pl diff --git a/76 Russian Roulette/perl/russianroulette.pl b/76 Russian Roulette/perl/russianroulette.pl new file mode 100644 index 00000000..0fa0cff7 --- /dev/null +++ b/76 Russian Roulette/perl/russianroulette.pl @@ -0,0 +1,39 @@ +#!/usr/bin/perl +#use strict; +# Automatic converted by bas2perl.pl + +print ' 'x28 . "RUSSIAN ROULETTE\n"; +print ' 'x15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; +print "\n"; print "\n"; print "\n"; +print "THIS IS A GAME OF >>>>>>>>>>RUSSIAN ROULETTE.\n"; +Line10: +print "\n"; print "HERE IS A REVOLVER.\n"; +Line20: +print "TYPE '1' TO SPIN CHAMBER AND PULL TRIGGER.\n"; +print "TYPE '2' TO GIVE UP.\n"; +print "GO"; +$N=0; +Line30: +print "? "; chomp($I = ); +if ($I ne 2) { goto Line35; } +print " CHICKEN!!!!!\n"; +goto Line72; +Line35: +$N=$N+1; +if (rand(1)>.833333) { goto Line70; } +if ($N>10) { goto Line80; } +print "- CLICK -\n"; +print "\n"; goto Line30; +Line70: +print " BANG!!!!! YOU'RE DEAD!\n"; +print "CONDOLENCES WILL BE SENT TO YOUR RELATIVES.\n"; +Line72: +print "\n"; print "\n"; print "\n"; +print "...NEXT VICTIM...\n"; goto Line20; +Line80: +print "YOU WIN!!!!!\n"; +print "LET SOMEONE ELSE BLOW HIS BRAINS OUT.\n"; +goto Line10; +exit; + + From e5c7625101ab8dcd1dce20d70d5beab7d633d16e Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sun, 2 Jan 2022 22:31:41 +0000 Subject: [PATCH 002/337] Typo vs. original listing screenshot --- 27_Civil_War/civilwar.bas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/27_Civil_War/civilwar.bas b/27_Civil_War/civilwar.bas index 63597944..f8fe9701 100644 --- a/27_Civil_War/civilwar.bas +++ b/27_Civil_War/civilwar.bas @@ -216,7 +216,7 @@ 2280 PRINT "CASUALTIES",C5,C6 2290 PRINT "DESERTIONS",INT(E),INT(E2) 2300 PRINT -2310 IF B$ <> "YES" THEN 2350 +2310 IF B$ <> "YES" THEN 2530 2320 PRINT "COMPARED TO THE ACTUAL CASUALTIES AT "C$ 2330 PRINT "CONFEDERATE:"INT(100*(C5/C1)+.5)"% OF THE ORIGINAL" 2340 PRINT "UNION: "INT(100*(C6/C2)+.5)"% OF THE ORIGINAL" From 6c9e90752fc251dced4389e3b8eeb4812bb43494 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sun, 2 Jan 2022 22:37:49 +0000 Subject: [PATCH 003/337] Create .gitignore --- 27_Civil_War/java/.gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 27_Civil_War/java/.gitignore diff --git a/27_Civil_War/java/.gitignore b/27_Civil_War/java/.gitignore new file mode 100644 index 00000000..a87dc8b2 --- /dev/null +++ b/27_Civil_War/java/.gitignore @@ -0,0 +1,3 @@ +*.class +*.iml +.idea/ \ No newline at end of file From e2d2cfcc8449cba7fe86c7ba44238d5d0fc8d817 Mon Sep 17 00:00:00 2001 From: Josh Gribbon Date: Sun, 2 Jan 2022 20:55:24 -0500 Subject: [PATCH 004/337] Add script to find missing implementations --- find-missing-implementations.js | 85 +++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 find-missing-implementations.js diff --git a/find-missing-implementations.js b/find-missing-implementations.js new file mode 100644 index 00000000..04cf3f84 --- /dev/null +++ b/find-missing-implementations.js @@ -0,0 +1,85 @@ +/** + * Program to find games that are missing solutions in a given language + * + * Scan each game folder, check for a folder for each language, and also make + * sure there's at least one file of the expected extension and not just a + * readme or something + */ + +const fs = require("fs"); +const glob = require("glob"); + +// relative path to the repository root +const ROOT_PATH = "."; + +const languages = [ + { name: "csharp", extension: "cs" }, + { name: "java", extension: "java" }, + { name: "javascript", extension: "js" }, + { name: "pascal", extension: "pas" }, + { name: "perl", extension: "pl" }, + { name: "python", extension: "py" }, + { name: "ruby", extension: "rb" }, + { name: "vbnet", extension: "vb" }, +]; + +const getFilesRecursive = async (path, extension) => { + return new Promise((resolve, reject) => { + glob(`${path}/**/*.${extension}`, (err, matches) => { + if (err) { + reject(err); + } + resolve(matches); + }); + }); +}; + +const getPuzzleFolders = () => { + return fs + .readdirSync(ROOT_PATH, { withFileTypes: true }) + .filter((dirEntry) => dirEntry.isDirectory()) + .filter((dirEntry) => ![".git", "node_modules"].includes(dirEntry.name)) + .map((dirEntry) => dirEntry.name); +}; + +(async () => { + let missingGames = {}; + let missingLanguageCounts = {}; + const puzzles = getPuzzleFolders(); + for (const puzzle of puzzles) { + for (const { name: language, extension } of languages) { + const files = await getFilesRecursive( + `${ROOT_PATH}/${puzzle}/${language}`, + extension + ); + if (files.length === 0) { + if (!missingGames[puzzle]) { + missingGames[puzzle] = []; + } + if (!missingLanguageCounts[language]) { + missingLanguageCounts[language] = 0; + } + missingGames[puzzle].push(language); + missingLanguageCounts[language]++; + } + } + } + const missingCount = Object.values(missingGames).flat().length; + if (missingCount === 0) { + console.log("All games have solutions for all languages"); + } else { + console.log(`Missing ${missingCount} implementations:`); + + console.log(`\nMissing languages by game:`); + for (const [puzzle, languages] of Object.entries(missingGames)) { + console.log(`${puzzle}: ${languages.join(", ")}`); + } + + console.log(`\nBy language:`); + for (const [language, count] of Object.entries(missingLanguageCounts)) { + console.log(`${language}: ${count} missing`); + } + } +})(); + +return; From 703b410f2e8a80e294a0ab2d11ea06c559e322bc Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 4 Jan 2022 10:03:48 -0500 Subject: [PATCH 005/337] Create High_IQ.py --- 48_High_IQ/python/High_IQ.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 48_High_IQ/python/High_IQ.py diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/48_High_IQ/python/High_IQ.py @@ -0,0 +1 @@ + From 24313121ca9d0d61b038776f8ee94e74f9497f62 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 4 Jan 2022 12:00:29 -0500 Subject: [PATCH 006/337] Started python function layout Totally not doing this through github.com --- 48_High_IQ/python/High_IQ.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 8b137891..237454b3 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -1 +1,13 @@ +def print_instructions(): + print("This is where you will find instructions") + +def play_game(): + print("Lets play a game") + +def main(): + if input("Do you want instrunctions?").lower().startswith("y"): + print_instructions() + +if __name__ == "__main__": + main() From 651ae5fa8e8600d0679a303f5e549150fc4de077 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 4 Jan 2022 13:59:37 -0500 Subject: [PATCH 007/337] Added Instructions --- 48_High_IQ/python/High_IQ.py | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 237454b3..90dd756a 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -1,12 +1,39 @@ def print_instructions(): - print("This is where you will find instructions") - + print("\n" * 3) + print("HERE IS THE BOARD:\n") + print("\n") + print(" ! ! !\n") + print(" 13 14 15\n") + print("\n") + print(" ! ! !\n") + print(" 22 23 24\n") + print("\n") + print("! ! ! ! ! ! !\n") + print("29 30 31 32 33 34 35\n") + print("\n") + print("! ! ! ! ! ! !\n") + print("38 39 40 41 42 43 44\n") + print("\n") + print("! ! ! ! ! ! !\n") + print("47 48 49 50 51 52 53\n") + print("\n") + print(" ! ! !\n") + print(" 58 59 60\n") + print("\n") + print(" ! ! !\n") + print(" 67 68 69\n") + print("\n") + print("TO SAVE TYPING TIME, A COMPRESSED VERSION OF THE GAME BOARD\n") + print("WILL BE USED DURING PLAY. REFER TO THE ABOVE ONE FOR PEG\n") + print("NUMBERS. OK, LET'S BEGIN.\n") + + def play_game(): print("Lets play a game") def main(): - if input("Do you want instrunctions?").lower().startswith("y"): + if input("Do you want instrunctions?\n").lower().startswith("y"): print_instructions() if __name__ == "__main__": From 497801d6ea3ef32b6534ca294c08e8d0c2ad7dc5 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 4 Jan 2022 14:05:39 -0500 Subject: [PATCH 008/337] no change --- 48_High_IQ/python/High_IQ.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 90dd756a..f7bc9669 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -31,10 +31,10 @@ def print_instructions(): def play_game(): print("Lets play a game") - + def main(): if input("Do you want instrunctions?\n").lower().startswith("y"): print_instructions() - + if __name__ == "__main__": main() From 639a33bdf1de7b7bfc6ec733b53dcc2cf5760e4e Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 4 Jan 2022 14:30:50 -0500 Subject: [PATCH 009/337] So the board was wrong... --- 48_High_IQ/python/High_IQ.py | 97 +++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 40 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index f7bc9669..18d48456 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -1,40 +1,57 @@ - -def print_instructions(): - print("\n" * 3) - print("HERE IS THE BOARD:\n") - print("\n") - print(" ! ! !\n") - print(" 13 14 15\n") - print("\n") - print(" ! ! !\n") - print(" 22 23 24\n") - print("\n") - print("! ! ! ! ! ! !\n") - print("29 30 31 32 33 34 35\n") - print("\n") - print("! ! ! ! ! ! !\n") - print("38 39 40 41 42 43 44\n") - print("\n") - print("! ! ! ! ! ! !\n") - print("47 48 49 50 51 52 53\n") - print("\n") - print(" ! ! !\n") - print(" 58 59 60\n") - print("\n") - print(" ! ! !\n") - print(" 67 68 69\n") - print("\n") - print("TO SAVE TYPING TIME, A COMPRESSED VERSION OF THE GAME BOARD\n") - print("WILL BE USED DURING PLAY. REFER TO THE ABOVE ONE FOR PEG\n") - print("NUMBERS. OK, LET'S BEGIN.\n") - - -def play_game(): - print("Lets play a game") - -def main(): - if input("Do you want instrunctions?\n").lower().startswith("y"): - print_instructions() - -if __name__ == "__main__": - main() + +def new_board(): + board = {} + for i in [13, 14, 15, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 38, 39, 40, 42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 58, 59, 60, 67, 68]: + board[i] = "X" + board[41] = "_" + return board + + +def print_instructions(): + print("\n" * 3) + print("HERE IS THE BOARD:\n") + # print("\n") + # print(" ! ! !\n") + # print(" 13 14 15\n") + # print("\n") + # print(" ! ! !\n") + # print(" 22 23 24\n") + # print("\n") + # print("! ! ! ! ! ! ! ! !\n") + # print("29 30 31 32 33 34 35 36 37\n") + # print("\n") + # print("! ! ! ! ! ! !\n") + # print("38 39 40 41 42 43 44\n") + # print("\n") + # print("! ! ! ! ! ! !\n") + # print("47 48 49 50 51 52 53\n") + # print("\n") + # print(" ! ! !\n") + # print(" 58 59 60\n") + # print("\n") + # print(" ! ! !\n") + # print(" 67 68 69\n") + # print("\n") + print("TO SAVE TYPING TIME, A COMPRESSED VERSION OF THE GAME BOARD\n") + print("WILL BE USED DURING PLAY. REFER TO THE ABOVE ONE FOR PEG\n") + print("NUMBERS. OK, LET'S BEGIN.\n") + +def print_board(board): + print(" " * 3 + board[13] + board[14] + board[15] + " " * 3) + print(" " * 3 + board[22] + board[23] + board[24] + " " * 3) + print(board[29] + board[30] + board[31] + board[32] + board[33] + board[34] + board[35]) + print(board[38] + board[39] + board[40] + board[41] + board[42] + board[43] + board[44]) + print(board[47] + board[48] + board[49] + board[50] + board[51] + board[52] + board[53]) + +def play_game(): + print("Lets play a game") + board = new_board() + print_board(board) + +def main(): + if input("Do you want instrunctions?\n").lower().startswith("y"): + print_instructions() + play_game() + +if __name__ == "__main__": + main() From 518562645afb24e66d0c5e00024d5fa2ad39d6c7 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Wed, 5 Jan 2022 00:00:36 +0000 Subject: [PATCH 010/337] Initial --- 27_Civil_War/java/src/CivilWar.java | 610 ++++++++++++++++++++++++++++ 1 file changed, 610 insertions(+) create mode 100644 27_Civil_War/java/src/CivilWar.java diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java new file mode 100644 index 00000000..fa6cd27a --- /dev/null +++ b/27_Civil_War/java/src/CivilWar.java @@ -0,0 +1,610 @@ +import java.io.PrintStream; +import java.util.List; +import java.util.Scanner; + +import static java.util.stream.Collectors.joining; +import static java.util.stream.IntStream.range; + +@SuppressWarnings("SpellCheckingInspection") +public class CivilWar { + + private final PrintStream out; + private final List data; + + private BattleState currentBattle; + private int R1; + private int R2; + private final int[] strategies; + private int numGenerals; + private final int[] B; + private final int[] F; + private final int[] H; + private final int[] D; + private final double[] O; + private int battleNumber; + private int Y; + private int Y2; + private final ArmyPair totalExpectedCasualties; + private final ArmyPair totalCasualties; + private int excessiveConfederateLosses; + private int excessiveUnionLosses; + private int L; + private int W; + private int M3; + private int M4; + private int Q1; + private int Q2; + private double C6; + private double E2; + private int W0; + private int confedTroops; // M5 + private int unionTroops; // M6 + private boolean confedSurrender; + private boolean unionSurrender; + private int I1; + private int I2; + private double R; + private boolean wantBattleDescriptions; + + /** + * ORIGINAL GAME DESIGN: CRAM, GOODIE, HIBBARD LEXINGTON H.S. + * MODIFICATIONS: G. PAUL, R. HESS (TIES), 1973 + */ + public static void main(String[] args) { + var x = new CivilWar(System.out); + x.showCredits(); + + // LET D=RND(-1) ??? + + System.out.print("DO YOU WANT INSTRUCTIONS? "); + + var terminalInput = new Scanner(System.in); + String s = terminalInput.nextLine(); + switch (s) { + case "Y" -> { + x.showHelp(); + x.gameLoop(); + } + case "N" -> x.gameLoop(); + default -> System.out.println("YES OR NO -- "); + } + } + + private void gameLoop() { + out.println(); + out.println(); + out.println(); + out.print("ARE THERE TWO GENERALS PRESENT (ANSWER YES OR NO)? "); + + var terminalInput = new Scanner(System.in); + String twoGeneralsAnswer = terminalInput.nextLine(); + switch (twoGeneralsAnswer) { + case "YES" -> this.numGenerals = 2; + case "NO" -> { + this.numGenerals = 1; + out.println(); + out.println("YOU ARE THE CONFEDERACY. GOOD LUCK!"); + out.println(); + } + default -> { + // FIXME Retry! + } + } + + out.println("SELECT A BATTLE BY TYPING A NUMBER FROM 1 TO 14 ON"); + out.println("REQUEST. TYPE ANY OTHER NUMBER TO END THE SIMULATION."); + out.println("BUT '0' BRINGS BACK EXACT PREVIOUS BATTLE SITUATION"); + out.println("ALLOWING YOU TO REPLAY IT"); + out.println(); + out.println("NOTE: A NEGATIVE FOOD$ ENTRY CAUSES THE PROGRAM TO "); + out.println("USE THE ENTRIES FROM THE PREVIOUS BATTLE"); + out.println(); + + out.print("AFTER REQUESTING A BATTLE, DO YOU WISH BATTLE DESCRIPTIONS (ANSWER YES OR NO)? "); + String descriptionsAnswer = terminalInput.nextLine(); + this.wantBattleDescriptions = descriptionsAnswer.equals("YES"); + // FIXME Retry if not "YES" or "NO" + + while (true) { + var battle = startBattle(); + if (battle == null) { + break; + } + + this.currentBattle = battle; + + offensiveLogic(battle.data); + + unionStrategy(); + + simulatedLosses(battle.data); + calcLosses(battle); + + reset(); + + if (this.confedSurrender) { + out.println("THE CONFEDERACY HAS SURRENDERED"); + } else if (unionSurrender) { // FIXME Is this actually possible? 2850 + out.println("THE UNION HAS SURRENDERED."); + } + } + + complete(); + } + + private BattleState startBattle() { + out.println(); + out.println(); + out.println(); + out.print("WHICH BATTLE DO YOU WISH TO SIMULATE ? "); + + var terminalInput = new Scanner(System.in); + var battleNumber = terminalInput.nextInt(); + + if (battleNumber == 0 && this.currentBattle != null) { + out.println(this.currentBattle.data.name + " INSTANT REPLAY"); + return this.currentBattle; + } + + if (battleNumber <= 0 || battleNumber > this.data.size()) { + return null; + } + + this.battleNumber = battleNumber; + + var battle = this.data.get(this.battleNumber - 1); + var battleState = new BattleState(battle); + + + excessiveConfederateLosses = 0; + + // INFLATION CALC + // REM - ONLY IN PRINTOUT IS CONFED INFLATION = I1+15% + I1 = 10 + (L - W) * 2; + I2 = 10 + (W - L) * 2; + + // MONEY AVAILABLE + this.D[0] = 100 * (int) Math.floor((battle.troops.confederate * (100.0 - I1) / 2000) * (1 + (R1 - Q1) / (R1 + 1.0)) + .5); + + // MEN AVAILABLE + this.confedTroops = (int) Math.floor(battle.troops.confederate * (1 + (totalExpectedCasualties.confederate - totalCasualties.confederate) / (M3 + 1.0))); + this.unionTroops = (int) Math.floor(battle.troops.union * (1 + (totalExpectedCasualties.union - totalCasualties.union) / (M4 + 1.0))); + battleState.F1 = 5 * battle.troops.confederate / 6.0; + + if (this.numGenerals == 2) { + this.D[1] = 100 * (int) Math.floor((battle.troops.union * (100.0 - I2) / 2000) * (1 + (R2 - Q2) / (R2 + 1.0)) + .5); + } else { + this.D[1] = 100 * (int) Math.floor(battle.troops.union * (100.0 - I2) / 2000 + .5); + } + + out.println(); + out.println(); + out.println(); + out.println(); + out.println(); + out.println("THIS IS THE BATTLE OF " + battle.name); + + if (this.wantBattleDescriptions) { + for (var eachLine : battle.blurb) { + out.println(eachLine); + } + } + + out.println(); + out.println(" CONFEDERACY UNION"); + out.println("MEN " + confedTroops + " " + unionTroops); + out.println("MONEY $ " + this.D[0] + " $ " + this.D[1]); + out.println("INFLATION " + (I1 + 15) + "% " + I2 + "%"); + + // ONLY IN PRINTOUT IS CONFED INFLATION = I1+15% + // IF TWO GENERALS, INPUT CONFED. FIRST + + for (int i = 0; i < numGenerals; i++) { + out.println(); + + if (this.numGenerals == 1 || i == 0) { + out.print("CONFEDERATE GENERAL --- "); + } else { + out.print("UNION GENERAL --- "); + } + + out.println("HOW MUCH DO YOU WISH TO SPEND FOR"); + out.print("- FOOD...... ? "); + var F = terminalInput.nextInt(); + if (F == 0) { + if (this.R1 != 0) { + out.println("ASSUME YOU WANT TO KEEP SAME ALLOCATIONS"); + out.println(); + } + } + + this.F[i] = F; + + out.print("- SALARIES.. ? "); + this.H[i] = terminalInput.nextInt(); + + out.print("- AMMUNITION ? "); + this.B[i] = terminalInput.nextInt(); // FIXME Retry if -ve + + if (this.F[i] + this.H[i] + this.B[i] > this.D[i]) { + out.println("THINK AGAIN! YOU HAVE ONLY $" + this.D[i]); + // FIXME Redo inputs from Food + } + } + + out.println(); + + // Record Morale + out.println(range(0, numGenerals).mapToObj(i -> moraleForArmy(battleState, i)).collect(joining(", "))); + + out.println(); + + return battleState; + } + + private String moraleForArmy(BattleState battleState, int armyIdx) { + var builder = new StringBuilder(); + + if (this.numGenerals == 1 || armyIdx == 0) { + builder.append("CONFEDERATE "); + } else { + builder.append("UNION "); + } + + // FIND MORALE + this.O[armyIdx] = (2 * Math.pow(F[armyIdx], 2) + Math.pow(H[armyIdx], 2)) / Math.pow(battleState.F1, 2) + 1; + if (this.O[armyIdx] >= 10) { + builder.append("MORALE IS HIGH"); + } else if (this.O[armyIdx] >= 5) { + builder.append("MORALE IS FAIR"); + } else { + builder.append("MORALE IS POOR"); + } + + return builder.toString(); + } + + private enum OffensiveStatus { + DEFENSIVE("YOU ARE ON THE DEFENSIVE"), OFFENSIVE("YOU ARE ON THE OFFENSIVE"), BOTH_OFFENSIVE("BOTH SIDES ARE ON THE OFFENSIVE"); + + private final String label; + + OffensiveStatus(String label) { + this.label = label; + } + } + + private void offensiveLogic(HistoricalDatum battle) { + out.print("CONFEDERATE GENERAL---"); + // ACTUAL OFF/DEF BATTLE SITUATION + out.println(battle.offensiveStatus.label); + + // CHOOSE STRATEGIES + + if (numGenerals == 2) { + out.print("CONFEDERATE STRATEGY ? "); + } else { + out.print("YOUR STRATEGY ? "); + } + + var terminalInput = new Scanner(System.in); + Y = terminalInput.nextInt(); + if (Math.abs(Y - 3) >= 3) { + out.println("STRATEGY " + Y + " NOT ALLOWED."); + // FIXME Proper numeric check!! Not abs + // FIXME Retry Y input + } + + if (Y == 5) { // 1970 + confedSurrender = true; + } + } + + // 2070 REM : SIMULATED LOSSES-NORTH + private void simulatedLosses(HistoricalDatum battle) { + C6 = (2.0 * battle.expectedCasualties.union / 5) * (1 + 1.0 / (2 * (Math.abs(Y2 - Y) + 1))); + C6 = C6 * (1.28 + (5.0 * battle.troops.union / 6) / (B[1] + 1)); + C6 = Math.floor(C6 * (1 + 1 / O[1]) + 0.5); + // IF LOSS > MEN PRESENT, RESCALE LOSSES + E2 = 100 / O[1]; + if (Math.floor(C6 + E2) >= unionTroops) { + C6 = Math.floor(13.0 * unionTroops / 20); + E2 = 7 * C6 / 13; + excessiveUnionLosses = 1; + } + } + + // 2170: CALCULATE SIMULATED LOSSES + private void calcLosses(BattleState battle) { + // 2190 + out.println(); + out.println(" CONFEDERACY UNION"); + + var C5 = (2 * battle.data.expectedCasualties.confederate / 5) * (1 + 1.0 / (2 * (Math.abs(Y2 - Y) + 1))); + C5 = (int) Math.floor(C5 * (1 + 1.0 / this.O[0]) * (1.28 + battle.F1 / (this.B[0] + 1.0)) + .5); + var E = 100 / O[0]; + + if (C5 + 100 / O[0] >= battle.data.troops.confederate * (1 + (totalExpectedCasualties.confederate - totalCasualties.confederate) / (M3 + 1.0))) { + C5 = (int) Math.floor(13.0 * battle.data.troops.confederate / 20 * (1 + (totalExpectedCasualties.union - totalCasualties.confederate) / (M3 + 1.0))); + E = 7 * C5 / 13.0; + excessiveConfederateLosses = 1; + } + + ///// 2270 + + if (this.numGenerals == 1) { + C6 = (int) Math.floor(17.0 * battle.data.expectedCasualties.union * battle.data.expectedCasualties.confederate / (C5 * 20)); + E2 = 5 * O[0]; + } + + out.println("CASUALTIES: " + rightAlignInt(C5) + " " + rightAlignInt(C6)); + out.println("DESERTIONS: " + rightAlignInt(E) + " " + rightAlignInt(E2)); + out.println(); + + if (numGenerals == 2) { + out.println("COMPARED TO THE ACTUAL CASUALTIES AT " + battle.data.name); + out.println("CONFEDERATE: " + (int) Math.floor(100 * (C5 / (double) battle.data.expectedCasualties.confederate) + 0.5) + " % OF THE ORIGINAL"); + out.println("UNION: " + (int) Math.floor(100 * (C6 / (double) battle.data.expectedCasualties.union) + 0.5) + " % OF THE ORIGINAL"); + + out.println(); + + // REM - 1 WHO WON + var winner = findWinner(C5 + E, C6 + E2); + switch (winner) { + case UNION -> { + out.println("THE UNION WINS " + battle.data.name); + L++; + } + case CONFED -> { + out.println("THE CONFEDERACY WINS " + battle.data.name); + W++; + } + case INDECISIVE -> { + out.println("BATTLE OUTCOME UNRESOLVED"); + this.W0++; + } + } + } else { + out.println("YOUR CASUALTIES WERE " + Math.floor(100 * (C5 / (double) battle.data.expectedCasualties.confederate) + 0.5) + "% OF THE ACTUAL CASUALTIES AT " + battle.data.name); + + // FIND WHO WON + + if (excessiveConfederateLosses == 1) { + out.println("YOU LOSE " + battle.data.name); + + if (this.battleNumber != 0) { + L++; + } + } else { + out.println("YOU WIN " + battle.data.name); + // CUMULATIVE BATTLE FACTORS WHICH ALTER HISTORICAL RESOURCES AVAILABLE.IF A REPLAY DON'T UPDATE. + W++; + } + } + + if (this.battleNumber != 0) { + totalCasualties.confederate += (int) (C5 + E); + totalCasualties.union += (int) (C6 + E2); + totalExpectedCasualties.confederate += battle.data.expectedCasualties.confederate; + totalExpectedCasualties.union += battle.data.expectedCasualties.union; + Q1 += F[0] + H[0] + B[0]; + Q2 += F[1] + H[1] + B[1]; + R1 += battle.data.troops.confederate * (100 - I1) / 20; + R2 += battle.data.troops.union * (100 - I2) / 20; + M3 += battle.data.troops.confederate; + M4 += battle.data.troops.union; + + updateStrategies(this.Y); + } + } + + // 2790 + private void reset() { + excessiveConfederateLosses = excessiveUnionLosses = 0; + + out.println("---------------"); + } + + // 2820 REM------FINISH OFF + private void complete() { + out.println(); + out.println(); + out.println(); + out.println(); + out.println(); + out.println(); + out.println("THE CONFEDERACY HAS WON " + this.W + " BATTLES AND LOST " + this.L); + + if (this.Y2 == 5) { + out.println("THE CONFEDERACY HAS WON THE WAR"); + } + + if (this.Y == 5 || this.W <= this.L) { + out.println("THE UNION HAS WON THE WAR"); + } + + out.println(); + + // FIXME 2960 IF R1=0 THEN 3100 + + out.println("FOR THE " + (W + L + W0) + " BATTLES FOUGHT (EXCLUDING RERUNS)"); +// out.println(" ", " ", " "); + out.println(" CONFEDERACY UNION"); + out.println("HISTORICAL LOSSES " + (int) Math.floor(totalExpectedCasualties.confederate + .5) + " " + (int) Math.floor(totalExpectedCasualties.union + .5)); + out.println("SIMULATED LOSSES " + (int) Math.floor(totalCasualties.confederate + .5) + " " + (int) Math.floor(totalCasualties.union + .5)); + out.println(); + out.println(" % OF ORIGINAL " + (int) Math.floor(100 * ((double) totalCasualties.confederate / totalExpectedCasualties.confederate) + .5) + " " + (int) Math.floor(100 * ((double) totalCasualties.union / totalExpectedCasualties.union) + .5)); + + if (this.numGenerals == 1) { + out.println(); + out.println("UNION INTELLIGENCE SUGGESTS THAT THE SOUTH USED "); + out.println("STRATEGIES 1, 2, 3, 4 IN THE FOLLOWING PERCENTAGES"); + out.println(this.strategies[0] + "," + this.strategies[1] + "," + this.strategies[2] + "," + this.strategies[3]); + } + } + + private Winner findWinner(double confLosses, double unionLosses) { + if (this.excessiveConfederateLosses == 1 && this.excessiveUnionLosses == 1) { + return Winner.INDECISIVE; + } + + if (this.excessiveConfederateLosses == 1) { + return Winner.UNION; + } + + if (this.excessiveUnionLosses == 1 || confLosses < unionLosses) { + return Winner.CONFED; + } + + if (confLosses == unionLosses) { + return Winner.INDECISIVE; + } + + return Winner.UNION; // FIXME Really? 2400-2420 ? + } + + private enum Winner { + CONFED, UNION, INDECISIVE + } + + private void unionStrategy() { + if (this.battleNumber != 0) { + out.print("UNION STRATEGY ? "); + var terminalInput = new Scanner(System.in); + Y2 = terminalInput.nextInt(); + if (Y2 < 0) { + out.println("ENTER 1, 2, 3, OR 4 (USUALLY PREVIOUS UNION STRATEGY)"); + // FIXME Retry Y2 input !!! + } + + if (Y2 < 5) { // 3155 + return; + } + } + + var S0 = 0; + + this.R = 100 * Math.random(); + + for (Y2 = 0; Y2 < 4; Y2++) { + S0 += this.strategies[Y2]; + // IF ACTUAL STRATEGY INFO IS IN PROGRAM DATA STATEMENTS THEN R-100 IS EXTRA WEIGHT GIVEN TO THAT STATEGY. + if (R < S0) { + break; + } + } + // IF ACTUAL STRAT. IN,THEN HERE IS Y2= HIST. STRAT. + out.println("UNION STRATEGY IS " + Y2); + } + + public CivilWar(PrintStream out) { + this.out = out; + + this.totalCasualties = new ArmyPair<>(0, 0); + this.totalExpectedCasualties = new ArmyPair<>(0, 0); + + // UNION INFO ON LIKELY CONFEDERATE STRATEGY + this.strategies = new int[]{25, 25, 25, 25}; + + this.F = new int[]{0, 0}; + this.H = new int[]{0, 0}; + this.B = new int[]{0, 0}; + this.D = new int[]{0, 0}; + this.O = new double[]{0, 0}; + + // READ HISTORICAL DATA. + // HISTORICAL DATA...CAN ADD MORE (STRAT.,ETC) BY INSERTING DATA STATEMENTS AFTER APPRO. INFO, AND ADJUSTING READ + this.data = List.of(new HistoricalDatum("BULL RUN", new ArmyPair<>(18000, 18500), new ArmyPair<>(1967, 2708), OffensiveStatus.DEFENSIVE, new String[]{"JULY 21, 1861. GEN. BEAUREGARD, COMMANDING THE SOUTH, MET", "UNION FORCES WITH GEN. MCDOWELL IN A PREMATURE BATTLE AT", "BULL RUN. GEN. JACKSON HELPED PUSH BACK THE UNION ATTACK."}), new HistoricalDatum("SHILOH", new ArmyPair<>(40000, 44894), new ArmyPair<>(10699, 13047), OffensiveStatus.OFFENSIVE, new String[]{"APRIL 6-7, 1862. THE CONFEDERATE SURPRISE ATTACK AT", "SHILOH FAILED DUE TO POOR ORGANIZATION."}), new HistoricalDatum("SEVEN DAYS", new ArmyPair<>(95000, 115000), new ArmyPair<>(20614, 15849), OffensiveStatus.OFFENSIVE, new String[]{"JUNE 25-JULY 1, 1862. GENERAL LEE (CSA) UPHELD THE", "OFFENSIVE THROUGHOUT THE BATTLE AND FORCED GEN. MCCLELLAN", "AND THE UNION FORCES AWAY FROM RICHMOND."}), new HistoricalDatum("SECOND BULL RUN", new ArmyPair<>(54000, 63000), new ArmyPair<>(10000, 14000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"AUG 29-30, 1862. THE COMBINED CONFEDERATE FORCES UNDER", " LEE", "AND JACKSON DROVE THE UNION FORCES BACK INTO WASHINGTON."}), new HistoricalDatum("ANTIETAM", new ArmyPair<>(40000, 50000), new ArmyPair<>(10000, 12000), OffensiveStatus.OFFENSIVE, new String[]{"SEPT 17, 1862. THE SOUTH FAILED TO INCORPORATE MARYLAND", "INTO THE CONFEDERACY."}), new HistoricalDatum("FREDERICKSBURG", new ArmyPair<>(75000, 120000), new ArmyPair<>(5377, 12653), OffensiveStatus.DEFENSIVE, new String[]{"DEC 13, 1862. THE CONFEDERACY UNDER LEE SUCCESSFULLY", "REPULSED AN ATTACK BY THE UNION UNDER GEN. BURNSIDE."}), new HistoricalDatum("MURFREESBORO", new ArmyPair<>(38000, 45000), new ArmyPair<>(11000, 12000), OffensiveStatus.DEFENSIVE, new String[]{"DEC 31, 1862. THE SOUTH UNDER GEN. BRAGG WON A CLOSE BATTLE."}), new HistoricalDatum("CHANCELLORSVILLE", new ArmyPair<>(32000, 90000), new ArmyPair<>(13000, 17197), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"MAY 1-6, 1863. THE SOUTH HAD A COSTLY VICTORY AND LOST", "ONE OF THEIR OUTSTANDING GENERALS, 'STONEWALL' JACKSON."}), new HistoricalDatum("VICKSBURG", new ArmyPair<>(50000, 70000), new ArmyPair<>(12000, 19000), OffensiveStatus.DEFENSIVE, new String[]{"JULY 4, 1863. VICKSBURG WAS A COSTLY DEFEAT FOR THE SOUTH", "BECAUSE IT GAVE THE UNION ACCESS TO THE MISSISSIPPI."}), new HistoricalDatum("GETTYSBURG", new ArmyPair<>(72500, 85000), new ArmyPair<>(20000, 23000), OffensiveStatus.OFFENSIVE, new String[]{"JULY 1-3, 1863. A SOUTHERN MISTAKE BY GEN. LEE AT GETTYSBURG", "COST THEM ONE OF THE MOST CRUCIAL BATTLES OF THE WAR."}), new HistoricalDatum("CHICKAMAUGA", new ArmyPair<>(66000, 60000), new ArmyPair<>(18000, 16000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"SEPT. 15, 1863. CONFUSION IN A FOREST NEAR CHICKAMAUGA LED", "TO A COSTLY SOUTHERN VICTORY."}), new HistoricalDatum("CHATTANOOGA", new ArmyPair<>(37000, 60000), new ArmyPair<>(36700, 5800), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"NOV. 25, 1863. AFTER THE SOUTH HAD SIEGED GEN. ROSENCRANS'", "ARMY FOR THREE MONTHS, GEN. GRANT BROKE THE SIEGE."}), new HistoricalDatum("SPOTSYLVANIA", new ArmyPair<>(62000, 110000), new ArmyPair<>(17723, 18000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"MAY 5, 1864. GRANT'S PLAN TO KEEP LEE ISOLATED BEGAN TO", "FAIL HERE, AND CONTINUED AT COLD HARBOR AND PETERSBURG."}), new HistoricalDatum("ATLANTA", new ArmyPair<>(65000, 100000), new ArmyPair<>(8500, 3700), OffensiveStatus.DEFENSIVE, new String[]{"AUGUST, 1864. SHERMAN AND THREE VETERAN ARMIES CONVERGED", "ON ATLANTA AND DEALT THE DEATH BLOW TO THE CONFEDERACY."})); + } + + private void showCredits() { + out.println(" ".repeat(26) + "CIVIL WAR"); + out.println(" ".repeat(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + out.println(); + out.println(); + out.println(); + } + + private void updateStrategies(int strategy) { + // REM LEARN PRESENT STRATEGY, START FORGETTING OLD ONES + // REM - PRESENT STRATEGY OF SOUTH GAINS 3*S, OTHERS LOSE S + // REM PROBABILITY POINTS, UNLESS A STRATEGY FALLS BELOW 5%. + + var S = 3; + var S0 = 0; + for (int i = 0; i < 4; i++) { + if (this.strategies[i] <= 5) { + continue; + } + + this.strategies[i] -= S; + S0 += S; + + } + this.strategies[strategy - 1] += S0; + + } + + private void showHelp() { + out.println(); + out.println(); + out.println(); + out.println(); + out.println("THIS IS A CIVIL WAR SIMULATION."); + out.println("TO PLAY TYPE A RESPONSE WHEN THE COMPUTER ASKS."); + out.println("REMEMBER THAT ALL FACTORS ARE INTERRELATED AND THAT YOUR"); + out.println("RESPONSES COULD CHANGE HISTORY. FACTS AND FIGURES USED ARE"); + out.println("BASED ON THE ACTUAL OCCURRENCE. MOST BATTLES TEND TO RESULT"); + out.println("AS THEY DID IN THE CIVIL WAR, BUT IT ALL DEPENDS ON YOU!!"); + out.println(); + out.println("THE OBJECT OF THE GAME IS TO WIN AS MANY BATTLES AS "); + out.println("POSSIBLE."); + out.println(); + out.println("YOUR CHOICES FOR DEFENSIVE STRATEGY ARE:"); + out.println(" (1) ARTILLERY ATTACK"); + out.println(" (2) FORTIFICATION AGAINST FRONTAL ATTACK"); + out.println(" (3) FORTIFICATION AGAINST FLANKING MANEUVERS"); + out.println(" (4) FALLING BACK"); + out.println(" YOUR CHOICES FOR OFFENSIVE STRATEGY ARE:"); + out.println(" (1) ARTILLERY ATTACK"); + out.println(" (2) FRONTAL ATTACK"); + out.println(" (3) FLANKING MANEUVERS"); + out.println(" (4) ENCIRCLEMENT"); + out.println("YOU MAY SURRENDER BY TYPING A '5' FOR YOUR STRATEGY."); + } + + private static final int MAX_NUM_LENGTH = 6; + + private String rightAlignInt(int number) { + var s = String.valueOf(number); + return " ".repeat(MAX_NUM_LENGTH - s.length()) + s; + } + + private String rightAlignInt(double number) { + return rightAlignInt((int) Math.floor(number)); + } + + private static class BattleState { + private final HistoricalDatum data; + private double F1; + + public BattleState(HistoricalDatum data) { + this.data = data; + } + } + + private static class ArmyPair { + private T confederate; + private T union; + + public ArmyPair(T confederate, T union) { + this.confederate = confederate; + this.union = union; + } + } + + private record HistoricalDatum(String name, ArmyPair troops, + ArmyPair expectedCasualties, + OffensiveStatus offensiveStatus, String[] blurb) { + } +} \ No newline at end of file From 2811e23a4f23e69a52790067790103f96ab4fcbf Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 08:36:05 -0500 Subject: [PATCH 011/337] Finished print_board(board) method --- 48_High_IQ/python/High_IQ.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 18d48456..83443466 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -42,7 +42,9 @@ def print_board(board): print(board[29] + board[30] + board[31] + board[32] + board[33] + board[34] + board[35]) print(board[38] + board[39] + board[40] + board[41] + board[42] + board[43] + board[44]) print(board[47] + board[48] + board[49] + board[50] + board[51] + board[52] + board[53]) - + print(" " * 3 + board[58] + board[59] + board[60] + " " * 3) + print(" " * 3 + board[67] + board[68] + board[69] + " " * 3) + def play_game(): print("Lets play a game") board = new_board() From 27b81d48710b3d9cb975157695b8cba1c2c7c970 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 08:37:28 -0500 Subject: [PATCH 012/337] Uncommented board-positions guide --- 48_High_IQ/python/High_IQ.py | 44 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 83443466..3f19a4f5 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -10,28 +10,28 @@ def new_board(): def print_instructions(): print("\n" * 3) print("HERE IS THE BOARD:\n") - # print("\n") - # print(" ! ! !\n") - # print(" 13 14 15\n") - # print("\n") - # print(" ! ! !\n") - # print(" 22 23 24\n") - # print("\n") - # print("! ! ! ! ! ! ! ! !\n") - # print("29 30 31 32 33 34 35 36 37\n") - # print("\n") - # print("! ! ! ! ! ! !\n") - # print("38 39 40 41 42 43 44\n") - # print("\n") - # print("! ! ! ! ! ! !\n") - # print("47 48 49 50 51 52 53\n") - # print("\n") - # print(" ! ! !\n") - # print(" 58 59 60\n") - # print("\n") - # print(" ! ! !\n") - # print(" 67 68 69\n") - # print("\n") + print("\n") + print(" ! ! !\n") + print(" 13 14 15\n") + print("\n") + print(" ! ! !\n") + print(" 22 23 24\n") + print("\n") + print("! ! ! ! ! ! ! ! !\n") + print("29 30 31 32 33 34 35 36 37\n") + print("\n") + print("! ! ! ! ! ! !\n") + print("38 39 40 41 42 43 44\n") + print("\n") + print("! ! ! ! ! ! !\n") + print("47 48 49 50 51 52 53\n") + print("\n") + print(" ! ! !\n") + print(" 58 59 60\n") + print("\n") + print(" ! ! !\n") + print(" 67 68 69\n") + print("\n") print("TO SAVE TYPING TIME, A COMPRESSED VERSION OF THE GAME BOARD\n") print("WILL BE USED DURING PLAY. REFER TO THE ABOVE ONE FOR PEG\n") print("NUMBERS. OK, LET'S BEGIN.\n") From 919bb2f682427a8226e2b20319bf8f9519bfc925 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 08:40:45 -0500 Subject: [PATCH 013/337] No longer asks before printing instructions --- 48_High_IQ/python/High_IQ.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 3f19a4f5..0f03dc04 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -51,8 +51,8 @@ def play_game(): print_board(board) def main(): - if input("Do you want instrunctions?\n").lower().startswith("y"): - print_instructions() +# if input("Do you want instrunctions?\n").lower().startswith("y"): + print_instructions() play_game() if __name__ == "__main__": From 92064c668a92e10f03aadb193108a53786d53bbb Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 08:43:12 -0500 Subject: [PATCH 014/337] Update High_IQ.py --- 48_High_IQ/python/High_IQ.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 0f03dc04..9561bbae 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -52,6 +52,8 @@ def play_game(): def main(): # if input("Do you want instrunctions?\n").lower().startswith("y"): + print("\t" * 33 + "H-I-Q") + print("\t" * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") print_instructions() play_game() From c207acaa561f7e6c3129c2f71f8ab375d930d1cc Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 08:46:27 -0500 Subject: [PATCH 015/337] Removed trailing spaces --- 48_High_IQ/python/High_IQ.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 9561bbae..df1ffdbd 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -37,13 +37,13 @@ def print_instructions(): print("NUMBERS. OK, LET'S BEGIN.\n") def print_board(board): - print(" " * 3 + board[13] + board[14] + board[15] + " " * 3) - print(" " * 3 + board[22] + board[23] + board[24] + " " * 3) + print(" " * 3 + board[13] + board[14] + board[15]) + print(" " * 3 + board[22] + board[23] + board[24]) print(board[29] + board[30] + board[31] + board[32] + board[33] + board[34] + board[35]) print(board[38] + board[39] + board[40] + board[41] + board[42] + board[43] + board[44]) print(board[47] + board[48] + board[49] + board[50] + board[51] + board[52] + board[53]) - print(" " * 3 + board[58] + board[59] + board[60] + " " * 3) - print(" " * 3 + board[67] + board[68] + board[69] + " " * 3) + print(" " * 3 + board[58] + board[59] + board[60]) + print(" " * 3 + board[67] + board[68] + board[69]) def play_game(): print("Lets play a game") From 58f68bcd2fd8271b9f73cfac0ca8ff2bc6f0f45e Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 09:54:18 -0500 Subject: [PATCH 016/337] Added is_game_finished I have absolutely no idea if it works.. --- 48_High_IQ/python/High_IQ.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index df1ffdbd..d80b95a4 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -56,6 +56,18 @@ def main(): print("\t" * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") print_instructions() play_game() + +def is_game_finished(board): + for pos in board.keys(): + if board[pos] == "X": + for space in [1,9]: + nextToPeg = ((pos + space) in board) and board[pos + space] + hasMovableSpace = (not ((pos - space) in board and board[pos - space])) or (not ((pos + space * 2) in board and board[pos + space * 2])) + if nextToPeg and hasMovableSpace: + return False + + return True + if __name__ == "__main__": main() From a0210ffe839fdd3b25f9003e1f51ae93a1564c7f Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 09:55:01 -0500 Subject: [PATCH 017/337] Forgot board isn't booleans Maybe I should make it booleans? --- 48_High_IQ/python/High_IQ.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index d80b95a4..52aff04c 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -61,8 +61,8 @@ def is_game_finished(board): for pos in board.keys(): if board[pos] == "X": for space in [1,9]: - nextToPeg = ((pos + space) in board) and board[pos + space] - hasMovableSpace = (not ((pos - space) in board and board[pos - space])) or (not ((pos + space * 2) in board and board[pos + space * 2])) + nextToPeg = ((pos + space) in board) and board[pos + space] == "X" + hasMovableSpace = (not ((pos - space) in board and board[pos - space] == "X")) or (not ((pos + space * 2) in board and board[pos + space * 2] == "X")) if nextToPeg and hasMovableSpace: return False From c41e7ce057acb8747e7ce159ed9f40214f31a95b Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 6 Jan 2022 13:58:12 -0500 Subject: [PATCH 018/337] Formatted Board into single string --- 48_High_IQ/python/High_IQ.py | 82 +++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 52aff04c..1f32e300 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -1,54 +1,58 @@ def new_board(): board = {} - for i in [13, 14, 15, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 38, 39, 40, 42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 58, 59, 60, 67, 68]: - board[i] = "X" - board[41] = "_" + for i in [13, 14, 15, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 38, 39, 40, 42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 58, 59, 60, 67, 68, 69]: + board[i] = "!" + board[41] = "O" return board def print_instructions(): - print("\n" * 3) - print("HERE IS THE BOARD:\n") - print("\n") - print(" ! ! !\n") - print(" 13 14 15\n") - print("\n") - print(" ! ! !\n") - print(" 22 23 24\n") - print("\n") - print("! ! ! ! ! ! ! ! !\n") - print("29 30 31 32 33 34 35 36 37\n") - print("\n") - print("! ! ! ! ! ! !\n") - print("38 39 40 41 42 43 44\n") - print("\n") - print("! ! ! ! ! ! !\n") - print("47 48 49 50 51 52 53\n") - print("\n") - print(" ! ! !\n") - print(" 58 59 60\n") - print("\n") - print(" ! ! !\n") - print(" 67 68 69\n") - print("\n") - print("TO SAVE TYPING TIME, A COMPRESSED VERSION OF THE GAME BOARD\n") - print("WILL BE USED DURING PLAY. REFER TO THE ABOVE ONE FOR PEG\n") - print("NUMBERS. OK, LET'S BEGIN.\n") + print(""" +HERE IS THE BOARD: + + ! ! ! + 13 14 15 + + ! ! ! + 22 23 24 + +! ! ! ! ! ! ! +29 30 31 32 33 34 35 + +! ! ! ! ! ! ! +38 39 40 41 42 43 44 + +! ! ! ! ! ! ! +47 48 49 50 51 52 53 + + ! ! ! + 58 59 60 + + ! ! ! + 67 68 69 + +TO SAVE TYPING TIME, A COMPRESSED VERSION OF THE GAME BOARD +WILL BE USED DURING PLAY. REFER TO THE ABOVE ONE FOR PEG +NUMBERS. OK, LET'S BEGIN. + """) def print_board(board): - print(" " * 3 + board[13] + board[14] + board[15]) - print(" " * 3 + board[22] + board[23] + board[24]) + print(" " * 2 + board[13] + board[14] + board[15]) + print(" " * 2 + board[22] + board[23] + board[24]) print(board[29] + board[30] + board[31] + board[32] + board[33] + board[34] + board[35]) print(board[38] + board[39] + board[40] + board[41] + board[42] + board[43] + board[44]) print(board[47] + board[48] + board[49] + board[50] + board[51] + board[52] + board[53]) - print(" " * 3 + board[58] + board[59] + board[60]) - print(" " * 3 + board[67] + board[68] + board[69]) - + print(" " * 2 + board[58] + board[59] + board[60]) + print(" " * 2 + board[67] + board[68] + board[69]) + def play_game(): print("Lets play a game") board = new_board() - print_board(board) + + while not is_game_finished(board): + print_board(board) + def main(): # if input("Do you want instrunctions?\n").lower().startswith("y"): @@ -56,7 +60,7 @@ def main(): print("\t" * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") print_instructions() play_game() - + def is_game_finished(board): for pos in board.keys(): if board[pos] == "X": @@ -65,9 +69,9 @@ def is_game_finished(board): hasMovableSpace = (not ((pos - space) in board and board[pos - space] == "X")) or (not ((pos + space * 2) in board and board[pos + space * 2] == "X")) if nextToPeg and hasMovableSpace: return False - + return True - + if __name__ == "__main__": main() From c8fccde8892305549e689e4eb353ee86a57dd0f5 Mon Sep 17 00:00:00 2001 From: Yuriy Lyeshchenko Date: Sat, 8 Jan 2022 19:00:19 -0600 Subject: [PATCH 019/337] Implementing https://github.com/coding-horror/basic-computer-games/blob/main/15_Boxing/boxing.bas in C# --- 15_Boxing/csharp/AttackStrategy.cs | 48 ++++++++ 15_Boxing/csharp/Boxer.cs | 45 ++++++++ 15_Boxing/csharp/Boxing.csproj | 10 ++ 15_Boxing/csharp/Boxing.sln | 22 ++++ 15_Boxing/csharp/OpponentAttackStrategy.cs | 115 ++++++++++++++++++++ 15_Boxing/csharp/PlayerAttackStrategy.cs | 121 +++++++++++++++++++++ 15_Boxing/csharp/Program.cs | 29 +++++ 15_Boxing/csharp/Punch.cs | 9 ++ 15_Boxing/csharp/Round.cs | 96 ++++++++++++++++ 15_Boxing/csharp/Utils.cs | 35 ++++++ 10 files changed, 530 insertions(+) create mode 100644 15_Boxing/csharp/AttackStrategy.cs create mode 100644 15_Boxing/csharp/Boxer.cs create mode 100644 15_Boxing/csharp/Boxing.csproj create mode 100644 15_Boxing/csharp/Boxing.sln create mode 100644 15_Boxing/csharp/OpponentAttackStrategy.cs create mode 100644 15_Boxing/csharp/PlayerAttackStrategy.cs create mode 100644 15_Boxing/csharp/Program.cs create mode 100644 15_Boxing/csharp/Punch.cs create mode 100644 15_Boxing/csharp/Round.cs create mode 100644 15_Boxing/csharp/Utils.cs diff --git a/15_Boxing/csharp/AttackStrategy.cs b/15_Boxing/csharp/AttackStrategy.cs new file mode 100644 index 00000000..5ffdb2cc --- /dev/null +++ b/15_Boxing/csharp/AttackStrategy.cs @@ -0,0 +1,48 @@ +namespace Boxing; + +public abstract class AttackStrategy +{ + protected const int KnockoutDamageThreshold = 35; + protected readonly Boxer Other; + protected readonly Stack Work; + private readonly Action _notifyGameEnded; + + public AttackStrategy(Boxer other, Stack work, Action notifyGameEnded) + { + Other = other; + Work = work; + _notifyGameEnded = notifyGameEnded; + } + + public void Attack() + { + var punch = GetPunch(); + if (punch.IsBestPunch) + { + Other.DamageTaken += 2; + } + + Work.Push(punch.Punch switch + { + Punch.FullSwing => FullSwing, + Punch.Hook => Hook, + Punch.Uppercut => Uppercut, + _ => Jab + }); + } + + protected abstract AttackPunch GetPunch(); + protected abstract void FullSwing(); + protected abstract void Hook(); + protected abstract void Uppercut(); + protected abstract void Jab(); + + protected void RegisterKnockout(string knockoutMessage) + { + Work.Clear(); + _notifyGameEnded(); + Console.WriteLine(knockoutMessage); + } + + protected record AttackPunch(Punch Punch, bool IsBestPunch); +} \ No newline at end of file diff --git a/15_Boxing/csharp/Boxer.cs b/15_Boxing/csharp/Boxer.cs new file mode 100644 index 00000000..3f5fdd26 --- /dev/null +++ b/15_Boxing/csharp/Boxer.cs @@ -0,0 +1,45 @@ +namespace Boxing; + +public class Boxer +{ + private int _wins; + + private string Name { get; set; } = string.Empty; + + public Punch BestPunch { get; set; } + + public Punch Vulnerability { get; set; } + + public void SetName(string prompt) + { + Console.WriteLine(prompt); + string? name; + do + { + name = Console.ReadLine(); + } while (string.IsNullOrWhiteSpace(name)); + Name = name; + } + + public int DamageTaken { get; set; } + + public void ResetForNewRound() => DamageTaken = 0; + + public void RecordWin() => _wins += 1; + + public bool IsWinner => _wins >= 2; + + public override string ToString() => Name; +} + +public class Opponent : Boxer +{ + public void SetRandomPunches() + { + do + { + BestPunch = (Punch) GameUtils.Roll(4); // B1 + Vulnerability = (Punch) GameUtils.Roll(4); // D1 + } while (BestPunch == Vulnerability); + } +} \ No newline at end of file diff --git a/15_Boxing/csharp/Boxing.csproj b/15_Boxing/csharp/Boxing.csproj new file mode 100644 index 00000000..74abf5c9 --- /dev/null +++ b/15_Boxing/csharp/Boxing.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/15_Boxing/csharp/Boxing.sln b/15_Boxing/csharp/Boxing.sln new file mode 100644 index 00000000..6202b593 --- /dev/null +++ b/15_Boxing/csharp/Boxing.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Boxing", "Boxing.csproj", "{52A7BDE5-3085-4F58-AC57-2BA4E65212D8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {52A7BDE5-3085-4F58-AC57-2BA4E65212D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52A7BDE5-3085-4F58-AC57-2BA4E65212D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52A7BDE5-3085-4F58-AC57-2BA4E65212D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52A7BDE5-3085-4F58-AC57-2BA4E65212D8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/15_Boxing/csharp/OpponentAttackStrategy.cs b/15_Boxing/csharp/OpponentAttackStrategy.cs new file mode 100644 index 00000000..c5bf3e38 --- /dev/null +++ b/15_Boxing/csharp/OpponentAttackStrategy.cs @@ -0,0 +1,115 @@ +using static Boxing.GameUtils; +using static System.Console; + +namespace Boxing; + +public class OpponentAttackStrategy : AttackStrategy +{ + private readonly Opponent _opponent; + + public OpponentAttackStrategy(Opponent opponent, Boxer player, Action notifyGameEnded, Stack work) : base(player, work, notifyGameEnded) + { + _opponent = opponent; + } + + protected override AttackPunch GetPunch() + { + var punch = (Punch)Roll(4); + return new AttackPunch(punch, punch == _opponent.BestPunch); + } + + protected override void FullSwing() // 720 + { + Write($"{_opponent} TAKES A FULL SWING AND"); + if (Other.Vulnerability == Punch.FullSwing) + { + ScoreFullSwing(); + } + else + { + if (RollSatisfies(60, x => x < 30)) + { + WriteLine(" IT'S BLOCKED!"); + } + else + { + ScoreFullSwing(); + } + } + + void ScoreFullSwing() + { + WriteLine(" POW!!!!! HE HITS HIM RIGHT IN THE FACE!"); + if (Other.DamageTaken > KnockoutDamageThreshold) + { + Work.Push(RegisterOtherKnockedOut); + } + Other.DamageTaken += 15; + } + } + + protected override void Hook() // 810 + { + Write($"{_opponent} GETS {Other} IN THE JAW (OUCH!)"); + Other.DamageTaken += 7; + WriteLine("....AND AGAIN!"); + Other.DamageTaken += 5; + if (Other.DamageTaken > KnockoutDamageThreshold) + { + Work.Push(RegisterOtherKnockedOut); + } + } + + protected override void Uppercut() // 860 + { + Write($"{Other} IS ATTACKED BY AN UPPERCUT (OH,OH)..."); + if (Other.Vulnerability == Punch.Uppercut) + { + ScoreUppercut(); + } + else + { + if (RollSatisfies(200, x => x > 75)) + { + WriteLine($" BLOCKS AND HITS {_opponent} WITH A HOOK."); + _opponent.DamageTaken += 5; + } + else + { + ScoreUppercut(); + } + } + + void ScoreUppercut() + { + WriteLine($"AND {_opponent} CONNECTS..."); + Other.DamageTaken += 8; + } + } + + protected override void Jab() // 640 + { + Write($"{_opponent} JABS AND "); + if (Other.Vulnerability == Punch.Jab) + { + ScoreJab(); + } + else + { + if (RollSatisfies(7, x => x > 4)) + { + WriteLine("BLOOD SPILLS !!!"); + ScoreJab(); + } + else + { + WriteLine("IT'S BLOCKED!"); + } + } + + void ScoreJab() => Other.DamageTaken += 5; + } + + private void RegisterOtherKnockedOut() + => RegisterKnockout($"{Other} IS KNOCKED COLD AND {_opponent} IS THE WINNER AND CHAMP!"); +} \ No newline at end of file diff --git a/15_Boxing/csharp/PlayerAttackStrategy.cs b/15_Boxing/csharp/PlayerAttackStrategy.cs new file mode 100644 index 00000000..fd43c0ed --- /dev/null +++ b/15_Boxing/csharp/PlayerAttackStrategy.cs @@ -0,0 +1,121 @@ +using static Boxing.GameUtils; +using static System.Console; +namespace Boxing; + +public class PlayerAttackStrategy : AttackStrategy +{ + private readonly Boxer _player; + + public PlayerAttackStrategy(Boxer player, Opponent opponent, Action notifyGameEnded, Stack work) + : base(opponent, work, notifyGameEnded) => _player = player; + + protected override AttackPunch GetPunch() + { + var punch = GameUtils.GetPunch($"{_player}'S PUNCH"); + return new AttackPunch(punch, punch == _player.BestPunch); + } + + protected override void FullSwing() // 340 + { + Write($"{_player} SWINGS AND "); + if (Other.Vulnerability == Punch.FullSwing) + { + ScoreFullSwing(); + } + else + { + if (RollSatisfies(30, x => x < 10)) + { + ScoreFullSwing(); + } + else + { + WriteLine("HE MISSES"); + } + } + + void ScoreFullSwing() + { + WriteLine("HE CONNECTS!"); + if (Other.DamageTaken > KnockoutDamageThreshold) + { + Work.Push(() => RegisterKnockout($"{Other} IS KNOCKED COLD AND {_player} IS THE WINNER AND CHAMP!")); + } + Other.DamageTaken += 15; + } + } + + protected override void Uppercut() // 520 + { + Write($"{_player} TRIES AN UPPERCUT "); + if (Other.Vulnerability == Punch.Uppercut) + { + ScoreUpperCut(); + } + else + { + if (RollSatisfies(100, x => x < 51)) + { + ScoreUpperCut(); + } + else + { + WriteLine("AND IT'S BLOCKED (LUCKY BLOCK!)"); + } + } + + void ScoreUpperCut() + { + WriteLine("AND HE CONNECTS!"); + Other.DamageTaken += 4; + } + } + + protected override void Hook() // 450 + { + Write($"{_player} GIVES THE HOOK... "); + if (Other.Vulnerability == Punch.Hook) + { + ScoreHookOnOpponent(); + } + else + { + if (RollSatisfies(2, x => x == 1)) + { + WriteLine("BUT IT'S BLOCKED!!!!!!!!!!!!!"); + } + else + { + ScoreHookOnOpponent(); + } + } + + void ScoreHookOnOpponent() + { + WriteLine("CONNECTS..."); + Other.DamageTaken += 7; + } + } + + protected override void Jab() + { + WriteLine($"{_player} JABS AT {Other}'S HEAD"); + if (Other.Vulnerability == Punch.Jab) + { + ScoreJabOnOpponent(); + } + else + { + if (RollSatisfies(8, x => x < 4)) + { + WriteLine("IT'S BLOCKED."); + } + else + { + ScoreJabOnOpponent(); + } + } + + void ScoreJabOnOpponent() => Other.DamageTaken += 3; + } +} \ No newline at end of file diff --git a/15_Boxing/csharp/Program.cs b/15_Boxing/csharp/Program.cs new file mode 100644 index 00000000..57923de0 --- /dev/null +++ b/15_Boxing/csharp/Program.cs @@ -0,0 +1,29 @@ +using Boxing; +using static Boxing.GameUtils; +using static System.Console; + +WriteLine(new string('\t', 33) + "BOXING"); +WriteLine(new string('\t', 15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); +WriteLine("{0}{0}{0}BOXING OLYMPIC STYLE (3 ROUNDS -- 2 OUT OF 3 WINS){0}", Environment.NewLine); + +var opponent = new Opponent(); +opponent.SetName("WHAT IS YOUR OPPONENT'S NAME"); // J$ +var player = new Boxer(); +player.SetName("INPUT YOUR MAN'S NAME"); // L$ + +PrintPunchDescription(); +player.BestPunch = GetPunch("WHAT IS YOUR MANS BEST"); // B +player.Vulnerability = GetPunch("WHAT IS HIS VULNERABILITY"); // D +opponent.SetRandomPunches(); +WriteLine($"{opponent}'S ADVANTAGE IS {opponent.BestPunch.ToFriendlyString()} AND VULNERABILITY IS SECRET."); + + +for (var i = 1; i <= 3; i ++) // R +{ + var round = new Round(player, opponent, i); + round.Start(); + round.CheckOpponentWin(); + round.CheckPlayerWin(); + if (round.GameEnded) break; +} +WriteLine("{0}{0}AND NOW GOODBYE FROM THE OLYMPIC ARENA.{0}", Environment.NewLine); \ No newline at end of file diff --git a/15_Boxing/csharp/Punch.cs b/15_Boxing/csharp/Punch.cs new file mode 100644 index 00000000..add2003a --- /dev/null +++ b/15_Boxing/csharp/Punch.cs @@ -0,0 +1,9 @@ +namespace Boxing; + +public enum Punch +{ + FullSwing = 1, + Hook = 2, + Uppercut = 3, + Jab = 4 +} \ No newline at end of file diff --git a/15_Boxing/csharp/Round.cs b/15_Boxing/csharp/Round.cs new file mode 100644 index 00000000..dfa1e26b --- /dev/null +++ b/15_Boxing/csharp/Round.cs @@ -0,0 +1,96 @@ +namespace Boxing; + +class Round +{ + + private readonly Boxer _player; + private readonly Boxer _opponent; + private readonly int _round; + private Stack _work = new(); + private readonly PlayerAttackStrategy _playerAttackStrategy; + private readonly OpponentAttackStrategy _opponentAttackStrategy; + + public bool GameEnded { get; private set; } + + public Round(Boxer player, Opponent opponent, int round) + { + _player = player; + _opponent = opponent; + _round = round; + _work.Push(ResetPlayers); + _work.Push(CheckOpponentWin); + _work.Push(CheckPlayerWin); + + void NotifyGameEnded() => GameEnded = true; + _playerAttackStrategy = new PlayerAttackStrategy(player, opponent, NotifyGameEnded, _work); + _opponentAttackStrategy = new OpponentAttackStrategy(opponent, player, NotifyGameEnded, _work); + } + + public void Start() + { + while (_work.Count > 0) + { + var action = _work.Pop(); + // This delay does not exist in the VB code but it makes a bit easier to follow the game. + // I assume the computers at the time were slow enough + // so that they did not need this delay... + Thread.Sleep(300); + action(); + } + } + + public void CheckOpponentWin() + { + if (_opponent.IsWinner) + { + Console.WriteLine($"{_opponent} WINS (NICE GOING, {_opponent})."); + GameEnded = true; + } + } + + public void CheckPlayerWin() + { + if (_player.IsWinner) + { + Console.WriteLine($"{_player} AMAZINGLY WINS!!"); + GameEnded = true; + } + } + + private void ResetPlayers() + { + _player.ResetForNewRound(); + _opponent.ResetForNewRound(); + _work.Push(RoundBegins); + } + + private void RoundBegins() + { + Console.WriteLine(); + Console.WriteLine($"ROUND {_round} BEGINS..."); + _work.Push(CheckRoundWinner); + for (var i = 0; i < 7; i++) + { + _work.Push(DecideWhoAttacks); + } + } + + private void CheckRoundWinner() + { + if (_opponent.DamageTaken > _player.DamageTaken) + { + Console.WriteLine($"{_player} WINS ROUND {_round}"); + _player.RecordWin(); + } + else + { + Console.WriteLine($"{_opponent} WINS ROUND {_round}"); + _opponent.RecordWin(); + } + } + + private void DecideWhoAttacks() + { + _work.Push( GameUtils.RollSatisfies(10, x => x > 5) ? _opponentAttackStrategy.Attack : _playerAttackStrategy.Attack ); + } +} \ No newline at end of file diff --git a/15_Boxing/csharp/Utils.cs b/15_Boxing/csharp/Utils.cs new file mode 100644 index 00000000..1ada516c --- /dev/null +++ b/15_Boxing/csharp/Utils.cs @@ -0,0 +1,35 @@ +namespace Boxing; +public static class GameUtils +{ + private static readonly Random Rnd = new((int) DateTime.UtcNow.Ticks); + public static void PrintPunchDescription() => + Console.WriteLine($"DIFFERENT PUNCHES ARE: {PunchDesc(Punch.FullSwing)}; {PunchDesc(Punch.Hook)}; {PunchDesc(Punch.Uppercut)}; {PunchDesc(Punch.Jab)}."); + + private static string PunchDesc(Punch punch) => $"({(int)punch}) {punch.ToFriendlyString()}"; + + public static Punch GetPunch(string prompt) + { + Console.WriteLine(prompt); + Punch result; + while (!Enum.TryParse(Console.ReadLine(), out result) || !Enum.IsDefined(typeof(Punch), result)) + { + PrintPunchDescription(); + } + return result; + } + + public static Func Roll { get; } = upperLimit => (int) (upperLimit * Rnd.NextSingle()) + 1; + + public static bool RollSatisfies(int upperLimit, Predicate predicate) => predicate(Roll(upperLimit)); + + public static string ToFriendlyString(this Punch punch) + => punch switch + { + Punch.FullSwing => "FULL SWING", + Punch.Hook => "HOOK", + Punch.Uppercut => "UPPERCUT", + Punch.Jab => "JAB", + _ => throw new ArgumentOutOfRangeException(nameof(punch), punch, null) + }; + +} \ No newline at end of file From 40617fa4fc357a94b58141e15980efd50382105f Mon Sep 17 00:00:00 2001 From: Mark Wieder Date: Sat, 8 Jan 2022 17:20:53 -0800 Subject: [PATCH 020/337] implementation of game 73 (Reverse) in ruby --- 73_Reverse/ruby/reverse.rb | 111 +++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 73_Reverse/ruby/reverse.rb diff --git a/73_Reverse/ruby/reverse.rb b/73_Reverse/ruby/reverse.rb new file mode 100644 index 00000000..0e2f7934 --- /dev/null +++ b/73_Reverse/ruby/reverse.rb @@ -0,0 +1,111 @@ +ARRAYSIZE = 9 +$digitArray = Array.new(ARRAYSIZE) +$winningArray = Array.new(ARRAYSIZE) + +# Method to print the rules +def displayTheRules + puts "This is the game of 'Reverse'. to win, all you have" + puts "to do is arrange a list of numbers (1 through " + ARRAYSIZE.to_s + ")" + puts "in numerical order from left to right. to move, you" + puts "tell me how many numbers (counting from the left) to" + puts "reverse. For example, if the current list is:" + puts "2 3 4 5 1 6 7 8 9" + puts "and you reverse 4, the result will be:" + puts "5 4 3 2 1 6 7 8 9" + puts "Now if you reverse 5, you win!" + puts "1 2 3 4 5 6 7 8 9" + puts "No doubt you will like this game, but" + puts "if you want to quit, reverse 0 (zero)." +end + +# Method to print the list +def printList + puts "\n" + $digitArray.join(" ") + "\n\n" +end + +# Zero-based arrays contain digits 1-9 +# Make a random array and an ordered winning answer array A[0] to A[N] +def makeRandomList + for kIndex in 0..ARRAYSIZE-1 do + $digitArray[kIndex] = kIndex+1 + $winningArray[kIndex] = kIndex+1 + end + # now randomize the digit array order + $digitArray.shuffle! +end + +def checkForWin? (triesSoFar) + # Check for a win (all array elements in order) + if $digitArray == $winningArray then + puts "You won it in " + triesSoFar.to_s + " moves!!!\n\n" + puts "try again (yes or no)?" + tryAgain = gets.strip.upcase + if tryAgain == "YES" then + return true + end + puts "\nO.K. Hope you had fun!!" + exit + end + return false +end + +def reverseIt (howManyToReverse, triesSoFar) + # REVERSE R NUMBERS AND PRINT NEW LIST + + # extract and reverse the first howManyToReverse elements of the array + subArray = $digitArray.take(howManyToReverse) + subArray.reverse! + + # get the remaining elements of the original array + endArray = $digitArray.slice(howManyToReverse, ARRAYSIZE) + # append those elements to the reversed elements + $digitArray = subArray.concat(endArray) + + # if we got all in order, randomize again + isWinner = checkForWin?(triesSoFar) + if isWinner == true then + makeRandomList + end + printList # always print the newly ordered list + return isWinner +end + +def askHowManyToReverse + puts "How many shall I reverse?"; + rNumber = gets.to_i + if rNumber > 0 then + if rNumber > ARRAYSIZE then + puts "Oops! Too many! I can reverse at most " + ARRAYSIZE.to_s + end + else + rNumber = 0 # zero or negative values end the game + end + return rNumber +end + +puts "REVERSE" +puts "Creative Computing Morristown, New Jersey\n\n\n" +puts "REVERSE -- A game of skill\n\n" + +puts "Do you want the rules?" +wantRules = gets.strip.upcase +if wantRules == "YES" then + displayTheRules +end + +makeRandomList +howManyTries = 0 +puts "\nHere we go ... the list is:" +printList # display the initial list +# start the game loop +r = askHowManyToReverse +while r != 0 do # zero will end the game + if r <= ARRAYSIZE then + howManyTries = howManyTries+1 + if reverseIt(r, howManyTries) then + howManyTries = 0 + end + end + r = askHowManyToReverse +end + From ccb2e5a7c422b61572d1f6b9b22a70a38442add0 Mon Sep 17 00:00:00 2001 From: "Eric S. Weilnau" Date: Sat, 8 Jan 2022 20:51:33 -0500 Subject: [PATCH 021/337] Add link to PowerShell implementation --- 01_Acey_Ducey/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/01_Acey_Ducey/README.md b/01_Acey_Ducey/README.md index 77ff8621..f8e16312 100644 --- a/01_Acey_Ducey/README.md +++ b/01_Acey_Ducey/README.md @@ -17,3 +17,4 @@ http://www.vintage-basic.net/games.html #### External Links - Common Lisp: https://github.com/koalahedron/lisp-computer-games/blob/master/01%20Acey%20Ducey/common-lisp/acey-deucy.lisp + - PowerShell: https://github.com/eweilnau/basic-computer-games-powershell/blob/main/AceyDucey.ps1 From 52cbd74d19496d7bf33ea5627690b52082b87f13 Mon Sep 17 00:00:00 2001 From: Kanykei Akmatova Date: Sat, 8 Jan 2022 21:55:47 -0500 Subject: [PATCH 022/337] FlipFlop port to csharp --- 36_Flip_Flop/csharp/FlipFlop.cs | 197 ++++++++++++++++++++++++++++ 36_Flip_Flop/csharp/FlipFlop.csproj | 10 ++ 36_Flip_Flop/csharp/FlipFlop.sln | 25 ++++ 3 files changed, 232 insertions(+) create mode 100644 36_Flip_Flop/csharp/FlipFlop.cs create mode 100644 36_Flip_Flop/csharp/FlipFlop.csproj create mode 100644 36_Flip_Flop/csharp/FlipFlop.sln diff --git a/36_Flip_Flop/csharp/FlipFlop.cs b/36_Flip_Flop/csharp/FlipFlop.cs new file mode 100644 index 00000000..53c613e8 --- /dev/null +++ b/36_Flip_Flop/csharp/FlipFlop.cs @@ -0,0 +1,197 @@ +// Flip Flop Game + +PrintGameInfo(); + +bool startNewGame = true; + +string[] board = new string[] { "X", "X", "X", "X", "X", "X", "X", "X", "X", "X" }; + +do +{ + int stepsCount = 0; + int lastMove = -1; + int moveIndex; + int gameSum; + double gameEntropyRate = Rnd(); + bool toPlay = false; + bool setNewBoard = true; + + Print(); + Print("HERE IS THE STARTING LINE OF X'S."); + Print(); + + do + { + bool illegalEntry; + bool equalToLastMove; + + if (setNewBoard) + { + PrintNewBoard(); + board = new string[] { "X", "X", "X", "X", "X", "X", "X", "X", "X", "X" }; + setNewBoard = false; + toPlay = true; + } + + stepsCount++; + gameSum = 0; + + // Read User's move + do + { + Write("INPUT THE NUMBER? "); + var input = Console.ReadLine(); + illegalEntry = !int.TryParse(input, out moveIndex); + + if (illegalEntry || moveIndex > 11) + { + illegalEntry = true; + Print("ILLEGAL ENTRY--TRY AGAIN."); + } + } + while (illegalEntry); + + if (moveIndex == 11) + { + // Run new game, To start a new game at any point + toPlay = false; + stepsCount = 12; + startNewGame = true; + } + + + if (moveIndex == 0) + { + // To reset the line to all X, same game + setNewBoard = true; + toPlay = false; + } + + if (toPlay) + { + board[moveIndex - 1] = board[moveIndex - 1] == "O" ? "X" : "O"; + + if (lastMove == moveIndex) + { + equalToLastMove = true; + } + else + { + equalToLastMove = false; + lastMove = moveIndex; + } + + do + { + moveIndex = equalToLastMove + ? GetMoveIndexWhenEqualeLastMove(moveIndex, gameEntropyRate) + : GetMoveIndex(moveIndex, gameEntropyRate); + + board[moveIndex] = board[moveIndex] == "O" ? "X" : "O"; + } + while (lastMove == moveIndex && board[moveIndex] == "X"); + + PrintGameBoard(board); + + foreach (var item in board) + { + if (item == "O") + { + gameSum++; + } + } + } + } + while (stepsCount < 12 && gameSum < 10); + + if (toPlay) + { + PrintGameResult(gameSum, stepsCount); + + Write("DO YOU WANT TO TRY ANOTHER PUZZLE "); + + var toContinue = Console.ReadLine(); + + if (!string.IsNullOrEmpty(toContinue) && toContinue?.ToUpper()[0] == 'N') + { + startNewGame = false; + } + + Print(); + } +} +while (startNewGame); + +void Print(string str = "") => Console.WriteLine(str); + +void Write(string value) => Console.Write(value); + +string Tab(int pos) => new(' ', pos); + +double Rnd() => new Random().NextDouble(); + +int GetMoveIndex(int moveIndex, double gameEntropyRate) +{ + double rate = Math.Tan(gameEntropyRate + moveIndex / gameEntropyRate - moveIndex) - Math.Sin(gameEntropyRate / moveIndex) + 336 * Math.Sin(8 * moveIndex); + return Convert.ToInt32(Math.Floor(10 * (rate - Math.Floor(rate)))); +} + +int GetMoveIndexWhenEqualeLastMove(int moveIndex, double gameEntropyRate) +{ + double rate = 0.592 * (1 / Math.Tan(gameEntropyRate / moveIndex + gameEntropyRate)) / Math.Sin(moveIndex * 2 + gameEntropyRate) - Math.Cos(moveIndex); + return Convert.ToInt32(Math.Floor(10 * (rate - Math.Floor(rate)))); +} + +void PrintNewBoard() +{ + Print("1 2 3 4 5 6 7 8 9 10"); + Print("X X X X X X X X X X"); + Print(); +} + +void PrintGameBoard(string[] board) +{ + Print("1 2 3 4 5 6 7 8 9 10"); + + foreach (var item in board) + { + Write($"{item} "); + } + + Print(); + Print(); +} + +void PrintGameResult(int gameSum, int stepsCount) +{ + if (gameSum == 10) + { + Print($"VERY GOOD. YOU GUESSED IT IN ONLY {stepsCount} GUESSES."); + } + else + { + Print($"TRY HARDER NEXT TIME. IT TOOK YOU {stepsCount} GUESSES."); + } +} + +void PrintGameInfo() +{ + Print(Tab(32) + "FLIPFLOP"); + Print(Tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Print(); + Print("THE OBJECT OF THIS PUZZLE IS TO CHANGE THIS:"); + Print(); + + Print("X X X X X X X X X X"); + Print(); + Print("TO THIS:"); + Print(); + Print("O O O O O O O O O O"); + Print(); + + Print("BY TYPING THE NUMBER CORRESPONDING TO THE POSITION OF THE"); + Print("LETTER ON SOME NUMBERS, ONE POSITION WILL CHANGE, ON"); + Print("OTHERS, TWO WILL CHANGE. TO RESET LINE TO ALL X'S, TYPE 0"); + Print("(ZERO) AND TO START OVER IN THE MIDDLE OF A GAME, TYPE "); + Print("11 (ELEVEN)."); +} \ No newline at end of file diff --git a/36_Flip_Flop/csharp/FlipFlop.csproj b/36_Flip_Flop/csharp/FlipFlop.csproj new file mode 100644 index 00000000..74abf5c9 --- /dev/null +++ b/36_Flip_Flop/csharp/FlipFlop.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/36_Flip_Flop/csharp/FlipFlop.sln b/36_Flip_Flop/csharp/FlipFlop.sln new file mode 100644 index 00000000..a26f312e --- /dev/null +++ b/36_Flip_Flop/csharp/FlipFlop.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FlipFlop", "FlipFlop.csproj", "{192EDAD4-5EF5-4B11-9EB3-B17FFAD0861F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {192EDAD4-5EF5-4B11-9EB3-B17FFAD0861F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {192EDAD4-5EF5-4B11-9EB3-B17FFAD0861F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {192EDAD4-5EF5-4B11-9EB3-B17FFAD0861F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {192EDAD4-5EF5-4B11-9EB3-B17FFAD0861F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {108E5099-D7AA-4260-B587-1B1FE1AF6B54} + EndGlobalSection +EndGlobal From 68e278095d8168d821eb91fafa8a714240a7708c Mon Sep 17 00:00:00 2001 From: Joseph Nellis Date: Sat, 8 Jan 2022 20:24:12 -0800 Subject: [PATCH 023/337] Add files via upload --- 01_Acey_Ducey/java/src/AceyDucey17.java | 196 ++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 01_Acey_Ducey/java/src/AceyDucey17.java diff --git a/01_Acey_Ducey/java/src/AceyDucey17.java b/01_Acey_Ducey/java/src/AceyDucey17.java new file mode 100644 index 00000000..9b229f0b --- /dev/null +++ b/01_Acey_Ducey/java/src/AceyDucey17.java @@ -0,0 +1,196 @@ +import java.util.Random; +import java.util.Scanner; + +/** + * A modern version (JDK17) of ACEY DUCEY using post Java 8 features. Notes + * regarding new java features or differences in the original basic + * implementation are numbered and at the bottom of this code. + * The goal is to recreate the exact look and feel of the original program + * minus a large glaring bug in the original code that lets you cheat. + */ +public class AceyDucey17 { + + public static void main(String[] args) { + // notes [1] + System.out.println(""" + ACEY DUCEY CARD GAME + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + + ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER + THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP + YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING + ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE + A VALUE BETWEEN THE FIRST TWO. + IF YOU DO NOT WANT TO BET, INPUT A 0"""); + + do { + playGame(); + } while (stillInterested()); + System.out.println("O.K., HOPE YOU HAD FUN!"); + } + + public static void playGame() { + int cashOnHand = 100; // our only mutable variable note [11] + System.out.println("YOU NOW HAVE "+ cashOnHand +" DOLLARS.");// note [6] + while (cashOnHand > 0) { + System.out.println(); + System.out.println("HERE ARE YOUR NEXT TWO CARDS:"); + + final Card lowCard = Card.getRandomCard(2, Card.KING); //note [3] + System.out.println(lowCard); + final Card highCard = Card.getRandomCard(lowCard.rank() + 1, Card.ACE); + System.out.println(highCard); + + final int bet = getBet(cashOnHand); + final int winnings = determineWinnings(lowCard,highCard,bet); + cashOnHand += winnings; + if(winnings != 0){ //note [2] + System.out.println("YOU NOW HAVE "+ cashOnHand +" DOLLARS.");//note [6] + } + } + } + + public static int determineWinnings(Card lowCard, Card highCard, int bet){ + if (bet <= 0) { // note [5] + System.out.println("CHICKEN!!"); + return 0; + } + Card nextCard = Card.getRandomCard(2, Card.ACE); + System.out.println(nextCard); + if(nextCard.between(lowCard,highCard)){ + System.out.println("YOU WIN!!!"); + return bet; + } + System.out.println("SORRY, YOU LOSE"); + return -bet; + } + + public static boolean stillInterested(){ + System.out.println(); + System.out.println(); + System.out.println("SORRY, FRIEND, BUT YOU BLEW YOUR WAD."); + System.out.println(); + System.out.println(); + System.out.println("TRY AGAIN (YES OR NO)"); + Scanner input = new Scanner(System.in); + return input.nextLine() + .toUpperCase() + .startsWith("Y"); // note [9] + } + + public static int getBet(int cashOnHand){ + int bet; + do{ + System.out.println(); + System.out.print("WHAT IS YOUR BET? "); + bet = inputNumber(); + if (bet > cashOnHand) { + System.out.println("SORRY, MY FRIEND, BUT YOU BET TOO MUCH."); + System.out.println("YOU HAVE ONLY "+cashOnHand+" DOLLARS TO BET."); + } + }while(bet > cashOnHand); + return bet; + } + + public static int inputNumber() { + final Scanner input = new Scanner(System.in); + // set to negative to mark as not entered yet in case of input error. + int number = -1; + while (number < 0) { + try { + number = input.nextInt(); + } catch(Exception ex) { // note [7] + System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE"); + System.out.print("? "); + try{ + input.nextLine(); + } + catch(Exception ns_ex){ // received EOF (ctrl-d or ctrl-z if windows) + System.out.println("END OF INPUT, STOPPING PROGRAM."); + System.exit(1); + } + } + } + return number; + } + + record Card(int rank){ + // Some constants to describe face cards. + public static final int JACK = 11, QUEEN = 12, KING = 13, ACE = 14; + private static final Random random = new Random(); + + public static Card getRandomCard(int from, int to){ + return new Card(random.nextInt(from, to+1)); // note [4] + } + + public boolean between(Card lower, Card higher){ + return lower.rank() < this.rank() && this.rank() < higher.rank(); + } + + @Override + public String toString() { // note [13] + return switch (rank) { + case JACK -> "JACK"; + case QUEEN -> "QUEEN"; + case KING -> "KING"; + case ACE -> "ACE\n"; // note [10] + default -> " "+rank+" "; // note [6] + }; + } + } + + /* + Notes: + 1. Multiline strings, a.k.a. text blocks, were added in JDK15. + 2. The original game only displays the players balance if it changed, + which it does not when the player chickens out and bets zero. + 3. To pick two cards to show, the original BASIC implementation has a + bug that could cause a race condition if the RND function never chose + a lower number first and higher number second. It loops infinitely + re-choosing random numbers until the condition is met of the first + one being lower. The logic is changed a bit here so that the first + card picked is anything but an ACE, the highest possible card, + and then the second card is between the just picked first card upto + and including the ACE. + 4. Random.nextInt(origin, bound) was added in JDK17, and allows to + directly pick a range for a random integer to be generated. The second + parameter is exclusive of the range and thus why they are stated with + +1's to the face card. + 5. The original BASIC implementation has a bug that allows negative value + bets. Since you can't bet MORE cash than you have you can always bet + less including a very, very large negative value. You would do this when + the chances of winning are slim or zero since losing a hand SUBTRACTS + your bet from your cash; subtracting a negative number actually ADDS + to your cash, potentially making you an instant billionaire. + This loophole is now closed. + 6. The subtle behavior of the BASIC PRINT command causes a space to be + printed before all positive numbers as well as a trailing space. Any + place a non-face card or the players balance is printed has extra space + to mimic this behavior. + 7. Errors on input were probably specific to the interpreter. This program + tries to match the Vintage Basic interpreter's error messages. The final + input.nextLine() command exists to clear the blockage of whatever + non-number input was entered. But even that could fail if the user + types Ctrl-D (windows Ctrl-Z), signifying an EOF (end of file) and thus + the closing of STDIN channel. The original program on an EOF signal prints + "END OF INPUT IN LINE 660" and thus we cover it roughly the same way. + All of this is necessary to avoid a messy stack trace from being + printed as the program crashes. + 9. The original game only accepted a full upper case "YES" to continue + playing if bankrupted. This program is more lenient and will accept + any input that starts with the letter 'y', uppercase or not. + 10. The original game prints an extra blank line if the card is an ACE. There + is seemingly no rationale for this. + 11. Modern java best practices are edging toward a more functional paradigm + and as such, mutating state is discouraged. All other variables besides + the cashOnHand are final and initialized only once. + 12. Refactoring of the concept of a card is done with a record. Records were + introduced in JDK14. Card functionality is encapsulated in this example + of a record. An enum could be a better alternative since there are + technically only 13 cards possible. + 13. Switch expressions were introduced as far back as JDK12 but continue to + be refined for clarity, exhaustiveness. As of JDK17 pattern matching + for switch expressions can be accessed by enabling preview features. + */ +} From f9a884e22a20edfcfe4753f4bc25d398f44a1ba4 Mon Sep 17 00:00:00 2001 From: xl-c7b3 Date: Sun, 9 Jan 2022 02:49:50 -0500 Subject: [PATCH 024/337] added non-source code exclusions to .gitignore --- .gitignore | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index d2115efc..9dda64ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,18 @@ +.local/ +.vscode/ +.gradle/ +node_modules/ +buildJvm/ + +build.gradle + +.classpath +.project +.settings +.metadata +*.iml +*.ipr + *.class */.vs *.suo @@ -12,6 +27,7 @@ obj/ out/ *.py[co] + Pipfile .DS_Store From 00d6881194180555073ad75736673631b920f1ba Mon Sep 17 00:00:00 2001 From: Joe Nellis Date: Sun, 9 Jan 2022 00:48:55 -0800 Subject: [PATCH 025/337] Only display player balance if balance isn't zero. Small formatting change with replay text. --- 01_Acey_Ducey/java/src/AceyDucey17.java | 397 ++++++++++++------------ 1 file changed, 201 insertions(+), 196 deletions(-) diff --git a/01_Acey_Ducey/java/src/AceyDucey17.java b/01_Acey_Ducey/java/src/AceyDucey17.java index 9b229f0b..6192fc14 100644 --- a/01_Acey_Ducey/java/src/AceyDucey17.java +++ b/01_Acey_Ducey/java/src/AceyDucey17.java @@ -1,196 +1,201 @@ -import java.util.Random; -import java.util.Scanner; - -/** - * A modern version (JDK17) of ACEY DUCEY using post Java 8 features. Notes - * regarding new java features or differences in the original basic - * implementation are numbered and at the bottom of this code. - * The goal is to recreate the exact look and feel of the original program - * minus a large glaring bug in the original code that lets you cheat. - */ -public class AceyDucey17 { - - public static void main(String[] args) { - // notes [1] - System.out.println(""" - ACEY DUCEY CARD GAME - CREATIVE COMPUTING MORRISTOWN, NEW JERSEY - - - ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER - THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP - YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING - ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE - A VALUE BETWEEN THE FIRST TWO. - IF YOU DO NOT WANT TO BET, INPUT A 0"""); - - do { - playGame(); - } while (stillInterested()); - System.out.println("O.K., HOPE YOU HAD FUN!"); - } - - public static void playGame() { - int cashOnHand = 100; // our only mutable variable note [11] - System.out.println("YOU NOW HAVE "+ cashOnHand +" DOLLARS.");// note [6] - while (cashOnHand > 0) { - System.out.println(); - System.out.println("HERE ARE YOUR NEXT TWO CARDS:"); - - final Card lowCard = Card.getRandomCard(2, Card.KING); //note [3] - System.out.println(lowCard); - final Card highCard = Card.getRandomCard(lowCard.rank() + 1, Card.ACE); - System.out.println(highCard); - - final int bet = getBet(cashOnHand); - final int winnings = determineWinnings(lowCard,highCard,bet); - cashOnHand += winnings; - if(winnings != 0){ //note [2] - System.out.println("YOU NOW HAVE "+ cashOnHand +" DOLLARS.");//note [6] - } - } - } - - public static int determineWinnings(Card lowCard, Card highCard, int bet){ - if (bet <= 0) { // note [5] - System.out.println("CHICKEN!!"); - return 0; - } - Card nextCard = Card.getRandomCard(2, Card.ACE); - System.out.println(nextCard); - if(nextCard.between(lowCard,highCard)){ - System.out.println("YOU WIN!!!"); - return bet; - } - System.out.println("SORRY, YOU LOSE"); - return -bet; - } - - public static boolean stillInterested(){ - System.out.println(); - System.out.println(); - System.out.println("SORRY, FRIEND, BUT YOU BLEW YOUR WAD."); - System.out.println(); - System.out.println(); - System.out.println("TRY AGAIN (YES OR NO)"); - Scanner input = new Scanner(System.in); - return input.nextLine() - .toUpperCase() - .startsWith("Y"); // note [9] - } - - public static int getBet(int cashOnHand){ - int bet; - do{ - System.out.println(); - System.out.print("WHAT IS YOUR BET? "); - bet = inputNumber(); - if (bet > cashOnHand) { - System.out.println("SORRY, MY FRIEND, BUT YOU BET TOO MUCH."); - System.out.println("YOU HAVE ONLY "+cashOnHand+" DOLLARS TO BET."); - } - }while(bet > cashOnHand); - return bet; - } - - public static int inputNumber() { - final Scanner input = new Scanner(System.in); - // set to negative to mark as not entered yet in case of input error. - int number = -1; - while (number < 0) { - try { - number = input.nextInt(); - } catch(Exception ex) { // note [7] - System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE"); - System.out.print("? "); - try{ - input.nextLine(); - } - catch(Exception ns_ex){ // received EOF (ctrl-d or ctrl-z if windows) - System.out.println("END OF INPUT, STOPPING PROGRAM."); - System.exit(1); - } - } - } - return number; - } - - record Card(int rank){ - // Some constants to describe face cards. - public static final int JACK = 11, QUEEN = 12, KING = 13, ACE = 14; - private static final Random random = new Random(); - - public static Card getRandomCard(int from, int to){ - return new Card(random.nextInt(from, to+1)); // note [4] - } - - public boolean between(Card lower, Card higher){ - return lower.rank() < this.rank() && this.rank() < higher.rank(); - } - - @Override - public String toString() { // note [13] - return switch (rank) { - case JACK -> "JACK"; - case QUEEN -> "QUEEN"; - case KING -> "KING"; - case ACE -> "ACE\n"; // note [10] - default -> " "+rank+" "; // note [6] - }; - } - } - - /* - Notes: - 1. Multiline strings, a.k.a. text blocks, were added in JDK15. - 2. The original game only displays the players balance if it changed, - which it does not when the player chickens out and bets zero. - 3. To pick two cards to show, the original BASIC implementation has a - bug that could cause a race condition if the RND function never chose - a lower number first and higher number second. It loops infinitely - re-choosing random numbers until the condition is met of the first - one being lower. The logic is changed a bit here so that the first - card picked is anything but an ACE, the highest possible card, - and then the second card is between the just picked first card upto - and including the ACE. - 4. Random.nextInt(origin, bound) was added in JDK17, and allows to - directly pick a range for a random integer to be generated. The second - parameter is exclusive of the range and thus why they are stated with - +1's to the face card. - 5. The original BASIC implementation has a bug that allows negative value - bets. Since you can't bet MORE cash than you have you can always bet - less including a very, very large negative value. You would do this when - the chances of winning are slim or zero since losing a hand SUBTRACTS - your bet from your cash; subtracting a negative number actually ADDS - to your cash, potentially making you an instant billionaire. - This loophole is now closed. - 6. The subtle behavior of the BASIC PRINT command causes a space to be - printed before all positive numbers as well as a trailing space. Any - place a non-face card or the players balance is printed has extra space - to mimic this behavior. - 7. Errors on input were probably specific to the interpreter. This program - tries to match the Vintage Basic interpreter's error messages. The final - input.nextLine() command exists to clear the blockage of whatever - non-number input was entered. But even that could fail if the user - types Ctrl-D (windows Ctrl-Z), signifying an EOF (end of file) and thus - the closing of STDIN channel. The original program on an EOF signal prints - "END OF INPUT IN LINE 660" and thus we cover it roughly the same way. - All of this is necessary to avoid a messy stack trace from being - printed as the program crashes. - 9. The original game only accepted a full upper case "YES" to continue - playing if bankrupted. This program is more lenient and will accept - any input that starts with the letter 'y', uppercase or not. - 10. The original game prints an extra blank line if the card is an ACE. There - is seemingly no rationale for this. - 11. Modern java best practices are edging toward a more functional paradigm - and as such, mutating state is discouraged. All other variables besides - the cashOnHand are final and initialized only once. - 12. Refactoring of the concept of a card is done with a record. Records were - introduced in JDK14. Card functionality is encapsulated in this example - of a record. An enum could be a better alternative since there are - technically only 13 cards possible. - 13. Switch expressions were introduced as far back as JDK12 but continue to - be refined for clarity, exhaustiveness. As of JDK17 pattern matching - for switch expressions can be accessed by enabling preview features. - */ -} +import java.util.Random; +import java.util.Scanner; + +/** + * A modern version (JDK17) of ACEY DUCEY using post Java 8 features. Notes + * regarding new java features or differences in the original basic + * implementation are numbered and at the bottom of this code. + * The goal is to recreate the exact look and feel of the original program + * minus a large glaring bug in the original code that lets you cheat. + */ +public class AceyDucey17 { + + public static void main(String[] args) { + // notes [1] + System.out.println(""" + ACEY DUCEY CARD GAME + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + + ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER + THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP + YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING + ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE + A VALUE BETWEEN THE FIRST TWO. + IF YOU DO NOT WANT TO BET, INPUT A 0"""); + + do { + playGame(); + } while (stillInterested()); + System.out.println("O.K., HOPE YOU HAD FUN!"); + } + + public static void playGame() { + int cashOnHand = 100; // our only mutable variable note [11] + System.out.println("YOU NOW HAVE "+ cashOnHand +" DOLLARS.");// note [6] + while (cashOnHand > 0) { + System.out.println(); + System.out.println("HERE ARE YOUR NEXT TWO CARDS:"); + + final Card lowCard = Card.getRandomCard(2, Card.KING); //note [3] + System.out.println(lowCard); + final Card highCard = Card.getRandomCard(lowCard.rank() + 1, Card.ACE); + System.out.println(highCard); + + final int bet = getBet(cashOnHand); + final int winnings = determineWinnings(lowCard,highCard,bet); + cashOnHand += winnings; + if(winnings != 0 || cashOnHand != 0){ //note [2] + System.out.println("YOU NOW HAVE "+ cashOnHand +" DOLLARS.");//note [6] + } + } + } + + public static int determineWinnings(Card lowCard, Card highCard, int bet){ + if (bet <= 0) { // note [5] + System.out.println("CHICKEN!!"); + return 0; + } + Card nextCard = Card.getRandomCard(2, Card.ACE); + System.out.println(nextCard); + if(nextCard.between(lowCard,highCard)){ + System.out.println("YOU WIN!!!"); + return bet; + } + System.out.println("SORRY, YOU LOSE"); + return -bet; + } + + public static boolean stillInterested(){ + System.out.println(); + System.out.println(); + System.out.println("SORRY, FRIEND, BUT YOU BLEW YOUR WAD."); + System.out.println(); + System.out.println(); + System.out.print("TRY AGAIN (YES OR NO)? "); + Scanner input = new Scanner(System.in); + boolean playAgain = input.nextLine() + .toUpperCase() + .startsWith("Y"); // note [9] + System.out.println(); + System.out.println(); + return playAgain; + } + + public static int getBet(int cashOnHand){ + int bet; + do{ + System.out.println(); + System.out.print("WHAT IS YOUR BET? "); + bet = inputNumber(); + if (bet > cashOnHand) { + System.out.println("SORRY, MY FRIEND, BUT YOU BET TOO MUCH."); + System.out.println("YOU HAVE ONLY "+cashOnHand+" DOLLARS TO BET."); + } + }while(bet > cashOnHand); + return bet; + } + + public static int inputNumber() { + final Scanner input = new Scanner(System.in); + // set to negative to mark as not entered yet in case of input error. + int number = -1; + while (number < 0) { + try { + number = input.nextInt(); + } catch(Exception ex) { // note [7] + System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE"); + System.out.print("? "); + try{ + input.nextLine(); + } + catch(Exception ns_ex){ // received EOF (ctrl-d or ctrl-z if windows) + System.out.println("END OF INPUT, STOPPING PROGRAM."); + System.exit(1); + } + } + } + return number; + } + + record Card(int rank){ + // Some constants to describe face cards. + public static final int JACK = 11, QUEEN = 12, KING = 13, ACE = 14; + private static final Random random = new Random(); + + public static Card getRandomCard(int from, int to){ + return new Card(random.nextInt(from, to+1)); // note [4] + } + + public boolean between(Card lower, Card higher){ + return lower.rank() < this.rank() && this.rank() < higher.rank(); + } + + @Override + public String toString() { // note [13] + return switch (rank) { + case JACK -> "JACK"; + case QUEEN -> "QUEEN"; + case KING -> "KING"; + case ACE -> "ACE\n"; // note [10] + default -> " "+rank+" "; // note [6] + }; + } + } + + /* + Notes: + 1. Multiline strings, a.k.a. text blocks, were added in JDK15. + 2. The original game only displays the players balance if it changed, + which it does not when the player chickens out and bets zero. + It also doesn't display the balance when it becomes zero because it has + a more appropriate message: Sorry, You Lose. + 3. To pick two cards to show, the original BASIC implementation has a + bug that could cause a race condition if the RND function never chose + a lower number first and higher number second. It loops infinitely + re-choosing random numbers until the condition is met of the first + one being lower. The logic is changed a bit here so that the first + card picked is anything but an ACE, the highest possible card, + and then the second card is between the just picked first card upto + and including the ACE. + 4. Random.nextInt(origin, bound) was added in JDK17, and allows to + directly pick a range for a random integer to be generated. The second + parameter is exclusive of the range and thus why they are stated with + +1's to the face card. + 5. The original BASIC implementation has a bug that allows negative value + bets. Since you can't bet MORE cash than you have you can always bet + less including a very, very large negative value. You would do this when + the chances of winning are slim or zero since losing a hand SUBTRACTS + your bet from your cash; subtracting a negative number actually ADDS + to your cash, potentially making you an instant billionaire. + This loophole is now closed. + 6. The subtle behavior of the BASIC PRINT command causes a space to be + printed before all positive numbers as well as a trailing space. Any + place a non-face card or the players balance is printed has extra space + to mimic this behavior. + 7. Errors on input were probably specific to the interpreter. This program + tries to match the Vintage Basic interpreter's error messages. The final + input.nextLine() command exists to clear the blockage of whatever + non-number input was entered. But even that could fail if the user + types Ctrl-D (windows Ctrl-Z), signifying an EOF (end of file) and thus + the closing of STDIN channel. The original program on an EOF signal prints + "END OF INPUT IN LINE 660" and thus we cover it roughly the same way. + All of this is necessary to avoid a messy stack trace from being + printed as the program crashes. + 9. The original game only accepted a full upper case "YES" to continue + playing if bankrupted. This program is more lenient and will accept + any input that starts with the letter 'y', uppercase or not. + 10. The original game prints an extra blank line if the card is an ACE. There + is seemingly no rationale for this. + 11. Modern java best practices are edging toward a more functional paradigm + and as such, mutating state is discouraged. All other variables besides + the cashOnHand are final and initialized only once. + 12. Refactoring of the concept of a card is done with a record. Records were + introduced in JDK14. Card functionality is encapsulated in this example + of a record. An enum could be a better alternative since there are + technically only 13 cards possible. + 13. Switch expressions were introduced as far back as JDK12 but continue to + be refined for clarity, exhaustiveness. As of JDK17 pattern matching + for switch expressions can be accessed by enabling preview features. + */ +} From 513892322e9eef7888f65196b07b38f82a1299bd Mon Sep 17 00:00:00 2001 From: Joseph Nellis Date: Sun, 9 Jan 2022 01:32:41 -0800 Subject: [PATCH 026/337] Update HOW_TO_RUN_THE_GAMES.md Add notice that you really don't need to compile single java files anymore. --- HOW_TO_RUN_THE_GAMES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HOW_TO_RUN_THE_GAMES.md b/HOW_TO_RUN_THE_GAMES.md index 44d82e98..6df23205 100644 --- a/HOW_TO_RUN_THE_GAMES.md +++ b/HOW_TO_RUN_THE_GAMES.md @@ -32,6 +32,8 @@ To run from the command line, you will need a Java SDK (eg. [Oracle JDK](https:/ * eg. `javac AceyDuceyGame.java` 1. Run the compiled program with `java`: * eg. `java AceyDuceyGame` + +or if you are **using JDK11 or later** you can now execute a self contained java file that has a main method directly with `java .java`. ## javascript From b492671bf038d204abb3218e8a2579523b2ccdec Mon Sep 17 00:00:00 2001 From: Tom Wyant Date: Sun, 9 Jan 2022 08:59:40 -0500 Subject: [PATCH 027/337] Revise the documentation for 80_Slots/perl Add instructions on how to restore the BASIC behavior to 80_Slots/perl/slots.pl Add the entire description section of the Perl documentation (including the change I made because I thought the original was a bug, and how to restore the original behavior) to 80_Slots/perl/README.md --- 80_Slots/perl/README.md | 20 ++++++++++++++++++++ 80_Slots/perl/slots.pl | 8 ++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/80_Slots/perl/README.md b/80_Slots/perl/README.md index e69c8b81..3a14d6cf 100644 --- a/80_Slots/perl/README.md +++ b/80_Slots/perl/README.md @@ -1,3 +1,23 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Perl](https://www.perl.org/) + +This Perl script is a port of slots, which is the 80th entry in Basic +Computer Games. + +I know nothing about slot machines, and my research into them says to me +that the payout tables can be fairly arbitrary. But I have taken the +liberty of deeming the BASIC program's refusal to pay on LEMON CHERRY +LEMON a bug, and made that case a double. + +My justification for this is that at the point where the BASIC has +detected the double in the first and third reels it has already detected +that there is no double in the first and second reels. After the check +for a bar (and therefore a double bar) fails it goes back and checks for +a double on the second and third reels. But we know this check will +fail, since the check for a double on the first and second reels failed. +So if a loss was intended at this point, why not just call it a loss? + +To restore the original behavior, comment out the entire line commented +'# Bug fix?' (about line 75) and uncomment the line with the trailing +comment '# Bug?' (about line 83). diff --git a/80_Slots/perl/slots.pl b/80_Slots/perl/slots.pl index b5c1ee39..b6749606 100755 --- a/80_Slots/perl/slots.pl +++ b/80_Slots/perl/slots.pl @@ -72,7 +72,7 @@ while ( 1 ) { # Iterate indefinitely } } elsif ( $reel_x == $reel_z ) { if ( $reel_z ) { - $winnings += double( $bet ); + $winnings += double( $bet ); # Bug fix? # NOTE that the below code is what is actually implemented # in the basic, but it is implemented strangely enough (a # GOTO a line that contains a test that, if I understand the @@ -80,7 +80,7 @@ while ( 1 ) { # Iterate indefinitely # I know nothing about slot machines, but research suggests # the payoff table is fairly arbitrary. The code above makes # code above makes the game orthogonal. - # $winnings += you_lost( $bet ); + # $winnings += you_lost( $bet ); # Bug? } else { $winnings += double_bar( $bet ); } @@ -215,6 +215,10 @@ a double on the second and third reels. But we know this check will fail, since the check for a double on the first and second reels failed. So if a loss was intended at this point, why not just call it a loss? +To restore the original behavior, comment out the entire line commented +C<'# Bug fix?'> (about line 75) and uncomment the line with the trailing +comment C<'# Bug?'> (about line 83). + =head1 PORTED BY Thomas R. Wyant, III F From d0c124a31257fef31d319ed33f166e8f4c32e87b Mon Sep 17 00:00:00 2001 From: Alex Scown Date: Sat, 8 Jan 2022 20:11:47 +0000 Subject: [PATCH 028/337] Initial port Game works, but AI behaves differently to the original. Need to try and remove the globals. --- 04_Awari/ruby/README.md | 2 +- 04_Awari/ruby/awari.rb | 286 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 04_Awari/ruby/awari.rb diff --git a/04_Awari/ruby/README.md b/04_Awari/ruby/README.md index fb32811e..9c8c96bf 100644 --- a/04_Awari/ruby/README.md +++ b/04_Awari/ruby/README.md @@ -1,3 +1,3 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) -Conversion to [Ruby](https://www.ruby-lang.org/en/) +Conversion to [Ruby](https://www.ruby-lang.org/en/) by [Alex Scown](https://github.com/TheScown) diff --git a/04_Awari/ruby/awari.rb b/04_Awari/ruby/awari.rb new file mode 100644 index 00000000..aaf29632 --- /dev/null +++ b/04_Awari/ruby/awari.rb @@ -0,0 +1,286 @@ +require 'strscan' + +def print_beans(beans) + puts + + # Print computer beans + print " " + beans[7..12].reverse.each {|bean_count| print_bean(bean_count)} + puts + + # Print home beans + print_bean(beans[13]) + print ' ' + print_number(beans[6]) # This is not print_bean in line with the original version + puts + + # Print player beans + print " " + beans[0..5].each {|bean_count| print_bean(bean_count)} + puts + + puts +end + +def print_bean(bean_count) + print ' ' if bean_count < 10 + print_number(bean_count) +end + +def print_number(n) + # PRINT adds padding after a number and before a positive number + print ' ' if n >= 0 + print n.to_s + print ' ' +end + +def get_move(prompt, beans) + move = get_integer_input(prompt) + + while move < 1 || move > 6 || beans[move - 1] == 0 + puts "ILLEGAL MOVE" + move = get_integer_input("AGAIN") + end + + move - 1 +end + +def get_integer_input(prompt) + integer_value = nil + + input_values = input(prompt) + + while integer_value.nil? + print '!EXTRA INPUT IGNORED' if (input_values.size > 1) + + value = input_values.first + + begin + integer_value = Integer(value) + rescue + puts '!NUMBER EXPECTED - RETRY INPUT LINE' + input_values = input('') + end + end + + integer_value +end + +def input(prompt) + prompt_suffix = '? ' + print "#{prompt}#{prompt_suffix}" + + input = gets.chomp.strip + scanner = StringScanner.new(input) + input_values = [] + + until scanner.eos? + scanner.scan(/\s+/) + + if scanner.check(/"/) + scanner.scan(/"/) + next_string = scanner.scan_until(/"/) + + if next_string + # Remove the trailing close quote + next_string.chomp!('"') + else + # No close quote – Vintage Basic crashes in this case + raise ArgumentError('Unmatched quotes in input') + end + elsif scanner.exist?(/,/) + next_string = scanner.scan_until(/,/).chomp(',') + else + next_string = scanner.scan_until(/\s+|$/).rstrip + end + + input_values << next_string + end + + input_values << '' if input_values.empty? + + input_values +end + + +def distribute_beans(beans, start_pit, home_pit) + beans_to_distribute = beans[start_pit] + beans[start_pit] = 0 + + current_pit = start_pit + + (0...beans_to_distribute).each do + current_pit = (current_pit + 1) % beans.size + beans[current_pit] += 1 + end + + # If the last pit was empty before we put a bean in it (and it's not a scoring pit), add beans to score + if beans[current_pit] == 1 && current_pit != 6 && current_pit != 13 && beans[12 - current_pit] != 0 + beans[home_pit] = beans[home_pit] + beans[12 - current_pit] + 1 + beans[current_pit] = 0 + beans[12 - current_pit] = 0 + end + + current_pit +end + +def update_internals(beans) + $k = $k - 7 if $k > 6 + $c = $c + 1 + + $f[$n] = $f[$n] * 6 + $k if $c < 9 + + unless beans[0...6].find { |b| b != 0 } && beans[7...13].find { |b| b != 0 } + $game_over = true + end +end + +# @param [Array] beans +# @param [Integer] move +# @param [Integer] home_pit +def perform_move(beans, move, home_pit) + last_pit = distribute_beans(beans, move, home_pit) + + update_internals(beans) + + last_pit +end + +def end_game(beans) + puts + puts "GAME OVER" + + difference = beans[6] - beans[13] + + if difference < 0 + puts "I WIN BY #{-difference} POINTS" + + return + end + + $n += 1 + + puts "YOU WIN BY #{difference} POINTS" if difference > 0 + puts "DRAWN GAME" if difference == 0 +end + +# @param [Array] beans +def get_computer_move(beans) + d = -99 + home_pit = 13 + beans_copy = beans.dup + + move_to_do = 0 + + (7..12).each do |move_under_test| + if beans[move_under_test] == 0 + next + end + + max_score = 0 + + distribute_beans(beans_copy, move_under_test, home_pit) + + (0...6).each do |i| + next if beans_copy[i] == 0 + + l = beans_copy[i] + i + r = l / 14 + l_mod_14 = l % 14 + + r = beans_copy[12 - l_mod_14] + r if beans_copy[l_mod_14] == 0 && l_mod_14 != 6 && l_mod_14 != 13 + + max_score = r if r > max_score + end + + final_score = beans_copy[13] - beans_copy[6] - max_score + + if $c <=8 + $k = move_under_test + $k = $k - 7 if $k > 6 + end + + (1...$n).each do |i| + final_score = final_score - 2 if $f[$n] * 6 + $k == (($f[i]/6 ** (7-$c)) + 0.1).floor + end + + if final_score >= d + move_to_do = move_under_test + d = final_score + end + end + + last_pit = perform_move(beans, move_to_do, home_pit) + + [move_to_do, last_pit] +end + +puts 'AWARI'.center(80) +puts 'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY'.center(80) + +# Initialise stable variables +$f = Array.new(50) +$n = 0 + +# APPLICATION LOOP +:game +while true + print "\n", "\n" + beans = Array.new(13, 3) + beans[6] = 0 + beans[13] = 0 + + $f[$n] = 0 + $game_over = false + $c = 0 + + until $game_over + print_beans(beans) + + move = get_move("YOUR MOVE", beans) + home_pit = 6 + computer_home_pit = 13 + $k = move + + last_pit = perform_move(beans, move, home_pit) + + print_beans(beans) + + if $game_over + end_game(beans) + next :game + end + + if home_pit == last_pit + second_move = get_move("AGAIN", beans) + $k = second_move + + perform_move(beans, second_move, home_pit) + + print_beans(beans) + + if $game_over + end_game(beans) + next :game + end + end + + computer_move, computer_last_pit = get_computer_move(beans) + print "MY MOVE IS #{computer_move - 6}" + + if $game_over + end_game(beans) + next :game + end + + if computer_last_pit == computer_home_pit + second_computer_move, _ = get_computer_move(beans) + print ",#{second_computer_move - 6}" + + if $game_over + end_game(beans) + next :game + end + end + end +end From 7239ca244ef590a1a6c4d28b143ca9c4f764e401 Mon Sep 17 00:00:00 2001 From: Alex Scown Date: Sun, 9 Jan 2022 12:41:49 +0000 Subject: [PATCH 029/337] Fix AI The issue was not resetting the clone array for every test move. Clarify some variable names. Shout out to Flavio Poletti for the comments on the Perl translation. --- 04_Awari/ruby/awari.rb | 56 ++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/04_Awari/ruby/awari.rb b/04_Awari/ruby/awari.rb index aaf29632..fa149d5f 100644 --- a/04_Awari/ruby/awari.rb +++ b/04_Awari/ruby/awari.rb @@ -125,7 +125,7 @@ def distribute_beans(beans, start_pit, home_pit) end def update_internals(beans) - $k = $k - 7 if $k > 6 + $k = $k % 7 $c = $c + 1 $f[$n] = $f[$n] * 6 + $k if $c < 9 @@ -168,51 +168,65 @@ end def get_computer_move(beans) d = -99 home_pit = 13 - beans_copy = beans.dup - move_to_do = 0 + chosen_move = 7 - (7..12).each do |move_under_test| - if beans[move_under_test] == 0 - next - end + # Test all possible moves + (7...13).each do |move_under_test| + # Create a copy of the beans to test against + beans_copy = beans.dup - max_score = 0 + # If the move is not legal, skip it + next if beans[move_under_test] == 0 + # Determine the best response the player may make to this move + player_max_score = 0 + + # Make the move under test against the copy distribute_beans(beans_copy, move_under_test, home_pit) + # Test every player response (0...6).each do |i| + # Skip the move if it would be illegal next if beans_copy[i] == 0 - l = beans_copy[i] + i - r = l / 14 - l_mod_14 = l % 14 + # Determine the last + landing_with_overflow = beans_copy[i] + i + # If landing > 13 the player has put a bean in both home pits + player_move_score = (landing_with_overflow > 14) ? 1 : 0 + # Find the actual pit + landing = landing_with_overflow % 14 - r = beans_copy[12 - l_mod_14] + r if beans_copy[l_mod_14] == 0 && l_mod_14 != 6 && l_mod_14 != 13 + # If the landing pit is empty, the player will steal beans + if beans_copy[landing] == 0 && landing != 6 && landing != 13 + player_move_score = beans_copy[12 - landing] + player_move_score + end - max_score = r if r > max_score + # Update the max score if this move is the best player move + player_max_score = player_move_score if player_move_score > player_max_score end - final_score = beans_copy[13] - beans_copy[6] - max_score + # Final score for move is computer score, minus the player's score and any player gains from their best move + final_score = beans_copy[13] - beans_copy[6] - player_max_score if $c <=8 - $k = move_under_test - $k = $k - 7 if $k > 6 + $k = move_under_test % 7 end - (1...$n).each do |i| - final_score = final_score - 2 if $f[$n] * 6 + $k == (($f[i]/6 ** (7-$c)) + 0.1).floor + (0...$n).each do |i| + final_score = final_score - 2 if $f[$n] * 6 + $k == ((Float($f[i])/6 ** (7-$c)) + 0.1).floor end + # Choose the move if it is the best move found so far if final_score >= d - move_to_do = move_under_test + chosen_move = move_under_test d = final_score end end - last_pit = perform_move(beans, move_to_do, home_pit) + last_pit = perform_move(beans, chosen_move, home_pit) - [move_to_do, last_pit] + [chosen_move, last_pit] end puts 'AWARI'.center(80) From 2fa142a246be226b4779e93fef5e7d8e9803f075 Mon Sep 17 00:00:00 2001 From: Alex Scown Date: Sun, 9 Jan 2022 12:51:48 +0000 Subject: [PATCH 030/337] Remove k global --- 04_Awari/ruby/awari.rb | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/04_Awari/ruby/awari.rb b/04_Awari/ruby/awari.rb index fa149d5f..466f1c71 100644 --- a/04_Awari/ruby/awari.rb +++ b/04_Awari/ruby/awari.rb @@ -124,11 +124,11 @@ def distribute_beans(beans, start_pit, home_pit) current_pit end -def update_internals(beans) - $k = $k % 7 +def update_internals(beans, current_move) + k = current_move % 7 $c = $c + 1 - $f[$n] = $f[$n] * 6 + $k if $c < 9 + $f[$n] = $f[$n] * 6 + k if $c < 9 unless beans[0...6].find { |b| b != 0 } && beans[7...13].find { |b| b != 0 } $game_over = true @@ -141,7 +141,7 @@ end def perform_move(beans, move, home_pit) last_pit = distribute_beans(beans, move, home_pit) - update_internals(beans) + update_internals(beans, move) last_pit end @@ -210,11 +210,11 @@ def get_computer_move(beans) final_score = beans_copy[13] - beans_copy[6] - player_max_score if $c <=8 - $k = move_under_test % 7 - end + k = move_under_test % 7 - (0...$n).each do |i| - final_score = final_score - 2 if $f[$n] * 6 + $k == ((Float($f[i])/6 ** (7-$c)) + 0.1).floor + (0...$n).each do |i| + final_score = final_score - 2 if $f[$n] * 6 + k == ((Float($f[i])/6 ** (7-$c)) + 0.1).floor + end end # Choose the move if it is the best move found so far @@ -254,7 +254,6 @@ while true move = get_move("YOUR MOVE", beans) home_pit = 6 computer_home_pit = 13 - $k = move last_pit = perform_move(beans, move, home_pit) @@ -267,7 +266,6 @@ while true if home_pit == last_pit second_move = get_move("AGAIN", beans) - $k = second_move perform_move(beans, second_move, home_pit) From a0fdf42166232e7825cbfd7dcbbb6e496f94b084 Mon Sep 17 00:00:00 2001 From: Alex Scown Date: Sun, 9 Jan 2022 13:19:18 +0000 Subject: [PATCH 031/337] Initial conversion to class --- 04_Awari/ruby/awari.rb | 150 ++++++++++++++++++++++------------------- 1 file changed, 82 insertions(+), 68 deletions(-) diff --git a/04_Awari/ruby/awari.rb b/04_Awari/ruby/awari.rb index 466f1c71..cd57132c 100644 --- a/04_Awari/ruby/awari.rb +++ b/04_Awari/ruby/awari.rb @@ -5,7 +5,7 @@ def print_beans(beans) # Print computer beans print " " - beans[7..12].reverse.each {|bean_count| print_bean(bean_count)} + beans[7..12].reverse.each { |bean_count| print_bean(bean_count) } puts # Print home beans @@ -16,7 +16,7 @@ def print_beans(beans) # Print player beans print " " - beans[0..5].each {|bean_count| print_bean(bean_count)} + beans[0..5].each { |bean_count| print_bean(bean_count) } puts puts @@ -102,7 +102,6 @@ def input(prompt) input_values end - def distribute_beans(beans, start_pit, home_pit) beans_to_distribute = beans[start_pit] beans[start_pit] = 0 @@ -124,15 +123,11 @@ def distribute_beans(beans, start_pit, home_pit) current_pit end -def update_internals(beans, current_move) +def update_history(current_move) k = current_move % 7 $c = $c + 1 - $f[$n] = $f[$n] * 6 + k if $c < 9 - - unless beans[0...6].find { |b| b != 0 } && beans[7...13].find { |b| b != 0 } - $game_over = true - end + $history[$non_win_count] = $history[$non_win_count] * 6 + k if $c < 9 end # @param [Array] beans @@ -141,11 +136,12 @@ end def perform_move(beans, move, home_pit) last_pit = distribute_beans(beans, move, home_pit) - update_internals(beans, move) + update_history(move) last_pit end +# @return [Boolean] True if the computer did not win def end_game(beans) puts puts "GAME OVER" @@ -158,10 +154,12 @@ def end_game(beans) return end - $n += 1 + $non_win_count += 1 puts "YOU WIN BY #{difference} POINTS" if difference > 0 puts "DRAWN GAME" if difference == 0 + + difference >= 0 end # @param [Array] beans @@ -209,11 +207,11 @@ def get_computer_move(beans) # Final score for move is computer score, minus the player's score and any player gains from their best move final_score = beans_copy[13] - beans_copy[6] - player_max_score - if $c <=8 + if $c < 9 k = move_under_test % 7 - (0...$n).each do |i| - final_score = final_score - 2 if $f[$n] * 6 + k == ((Float($f[i])/6 ** (7-$c)) + 0.1).floor + (0...$non_win_count).each do |i| + final_score = final_score - 2 if $history[$non_win_count] * 6 + k == ((Float($history[i]) / 6 ** (7 - $c)) + 0.1).floor end end @@ -229,70 +227,86 @@ def get_computer_move(beans) [chosen_move, last_pit] end +class Game + def initialize(history, non_win_count) + @beans = Array.new(13, 3) + @beans[6] = 0 + @beans[13] = 0 + + @turn_counter = 0 + + @history = history + @non_win_count = non_win_count + end + + def game_over + @beans[0...6].all? { |b| b == 0 } || @beans[7...13].all? { |b| b == 0 } + end + + def play + until game_over + print_beans(@beans) + + move = get_move("YOUR MOVE", @beans) + home_pit = 6 + computer_home_pit = 13 + + last_pit = perform_move(@beans, move, home_pit) + + print_beans(@beans) + + if game_over + return end_game(@beans) + end + + if home_pit == last_pit + second_move = get_move("AGAIN", @beans) + + perform_move(@beans, second_move, home_pit) + + print_beans(@beans) + + if game_over + return end_game(@beans) + end + end + + computer_move, computer_last_pit = get_computer_move(@beans) + print "MY MOVE IS #{computer_move - 6}" + + if game_over + return end_game(@beans) + end + + if computer_last_pit == computer_home_pit + second_computer_move, _ = get_computer_move(@beans) + print ",#{second_computer_move - 6}" + + if game_over + return end_game(@beans) + end + end + end + end + +end + puts 'AWARI'.center(80) puts 'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY'.center(80) # Initialise stable variables -$f = Array.new(50) -$n = 0 +$history = Array.new(50) +$non_win_count = 0 # APPLICATION LOOP -:game while true print "\n", "\n" - beans = Array.new(13, 3) - beans[6] = 0 - beans[13] = 0 - $f[$n] = 0 - $game_over = false + $history[$non_win_count] = 0 $c = 0 - until $game_over - print_beans(beans) + game = Game.new($history, $non_win_count) - move = get_move("YOUR MOVE", beans) - home_pit = 6 - computer_home_pit = 13 - - last_pit = perform_move(beans, move, home_pit) - - print_beans(beans) - - if $game_over - end_game(beans) - next :game - end - - if home_pit == last_pit - second_move = get_move("AGAIN", beans) - - perform_move(beans, second_move, home_pit) - - print_beans(beans) - - if $game_over - end_game(beans) - next :game - end - end - - computer_move, computer_last_pit = get_computer_move(beans) - print "MY MOVE IS #{computer_move - 6}" - - if $game_over - end_game(beans) - next :game - end - - if computer_last_pit == computer_home_pit - second_computer_move, _ = get_computer_move(beans) - print ",#{second_computer_move - 6}" - - if $game_over - end_game(beans) - next :game - end - end - end + computer_didnt_win = game.play + $non_win_count += 1 if computer_didnt_win end From 5195ef74c673094e2290ea38f3f77b5af7102865 Mon Sep 17 00:00:00 2001 From: Alex Scown Date: Sun, 9 Jan 2022 13:55:27 +0000 Subject: [PATCH 032/337] Move remaining functions into class --- 04_Awari/ruby/awari.rb | 453 ++++++++++++++++++++--------------------- 1 file changed, 223 insertions(+), 230 deletions(-) diff --git a/04_Awari/ruby/awari.rb b/04_Awari/ruby/awari.rb index cd57132c..a9864dc7 100644 --- a/04_Awari/ruby/awari.rb +++ b/04_Awari/ruby/awari.rb @@ -1,32 +1,5 @@ require 'strscan' -def print_beans(beans) - puts - - # Print computer beans - print " " - beans[7..12].reverse.each { |bean_count| print_bean(bean_count) } - puts - - # Print home beans - print_bean(beans[13]) - print ' ' - print_number(beans[6]) # This is not print_bean in line with the original version - puts - - # Print player beans - print " " - beans[0..5].each { |bean_count| print_bean(bean_count) } - puts - - puts -end - -def print_bean(bean_count) - print ' ' if bean_count < 10 - print_number(bean_count) -end - def print_number(n) # PRINT adds padding after a number and before a positive number print ' ' if n >= 0 @@ -34,38 +7,6 @@ def print_number(n) print ' ' end -def get_move(prompt, beans) - move = get_integer_input(prompt) - - while move < 1 || move > 6 || beans[move - 1] == 0 - puts "ILLEGAL MOVE" - move = get_integer_input("AGAIN") - end - - move - 1 -end - -def get_integer_input(prompt) - integer_value = nil - - input_values = input(prompt) - - while integer_value.nil? - print '!EXTRA INPUT IGNORED' if (input_values.size > 1) - - value = input_values.first - - begin - integer_value = Integer(value) - rescue - puts '!NUMBER EXPECTED - RETRY INPUT LINE' - input_values = input('') - end - end - - integer_value -end - def input(prompt) prompt_suffix = '? ' print "#{prompt}#{prompt_suffix}" @@ -102,131 +43,6 @@ def input(prompt) input_values end -def distribute_beans(beans, start_pit, home_pit) - beans_to_distribute = beans[start_pit] - beans[start_pit] = 0 - - current_pit = start_pit - - (0...beans_to_distribute).each do - current_pit = (current_pit + 1) % beans.size - beans[current_pit] += 1 - end - - # If the last pit was empty before we put a bean in it (and it's not a scoring pit), add beans to score - if beans[current_pit] == 1 && current_pit != 6 && current_pit != 13 && beans[12 - current_pit] != 0 - beans[home_pit] = beans[home_pit] + beans[12 - current_pit] + 1 - beans[current_pit] = 0 - beans[12 - current_pit] = 0 - end - - current_pit -end - -def update_history(current_move) - k = current_move % 7 - $c = $c + 1 - - $history[$non_win_count] = $history[$non_win_count] * 6 + k if $c < 9 -end - -# @param [Array] beans -# @param [Integer] move -# @param [Integer] home_pit -def perform_move(beans, move, home_pit) - last_pit = distribute_beans(beans, move, home_pit) - - update_history(move) - - last_pit -end - -# @return [Boolean] True if the computer did not win -def end_game(beans) - puts - puts "GAME OVER" - - difference = beans[6] - beans[13] - - if difference < 0 - puts "I WIN BY #{-difference} POINTS" - - return - end - - $non_win_count += 1 - - puts "YOU WIN BY #{difference} POINTS" if difference > 0 - puts "DRAWN GAME" if difference == 0 - - difference >= 0 -end - -# @param [Array] beans -def get_computer_move(beans) - d = -99 - home_pit = 13 - - chosen_move = 7 - - # Test all possible moves - (7...13).each do |move_under_test| - # Create a copy of the beans to test against - beans_copy = beans.dup - - # If the move is not legal, skip it - next if beans[move_under_test] == 0 - - # Determine the best response the player may make to this move - player_max_score = 0 - - # Make the move under test against the copy - distribute_beans(beans_copy, move_under_test, home_pit) - - # Test every player response - (0...6).each do |i| - # Skip the move if it would be illegal - next if beans_copy[i] == 0 - - # Determine the last - landing_with_overflow = beans_copy[i] + i - # If landing > 13 the player has put a bean in both home pits - player_move_score = (landing_with_overflow > 14) ? 1 : 0 - # Find the actual pit - landing = landing_with_overflow % 14 - - # If the landing pit is empty, the player will steal beans - if beans_copy[landing] == 0 && landing != 6 && landing != 13 - player_move_score = beans_copy[12 - landing] + player_move_score - end - - # Update the max score if this move is the best player move - player_max_score = player_move_score if player_move_score > player_max_score - end - - # Final score for move is computer score, minus the player's score and any player gains from their best move - final_score = beans_copy[13] - beans_copy[6] - player_max_score - - if $c < 9 - k = move_under_test % 7 - - (0...$non_win_count).each do |i| - final_score = final_score - 2 if $history[$non_win_count] * 6 + k == ((Float($history[i]) / 6 ** (7 - $c)) + 0.1).floor - end - end - - # Choose the move if it is the best move found so far - if final_score >= d - chosen_move = move_under_test - d = final_score - end - end - - last_pit = perform_move(beans, chosen_move, home_pit) - - [chosen_move, last_pit] -end - class Game def initialize(history, non_win_count) @beans = Array.new(13, 3) @@ -239,74 +55,251 @@ class Game @non_win_count = non_win_count end + def play + while true + print_beans + + move = get_move("YOUR MOVE") + home_pit = 6 + computer_home_pit = 13 + + last_pit = perform_move(move, home_pit) + + print_beans + + break if game_over + + if home_pit == last_pit + second_move = get_move("AGAIN") + + perform_move(second_move, home_pit) + + print_beans + + break if game_over + end + + computer_move, computer_last_pit = get_computer_move + print "MY MOVE IS #{computer_move - 6}" + + break if game_over + + if computer_last_pit == computer_home_pit + second_computer_move, _ = get_computer_move + print ",#{second_computer_move - 6}" + + break if game_over + end + end + + end_game + end + + private + def game_over @beans[0...6].all? { |b| b == 0 } || @beans[7...13].all? { |b| b == 0 } end - def play - until game_over - print_beans(@beans) + # @return [Boolean] True if the computer did not win + def end_game + puts + puts "GAME OVER" - move = get_move("YOUR MOVE", @beans) - home_pit = 6 - computer_home_pit = 13 + difference = @beans[6] - @beans[13] - last_pit = perform_move(@beans, move, home_pit) + if difference < 0 + puts "I WIN BY #{-difference} POINTS" - print_beans(@beans) - - if game_over - return end_game(@beans) - end - - if home_pit == last_pit - second_move = get_move("AGAIN", @beans) - - perform_move(@beans, second_move, home_pit) - - print_beans(@beans) - - if game_over - return end_game(@beans) - end - end - - computer_move, computer_last_pit = get_computer_move(@beans) - print "MY MOVE IS #{computer_move - 6}" - - if game_over - return end_game(@beans) - end - - if computer_last_pit == computer_home_pit - second_computer_move, _ = get_computer_move(@beans) - print ",#{second_computer_move - 6}" - - if game_over - return end_game(@beans) - end - end + return end + + puts "YOU WIN BY #{difference} POINTS" if difference > 0 + puts "DRAWN GAME" if difference == 0 + + difference >= 0 end + # @param [Integer] move + # @param [Integer] home_pit + def perform_move(move, home_pit) + last_pit = distribute_beans(move, home_pit) + + update_history(move) + + last_pit + end + + def update_history(current_move) + k = current_move % 7 + @turn_counter += 1 + + # Add the move to the history + @history[@non_win_count] = @history[@non_win_count] * 6 + k if @turn_counter < 9 + end + + def print_beans + puts + + # Print computer beans + print ' ' * 3 + @beans[7...13].reverse.each { |bean_count| print_bean(bean_count) } + puts + + # Print home beans + print_bean(@beans[13]) + print ' ' * 23 + print_number(@beans[6]) # This is not print_bean in line with the original version + puts + + # Print player beans + print ' ' * 3 + @beans[0...6].each { |bean_count| print_bean(bean_count) } + puts + + puts + end + + def get_move(prompt) + move = get_integer_input(prompt) + + while move < 1 || move > 6 || @beans[move - 1] == 0 + puts "ILLEGAL MOVE" + move = get_integer_input("AGAIN") + end + + move - 1 + end + + def distribute_beans(start_pit, home_pit, beans = @beans) + beans_to_distribute = beans[start_pit] + beans[start_pit] = 0 + + current_pit = start_pit + + (0...beans_to_distribute).each do + current_pit = (current_pit + 1) % beans.size + beans[current_pit] += 1 + end + + # If the last pit was empty before we put a bean in it (and it's not a scoring pit), add beans to score + if beans[current_pit] == 1 && current_pit != 6 && current_pit != 13 && beans[12 - current_pit] != 0 + beans[home_pit] = beans[home_pit] + beans[12 - current_pit] + 1 + beans[current_pit] = 0 + beans[12 - current_pit] = 0 + end + + current_pit + end + + def print_bean(bean_count) + print ' ' if bean_count < 10 + print_number(bean_count) + end + + def get_integer_input(prompt) + integer_value = nil + + input_values = input(prompt) + + while integer_value.nil? + print '!EXTRA INPUT IGNORED' if (input_values.size > 1) + + value = input_values.first + + begin + integer_value = Integer(value) + rescue + puts '!NUMBER EXPECTED - RETRY INPUT LINE' + input_values = input('') + end + end + + integer_value + end + + # @param [Array] beans + def get_computer_move + d = -99 + home_pit = 13 + + chosen_move = 7 + + # Test all possible moves + (7...13).each do |move_under_test| + # Create a copy of the beans to test against + beans_copy = @beans.dup + + # If the move is not legal, skip it + next if beans_copy[move_under_test] == 0 + + # Determine the best response the player may make to this move + player_max_score = 0 + + # Make the move under test against the copy + distribute_beans(move_under_test, home_pit, beans_copy) + + # Test every player response + (0...6).each do |i| + # Skip the move if it would be illegal + next if beans_copy[i] == 0 + + # Determine the last + landing_with_overflow = beans_copy[i] + i + # If landing > 13 the player has put a bean in both home pits + player_move_score = (landing_with_overflow > 14) ? 1 : 0 + # Find the actual pit + landing = landing_with_overflow % 14 + + # If the landing pit is empty, the player will steal beans + if beans_copy[landing] == 0 && landing != 6 && landing != 13 + player_move_score = beans_copy[12 - landing] + player_move_score + end + + # Update the max score if this move is the best player move + player_max_score = player_move_score if player_move_score > player_max_score + end + + # Final score for move is computer score, minus the player's score and any player gains from their best move + final_score = beans_copy[13] - beans_copy[6] - player_max_score + + if @turn_counter < 9 + k = move_under_test % 7 + + (0...@non_win_count).each do |i| + # Penalise move if it was used in a losing game + final_score = final_score - 2 if @history[@non_win_count] * 6 + k == ((Float(@history[i]) / 6 ** (7 - @turn_counter)) + 0.1).floor + end + end + + # Choose the move if it is the best move found so far + if final_score >= d + chosen_move = move_under_test + d = final_score + end + end + + last_pit = perform_move(chosen_move, home_pit) + + [chosen_move, last_pit] + end end puts 'AWARI'.center(80) puts 'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY'.center(80) # Initialise stable variables -$history = Array.new(50) -$non_win_count = 0 +history = Array.new(50) +non_win_count = 0 # APPLICATION LOOP while true print "\n", "\n" - $history[$non_win_count] = 0 - $c = 0 + history[non_win_count] = 0 - game = Game.new($history, $non_win_count) + game = Game.new(history, non_win_count) computer_didnt_win = game.play - $non_win_count += 1 if computer_didnt_win + non_win_count += 1 if computer_didnt_win end From 10a2f535ebed117a68e8782dfe1edd24d612529e Mon Sep 17 00:00:00 2001 From: Alex Scown Date: Sun, 9 Jan 2022 14:12:00 +0000 Subject: [PATCH 033/337] Final tidy --- 04_Awari/ruby/awari.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/04_Awari/ruby/awari.rb b/04_Awari/ruby/awari.rb index a9864dc7..65e27c25 100644 --- a/04_Awari/ruby/awari.rb +++ b/04_Awari/ruby/awari.rb @@ -1,5 +1,7 @@ require 'strscan' +# Prints a number according to Vintage Basic's PRINT statement +# @param n The number to print def print_number(n) # PRINT adds padding after a number and before a positive number print ' ' if n >= 0 @@ -7,6 +9,9 @@ def print_number(n) print ' ' end +# Mimic the INPUT statement using Vintage Basic as a reference +# @param prompt The prompt to show to the user +# @return An array of strings representing the inputted values def input(prompt) prompt_suffix = '? ' print "#{prompt}#{prompt_suffix}" @@ -55,6 +60,7 @@ class Game @non_win_count = non_win_count end + # @return [Boolean] True if the computer did not win the game def play while true print_beans @@ -218,7 +224,6 @@ class Game integer_value end - # @param [Array] beans def get_computer_move d = -99 home_pit = 13 @@ -294,7 +299,8 @@ non_win_count = 0 # APPLICATION LOOP while true - print "\n", "\n" + puts + puts history[non_win_count] = 0 From 63100a55921e863064de7fe7f7e09c848c13b29d Mon Sep 17 00:00:00 2001 From: Alex Scown Date: Sun, 9 Jan 2022 14:29:39 +0000 Subject: [PATCH 034/337] Fix unmatched quotes error --- 04_Awari/ruby/awari.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04_Awari/ruby/awari.rb b/04_Awari/ruby/awari.rb index 65e27c25..6c68a4e0 100644 --- a/04_Awari/ruby/awari.rb +++ b/04_Awari/ruby/awari.rb @@ -32,7 +32,7 @@ def input(prompt) next_string.chomp!('"') else # No close quote – Vintage Basic crashes in this case - raise ArgumentError('Unmatched quotes in input') + raise 'Unmatched quotes in input' end elsif scanner.exist?(/,/) next_string = scanner.scan_until(/,/).chomp(',') From 3dacdcc878e4c74e80c7027e60639d4760a1cae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=8C=AF=E8=80=80?= Date: Sun, 9 Jan 2022 23:51:08 +0800 Subject: [PATCH 035/337] Ignore program-independent content generated by VisualStudio --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d2115efc..c3aa9f13 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ out/ Pipfile .DS_Store +/.vs/basic-computer-games/v16 +/.vs From d2e2b920f1fced0d6d3c049e349c3b8017718a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=8C=AF=E8=80=80?= Date: Sun, 9 Jan 2022 23:54:29 +0800 Subject: [PATCH 036/337] 93_23_Matches\csharp The program is available in two versions, a "goto" version that mimics the original program and an "object-oriented" version. --- 93_23_Matches/csharp/23matches.csproj | 9 + 93_23_Matches/csharp/23matches.sln | 25 +++ 93_23_Matches/csharp/Goto.Program.cs | 129 ++++++++++++++ .../csharp/ObjectOrientedVersion.Program.cs | 161 ++++++++++++++++++ 93_23_Matches/csharp/README.md | 2 + 5 files changed, 326 insertions(+) create mode 100644 93_23_Matches/csharp/23matches.csproj create mode 100644 93_23_Matches/csharp/23matches.sln create mode 100644 93_23_Matches/csharp/Goto.Program.cs create mode 100644 93_23_Matches/csharp/ObjectOrientedVersion.Program.cs diff --git a/93_23_Matches/csharp/23matches.csproj b/93_23_Matches/csharp/23matches.csproj new file mode 100644 index 00000000..11091f71 --- /dev/null +++ b/93_23_Matches/csharp/23matches.csproj @@ -0,0 +1,9 @@ + + + + Exe + netcoreapp3.1 + _23matches + + + diff --git a/93_23_Matches/csharp/23matches.sln b/93_23_Matches/csharp/23matches.sln new file mode 100644 index 00000000..78fce16e --- /dev/null +++ b/93_23_Matches/csharp/23matches.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32002.261 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "23matches", "23matches.csproj", "{9DBE7354-0749-4750-9224-5F9F95C64905}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9DBE7354-0749-4750-9224-5F9F95C64905}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9DBE7354-0749-4750-9224-5F9F95C64905}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9DBE7354-0749-4750-9224-5F9F95C64905}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9DBE7354-0749-4750-9224-5F9F95C64905}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0A87AE2F-68AC-4354-9C8D-578209D41174} + EndGlobalSection +EndGlobal diff --git a/93_23_Matches/csharp/Goto.Program.cs b/93_23_Matches/csharp/Goto.Program.cs new file mode 100644 index 00000000..e23be8a4 --- /dev/null +++ b/93_23_Matches/csharp/Goto.Program.cs @@ -0,0 +1,129 @@ +using System; +using System.Threading; + +namespace _23matches +{ + class Program + { + /// + /// Mimics the "goto" version of the original program + /// + /// + static void Main(string[] args) + { + Random random = new Random(); + StartNewGame: + Console.WriteLine("23 MATCHES".PadLeft(31)); + Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY".PadLeft(15)); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("THIS IS A GAME CALLED '23 MATCHES'."); + Console.WriteLine(); + Console.WriteLine("WHEN IT IS YOUR TURN, YOU MAY TAKE ONE, TWO, OR THREE"); + Console.WriteLine("MATCHES. THE OBJECT OF THE GAME IS NOT TO HAVE TO TAKE"); + Console.WriteLine("THE LAST MATCH."); + Console.WriteLine(); + Console.WriteLine("Input exit to close the program."); + Console.WriteLine("Input cls Screen Clear."); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("LET'S FLIP A COIN TO SEE WHO GOES FIRST."); + Console.WriteLine("IF IT COMES UP HEADS, I WILL WIN THE TOSS."); + Console.WriteLine(); + StartTheGame: + string command; + int N = 23; + int K = 0; + int Q = random.Next(2); + if (Q == 1) + goto ComputerFirst; + else + goto PlayerFirst; + + ComputerFirst: + Console.WriteLine("HEADS! I WIN! HA! HA!"); + Console.WriteLine("PREPARE TO LOSE, MEATBALL-NOSE!!"); + Console.WriteLine(); + int ain = random.Next(1, 3); + Console.WriteLine($"I TAKE {ain} MATCHES"); + N = N - ain; + goto PlayersProceed; + + PlayerFirst: + Console.WriteLine("TAILS! YOU GO FIRST. "); + Console.WriteLine(); + goto PlayersSpeak; + + PlayersProceed: + Console.WriteLine($"THE NUMBER OF MATCHES IS NOW {N}"); + Console.WriteLine(); + Console.WriteLine("YOUR TURN -- YOU MAY TAKE 1, 2 OR 3 MATCHES."); + Console.WriteLine("HOW MANY DO YOU WISH TO REMOVE "); + goto PlayersSpeak; + + PlayersSpeak: + command = Console.ReadLine().ToLower(); + if (command.Equals("exit")) + { + System.Diagnostics.Process tt = System.Diagnostics.Process.GetProcessById(System.Diagnostics.Process.GetCurrentProcess().Id); + tt.Kill(); + } + if (command.Equals("cls")) + { + Console.Clear(); + goto PlayersProceed; + } + try + { + K = Convert.ToInt32(command); + } + catch (System.Exception) + { + goto PlayerInputError; + } + if (K > 3 || K <= 0) + goto PlayerInputError; + N = N - K; + Console.WriteLine($"THERE ARE NOW {N} MATCHES REMAINING."); + if (N == 4 || N == 3 || N == 2) + goto TheComputerSpeaks; + else if (N <= 1) + goto ThePlayerWins; + else + goto TheComputerSpeaks; + + TheComputerSpeaks: + int Z = 4 - K; + Console.WriteLine($"MY TURN ! I REMOVE {Z} MATCHES"); + N = N - Z; + if (N <= 1) + goto TheComputerWins; + else + goto PlayersProceed; + + PlayerInputError: + Console.WriteLine("VERY FUNNY! DUMMY!"); + Console.WriteLine("DO YOU WANT TO PLAY OR GOOF AROUND?"); + Console.WriteLine("NOW, HOW MANY MATCHES DO YOU WANT "); + goto PlayersSpeak; + ThePlayerWins: + Console.WriteLine("YOU WON, FLOPPY EARS !"); + Console.WriteLine("THINK YOU'RE PRETTY SMART !"); + Console.WriteLine("LETS PLAY AGAIN AND I'LL BLOW YOUR SHOES OFF !!"); + Console.WriteLine(); + Console.WriteLine(); + goto StartTheGame; + TheComputerWins: + Console.WriteLine(); + Console.WriteLine("YOU POOR BOOB! YOU TOOK THE LAST MATCH! I GOTCHA!!"); + Console.WriteLine("HA ! HA ! I BEAT YOU !!!"); + Console.WriteLine(); + Console.WriteLine("GOOD BYE LOSER!"); + Console.WriteLine(); + Console.WriteLine(); + goto StartNewGame; + + } + } +} diff --git a/93_23_Matches/csharp/ObjectOrientedVersion.Program.cs b/93_23_Matches/csharp/ObjectOrientedVersion.Program.cs new file mode 100644 index 00000000..7b88d7b7 --- /dev/null +++ b/93_23_Matches/csharp/ObjectOrientedVersion.Program.cs @@ -0,0 +1,161 @@ +using System; +using System.Threading; + +namespace _23matches +{ + class ObjectOrientedVersion_Program + { + /// + /// Object-oriented version + /// + /// + static void Main_Two(string[] args) + { + Game game = new Game(); + game.GameRun(); + } + } + public class Game + { + string command; + int N; + int K; + Random random = new Random(); + public void GameRun() + { + StartNewGame(); + StartTheGame(); + } + void StartNewGame() + { + Console.WriteLine("23 MATCHES".PadLeft(31)); + Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY".PadLeft(15)); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("THIS IS A GAME CALLED '23 MATCHES'."); + Console.WriteLine(); + Console.WriteLine("WHEN IT IS YOUR TURN, YOU MAY TAKE ONE, TWO, OR THREE"); + Console.WriteLine("MATCHES. THE OBJECT OF THE GAME IS NOT TO HAVE TO TAKE"); + Console.WriteLine("THE LAST MATCH."); + Console.WriteLine(); + Console.WriteLine("Input exit to close the program."); + Console.WriteLine("Input cls Screen Clear."); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("LET'S FLIP A COIN TO SEE WHO GOES FIRST."); + Console.WriteLine("IF IT COMES UP HEADS, I WILL WIN THE TOSS."); + Console.WriteLine(); + } + void StartTheGame() + { + N = 23; + K = 0; + int Q = random.Next(2); + if (Q == 1) + ComputerFirst(); + else + { + PlayerFirst(); + } + } + void ComputerFirst() + {//210 + Console.WriteLine("HEADS! I WIN! HA! HA!"); + Console.WriteLine("PREPARE TO LOSE, MEATBALL-NOSE!!"); + Console.WriteLine(); + int ain = random.Next(1, 3); + Console.WriteLine($"I TAKE {ain} MATCHES"); + N = N - ain; + PlayersProceed(); + } + void PlayerFirst() + { + Console.WriteLine("TAILS! YOU GO FIRST. "); + Console.WriteLine(); + PlayersSpeak(); + } + void PlayersProceed() + { + Console.WriteLine($"THE NUMBER OF MATCHES IS NOW {N}"); + Console.WriteLine(); + PlayersSpeak(); + } + void RemindsPlayersToEnter() + { + Console.WriteLine("YOUR TURN -- YOU MAY TAKE 1, 2 OR 3 MATCHES."); + Console.WriteLine("HOW MANY DO YOU WISH TO REMOVE "); + } + void PlayersSpeak() + { + RemindsPlayersToEnter(); + command = Console.ReadLine().ToLower(); + if (command.Equals("exit")) + { + System.Diagnostics.Process tt = System.Diagnostics.Process.GetProcessById(System.Diagnostics.Process.GetCurrentProcess().Id); + tt.Kill(); + } + if (command.Equals("cls")) + { + Console.Clear(); + PlayersSpeak(); + } + try + { + K = Convert.ToInt32(command); + } + catch (System.Exception) + { + PlayerInputError(); + } + if (K > 3 || K <= 0) + PlayerInputError(); + N = N - K; + Console.WriteLine($"THERE ARE NOW {N} MATCHES REMAINING."); + if (N == 4 || N == 3 || N == 2) + TheComputerSpeaks(N); + else if (N <= 1) + ThePlayerWins(); + else + TheComputerSpeaks(4 - K); + + } + void PlayerInputError() + { + Console.WriteLine("VERY FUNNY! DUMMY!"); + Console.WriteLine("DO YOU WANT TO PLAY OR GOOF AROUND?"); + Console.WriteLine("NOW, HOW MANY MATCHES DO YOU WANT "); + PlayersSpeak(); + } + void TheComputerSpeaks(int ain) + { + int Z = ain; + Console.WriteLine($"MY TURN ! I REMOVE {Z} MATCHES");//390 + N = N - Z; + if (N <= 1) + TheComputerWins(); + else + PlayersProceed(); + } + void ThePlayerWins() + { + Console.WriteLine("YOU WON, FLOPPY EARS !"); + Console.WriteLine("THINK YOU'RE PRETTY SMART !"); + Console.WriteLine("LETS PLAY AGAIN AND I'LL BLOW YOUR SHOES OFF !!"); + Console.WriteLine(); + Console.WriteLine(); + StartTheGame(); + } + void TheComputerWins() + { + Console.WriteLine(); + Console.WriteLine("YOU POOR BOOB! YOU TOOK THE LAST MATCH! I GOTCHA!!"); + Console.WriteLine("HA ! HA ! I BEAT YOU !!!"); + Console.WriteLine(); + Console.WriteLine("GOOD BYE LOSER!"); + Console.WriteLine(); + Console.WriteLine(); + GameRun(); + } + } +} diff --git a/93_23_Matches/csharp/README.md b/93_23_Matches/csharp/README.md index 4daabb5c..0f4d812a 100644 --- a/93_23_Matches/csharp/README.md +++ b/93_23_Matches/csharp/README.md @@ -1,3 +1,5 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Microsoft C#](https://docs.microsoft.com/en-us/dotnet/csharp/) + +The program is available in two versions, a "goto" version that mimics the original program and an "object-oriented" version. \ No newline at end of file From cc3b941bcb38b8c705d1ec5d949d3951008525fa Mon Sep 17 00:00:00 2001 From: Tom Wyant Date: Sun, 9 Jan 2022 11:21:48 -0500 Subject: [PATCH 037/337] Port 68_Orbit to Perl. Nothing fancy; just a straight port to idiomatic Perl. --- 68_Orbit/perl/README.md | 8 ++ 68_Orbit/perl/orbit.pl | 239 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+) create mode 100755 68_Orbit/perl/orbit.pl diff --git a/68_Orbit/perl/README.md b/68_Orbit/perl/README.md index e69c8b81..e3bc2e31 100644 --- a/68_Orbit/perl/README.md +++ b/68_Orbit/perl/README.md @@ -1,3 +1,11 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Perl](https://www.perl.org/) + +This Perl script is a port of orbit, which is the 68th entry in Basic +Computer Games. + +In this game you are a planetary defense gunner trying to shoot down a +cloaked Romulan ship before it can escape. + +This is pretty much a straight port of the BASIC into idiomatic Perl. diff --git a/68_Orbit/perl/orbit.pl b/68_Orbit/perl/orbit.pl new file mode 100755 index 00000000..f8e9fccf --- /dev/null +++ b/68_Orbit/perl/orbit.pl @@ -0,0 +1,239 @@ +#!/usr/bin/env perl + +use 5.010; # To get 'state' and 'say' + +use strict; # Require explicit declaration of variables +use warnings; # Enable optional compiler warnings + +use English; # Use more friendly names for Perl's magic variables +use Term::ReadLine; # Prompt and return user input + +our $VERSION = '0.000_01'; + +use constant PI => atan2( 0, -1 ); +use constant DEG_TO_RAD => atan2( 0, -1 ) / 180; + +print <<'EOD'; + ORBIT + Creative Computing Morristown, New Jersey + + + +Somewhere above your planet is a Romulan ship. + +The ship is in a constant polar orbit. Its +distance from the center of your planet is from +10,000 to 30,000 miles and at its present velocity can +circle your planet once every 12 to 36 hours. + +Unfortunately, they are using a cloaking device so +you are unable to see them, but with a special +instrument you can tell how near their ship your +photon bomb exploded. You have seven hours until they +have built up sufficient power in order to escape +your planet's gravity. + +Your planet has enough power to fire one bomb an hour. + +At the beginning of each hour you will be asked to give an +angle (between 0 and 360) and a distance in units of +100 miles (between 100 and 300), after which your bomb's +distance from the enemy ship will be given. + +An explosion within 5,000 miles of the Romulan ship +will destroy it. + +Below is a diagram to help you visualize your plight. + + + 90 + 0000000000000 + 0000000000000000000 + 000000 000000 + 00000 00000 + 00000 XXXXXXXXXXX 00000 + 00000 XXXXXXXXXXXXX 00000 + 0000 XXXXXXXXXXXXXXX 0000 + 0000 XXXXXXXXXXXXXXXXX 0000 + 0000 XXXXXXXXXXXXXXXXXXX 0000 +180<== 00000 XXXXXXXXXXXXXXXXXXX 00000 ==>0 + 0000 XXXXXXXXXXXXXXXXXXX 0000 + 0000 XXXXXXXXXXXXXXXXX 0000 + 0000 XXXXXXXXXXXXXXX 0000 + 00000 XXXXXXXXXXXXX 00000 + 00000 XXXXXXXXXXX 00000 + 00000 00000 + 000000 000000 + 0000000000000000000 + 0000000000000 + 270 + +X - Your planet +O - The orbit of the Romulan ship + +On the above diagram, the Romulan ship is circling +counterclockwise around your planet. Don't forget that +without sufficient power the Romulan ship's altitude +and orbital rate will remain constant. + +Good luck. The Federation is counting on you. +EOD + +while ( 1 ) { # Iterate indefinitely + + my $romulan_angle = int( 360 * rand() ); + my $romulan_distance = int( 200 * rand() + 200 ); + my $romulan_velocity = int( 20 * rand() + 10 ); + + my $hour = 0; + while ( 1 ) { # Iterate indefinitely + $hour++; + + print <<"EOD"; + + +This is hour $hour, at what angle do you wish to send +EOD + my $bomb_angle = get_input( + 'do you wish to send your photon bomb? ', + sub { m/ \A [0-9]+ \z /smx }, + "Please enter an integer angle in degrees\n", + ); + say ''; + my $bomb_distance = get_input( + 'How far out do you wish to detonate it? ', + sub { m/ \A [0-9]+ \z /smx }, + "Please enter an integer distance in hundreds of miles\n", + ); + + $romulan_angle = ( $romulan_angle + $romulan_velocity ) % 360; + my $miss_angle = abs( $romulan_angle - $bomb_angle ); + $miss_angle = 360 - $miss_angle if $miss_angle >= 180; + my $miss_distance = int sqrt( + $romulan_distance * $romulan_distance + + $bomb_distance * $bomb_distance - + 2 * $romulan_distance * $bomb_distance * + cos( $miss_angle * DEG_TO_RAD ) ); + print <<"EOD"; + +Your photon bomb exploded $miss_distance*10^2 miles from the +Romulan ship. +EOD + if ( $miss_distance <= 50 ) { + say "\nYou have successfully completed your mission."; + last; + } elsif ( $hour > 6 ) { + say "\nYou have allowed the Romulans to escape."; + last; + } + } + + say "\nAnother Romulan ship has gone into orbit."; + last unless get_yes_no( 'Do you wish to try to destroy it' ); +} + +print <<'EOD'; + +Good bye. +EOD + +# Get input from the user. The arguments are: +# * The prompt +# * A reference to validation code. This code receives the response in +# $ARG and returns true for a valid response. +# * A warning to print if the response is not valid. This must end in a +# return. +# The first valid response is returned. An end-of-file terminates the +# script. +sub get_input { + my ( $prompt, $validate, $warning ) = @ARG; + + # If no validator is passed, default to one that always returns + # true. + $validate ||= sub { 1 }; + + # Create the readline object. The 'state' causes the variable to be + # initialized only once, no matter how many times this subroutine is + # called. The do { ... } is a compound statement used because we + # need to tweak the created object before we store it. + state $term = do { + my $obj = Term::ReadLine->new( 'reverse' ); + $obj->ornaments( 0 ); + $obj; + }; + + while ( 1 ) { # Iterate indefinitely + + # Read the input into the topic variable, localized to prevent + # Spooky Action at a Distance. We exit on undef, which signals + # end-of-file. + exit unless defined( local $ARG = $term->readline( $prompt ) ); + + # Return the input if it is valid. + return $ARG if $validate->(); + + # Issue the warning, and go around the merry-go-round again. + warn $warning; + } +} + +# Get a yes-or-no answer. The argument is the prompt, which will have +# '? [y/n]: ' appended. The donkey work is done by get_input(), which is +# requested to validate the response as beginning with 'y' or 'n', +# case-insensitive. The return is a true value for 'y' and a false value +# for 'n'. +sub get_yes_no { + my ( $prompt ) = @ARG; + state $map_answer = { + n => 0, + y => 1, + }; + my $resp = lc get_input( + "$prompt? [y/n]: ", + sub { m/ \A [yn] /smxi }, + "Please respond 'y' or 'n'\n", + ); + return $map_answer->{ substr $resp, 0, 1 }; +} + +__END__ + +=head1 TITLE + +orbit - Play the game 'Orbit' from Basic Computer Games + +=head1 SYNOPSIS + + orbit.pl + +=head1 DETAILS + +This Perl script is a port of orbit, which is the 68th entry in Basic +Computer Games. + +In this game you are a planetary defense gunner trying to shoot down a +cloaked Romulan ship before it can escape. + +This is pretty much a straight port of the BASIC into idiomatic Perl. + +=head1 PORTED BY + +Thomas R. Wyant, III F + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2022 by Thomas R. Wyant, III + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl 5.10.0. For more details, see the Artistic +License 1.0 at +L, and/or the +Gnu GPL at L. + +This program is distributed in the hope that it will be useful, but +without any warranty; without even the implied warranty of +merchantability or fitness for a particular purpose. + +=cut + +# ex: set expandtab tabstop=4 textwidth=72 : From dedca6ac0d3662863fa3721fb0ad4f08b00355b5 Mon Sep 17 00:00:00 2001 From: Flow Date: Sun, 9 Jan 2022 18:51:34 +0100 Subject: [PATCH 038/337] Add pizza implementation in c# --- 69_Pizza/csharp/Pizza/CustomerMap.cs | 131 ++++++++ 69_Pizza/csharp/Pizza/Pizza.csproj | 10 + 69_Pizza/csharp/Pizza/Pizza.sln | 25 ++ 69_Pizza/csharp/Pizza/PizzaGame.cs | 296 ++++++++++++++++++ 69_Pizza/csharp/Pizza/Program.cs | 11 + .../csharp/Pizza/StringBuilderExtensions.cs | 21 ++ 6 files changed, 494 insertions(+) create mode 100644 69_Pizza/csharp/Pizza/CustomerMap.cs create mode 100644 69_Pizza/csharp/Pizza/Pizza.csproj create mode 100644 69_Pizza/csharp/Pizza/Pizza.sln create mode 100644 69_Pizza/csharp/Pizza/PizzaGame.cs create mode 100644 69_Pizza/csharp/Pizza/Program.cs create mode 100644 69_Pizza/csharp/Pizza/StringBuilderExtensions.cs diff --git a/69_Pizza/csharp/Pizza/CustomerMap.cs b/69_Pizza/csharp/Pizza/CustomerMap.cs new file mode 100644 index 00000000..ee991de3 --- /dev/null +++ b/69_Pizza/csharp/Pizza/CustomerMap.cs @@ -0,0 +1,131 @@ +using System.Text; + +namespace Pizza +{ + internal class CustomerMap + { + private readonly int _mapSize; + private readonly string[,] _customerMap; + + public CustomerMap(int mapSize) + { + _mapSize = mapSize; + _customerMap = GenerateCustomerMap(); + } + + /// + /// Gets customer on position X, Y. + /// + /// Represents X position. + /// Represents Y position. + /// If positions is valid then returns customer name otherwise returns empty string. + public string GetCustomerOnPosition(int x, int y) + { + if(IsPositionOutOfRange(x, y)) + { + return string.Empty; + } + + return _customerMap[y, x]; + } + + /// + /// Overridden ToString for getting text representation of customers map. + /// + /// Text representation of customers map. + public override string ToString() + { + int verticalSpace = 4; + int horizontalSpace = 5; + + var mapToDisplay = new StringBuilder(); + + AppendXLine(mapToDisplay, horizontalSpace); + + for (int i = _customerMap.GetLength(0) - 1; i >= 0; i--) + { + mapToDisplay.AppendLine("-", verticalSpace); + mapToDisplay.Append($"{i + 1}"); + mapToDisplay.Append(' ', horizontalSpace); + + for (var j = 0; j < _customerMap.GetLength(1); j++) + { + mapToDisplay.Append($"{_customerMap[i, j]}"); + mapToDisplay.Append(' ', horizontalSpace); + } + + mapToDisplay.Append($"{i + 1}"); + mapToDisplay.Append(' ', horizontalSpace); + mapToDisplay.Append(Environment.NewLine); + } + + mapToDisplay.AppendLine("-", verticalSpace); + + AppendXLine(mapToDisplay, horizontalSpace); + + return mapToDisplay.ToString(); + } + + /// + /// Checks if position is out of range or not. + /// + /// Represents X position. + /// Represents Y position. + /// True if position is out of range otherwise false. + private bool IsPositionOutOfRange(int x, int y) + { + return + x < 0 || x > _mapSize - 1 || + y < 0 || y > _mapSize - 1; + } + + /// + /// Generates array which represents customers map. + /// + /// Returns customers map. + private string[,] GenerateCustomerMap() + { + string[,] customerMap = new string[_mapSize, _mapSize]; + string[] customerNames = GetCustomerNames(_mapSize * _mapSize); + int currentCustomerNameIndex = 0; + + for (int i = 0; i < customerMap.GetLength(0); i++) + { + for (int j = 0; j < customerMap.GetLength(1); j++) + { + customerMap[i, j] = customerNames[currentCustomerNameIndex++].ToString(); + } + } + + return customerMap; + } + + /// + /// Generates customer names. Names are represented by alphanumerics from 'A'. Name of last customer depends on passed parameter. + /// + /// How many customers need to be generated. + /// List of customer names. + private static string[] GetCustomerNames(int numberOfCustomers) + { + // returns ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P"]; + return Enumerable.Range(65, numberOfCustomers).Select(c => ((Char)c).ToString()).ToArray(); + } + + /// + /// Appends line with X coordinates. + /// + /// Current map where a new line will be appended. + /// Number of horizontal delimiters which will be added between each coordination. + private void AppendXLine(StringBuilder mapToDisplay, int horizontalSpace) + { + mapToDisplay.Append(' '); + mapToDisplay.Append('-', horizontalSpace); + for (var i = 0; i < _customerMap.GetLength(0); i++) + { + mapToDisplay.Append($"{i + 1}"); + mapToDisplay.Append('-', horizontalSpace); + } + mapToDisplay.Append(Environment.NewLine); + } + } +} \ No newline at end of file diff --git a/69_Pizza/csharp/Pizza/Pizza.csproj b/69_Pizza/csharp/Pizza/Pizza.csproj new file mode 100644 index 00000000..74abf5c9 --- /dev/null +++ b/69_Pizza/csharp/Pizza/Pizza.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/69_Pizza/csharp/Pizza/Pizza.sln b/69_Pizza/csharp/Pizza/Pizza.sln new file mode 100644 index 00000000..91785a8c --- /dev/null +++ b/69_Pizza/csharp/Pizza/Pizza.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31912.275 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pizza", "Pizza.csproj", "{6AABE938-39C4-4661-AEA5-23CECA1DFEE1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6AABE938-39C4-4661-AEA5-23CECA1DFEE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AABE938-39C4-4661-AEA5-23CECA1DFEE1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AABE938-39C4-4661-AEA5-23CECA1DFEE1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AABE938-39C4-4661-AEA5-23CECA1DFEE1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8F7E9FAD-38C5-47A2-B5CA-2B6E5947B982} + EndGlobalSection +EndGlobal diff --git a/69_Pizza/csharp/Pizza/PizzaGame.cs b/69_Pizza/csharp/Pizza/PizzaGame.cs new file mode 100644 index 00000000..22c78e05 --- /dev/null +++ b/69_Pizza/csharp/Pizza/PizzaGame.cs @@ -0,0 +1,296 @@ +namespace Pizza +{ + internal class PizzaGame + { + private const int CustomerMapSize = 4; + private readonly CustomerMap _customerMap = new CustomerMap(CustomerMapSize); + + /// + /// Starts game. Main coordinator for pizza game. + /// It is responsible for showing information, getting data from user and starting to delivery pizza. + /// + public void Play() + { + ShowHeader(); + + string playerName = GetPlayerName(); + + ShowIntroduction(playerName); + ShowMap(); + + if (AskForMoreDirections()) + { + ShowMoreDirections(playerName); + + var playerUnderstands = AskIfPlayerUnderstand(); + if (!playerUnderstands) + { + return; + } + } + + StartDelivery(playerName); + EndDelivery(playerName); + } + + /// + /// Starts with pizza delivering to customers. + /// Every 5 deliveries it is asking user whether want to continue in delivering. + /// + /// Player name which was filled by user. + private void StartDelivery(string playerName) + { + var numberOfDeliveredPizzas = 0; + while (true) + { + numberOfDeliveredPizzas++; + string deliverPizzaToCustomer = GetRandomCustomer(); + + WriteEmptyLine(); + Console.WriteLine($"HELLO {playerName}'S PIZZA. THIS IS {deliverPizzaToCustomer}."); + Console.WriteLine("\tPLEASE SEND A PIZZA."); + + DeliverPizzaByPlayer(playerName, deliverPizzaToCustomer); + + if (numberOfDeliveredPizzas % 5 == 0) + { + bool playerWantToDeliveryMorePizzas = AskQuestionWithYesNoResponse("DO YOU WANT TO DELIVER MORE PIZZAS?"); + if (!playerWantToDeliveryMorePizzas) + { + WriteEmptyLine(); + break; + } + } + } + } + + /// + /// Gets random customer for which pizza should be delivered. + /// + /// Customer name. + private string GetRandomCustomer() + { + int randomPositionOnX = Random.Shared.Next(0, CustomerMapSize); + int randomPositionOnY = Random.Shared.Next(0, CustomerMapSize); + + return _customerMap.GetCustomerOnPosition(randomPositionOnX, randomPositionOnY); + } + + /// + /// Delivers pizza to customer by player. It verifies whether player was delivering pizza to correct customer. + /// + /// Player name which was filled by user. + /// Customer name which order pizza. + private void DeliverPizzaByPlayer(string playerName, string deliverPizzaToCustomer) + { + while (true) + { + string userInput = GetPlayerInput($"\tDRIVER TO {playerName}: WHERE DOES {deliverPizzaToCustomer} LIVE?"); + var deliveredToCustomer = GetCustomerFromPlayerInput(userInput); + if (string.IsNullOrEmpty(deliveredToCustomer)) + { + deliveredToCustomer = "UNKNOWN CUSTOMER"; + } + + if (deliveredToCustomer.Equals(deliverPizzaToCustomer)) + { + Console.WriteLine($"HELLO {playerName}. THIS IS {deliverPizzaToCustomer}, THANKS FOR THE PIZZA."); + break; + } + + Console.WriteLine($"THIS IS {deliveredToCustomer}. I DID NOT ORDER A PIZZA."); + Console.WriteLine($"I LIVE AT {userInput}"); + } + } + + /// + /// Gets customer name by user input with customer coordinations. + /// + /// Input from users - it should represent customer coordination separated by ','. + /// If coordinations are correct and customer exists then returns true otherwise false. + private string GetCustomerFromPlayerInput(string userInput) + { + var pizzaIsDeliveredToPosition = userInput? + .Split(',') + .Select(i => int.TryParse(i, out var customerPosition) ? (customerPosition - 1) : -1) + .Where(i => i != -1) + .ToArray() ?? Array.Empty(); + if (pizzaIsDeliveredToPosition.Length != 2) + { + return string.Empty; + } + + return _customerMap.GetCustomerOnPosition(pizzaIsDeliveredToPosition[0], pizzaIsDeliveredToPosition[1]); + } + + /// + /// Shows game header in console. + /// + private void ShowHeader() + { + Console.WriteLine("PIZZA".PadLeft(22)); + Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + WriteEmptyLine(3); + Console.WriteLine("PIZZA DELIVERY GAME"); + WriteEmptyLine(); + } + + /// + /// Asks user for name which will be used in game. + /// + /// Player name. + private string GetPlayerName() + { + return GetPlayerInput("WHAT IS YOUR FIRST NAME:"); + } + + /// + /// Shows game introduction in console + /// + /// Player name which was filled by user. + private void ShowIntroduction(string playerName) + { + Console.WriteLine($"HI, {playerName}. IN THIS GAME YOU ARE TO TAKE ORDERS"); + Console.WriteLine("FOR PIZZAS. THEN YOU ARE TO TELL A DELIVERY BOY"); + Console.WriteLine("WHERE TO DELIVER THE ORDERED PIZZAS."); + WriteEmptyLine(2); + } + + /// + /// Shows customers map in console. In this method is used overridden method 'ToString' for getting text representation of customers map. + /// + private void ShowMap() + { + Console.WriteLine("MAP OF THE CITY OF HYATTSVILLE"); + WriteEmptyLine(); + + Console.WriteLine(_customerMap.ToString()); + + Console.WriteLine("THE OUTPUT IS A MAP OF THE HOMES WHERE"); + Console.WriteLine("YOU ARE TO SEND PIZZAS."); + WriteEmptyLine(); + Console.WriteLine("YOUR JOB IS TO GIVE A TRUCK DRIVER"); + Console.WriteLine("THE LOCATION OR COORDINATES OF THE"); + Console.WriteLine("HOME ORDERING THE PIZZA."); + WriteEmptyLine(); + } + + /// + /// Asks user if needs more directions. + /// + /// True if user need more directions otherwise false. + private bool AskForMoreDirections() + { + var playerNeedsMoreDirections = AskQuestionWithYesNoResponse("DO YOU NEED MORE DIRECTIONS?"); + WriteEmptyLine(); + + return playerNeedsMoreDirections; + } + + /// + /// Shows more directions. + /// + /// Player name which was filled by user. + private void ShowMoreDirections(string playerName) + { + Console.WriteLine("SOMEBODY WILL ASK FOR A PIZZA TO BE"); + Console.WriteLine("DELIVERED. THEN A DELIVERY BOY WILL"); + Console.WriteLine("ASK YOU FOR THE LOCATION."); + Console.WriteLine("\tEXAMPLE:"); + Console.WriteLine("THIS IS J. PLEASE SEND A PIZZA."); + Console.WriteLine($"DRIVER TO {playerName}. WHERE DOES J LIVE?"); + Console.WriteLine("YOUR ANSWER WOULD BE 2,3"); + } + + /// + /// Asks user if understands to instructions. + /// + /// True if user understand otherwise false. + private bool AskIfPlayerUnderstand() + { + var playerUnderstands = AskQuestionWithYesNoResponse("UNDERSTAND?"); + if (!playerUnderstands) + { + Console.WriteLine("THIS JOB IS DEFINITELY TOO DIFFICULT FOR YOU. THANKS ANYWAY"); + return false; + } + + WriteEmptyLine(); + Console.WriteLine("GOOD. YOU ARE NOW READY TO START TAKING ORDERS."); + WriteEmptyLine(); + Console.WriteLine("GOOD LUCK!!"); + WriteEmptyLine(); + + return true; + } + + /// + /// Shows message about ending delivery in console. + /// + /// Player name which was filled by user. + private void EndDelivery(string playerName) + { + Console.WriteLine($"O.K. {playerName}, SEE YOU LATER!"); + WriteEmptyLine(); + } + + /// + /// Gets input from user. + /// + /// Question which is displayed in console. + /// User input. + private string GetPlayerInput(string question) + { + Console.Write($"{question} "); + + while (true) + { + var userInput = Console.ReadLine(); + if (!string.IsNullOrWhiteSpace(userInput)) + { + return userInput; + } + } + } + + /// + /// Asks user with required resposne 'YES', 'Y, 'NO', 'N'. + /// + /// Question which is displayed in console. + /// True if user write 'YES', 'Y'. False if user write 'NO', 'N'. + private static bool AskQuestionWithYesNoResponse(string question) + { + var possitiveResponse = new string[] { "Y", "YES" }; + var negativeResponse = new string[] { "N", "NO" }; + var validUserInputs = possitiveResponse.Concat(negativeResponse); + + Console.Write($"{question} "); + + string? userInput; + while (true) + { + userInput = Console.ReadLine(); + if (!string.IsNullOrWhiteSpace(userInput) && validUserInputs.Contains(userInput.ToUpper())) + { + break; + } + + Console.Write($"'YES' OR 'NO' PLEASE, NOW THEN, {question} "); + } + + return possitiveResponse.Contains(userInput.ToUpper()); + } + + /// + /// Writes empty line in console. + /// + /// Number of empty lines which will be written in console. Parameter is optional and default value is 1. + private void WriteEmptyLine(int numberOfEmptyLines = 1) + { + for (int i = 0; i < numberOfEmptyLines; i++) + { + Console.WriteLine(); + } + } + } +} \ No newline at end of file diff --git a/69_Pizza/csharp/Pizza/Program.cs b/69_Pizza/csharp/Pizza/Program.cs new file mode 100644 index 00000000..6c21fad0 --- /dev/null +++ b/69_Pizza/csharp/Pizza/Program.cs @@ -0,0 +1,11 @@ +namespace Pizza +{ + internal class Program + { + static void Main(string[] args) + { + var pizzaGame = new PizzaGame(); + pizzaGame.Play(); + } + } +} \ No newline at end of file diff --git a/69_Pizza/csharp/Pizza/StringBuilderExtensions.cs b/69_Pizza/csharp/Pizza/StringBuilderExtensions.cs new file mode 100644 index 00000000..f7cb828d --- /dev/null +++ b/69_Pizza/csharp/Pizza/StringBuilderExtensions.cs @@ -0,0 +1,21 @@ +using System.Text; + +namespace Pizza +{ + internal static class StringBuilderExtensions + { + /// + /// Extensions for adding new lines of specific value. + /// + /// Extended class. + /// Value which will be repeated. + /// Number of lines that will be appended. + public static void AppendLine(this StringBuilder stringBuilder, string value, int numberOfLines) + { + for (int i = 0; i < numberOfLines; i++) + { + stringBuilder.AppendLine(value); + } + } + } +} \ No newline at end of file From fbbf0bf622bde3293b10f6cafd4743812142d931 Mon Sep 17 00:00:00 2001 From: jcoehoorn Date: Sun, 9 Jan 2022 12:37:32 -0600 Subject: [PATCH 039/337] Create program.vb --- 02_Amazing/vbnet/program.vb | 295 ++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 02_Amazing/vbnet/program.vb diff --git a/02_Amazing/vbnet/program.vb b/02_Amazing/vbnet/program.vb new file mode 100644 index 00000000..d39eb450 --- /dev/null +++ b/02_Amazing/vbnet/program.vb @@ -0,0 +1,295 @@ +Imports System + +Module Program + + Enum Directions + SolveAndReset = 0 + Left = 1 + Up = 2 + Right = 3 + Down = 4 + End Enum + + 'Program State + Dim Width As Integer = 0, Height As Integer = 0, Q As Integer = 0, CellsVisited As Integer = 2, curCol As Integer, curRow As Integer = 1 + Dim SolutionCompleted As Boolean = False + Dim CellVisitHistory(,) As Integer + Dim CellState(,) As Integer + + Dim rnd As New Random() + + Public ReadOnly Property BlockedLeft As Boolean + Get + Return curCol - 1 = 0 OrElse CellVisitHistory(curCol - 1, curRow) <> 0 + End Get + End Property + Public ReadOnly Property BlockedAbove As Boolean + Get + Return curRow - 1 = 0 OrElse CellVisitHistory(curCol, curRow - 1) <> 0 + End Get + End Property + Public ReadOnly Property BlockedRight As Boolean + Get + Return curCol = Width OrElse CellVisitHistory(curCol + 1, curRow) <> 0 + End Get + End Property + 'Note: "BlockedBelow" does NOT include checking if we have a solution! + Public ReadOnly Property BlockedBelow As Boolean + Get + Return curRow = Height OrElse CellVisitHistory(curCol, curRow + 1) <> 0 + End Get + End Property + Public ReadOnly Property OnBottomRow As Boolean + Get + Return curRow.Equals(Height) + End Get + End Property + + Sub Main(args As String()) + Const header As String = +" AMAZING PROGRAM + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + + +" + Console.WriteLine(header) + + While Width <= 1 OrElse Height <= 1 + Console.Write("WHAT ARE YOUR WIDTH AND LENGTH? ") + + 'We no longer have the old convenient INPUT command, so need to parse out the inputs + Dim parts = Console.ReadLine().Split(","c).Select(Function(s) Convert.ToInt32(s.Trim())).ToList() + Width = parts(0) + Height = parts(1) + + If Width <= 1 OrElse Height <= 1 Then Console.WriteLine($"MEANINGLESS DIMENSIONS. TRY AGAIN.{vbCrLf}") + End While + + ReDim CellVisitHistory(Width, Height), CellState(Width, Height) + + Console.WriteLine(" + +") + + curCol = rnd.Next(1, Width + 1) 'Starting X position + CellVisitHistory(curCol, 1) = 1 + Dim startXPos As Integer = curCol 'we need to know this at the end to print opening line + + Dim keepGoing As Boolean = True + While keepGoing + If BlockedLeft Then + keepGoing = ChoosePath_BlockedToTheLeft() + ElseIf BlockedAbove Then + keepGoing = ChoosePath_BlockedAbove() + ElseIf BlockedRight Then + keepGoing = ChoosePath_BlockedToTheRight() + Else + keepGoing = SelectRandomDirection(Directions.Left, Directions.Up, Directions.Right) 'Go anywhere but down + End If + End While + + PrintFinalResults(startXPos) + End Sub + + Public Sub ResetCurrentPosition() + Do + If curCol <> Width Then 'not at the right edge + curCol += 1 + ElseIf curRow <> Height Then 'not at the bottom + curCol = 1 + curRow += 1 + Else + curCol = 1 + curRow = 1 + End If + Loop While CellVisitHistory(curCol, curRow) = 0 + End Sub + + Dim methods() As Func(Of Boolean) = {AddressOf MarkSolvedAndResetPosition, AddressOf GoLeft, AddressOf GoUp, AddressOf GoRight, AddressOf GoDown} + Public Function SelectRandomDirection(ParamArray possibles() As Directions) As Boolean + Dim x As Integer = rnd.Next(0, possibles.Length) + Return methods(possibles(x))() + End Function + + Public Function ChoosePath_BlockedToTheLeft() As Boolean + If BlockedAbove Then + If BlockedRight Then + If curRow <> Height Then + If CellVisitHistory(curCol, curRow + 1) <> 0 Then ' Can't go down, but not at the edge...blocked. Reset and try again + ResetCurrentPosition() + Return True + Else + Return GoDown() + End If + ElseIf SolutionCompleted Then 'Can't go Down (there's already another solution) + ResetCurrentPosition() + Return True + Else 'Can't go LEFT, UP, RIGHT, or DOWN, but we're on the bottom and there's no solution yet + Return MarkSolvedAndResetPosition() + End If + ElseIf BlockedBelow Then + Return GoRight() + ElseIf Not OnBottomRow Then + Return SelectRandomDirection(Directions.Right, Directions.Down) + ElseIf SolutionCompleted Then 'Can only go right, and we're at the bottom + Return GoRight() + Else 'Can only go right, we're at the bottom, and there's not a solution yet + Return SelectRandomDirection(Directions.Right, Directions.SolveAndReset) + End If + '== Definitely can go Up == + ElseIf BlockedRight Then + If BlockedBelow Then + Return GoUp() + ElseIf Not OnBottomRow Then + Return SelectRandomDirection(Directions.Up, Directions.Down) + ElseIf SolutionCompleted Then 'We're on the bottom row, can only go up + Return GoUp() + Else 'We're on the bottom row, can only go up, but there's no solution + Return SelectRandomDirection(Directions.Up, Directions.SolveAndReset) + End If + '== Definitely can go Up and Right == + ElseIf BlockedBelow Then + Return SelectRandomDirection(Directions.Up, Directions.Right) + ElseIf Not OnBottomRow Then + Return SelectRandomDirection(Directions.Up, Directions.Right, Directions.Down) + ElseIf SolutionCompleted Then 'at the bottom, but already have a solution + Return SelectRandomDirection(Directions.Up, Directions.Right) + Else + Return SelectRandomDirection(Directions.Up, Directions.Right, Directions.SolveAndReset) + End If + End Function + + Public Function ChoosePath_BlockedAbove() As Boolean + 'No need to check the left side, only called from the "keepGoing" loop where LEFT is already cleared + If BlockedRight Then + If BlockedBelow Then + Return GoLeft() + ElseIf Not OnBottomRow Then + Return SelectRandomDirection(Directions.Left, Directions.Down) + ElseIf SolutionCompleted Then 'Can't go down because there's already a solution + Return GoLeft() + Else 'At the bottom, no solution yet... + Return SelectRandomDirection(Directions.Left, Directions.SolveAndReset) + End If + ElseIf BlockedBelow Then + Return SelectRandomDirection(Directions.Left, Directions.Right) + ElseIf Not OnBottomRow Then + Return SelectRandomDirection(Directions.Left, Directions.Right, Directions.Down) + ElseIf SolutionCompleted Then + Return SelectRandomDirection(Directions.Left, Directions.Right) + Else + Return SelectRandomDirection(Directions.Left, Directions.Right, Directions.SolveAndReset) + End If + End Function + + Public Function ChoosePath_BlockedToTheRight() As Boolean + 'No need to check Left or Up, only called from the "keepGoing" loop where LEFT and UP are already cleared + If BlockedRight Then 'Can't go Right -- why? we knew this when calling the function + If BlockedBelow Then + Return SelectRandomDirection(Directions.Left, Directions.Up) + ElseIf Not OnBottomRow Then + Return SelectRandomDirection(Directions.Left, Directions.Up, Directions.Down) + ElseIf SolutionCompleted Then + Return SelectRandomDirection(Directions.Left, Directions.Up) + Else + Return SelectRandomDirection(Directions.Left, Directions.Up, Directions.SolveAndReset) + End If + Else 'Should never get here + Return SelectRandomDirection(Directions.Left, Directions.Up, Directions.Right) 'Go Left, Up, or Right (but path is blocked?) + End If + End Function + + Public Sub PrintFinalResults(startPos As Integer) + For i As Integer = 0 To Width - 1 + If i = startPos Then Console.Write(". ") Else Console.Write(".--") + Next + Console.WriteLine(".") + + If Not SolutionCompleted Then 'Pick a random exit + Dim X As Integer = rnd.Next(1, Width + 1) + If CellState(X, Height) = 0 Then + CellState(X, Height) = 1 + Else + CellState(X, Height) = 3 + End If + End If + + For j As Integer = 1 To Height + Console.Write("I") + For i As Integer = 1 To Width + If CellState(i, j) < 2 Then + Console.Write(" I") + Else + Console.Write(" ") + End If + Next + Console.WriteLine() + + For i As Integer = 1 To Width + If CellState(i, j) = 0 OrElse CellState(i, j) = 2 Then + Console.Write(":--") + Else + Console.Write(": ") + End If + Next + Console.WriteLine(".") + Next + End Sub + + Public Function GoLeft() As Boolean + curCol -= 1 + CellVisitHistory(curCol, curRow) = CellsVisited + CellsVisited += 1 + CellState(curCol, curRow) = 2 + If CellsVisited > Width * Height Then Return False + Q = 0 + Return True + End Function + + Public Function GoUp() As Boolean + curRow -= 1 + CellVisitHistory(curCol, curRow) = CellsVisited + CellsVisited += 1 + CellState(curCol, curRow) = 1 + If CellsVisited > Width * Height Then Return False + Q = 0 + Return True + End Function + + Public Function GoRight() As Boolean + CellVisitHistory(curCol + 1, curRow) = CellsVisited + CellsVisited += 1 + If CellState(curCol, curRow) = 0 Then CellState(curCol, curRow) = 2 Else CellState(curCol, curRow) = 3 + curCol += 1 + If CellsVisited > Width * Height Then Return False + Return ChoosePath_BlockedToTheLeft() + End Function + + Public Function GoDown() As Boolean + If Q = 1 Then Return MarkSolvedAndResetPosition() + + CellVisitHistory(curCol, curRow + 1) = CellsVisited + CellsVisited += 1 + If CellState(curCol, curRow) = 0 Then CellState(curCol, curRow) = 1 Else CellState(curCol, curRow) = 3 + curRow += 1 + If CellsVisited > Width * Height Then Return False + Return True + End Function + + Public Function MarkSolvedAndResetPosition() As Boolean + ' AlWAYS returns true + SolutionCompleted = True + Q = 1 + If CellState(curCol, curRow) = 0 Then + CellState(curCol, curRow) = 1 + curCol = 1 + curRow = 1 + If CellVisitHistory(curCol, curRow) = 0 Then ResetCurrentPosition() + Else + CellState(curCol, curRow) = 3 + ResetCurrentPosition() + End If + Return True + End Function +End Module From e0b041dfd7fc75f1eb1e53f566b9f27581d52b6b Mon Sep 17 00:00:00 2001 From: Jackson Brouwer Date: Sun, 9 Jan 2022 15:05:24 -0600 Subject: [PATCH 040/337] Python version --- 07_Basketball/python/basketball.py | 343 +++++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 07_Basketball/python/basketball.py diff --git a/07_Basketball/python/basketball.py b/07_Basketball/python/basketball.py new file mode 100644 index 00000000..5ba88188 --- /dev/null +++ b/07_Basketball/python/basketball.py @@ -0,0 +1,343 @@ +import random + +# The basketball class is a computer game that allows you to play as +# Dartmouth College's captain and playmaker +# The game uses set probabilites to simulate outcomes of each posession +# You are able to choose your shot types as well as defensive formations + + +class Basketball(): + def __init__(self): + self.time = 0 + self.score = [0, 0] # first value is opponents score, second is home + self.defense = None + self.defense_choices = [6, 6.5, 7, 7.5] + self.shot = None + self.shot_choices = [1, 2, 3, 4] + self.z1 = None + + # Explains the keyboard inputs + print("\t\t\t Basketball") + print("\t Creative Computing Morristown, New Jersey\n\n\n") + print("This is Dartmouth College basketball. ") + print("Υou will be Dartmouth captain and playmaker.") + print("Call shots as follows:") + print("1. Long (30ft.) Jump Shot; 2. Short (15 ft.) Jump Shot; " + + "3. Lay up; 4. Set Shot") + print("Both teams will use the same defense. Call Defense as follows:") + print("6. Press; 6.5 Man-to-Man; 7. Zone; 7.5 None.") + print("To change defense, just type 0 as your next shot.") + print("Your starting defense will be? ", end='') + + # takes input for a defense + try: + self.defense = float(input()) + + except ValueError: + self.defense = None + + # if the input wasn't a valid defense, takes input again + while self.defense not in self.defense_choices: + print("Your new defensive allignment is? ", end='') + try: + self.defense = float(input()) + + except ValueError: + continue + + # takes input for opponent's name + print("\nChoose your opponent? ", end='') + + self.opponent = input() + self.start_of_period() + + # adds points to the score + # team can take 0 or 1, for opponent or Dartmouth, respectively + def add_points(self, team, points): + self.score[team] += points + self.print_score() + + def ball_passed_back(self): + print("Ball passed back to you. ", end='') + self.dartmouth_ball() + + # change defense, called when the user enters 0 for their shot + def change_defense(self): + self.defense = None + + while self.defense not in self.defense_choices: + print("Your new defensive allignment is? ") + try: + self.defense = float(input()) + + except ValueError: + continue + self.dartmouth_ball() + + # simulates two foul shots for a player and adds the points + def foul_shots(self, team): + print("Shooter fouled. Two shots.") + if random.random() > .49: + if random.random() > .75: + print("Both shots missed.") + else: + print("Shooter makes one shot and misses one.") + self.score[team] += 1 + else: + print("Shooter makes both shots.") + self.score[team] += 2 + + self.print_score() + + # called when t = 50, starts a new period + def halftime(self): + print("\n ***** End of first half *****\n") + self.print_score() + self.start_of_period() + + # prints the current score + def print_score(self): + print("Score: " + str(self.score[1]) + + " to " + str(self.score[0]) + "\n") + + # simulates a center jump for posession at the beginning of a period + def start_of_period(self): + print("Center jump") + if random.random() > .6: + print("Dartmouth controls the tap.\n") + self.dartmouth_ball() + else: + print(self.opponent + " controls the tap.\n") + self.opponent_ball() + + # called when t = 92 + def two_minute_warning(self): + print(" *** Two minutes left in the game ***") + + # called when the user enters 1 or 2 for their shot + def dartmouth_jump_shot(self): + self.time += 1 + if self.time == 50: + self.halftime() + elif self.time == 92: + self.two_minute_warning() + print("Jump Shot.") + # simulates chances of different possible outcomes + if random.random() > .341 * self.defense / 8: + if random.random() > .682 * self.defense / 8: + if random.random() > .782 * self.defense / 8: + if random.random() > .843 * self.defense / 8: + print("Charging foul. Dartmouth loses ball.\n") + self.opponent_ball() + else: + # player is fouled + self.foul_shots(1) + self.opponent_ball() + else: + if random.random() > .5: + print("Shot is blocked. Ball controlled by " + + self.opponent + ".\n") + self.opponent_ball() + else: + print("Shot is blocked. Ball controlled by Dartmouth.") + self.dartmouth_ball() + else: + print("Shot is off target.") + if self.defense / 6 * random.random() > .45: + print("Rebound to " + self.opponent + "\n") + self.opponent_ball() + else: + print("Dartmouth controls the rebound.") + if random.random() > .4: + if self.defense == 6 and random.random() > .6: + print("Pass stolen by " + self.opponent + + ", easy lay up") + self.add_points(0, 2) + self.dartmouth_ball() + else: + # ball is passed back to you + self.ball_passed_back() + else: + print("") + self.dartmouth_non_jump_shot() + else: + print("Shot is good.") + self.add_points(1, 2) + self.opponent_ball() + + # called when the user enters 0, 3, or 4 + # lay up, set shot, or defense change + def dartmouth_non_jump_shot(self): + self.time += 1 + if self.time == 50: + self.halftime() + elif self.time == 92: + self.two_minute_warning() + + if self.shot == 4: + print("Set shot.") + elif self.shot == 3: + print("Lay up.") + elif self.shot == 0: + self.change_defense() + + # simulates different outcomes after a lay up or set shot + if 7/self.defense*random.random() > .4: + if 7/self.defense*random.random() > .7: + if 7/self.defense*random.random() > .875: + if 7/self.defense*random.random() > .925: + print("Charging foul. Dartmouth loses the ball.\n") + self.opponent_ball() + else: + print("Shot blocked. " + self.opponent + "'s ball.\n") + self.opponent_ball() + else: + self.foul_shots(1) + self.opponent_ball() + else: + print("Shot is off the rim.") + if random.random() > 2/3: + print("Dartmouth controls the rebound.") + if random.random() > .4: + print("Ball passed back to you.\n") + self.dartmouth_ball() + else: + self.dartmouth_non_jump_shot() + else: + print(self.opponent + " controls the rebound.\n") + self.opponent_ball() + else: + print("Shot is good. Two points.") + self.add_points(1, 2) + self.opponent_ball() + + # plays out a Dartmouth posession, starting with your choice of shot + def dartmouth_ball(self): + print("Your shot? ", end='') + self.shot = None + try: + self.shot = int(input()) + except ValueError: + self.shot = None + + while self.shot not in self.shot_choices: + print("Incorrect answer. Retype it. Your shot? ", end='') + try: + self.shot = int(input()) + except: + continue + + if self.time < 100 or random.random() < .5: + if self.shot == 1 or self.shot == 2: + self.dartmouth_jump_shot() + else: + self.dartmouth_non_jump_shot() + else: + if self.score[0] != self.score[1]: + print("\n ***** End Of Game *****") + print("Final Score: Dartmouth: " + str(self.score[1]) + " " + + self.opponent + ": " + str(self.score[0])) + else: + print("\n ***** End Of Second Half *****") + print("Score at end of regulation time:") + print(" Dartmouth: " + str(self.score[1]) + " " + + self.opponent + ": " + str(self.score[0])) + print("Begin two minute overtime period") + self.time = 93 + self.start_of_period() + + # simulates the opponents jumpshot + def opponent_jumpshot(self): + print("Jump Shot.") + if 8/self.defense*random.random() > .35: + if 8/self.defense*random.random() > .75: + if 8/self.defense*random.random() > .9: + print("Offensive foul. Dartmouth's ball.\n") + self.dartmouth_ball() + else: + self.foul_shots(0) + self.dartmouth_ball() + else: + print("Shot is off the rim.") + if self.defense/6*random.random() > .5: + print(self.opponent + " controls the rebound.") + if self.defense == 6: + if random.random() > .75: + print("Ball stolen. Easy lay up for Dartmouth.") + self.add_points(1, 2) + self.opponent_ball() + else: + if random.random() > .5: + print("") + self.opponent_non_jumpshot() + else: + print("Pass back to " + self.opponent + + " guard.\n") + self.opponent_ball() + else: + if random.random() > .5: + self.opponent_non_jumpshot() + else: + print("Pass back to " + self.opponent + + " guard.\n") + self.opponent_ball() + else: + print("Dartmouth controls the rebound.\n") + self.dartmouth_ball() + else: + print("Shot is good.") + self.add_points(0, 2) + self.dartmouth_ball() + + # simulates opponents lay up or set shot + def opponent_non_jumpshot(self): + if self.z1 > 3: + print("Set shot.") + else: + print("Lay up") + if 7/self.defense*random.random() > .413: + print("Shot is missed.") + if self.defense/6*random.random() > .5: + print(self.opponent + " controls the rebound.") + if self.defense == 6: + if random.random() > .75: + print("Ball stolen. Easy lay up for Dartmouth.") + self.add_points(1, 2) + self.opponent_ball() + else: + if random.random() > .5: + print("") + self.opponent_non_jumpshot() + else: + print("Pass back to " + self.opponent + + " guard.\n") + self.opponent_ball() + else: + if random.random() > .5: + print("") + self.opponent_non_jumpshot() + else: + print("Pass back to " + self.opponent + " guard\n") + self.opponent_ball() + else: + print("Dartmouth controls the rebound.\n") + self.dartmouth_ball() + else: + print("Shot is good.") + self.add_points(0, 2) + self.dartmouth_ball() + + # simulates an opponents possesion + # #randomly picks jump shot or lay up / set shot. + def opponent_ball(self): + self.time += 1 + if self.time == 50: + self.halftime() + self.z1 = 10/4*random.random()+1 + if self.z1 > 2: + self.opponent_non_jumpshot() + else: + self.opponent_jumpshot() + + +new_game = Basketball() From e22e1bed266fd9e6224a9bdd751645cf2d502926 Mon Sep 17 00:00:00 2001 From: Bastiaan Veelo Date: Sun, 9 Jan 2022 23:38:17 +0100 Subject: [PATCH 041/337] Add D version of High_IQ (48). --- 48_High_IQ/d/.gitignore | 2 + 48_High_IQ/d/README.md | 214 ++++++++++++++++++++++++++++++++++++ 48_High_IQ/d/highiq.d | 238 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 454 insertions(+) create mode 100644 48_High_IQ/d/.gitignore create mode 100644 48_High_IQ/d/README.md create mode 100644 48_High_IQ/d/highiq.d diff --git a/48_High_IQ/d/.gitignore b/48_High_IQ/d/.gitignore new file mode 100644 index 00000000..d969f6b2 --- /dev/null +++ b/48_High_IQ/d/.gitignore @@ -0,0 +1,2 @@ +*.exe +*.obj diff --git a/48_High_IQ/d/README.md b/48_High_IQ/d/README.md new file mode 100644 index 00000000..0eea7b00 --- /dev/null +++ b/48_High_IQ/d/README.md @@ -0,0 +1,214 @@ +Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html) + +Converted to [D](https://dlang.org/) by [Bastiaan Veelo](https://github.com/veelo). + +## Running the code + +Assuming the reference [dmd](https://dlang.org/download.html#dmd) compiler: +```shell +dmd -dip1000 -run highiq.d +``` + +[Other compilers](https://dlang.org/download.html) also exist. + + +## Discussion + +The original BASIC game code made use of calculus and clever choises of field IDs to determine the validity of moves. +This is the original layout of IDs over the board: + +``` + 13 14 15 + + 22 23 24 + +29 30 31 32 33 34 35 + +38 39 40 41 42 43 44 + +47 48 49 50 51 52 53 + + 58 59 60 + + 67 68 69 +``` + +This seems not very logical, because, wouldn't it make much more sense to let columns increase with 1 and rows increase +with 10, so you'd get a consistent coordinate system? It seems that the original author's first step in validating +moves was to check that moves jumped from one field over another one onto the next. He did this by making sure that +adjacent IDs alter between even and odd horizontally *and* vertically. So a valid move was always from an even ID to an +even ID *or* from an odd ID to an odd ID. So one of the checks that the BASIC code made was that the sum of both IDs +was even. This is of course not a sufficient test, because moves that jump over three fields are illegal. Therefore the +IDs seem to have been carefully laid oud so that the IDs increase with 1 horizontally, and 9 vertically, everywhere. So +the only valid difference between IDs for a horizontal move was always 2, and the only valid difference for a vertical +move was always 18. + +Fact of the matter is, however, that checking for difference is sufficient and the even sum rule is superfluous, so +there is no need for the peculiar distribution of field IDs. Therefore I have chosen the following more logical +distribution: + +``` + 13 14 15 + + 23 24 25 + +31 32 33 34 35 36 37 + +41 42 43 44 45 46 47 + +51 52 53 54 55 56 57 + + 63 64 65 + + 73 74 75 +``` + +As a consequence, the implementation of the game code has become much simpler; Not alone due to one less check, but due +to the fact that conversions between IDs and board coordinates have become unnecessary and thus we can work with a single +representation of the board state. + +This version makes a prettier print of the board than the BASIC original, with coordinates for every move, and explains +illegal moves. + + +## Demo + +``` + H-I-Q +(After Creative Computing Morristown, New Jersey) + + +Fields are identified by 2-digit numbers, each +between 1 and 7. Example: the middle field is 44, +the bottom middle is 74. + + _1 _2 _3 _4 _5 _6 _7 + ┌───┬───┬───┐ + 1_ │ ■ │ ■ │ ■ │ + ├───┼───┼───┤ + 2_ │ ■ │ ■ │ ■ │ + ┌───┬───┼───┼───┼───┼───┬───┐ + 3_ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ + ├───┼───┼───┼───┼───┼───┼───┤ + 4_ │ ■ │ ■ │ ■ │ │ ■ │ ■ │ ■ │ + ├───┼───┼───┼───┼───┼───┼───┤ + 5_ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ + └───┴───┼───┼───┼───┼───┴───┘ + 6_ │ ■ │ ■ │ ■ │ + ├───┼───┼───┤ + 7_ │ ■ │ ■ │ ■ │ + └───┴───┴───┘ + +Move which peg? 23 +The peg at 23 has nowhere to go. Try again. + +Move which peg? 24 +To where? 34 +Field 34 is occupied. Try again. +To where? 54 +Field 54 is occupied. Try again. +To where? 44 + + _1 _2 _3 _4 _5 _6 _7 + ┌───┬───┬───┐ + 1_ │ ■ │ ■ │ ■ │ + ├───┼───┼───┤ + 2_ │ ■ │ │ ■ │ + ┌───┬───┼───┼───┼───┼───┬───┐ + 3_ │ ■ │ ■ │ ■ │ │ ■ │ ■ │ ■ │ + ├───┼───┼───┼───┼───┼───┼───┤ + 4_ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ + ├───┼───┼───┼───┼───┼───┼───┤ + 5_ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ + └───┴───┼───┼───┼───┼───┴───┘ + 6_ │ ■ │ ■ │ ■ │ + ├───┼───┼───┤ + 7_ │ ■ │ ■ │ ■ │ + └───┴───┴───┘ + +Move which peg? 14 +The peg at 14 has nowhere to go. Try again. + +Move which peg? 24 +There is no peg at 24. Try again. + +Move which peg? 44 +The peg at 44 has nowhere to go. Try again. + +Move which peg? 32 +To where? 22 +Field 22 is ouside the board. Try again. +To where? 33 +Field 33 is occupied. Try again. +To where? 34 + + _1 _2 _3 _4 _5 _6 _7 + ┌───┬───┬───┐ + 1_ │ ■ │ ■ │ ■ │ + ├───┼───┼───┤ + 2_ │ ■ │ │ ■ │ + ┌───┬───┼───┼───┼───┼───┬───┐ + 3_ │ ■ │ │ │ ■ │ ■ │ ■ │ ■ │ + ├───┼───┼───┼───┼───┼───┼───┤ + 4_ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ + ├───┼───┼───┼───┼───┼───┼───┤ + 5_ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ + └───┴───┼───┼───┼───┼───┴───┘ + 6_ │ ■ │ ■ │ ■ │ + ├───┼───┼───┤ + 7_ │ ■ │ ■ │ ■ │ + └───┴───┴───┘ + +Move which peg? 44 +To where? 33 +You cannot move diagonally. Try again. +To where? 24 + + _1 _2 _3 _4 _5 _6 _7 + ┌───┬───┬───┐ + 1_ │ ■ │ ■ │ ■ │ + ├───┼───┼───┤ + 2_ │ ■ │ ■ │ ■ │ + ┌───┬───┼───┼───┼───┼───┬───┐ + 3_ │ ■ │ │ │ │ ■ │ ■ │ ■ │ + ├───┼───┼───┼───┼───┼───┼───┤ + 4_ │ ■ │ ■ │ ■ │ │ ■ │ ■ │ ■ │ + ├───┼───┼───┼───┼───┼───┼───┤ + 5_ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ + └───┴───┼───┼───┼───┼───┴───┘ + 6_ │ ■ │ ■ │ ■ │ + ├───┼───┼───┤ + 7_ │ ■ │ ■ │ ■ │ + └───┴───┴───┘ + +Move which peg? 36 +To where? 33 +You can't jump that far. Try again. +To where? 35 +Field 35 is occupied. Try again. +To where? 34 + + _1 _2 _3 _4 _5 _6 _7 + ┌───┬───┬───┐ + 1_ │ ■ │ ■ │ ■ │ + ├───┼───┼───┤ + 2_ │ ■ │ ■ │ ■ │ + ┌───┬───┼───┼───┼───┼───┬───┐ + 3_ │ ■ │ │ │ ■ │ │ │ ■ │ + ├───┼───┼───┼───┼───┼───┼───┤ + 4_ │ ■ │ ■ │ ■ │ │ ■ │ ■ │ ■ │ + ├───┼───┼───┼───┼───┼───┼───┤ + 5_ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ ■ │ + └───┴───┼───┼───┼───┼───┴───┘ + 6_ │ ■ │ ■ │ ■ │ + ├───┼───┼───┤ + 7_ │ ■ │ ■ │ ■ │ + └───┴───┴───┘ + +Move which peg? 46 +To where? 36 +You need to jump over another peg. Try again. +To where? down +Field 00 is ouside the board. Try again. +To where? +``` diff --git a/48_High_IQ/d/highiq.d b/48_High_IQ/d/highiq.d new file mode 100644 index 00000000..78445545 --- /dev/null +++ b/48_High_IQ/d/highiq.d @@ -0,0 +1,238 @@ +@safe: // Make @safe the default for this file, enforcing memory-safety. +import std; + +void main() +{ + enum width = 50; + writeln(center("H-I-Q", width)); + writeln(center("(After Creative Computing Morristown, New Jersey)\n\n", width)); + writeln(wrap("Fields are identified by 2-digit numbers, each between 1 and 7. " ~ + "Example: the middle field is 44, the bottom middle is 74.", width)); + + Board board; + + while (true) + { + while (!board.isGameOver) + { + writeln(board); // Calls board.toString(). + board.makeMove; + } + writeln(board, "\nThe game is over.\nYou had ", board.numPegs, " pieces remaining."); + if (board.numPegs == 1) + writeln("Bravo! You made a perfect score!\n", + "Make a screen dump as a record of your accomplishment!\n"); + write("Play again? (Yes or No) "); + if (readString.toLower != "yes") + break; + writeln; writeln; + board = Board.init; + } + writeln("\nSo long for now.\n"); +} + +/// Representation of the game board with pegs. +struct Board +{ + enum {outside, taken, empty}; + int[8][8] state = [ + 1: [ 3: taken, 4: taken, 5: taken], + 2: [ 3: taken, 4: taken, 5: taken], + 3: [1: taken, 2: taken, 3: taken, 4: taken, 5: taken, 6: taken, 7: taken], + 4: [1: taken, 2: taken, 3: taken, 4: empty, 5: taken, 6: taken, 7: taken], + 5: [1: taken, 2: taken, 3: taken, 4: taken, 5: taken, 6: taken, 7: taken], + 6: [ 3: taken, 4: taken, 5: taken], + 7: [ 3: taken, 4: taken, 5: taken] + ]; // Row 0 and column 0 are unused. Default is 0 (outside). + + /// Returns a string representing the board and its current state. + string toString() const + { + dchar[][] lines = [(" _1 _2 _3 _4 _5 _6 _7 ").to!(dchar[]), + (" ┌───┬───┬───┐ ").to!(dchar[]), + (" 1_ │ │ │ │ ").to!(dchar[]), + (" ├───┼───┼───┤ ").to!(dchar[]), + (" 2_ │ │ │ │ ").to!(dchar[]), + (" ┌───┬───┼───┼───┼───┼───┬───┐").to!(dchar[]), + (" 3_ │ │ │ │ │ │ │ │").to!(dchar[]), + (" ├───┼───┼───┼───┼───┼───┼───┤").to!(dchar[]), + (" 4_ │ │ │ │ │ │ │ │").to!(dchar[]), + (" ├───┼───┼───┼───┼───┼───┼───┤").to!(dchar[]), + (" 5_ │ │ │ │ │ │ │ │").to!(dchar[]), + (" └───┴───┼───┼───┼───┼───┴───┘").to!(dchar[]), + (" 6_ │ │ │ │ ").to!(dchar[]), + (" ├───┼───┼───┤ ").to!(dchar[]), + (" 7_ │ │ │ │ ").to!(dchar[]), + (" └───┴───┴───┘ ").to!(dchar[])]; + foreach (y, row; state) + foreach (x, field; row) + if (field == taken) + lines[y * 2][x * 4 + 2] = '■'; + return lines.join("\n").to!string; + } + + /// Tests for possible moves. + bool isGameOver() const + { + foreach (r, row; state) + foreach (c, field; row) + if (field == taken && canMoveFrom(r, c)) + return false; + return true; + } + + bool canMoveFrom(int row, int col) const + { + if (row >= 3 && state[row - 2][col] == empty) // Up + return state[row - 1][col] == taken; + if (row <= 5 && state[row + 2][col] == empty) // Down + return state[row + 1][col] == taken; + if (col >= 3 && state[row][col - 2] == empty) // Left + return state[row][col - 1] == taken; + if (col <= 5 && state[row][col + 2] == empty) // Right + return state[row][col + 1] == taken; + return false; + } + + /// Asks for input, validates the move and updates the board. + void makeMove() + { + bool isOutside(int row, int col) + { + if (row < 1 || row > 7 || + col < 1 || col > 7 || + state[row][col] == outside) + { + writeln("Field ", row, col, " is ouside the board. Try again."); + return true; + } + return false; + } + + while (true) + { + auto from = (){ + while (true) + { + write("\nMove which peg? "); + int field = readInt; + int row = field / 10, col = field % 10; + if (isOutside(row, col)) + continue; + if (state[row][col] != taken) + { + writeln("There is no peg at ", field, ". Try again."); + continue; + } + if (!canMoveFrom(row, col)) + { + writeln("The peg at ", field, " has nowhere to go. Try again."); + continue; + } + return tuple!("row", "col")(row, col); + } + }(); + auto to = (){ + while (true) + { + write("To where? "); + int field = readInt; + int row = field / 10, col = field % 10; + if (isOutside(row, col)) + continue; + if (state[row][col] == taken) + { + writeln("Field ", field, " is occupied. Try again."); + continue; + } + if (row != from.row && col != from.col) + { + writeln("You cannot move diagonally. Try again."); + continue; + } + if (row == from.row && col == from.col) + { + writeln("You aren't going anywhere. Try again."); + continue; + } + if (abs(row - from.row) + abs(col - from.col) > 2) + { + writeln("You can't jump that far. Try again."); + continue; + } + if (abs(row - from.row) + abs(col - from.col) < 2 || + state[(row + from.row) / 2][(col + from.col) / 2] != taken) + { + writeln("You need to jump over another peg. Try again."); + continue; + } + return tuple!("row", "col")(row, col); + } + }(); + // The move is legal. Update the board state. + state[from.row][from.col] = empty; + state[ to.row][ to.col] = taken; + state[(from.row + to.row) / 2][(from.col + to.col) / 2] = empty; + writeln; + break; + } + } + + /// Returns the number of remaining pegs on the board. + int numPegs() const + { + int num = 0; + foreach (row; state) + foreach (field; row) + if (field == taken) + num++; + return num; + } +} + +/// Reads an integer from standard input. +int readInt() nothrow +{ + try + return readString.to!int; + catch (Exception) // Not an integer. + return 0; +} + +/// Reads a string from standard input. +string readString() nothrow +{ + try + return trustedReadln.strip; + catch (Exception) // readln throws on I/O and Unicode errors, which we handle here. + return ""; +} + +/** An @trusted wrapper around readln. + * + * This is the only function that formally requires manual review for memory-safety. + * [Arguably readln should be safe already](https://forum.dlang.org/post/rab398$1up$1@digitalmars.com) + * which would remove the need to have any @trusted code in this program. + */ +string trustedReadln() @trusted +{ + return readln; +} + +version (Windows) +{ + // Make the Windows console do a better job at printing UTF-8 strings, + // and restore the default upon termination. + + import core.sys.windows.windows; + + shared static this() @trusted + { + SetConsoleOutputCP(CP_UTF8); + } + + shared static ~this() @trusted + { + SetConsoleOutputCP(GetACP); + } +} From 5d00a092af55935b604d4c7f00af71314420094c Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Tue, 11 Jan 2022 00:00:22 +1100 Subject: [PATCH 042/337] Building kotlin files. IntelliJ import instructions. --- HOW_TO_RUN_THE_GAMES.md | 28 ++++++++++++++++++++-------- buildJvm/README.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/HOW_TO_RUN_THE_GAMES.md b/HOW_TO_RUN_THE_GAMES.md index 6df23205..f067f872 100644 --- a/HOW_TO_RUN_THE_GAMES.md +++ b/HOW_TO_RUN_THE_GAMES.md @@ -23,16 +23,23 @@ Alternatively, for non-dotnet compatible translations, you will need [Visual Stu ## java +{% tip %} + +You can build all the java and kotlin games at once +using the instructions in the [buildJvm directory](buildJvm/README.md) + +{% endtip %} + The Java translations can be run via the command line or from an IDE such as [Eclipse](https://www.eclipse.org/downloads/packages/release/kepler/sr1/eclipse-ide-java-developers) or [IntelliJ](https://www.jetbrains.com/idea/) To run from the command line, you will need a Java SDK (eg. [Oracle JDK](https://www.oracle.com/java/technologies/downloads/) or [Open JDK](https://openjdk.java.net/)). 1. Navigate to the corresponding directory. 1. Compile the program with `javac`: - * eg. `javac AceyDuceyGame.java` + * eg. `javac AceyDuceyGame.java` 1. Run the compiled program with `java`: - * eg. `java AceyDuceyGame` - + * eg. `java AceyDuceyGame` + or if you are **using JDK11 or later** you can now execute a self contained java file that has a main method directly with `java .java`. ## javascript @@ -41,6 +48,11 @@ The javascript examples can be run from within your web browser: 1. Simply open the corresponding `.html` file from your web browser. +## kotlin + +Use the directions in [buildJvm](buildJvm/README.md) to build for kotlin. You can also use those directions to +build java games. + ## pascal The pascal examples can be run using [Free Pascal](https://www.freepascal.org/). Additionally, `.lsi` project files can be opened with the [Lazarus Project IDE](https://www.lazarus-ide.org/). @@ -48,7 +60,7 @@ The pascal examples can be run using [Free Pascal](https://www.freepascal.org/). The pascal examples include both *simple* (single-file) and *object-oriented* (in the `/object-pascal`directories) examples. 1. You can compile the program from the command line with the `fpc` command. - * eg. `fpc amazing.pas` + * eg. `fpc amazing.pas` 1. The output is an executable file that can be run directly. ## perl @@ -57,7 +69,7 @@ The perl translations can be run using a perl interpreter (a copy can be downloa 1. From the command-line, navigate to the corresponding directory. 1. Invoke with the `perl` command. - * eg. `perl aceyducey.pl` + * eg. `perl aceyducey.pl` ## python @@ -65,8 +77,8 @@ The python translations can be run from the command line by using the `py` inter 1. From the command-line, navigate to the corresponding directory. 1. Invoke with the `py` or `python` interpreter (depending on your python version). - * eg. `py acey_ducey_oo.py` - * eg. `python aceyducey.py` + * eg. `py acey_ducey_oo.py` + * eg. `python aceyducey.py` **Note** @@ -80,7 +92,7 @@ If you don't already have a ruby interpreter, you can download it from the [ruby 1. From the command-line, navigate to the corresponding directory. 1. Invoke with the `ruby` tool. - * eg. `ruby aceyducey.rb` + * eg. `ruby aceyducey.rb` ## vbnet diff --git a/buildJvm/README.md b/buildJvm/README.md index f0046ab3..c70bf573 100644 --- a/buildJvm/README.md +++ b/buildJvm/README.md @@ -20,6 +20,34 @@ Then, run a game You will need to install openjdk 17, because some games use advanced Java features. We should be using version 17 anyway, because anything less than 17 is deprecated. +--- +## Using an IDE to work on JVM games + +You can open the entire Basic Computer Games project in an IDE, with any IDE capable +of importing from a gradle project. + +### IntelliJ / Android Studio + +1. (Optional) If you want to make changes, or contribute a new kotlin or java version +of one of the games, use [github "fork"](https://docs.github.com/en/get-started/quickstart/fork-a-repo) +to create your own editable fork of the project. +2. Check out the code using `File` -> `New` -> `Project from Version Control` + 1. Enter the URL of the project. For the main project this will be `https://github.com/coding-horror/basic-computer-games.git`, for your +own fork this will be `https://github.com/YOURNAMEHERE/basic-computer-games.git` + 2. Choose a directory for the clone to live in +3. Click `Clone` + +The project will open, and eventually you will get a little alert box in the bottom right corner saying "Gradle build script found". + +Click the "Load" link in the alert box, to load the gradle project. + +You should see all the games appear on the left side of the screen. If you have loaded +your own fork, you can modify, commit and push your changes to github. + +If you are using the main `coding-horror` branch, you can still make and run your own changes. If +your git skills are up to the task, you might even fork the project and change your +local clone to point to your new forked project. + --- ## Adding a new game @@ -37,6 +65,7 @@ The `build.gradle` file will normally be identical to this: plugins { id 'application' + // id 'org.jetbrains.kotlin.jvm' // UNCOMMENT for kotlin projects } sourceSets { From 25c79621a0c42a3f755a962bb9a5913ef5ae5cf8 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Tue, 11 Jan 2022 00:09:09 +1100 Subject: [PATCH 043/337] Update HOW_TO_RUN_THE_GAMES.md remove bad formatting --- HOW_TO_RUN_THE_GAMES.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/HOW_TO_RUN_THE_GAMES.md b/HOW_TO_RUN_THE_GAMES.md index f067f872..fae0656f 100644 --- a/HOW_TO_RUN_THE_GAMES.md +++ b/HOW_TO_RUN_THE_GAMES.md @@ -23,13 +23,9 @@ Alternatively, for non-dotnet compatible translations, you will need [Visual Stu ## java -{% tip %} - -You can build all the java and kotlin games at once +**TIP:** You can build all the java and kotlin games at once using the instructions in the [buildJvm directory](buildJvm/README.md) -{% endtip %} - The Java translations can be run via the command line or from an IDE such as [Eclipse](https://www.eclipse.org/downloads/packages/release/kepler/sr1/eclipse-ide-java-developers) or [IntelliJ](https://www.jetbrains.com/idea/) To run from the command line, you will need a Java SDK (eg. [Oracle JDK](https://www.oracle.com/java/technologies/downloads/) or [Open JDK](https://openjdk.java.net/)). From 8b2c72bc21fc93fcabdb108721fbadad8ec0e1d3 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Tue, 11 Jan 2022 00:12:21 +1100 Subject: [PATCH 044/337] update README.md --- buildJvm/README.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/buildJvm/README.md b/buildJvm/README.md index c70bf573..a5169abd 100644 --- a/buildJvm/README.md +++ b/buildJvm/README.md @@ -1,25 +1,28 @@ # JVM gradle scripts ## Quickstart +You will need to install openjdk 17, because some games use advanced Java features. +We should be using version 17 anyway, because anything less than 17 is deprecated. Build all the games: - - cd buildJvm - ./gradlew -q assemble installDist distributeBin distributeLib +```shell + cd buildJvm + ./gradlew -q assemble installDist distributeBin distributeLib +``` Then, run a game ### Mac or linux: - - build/distrib/bin/build_53_King_kotlin - +```shell +build/distrib/bin/build_53_King_kotlin +``` ### Windows [not tested yet] - build\distrib\bin\build_53_King_kotlin.bat +```shell +build\distrib\bin\build_53_King_kotlin.bat +``` -You will need to install openjdk 17, because some games use advanced Java features. -We should be using version 17 anyway, because anything less than 17 is deprecated. --- ## Using an IDE to work on JVM games @@ -62,7 +65,7 @@ there is some special requirement. directory for the java or kotlin file, and the class that contains the `main` method. The `build.gradle` file will normally be identical to this: - +```groovy plugins { id 'application' // id 'org.jetbrains.kotlin.jvm' // UNCOMMENT for kotlin projects @@ -83,6 +86,7 @@ The `build.gradle` file will normally be identical to this: application { mainClass = gameMain } +``` And the `gradle.properties` file should look like this: From eaf24739e3e8f0b8f4ff5b7e9d7c306a99620622 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Mon, 10 Jan 2022 10:05:28 -0500 Subject: [PATCH 045/337] Initial Commit, added instructions --- 75_Roulette/java/src/Roulette.java | 69 ++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 75_Roulette/java/src/Roulette.java diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/src/Roulette.java new file mode 100644 index 00000000..a07d2afd --- /dev/null +++ b/75_Roulette/java/src/Roulette.java @@ -0,0 +1,69 @@ +import java.io.PrintStream; + +public class Roulette { + + private PrintStream out; + + public static void main(String[] args) { + new Roulette(System.out).play(); + } + + public Roulette(PrintStream out) { + this.out = out; + } + + public void play() { + printInstructions(); + } + + + public void printInstructions() { + System.out.println(); + System.out.println( "THIS IS THE BETTING LAYOUT"); + System.out.println( " (*=RED)"); + System.out.println(); + System.out.println( " 1* 2 3*"); + System.out.println( " 4 5* 6 "); + System.out.println( " 7* 8 9*"); + System.out.println( "10 11 12*"); + System.out.println( "---------------"); + System.out.println( "13 14* 15 "); + System.out.println( "16* 17 18*"); + System.out.println( "19* 20 21*"); + System.out.println( "22 23* 24 "); + System.out.println( "---------------"); + System.out.println( "25* 26 27*"); + System.out.println( "28 29 30*"); + System.out.println( "31 32* 33 "); + System.out.println( "34* 35 36*"); + System.out.println( "---------------"); + System.out.println( " 00 0 "); + System.out.println(); + System.out.println( "TYPES OF BETS"); + System.out.println(); + System.out.println( "THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET"); + System.out.println( "ON THAT NUMBER."); + System.out.println( "THESE PAY OFF 35:1"); + System.out.println(); + System.out.println( "THE 2:1 BETS ARE:"); + System.out.println( " 37) 1-12 40) FIRST COLUMN"); + System.out.println( " 38) 13-24 41) SECOND COLUMN"); + System.out.println( " 39) 25-36 42) THIRD COLUMN"); + System.out.println(); + System.out.println( "THE EVEN MONEY BETS ARE:"); + System.out.println( " 43) 1-18 46) ODD"); + System.out.println( " 44) 19-36 47) RED"); + System.out.println( " 45) EVEN 48) BLACK"); + System.out.println(); + System.out.println( " 49)0 AND 50)00 PAY OFF 35:1"); + System.out.println( " NOTE: 0 AND 00 DO NOT COUNT UNDER ANY"); + System.out.println( " BETS EXCEPT THEIR OWN."); + System.out.println(); + System.out.println( "WHEN I ASK FOR EACH BET, TYPE THE NUMBER"); + System.out.println( "AND THE AMOUNT, SEPARATED BY A COMMA."); + System.out.println( "FOR EXAMPLE: TO BET $500 ON BLACK, TYPE 48,500"); + System.out.println( "WHEN I ASK FOR A BET."); + System.out.println(); + System.out.println( "THE MINIMUM BET IS $5, THE MAXIMUM IS $500."); + } +} From b97f4f5e3e404970124e78bb55674cee8e38d4a1 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Mon, 10 Jan 2022 10:44:49 -0500 Subject: [PATCH 046/337] Added querying of bets and randomized roll --- 75_Roulette/java/src/Roulette.java | 198 +++++++++++++++++++++-------- 1 file changed, 147 insertions(+), 51 deletions(-) diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/src/Roulette.java index a07d2afd..3522364d 100644 --- a/75_Roulette/java/src/Roulette.java +++ b/75_Roulette/java/src/Roulette.java @@ -1,69 +1,165 @@ +import java.io.InputStream; import java.io.PrintStream; +import java.util.*; public class Roulette { private PrintStream out; + private Scanner scanner; - public static void main(String[] args) { - new Roulette(System.out).play(); + private int houseBalance, playerBalance; + + private Random random; + + private static Set RED_NUMBERS; + + static { + RED_NUMBERS = Set.of(1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36); } - public Roulette(PrintStream out) { + public static void main(String[] args) { + new Roulette(System.out, System.in).play(); + } + + public Roulette(PrintStream out, InputStream in) { this.out = out; + this.scanner = new Scanner(in); + houseBalance = 100000; + playerBalance = 1000; + random = new Random(); } public void play() { - printInstructions(); + out.println(" ROULETTE"); + out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + out.println("WELCOME TO THE ROULETTE TABLE\n"); + out.println("DO YOU WANT INSTRUCTIONS"); + if(scanner.nextLine().toLowerCase().charAt(0) != 'n') { + printInstructions(); + } + + while(houseBalance > 0 && playerBalance > 0) { + + Bet[] bets = queryBets(); + + out.println("SPINNING...\n\n\n"); + int result = random.nextInt(1,39); + + /* + Equivalent to following line + if(RED_NUMBERS.contains(result)) { + out.println(result + " RED"); + } else { + out.println(result + " BLACK"); + } + */ + out.println(result + (RED_NUMBERS.contains(result) ? " RED\n" : " BLACK\n")); + + + } } + private Bet[] queryBets() { + int numBets = -1; + while(numBets < 1) { + out.println("HOW MANY BETS"); + try { + numBets = Integer.parseInt(scanner.nextLine()); + } catch(NumberFormatException exception) { + out.println("THAT IS NOT A NUMBER"); + } + } + + Bet[] bets = new Bet[numBets]; + + for(int i = 0; i < numBets; i++) { + try { + out.println("BET NUMBER " + (i + 1) + ":"); + String[] values = scanner.nextLine().split(","); + int betNumber = Integer.parseInt(values[0]); + int betValue = Integer.parseInt(values[1]); + + for(int j = 0; j < i; j++) { + if(bets[j].number == betNumber) { + out.println("YOU MADE THAT BET ONCE ALREADY,DUM-DUM"); + throw new Exception(); + } + } + + if(betNumber < 1 || betNumber > 50 || betValue < 5 || betValue > 500) { + out.println("INVALID VALUE, TRY AGAIN"); + i--; + continue; + } + + bets[i] = new Bet(betNumber,betValue); + + } catch(Exception exception) { + if(exception instanceof NumberFormatException) { + out.println("SYNTAX ERROR, TRY AGAIN"); + } + i--; + } + } + return bets; + } public void printInstructions() { - System.out.println(); - System.out.println( "THIS IS THE BETTING LAYOUT"); - System.out.println( " (*=RED)"); - System.out.println(); - System.out.println( " 1* 2 3*"); - System.out.println( " 4 5* 6 "); - System.out.println( " 7* 8 9*"); - System.out.println( "10 11 12*"); - System.out.println( "---------------"); - System.out.println( "13 14* 15 "); - System.out.println( "16* 17 18*"); - System.out.println( "19* 20 21*"); - System.out.println( "22 23* 24 "); - System.out.println( "---------------"); - System.out.println( "25* 26 27*"); - System.out.println( "28 29 30*"); - System.out.println( "31 32* 33 "); - System.out.println( "34* 35 36*"); - System.out.println( "---------------"); - System.out.println( " 00 0 "); - System.out.println(); - System.out.println( "TYPES OF BETS"); - System.out.println(); - System.out.println( "THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET"); - System.out.println( "ON THAT NUMBER."); - System.out.println( "THESE PAY OFF 35:1"); - System.out.println(); - System.out.println( "THE 2:1 BETS ARE:"); - System.out.println( " 37) 1-12 40) FIRST COLUMN"); - System.out.println( " 38) 13-24 41) SECOND COLUMN"); - System.out.println( " 39) 25-36 42) THIRD COLUMN"); - System.out.println(); - System.out.println( "THE EVEN MONEY BETS ARE:"); - System.out.println( " 43) 1-18 46) ODD"); - System.out.println( " 44) 19-36 47) RED"); - System.out.println( " 45) EVEN 48) BLACK"); - System.out.println(); - System.out.println( " 49)0 AND 50)00 PAY OFF 35:1"); - System.out.println( " NOTE: 0 AND 00 DO NOT COUNT UNDER ANY"); - System.out.println( " BETS EXCEPT THEIR OWN."); - System.out.println(); - System.out.println( "WHEN I ASK FOR EACH BET, TYPE THE NUMBER"); - System.out.println( "AND THE AMOUNT, SEPARATED BY A COMMA."); - System.out.println( "FOR EXAMPLE: TO BET $500 ON BLACK, TYPE 48,500"); - System.out.println( "WHEN I ASK FOR A BET."); - System.out.println(); - System.out.println( "THE MINIMUM BET IS $5, THE MAXIMUM IS $500."); + out.println(); + out.println( "THIS IS THE BETTING LAYOUT"); + out.println( " (*=RED)"); + out.println(); + out.println( " 1* 2 3*"); + out.println( " 4 5* 6 "); + out.println( " 7* 8 9*"); + out.println( "10 11 12*"); + out.println( "---------------"); + out.println( "13 14* 15 "); + out.println( "16* 17 18*"); + out.println( "19* 20 21*"); + out.println( "22 23* 24 "); + out.println( "---------------"); + out.println( "25* 26 27*"); + out.println( "28 29 30*"); + out.println( "31 32* 33 "); + out.println( "34* 35 36*"); + out.println( "---------------"); + out.println( " 00 0 "); + out.println(); + out.println( "TYPES OF BETS"); + out.println(); + out.println( "THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET"); + out.println( "ON THAT NUMBER."); + out.println( "THESE PAY OFF 35:1"); + out.println(); + out.println( "THE 2:1 BETS ARE:"); + out.println( " 37) 1-12 40) FIRST COLUMN"); + out.println( " 38) 13-24 41) SECOND COLUMN"); + out.println( " 39) 25-36 42) THIRD COLUMN"); + out.println(); + out.println( "THE EVEN MONEY BETS ARE:"); + out.println( " 43) 1-18 46) ODD"); + out.println( " 44) 19-36 47) RED"); + out.println( " 45) EVEN 48) BLACK"); + out.println(); + out.println( " 49)0 AND 50)00 PAY OFF 35:1"); + out.println( " NOTE: 0 AND 00 DO NOT COUNT UNDER ANY"); + out.println( " BETS EXCEPT THEIR OWN."); + out.println(); + out.println( "WHEN I ASK FOR EACH BET, TYPE THE NUMBER"); + out.println( "AND THE AMOUNT, SEPARATED BY A COMMA."); + out.println( "FOR EXAMPLE: TO BET $500 ON BLACK, TYPE 48,500"); + out.println( "WHEN I ASK FOR A BET."); + out.println(); + out.println( "THE MINIMUM BET IS $5, THE MAXIMUM IS $500."); + } + + public class Bet { + final int number, value; + + public Bet(int number, int value) { + this.number = number; + this.value = value; + } } } From c32798aa755eddc94a878faf09e8c72f9732dd45 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Mon, 10 Jan 2022 11:14:10 -0500 Subject: [PATCH 047/337] Added bet checking conditions --- 75_Roulette/java/src/Roulette.java | 45 ++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/src/Roulette.java index 3522364d..533afe4e 100644 --- a/75_Roulette/java/src/Roulette.java +++ b/75_Roulette/java/src/Roulette.java @@ -53,7 +53,11 @@ public class Roulette { out.println(result + " BLACK"); } */ - out.println(result + (RED_NUMBERS.contains(result) ? " RED\n" : " BLACK\n")); + switch(result) { + case 37 -> out.print("00"); + case 38 -> out.print("0"); + default -> out.println(result + (RED_NUMBERS.contains(result) ? " RED\n" : " BLACK\n")); + } } @@ -80,7 +84,7 @@ public class Roulette { int betValue = Integer.parseInt(values[1]); for(int j = 0; j < i; j++) { - if(bets[j].number == betNumber) { + if(bets[j].num == betNumber) { out.println("YOU MADE THAT BET ONCE ALREADY,DUM-DUM"); throw new Exception(); } @@ -104,6 +108,35 @@ public class Roulette { return bets; } + private void betResults(Bet[] bets, int num) { + for(int i = 0; i < bets.length; i++) { + Bet bet = bets[i]; + /* + Using a switch statement of ternary operators that check if a certain condition is met based on the bet value + Returns the coefficient that the bet amount should be multiplied by to get the resulting value + */ + int coefficient = switch(bet.num) { + case 37 -> (num <= 12) ? 2 : -1; + case 38 -> (num > 12 && num <= 24) ? 2 : -1; + case 39 -> (num > 24 && num < 37) ? 2 : -1; + case 40 -> (num < 37 && num % 3 == 1) ? 2 : -1; + case 41 -> (num < 37 && num % 3 == 2) ? 2 : -1; + case 42 -> (num < 37 && num % 3 == 0) ? 2 : -1; + case 43 -> (num <= 18) ? 1 : -1; + case 44 -> (num > 18 && num <= 36) ? 1 : -1; + case 45 -> (num % 2 == 0) ? 1 : -1; + case 46 -> (num % 2 == 1) ? 1 : -1; + case 47 -> RED_NUMBERS.contains(num) ? 1 : -1; + case 48 -> !RED_NUMBERS.contains(num) ? 1 : -1; + case 49 -> (num == 37) ? 35 : -1; + case 50 -> (num == 38) ? 35 : -1; + default -> (bet.num < 49 && bet.num == num) ? 35 : -1; + }; + + int betResult = bet.amount * coefficient; + } + } + public void printInstructions() { out.println(); out.println( "THIS IS THE BETTING LAYOUT"); @@ -155,11 +188,11 @@ public class Roulette { } public class Bet { - final int number, value; + final int num, amount; - public Bet(int number, int value) { - this.number = number; - this.value = value; + public Bet(int num, int amount) { + this.num = num; + this.amount = amount; } } } From a40c2fc5345b69bd4658e69d5657fc76e4836c42 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Mon, 10 Jan 2022 11:29:50 -0500 Subject: [PATCH 048/337] Added replay and ending I think... --- 75_Roulette/java/src/Roulette.java | 42 +++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/src/Roulette.java index 533afe4e..49d14275 100644 --- a/75_Roulette/java/src/Roulette.java +++ b/75_Roulette/java/src/Roulette.java @@ -1,5 +1,6 @@ import java.io.InputStream; import java.io.PrintStream; +import java.lang.management.PlatformLoggingMXBean; import java.util.*; public class Roulette { @@ -38,7 +39,7 @@ public class Roulette { printInstructions(); } - while(houseBalance > 0 && playerBalance > 0) { + do { Bet[] bets = queryBets(); @@ -53,13 +54,33 @@ public class Roulette { out.println(result + " BLACK"); } */ - switch(result) { - case 37 -> out.print("00"); - case 38 -> out.print("0"); - default -> out.println(result + (RED_NUMBERS.contains(result) ? " RED\n" : " BLACK\n")); - } + switch(result) { + case 37 -> out.print("00"); + case 38 -> out.print("0"); + default -> out.println(result + (RED_NUMBERS.contains(result) ? " RED\n" : " BLACK\n")); + } + betResults(bets,result); + out.println(); + out.println("TOTALS:"); + out.println("\tME: " + houseBalance); + out.println("\tYOU " + playerBalance); + + } while(playAgain()); + if(playerBalance <= 0) { + out.println("OOPS! YOU JUST SPENT YOUR LAST DOLLAR!"); + } else if(houseBalance <= 0) { + out.println("YOU BROKE THE HOUSE!"); + } + } + + private boolean playAgain() { + if(playerBalance > 0 && houseBalance > 0) { + out.println("PLAY AGAIN?"); + return scanner.nextLine().toLowerCase().charAt(0) == 'y'; + } else { + return false; } } @@ -134,6 +155,15 @@ public class Roulette { }; int betResult = bet.amount * coefficient; + + if(betResult < 0) { + out.println("YOU LOSE " + -betResult + " DOLLARS ON BET " + (i + 1)); + } else { + out.println("YOU WIN " + betResult + " DOLLARS ON BET " + (i + 1)); + } + + playerBalance += betResult; + houseBalance -= betResult; } } From 0d7f407197e19fd76068691270945863d830e397 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Mon, 10 Jan 2022 11:31:04 -0500 Subject: [PATCH 049/337] Create roulette.py --- 75_Roulette/python/roulette.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 75_Roulette/python/roulette.py diff --git a/75_Roulette/python/roulette.py b/75_Roulette/python/roulette.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/75_Roulette/python/roulette.py @@ -0,0 +1 @@ + From 2dc63bb95a75326a78472a8698638c6e829ce258 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Mon, 10 Jan 2022 11:41:02 -0500 Subject: [PATCH 050/337] Still unsure about $$ Is the check for the difference? Is it only when the house cannot pay what it owes? --- 75_Roulette/java/src/Roulette.java | 47 ++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/src/Roulette.java index 49d14275..c6e46152 100644 --- a/75_Roulette/java/src/Roulette.java +++ b/75_Roulette/java/src/Roulette.java @@ -1,6 +1,7 @@ import java.io.InputStream; import java.io.PrintStream; import java.lang.management.PlatformLoggingMXBean; +import java.time.LocalDateTime; import java.util.*; public class Roulette { @@ -69,14 +70,54 @@ public class Roulette { } while(playAgain()); if(playerBalance <= 0) { - out.println("OOPS! YOU JUST SPENT YOUR LAST DOLLAR!"); + out.println("THANKS FOR YOUR MONEY\nI'LL USE IT TO BUY A SOLID GOLD ROULETTE WHEEL"); } else if(houseBalance <= 0) { - out.println("YOU BROKE THE HOUSE!"); + out.println("TO WHOM SHALL I MAKE THE CHECK"); + String name = scanner.nextLine(); + out.println(); + for(int i = 0; i < 72; i++) { + out.print("-"); + } + out.println(); + for(int i = 0; i < 50; i++) { + out.print(" "); + } + out.println("CHECK NO. " + random.nextInt(0,1000)); + out.println(); + for(int i = 0; i < 40; i++) { + out.print(" "); + } + out.println(LocalDateTime.now()); + out.println("\n"); + out.println("PAY TO THE ORDER OF----- " + name + "------$" + (playerBalance - 1000)); + out.println("\n"); + for(int i = 0; i < 10; i++) { + out.print(" "); + } + out.println("THE MEMORY BANK OF NEW YORK"); + for(int i = 0; i < 40; i++) { + out.print(" "); + } + out.println("THE COMPUTER"); + for(int i = 0; i < 40; i++) { + out.print(" "); + } + out.println("----------X-----"); + for(int i = 0; i < 72; i++) { + out.print("-"); + } + out.println("\n"); + out.println("COME BACK SOON"); } } private boolean playAgain() { - if(playerBalance > 0 && houseBalance > 0) { + if(playerBalance > 0) { + if(houseBalance <= 0) { + out.println("YOU BROKE THE HOUSE!"); + //using default values + playerBalance = 101000; + } out.println("PLAY AGAIN?"); return scanner.nextLine().toLowerCase().charAt(0) == 'y'; } else { From 82a126bce36b1c3aea47fbaa017953968cd968c7 Mon Sep 17 00:00:00 2001 From: Mark Wieder Date: Mon, 10 Jan 2022 10:18:24 -0800 Subject: [PATCH 051/337] initial attempt --- 65_Nim/ruby/nim.rb | 282 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 65_Nim/ruby/nim.rb diff --git a/65_Nim/ruby/nim.rb b/65_Nim/ruby/nim.rb new file mode 100644 index 00000000..a326695f --- /dev/null +++ b/65_Nim/ruby/nim.rb @@ -0,0 +1,282 @@ +puts "NIM".center(80) +puts"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY".center(80) +puts "\n\n\n" + +#210 DIM A(100),B(100,10),D(2) +$pileArray = Array.new[100] +$bArray = Array.new +$dArray = Array.new[2] +$winOption = 0 # take-last option +$numberOfPiles = 1 +$c = 0 +$e = 0 +$f = 0 +$g = 0 +$h = 0 + +def displayTheRules +puts "THE GAME IS PLAYED WITH A NUMBER OF PILES OF OBJECTS." +puts "ANY NUMBER OF OBJECTS ARE REMOVED FROM ONE PILE BY YOU AND" +puts "THE MACHINE ALTERNATELY. ON YOUR TURN, YOU MAY TAKE" +puts "ALL THE OBJECTS THAT REMAIN IN ANY PILE, BUT YOU MUST" +puts "TAKE AT LEAST ONE OBJECT, AND YOU MAY TAKE OBJECTS FROM" +puts "ONLY ONE PILE ON A SINGLE TURN. YOU MUST SPECIFY WHETHER" +puts "WINNING IS DEFINED AS TAKING OR NOT TAKING THE LAST OBJECT," +puts "THE NUMBER OF PILES IN THE GAME, AND HOW MANY OBJECTS ARE" +puts "ORIGINALLY IN EACH PILE. EACH PILE MAY CONTAIN A" +puts "DIFFERENT NUMBER OF OBJECTS." +puts "THE MACHINE WILL SHOW ITS MOVE BY LISTING EACH PILE AND THE" +puts "NUMBER OF OBJECTS REMAINING IN THE PILES AFTER EACH OF ITS" +puts "MOVES." +end + +def sub1570 + $z=0 + for i in 1..$numberOfPiles do + if $pileArray[i] != 0 then + return + end + $z=1 + return + end +end + +def playAnother + put "do you want to play another game"; + return gets.strip.ucase == "YES" +end +puts "THIS IS THE GAME OF NIM." +print "DO YOU WANT INSTRUCTIONS?" +240 +wantInstructions = gets.strip.upcase +if wantInstructions == "YES" then + displayTheRules +end +#250 IF Z$="NO" THEN 440 +#260 IF Z$="no" THEN 440 +#270 IF Z$="YES" THEN displayTheRules +#280 IF Z$="yes" THEN displayTheRules +#290 PRINT "PLEASE ANSWER YES OR NO" +#300 GOTO 240 + +def sub490 # get number of piles + print "ENTER NUMBER OF PILES:" + while $numberOfPiles < 0 && $numberOfPiles <= 100 do + $numberOfPiles = gets.strip.to_i + end +end + +def getPileSizes + puts "ENTER PILE SIZES:" + for i in 1..$numberOfPiles do + print i + while true do + $pileArray[i] = gets.strip.to_i + if $pileArray[i] < 2000 && $pileArray[i] > 0 then + break + end + end + end +end + +def sub440 # get win option + puts "" + $winOption = 0 + while $winOption != 1 && q != 2 do + puts "ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST" + $winOption = gets.strip.to_i + end +end + +puts "DO YOU WANT TO MOVE FIRST?"; +#630 INPUT Q9$ +moveFirst = "" +while moveFirst != "YES" && moveFirst != "NO" do + moveFirst = gets.strip.upcase + case moveFirst + when "YES" + yourMove + when "NO" + machineMove + end +end + +#640 IF Q9$="YES" THEN 1450 +#650 IF Q9$="yes" THEN 1450 +#660 IF Q9$="NO" THEN 700 +#670 IF Q9$="no" THEN 700 +#680 PRINT "PLEASE ANSWER YES OR NO." +#690 GOTO 630 + +def machineMove + if $winOption == 1 then + sub940 # take last + end + $c=0 + for i in 1..$numberOfPiles do + if $pileArray[i] != 0 then 770 + $c=$c+1 + if $c == 3 then + sub840 + end + $dArray[$c-1]=i + end + end + + if $c == 2 then + sub920 + end + if $pileArray[$dArray[0]] > 1 then + machineWins + end + machineLoses +end + +def machineLoses + puts "MACHINE LOSES" +# 810 GOTO playAnother + if playAnother then + sub440 # loop for another + end +end + +def machineWins + puts "MACHINE WINS" +# 830 GOTO playAnother + if playAnother then + sub440 # loop for another + end +end + +def sub840 + $c=0 + for i in 1..$numberOfPiles do + if $pileArray[i] > 1 then + sub940 + end + if $pileArray[i] == 0 then 890 + $c=$c+1 + end + if $c/2 != ($c/2).to_i then + machineLoses + end + sub940 # goto + end +end + +def sub920 + if $pileArray[$dArray[0]] == 1 then + machineWins + end + if $pileArray[$dArray[1]] == 1 then + machineWins + end +end + +def sub940 + for i in 1..$numberOfPiles do + e=$pileArray[i] + for j in 0..10 do + $f = $e/2 + $bArray[i][j] = 2*($f-($f.to_i)) + $e = $f.to_i + end + end +end + +#for j in 10..0 STEP -1 do +10..0.step(-1).each do|index| + $c=0 + $h=0 + for i in 1..$numberOfPiles do + if $bArray[i][index] != 0 then + $c=$c+1 + if $pileArray[i] > $h then + $h = $pileArray[i] + $g = i + end + end + end +end + +if $c/2 != ($c/2).to_i then 1190 +end +$e = rand($numberOfPiles).to_i +#if $pileArray[$e] == 0 then 1140 + +$f = rand($pileArray[$e]).to_i +$pileArray[$e] = $pileArray[$e]-$f +sub1380 +$pileArray[$g]=0 +for j in 0..10 do +$bArray[$g][index]=0 +$c=0 +for i in 1..$numberOfPiles do + if $bArray[i][index] != 0 then + $c=$c+1 + end + end +$pileArray[$g]=$pileArray[$g]+2*($c/2-($c/2)).to_i*2^j +end +if $winOption == 1 then + sub1380 +end +$c=0 +for i in 1..$numberOfPiles do +if $pileArray[i]>1 then + sub1380 +end +if $pileArray[i] != 0 then + $c=$c+1 +end +if $c/2 == ($c/2).to_i then + sub1380 +end +$pileArray[$g] == 1 -$pileArray[$g] + +def sub1380 + puts "PILE SIZE" + for i in 1..$numberOfPiles do + put i + put $pileArray[i] + end + if $winOption == 2 then # avoid take-last option + yourMove + end + sub1570 + if $z == 1 then + machineWins + end +end + +def yourMove + put "YOUR MOVE - PILE, NUMBER TO BE REMOVED" +# 1460 INPUT x,y +x = gets.strip.to_i +y = gets.strip.to_i + if x > $numberOfPiles then yourMove + if x < 1 then yourMove + if x != INT(x) then yourMove + if y > $pileArray[x] then yourMove + if y < 1 then + yourMove + end + if y != INT(y) then + yourMove + end + + $pileArray[x] = $pileArray[x]-y + sub1570 # gosub + if $z == 1 then + machineLoses + end +# 1560 GOTO 700 +end + +end +end +end +end +end + + From 420597dbcf4ee0b1f7859b719ca2a46c53497326 Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 10 Jan 2022 19:21:15 +0000 Subject: [PATCH 052/337] First cut java battleships --- 09_Battle/java/Battle.java | 372 +++++++++++++++++++++++++++++++++++++ 1 file changed, 372 insertions(+) create mode 100644 09_Battle/java/Battle.java diff --git a/09_Battle/java/Battle.java b/09_Battle/java/Battle.java new file mode 100644 index 00000000..aa53896c --- /dev/null +++ b/09_Battle/java/Battle.java @@ -0,0 +1,372 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Random; +import java.util.function.Predicate; +import java.text.NumberFormat; + +public class Battle { + private int seaSize; + private int[] sizes; + private int[] counts; + + private ArrayList ships; + private Sea sea; + + private int[] losses; + private int hits; + private int misses; + + private static String NAMES_BY_SIZE[] = { + "error", + "size1", + "destroyer", + "cruiser", + "aircraft carrier", + "size5" }; + + public static void main(String args[]) { + Battle game = new Battle(6, + new int[] { 2, 3, 4 }, + new int[] { 2, 2, 2 }); + game.play(); + } + + public Battle(int scale, int[] shipSizes, int[] shipCounts) { + seaSize = scale; + sizes = shipSizes; + counts = shipCounts; + + /* validate parameters */ + if (seaSize < 4) throw new RuntimeException("Sea Size " + seaSize + " invalid, must be at least 4"); + + for (int sz : sizes) { + if ((sz < 1) || (sz > seaSize)) + throw new RuntimeException("Ship has invalid size " + sz); + } + + if (counts.length != sizes.length) { + throw new RuntimeException("Ship counts must match"); + } + + sea = new Sea(seaSize); + ships = new ArrayList(); + losses = new int[counts.length]; + + int shipNumber = 1; + for (int type = 0; type < counts.length; ++type) { + for (int i = 0; i < counts[i]; ++i) { + ships.add(new Ship(shipNumber++, "Ship", sizes[type])); + } + } + + ArrayList largestFirst = new ArrayList<>(ships); + Collections.sort(largestFirst, Comparator.comparingInt((Ship ship) -> ship.size()).reversed()); + + for (Ship ship : largestFirst) { + ship.placeRandom(sea); + } + } + + public void play() { + System.out.println("The following code of the bad guys' fleet disposition\nhas been captured but not decoded:\n"); + System.out.println(sea.encodedDump()); + System.out.println("De-code it and use it if you can\nbut keep the de-coding method a secret.\n"); + + int lost = 0; + System.out.println("Start game"); + try { + BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); + NumberFormat parser = NumberFormat.getIntegerInstance(); + + while (lost < ships.size()) { + System.out.print("\nTarget x,y\n> "); + String inputLine = input.readLine(); + if (inputLine == null) { + System.out.println("Game quit\n"); + return; + } + String[] coords = inputLine.split(","); + if (coords.length != 2) { + System.out.println("Need two coordinates separated by ','"); + continue; + } + int[] xy = new int[2]; + boolean error = false; + try { + for (int c = 0 ; c < 2; ++c ) { + int val = Integer.parseInt(coords[c].strip()); + if ((val < 1) || (val > seaSize)) { + System.out.println("Coordinates must be from 1 to " + seaSize); + error = true; + } else { + xy[c] = val; + } + } + } + catch (NumberFormatException ne) { + System.out.println("Coordinates must be numbers"); + error = true; + } + if (error) continue; + + int row = seaSize - xy[1]; + int col = xy[0] - 1; + + if (sea.isEmpty(col, row)) { + ++misses; + System.out.println("Splash! Try again."); + } else { + Ship ship = ships.get(sea.get(col, row) - 1); + if (ship.isSunk()) { + ++misses; + System.out.println("There used to be a ship at that point, but you sunk it."); + System.out.println("Splash! Try again."); + } else if (ship.wasHit(col, row)) { + ++misses; + System.out.println("You already put a hole in ship number " + ship.id()); + System.out.println("Splash! Try again."); + } else { + ship.hit(col, row); + ++hits; + System.out.println("A direct hit on ship number " + ship.id()); + if (ship.isSunk()) { + ++lost; + System.out.println("And you sunk it. Hurrah for the good guys."); + System.out.print("So far, the bad guys have lost "); + ArrayList typeDescription = new ArrayList<>(); + for (int i = 0 ; i < sizes.length; ++i) { + if (sizes[i] == ship.size()) { + ++losses[i]; + } + StringBuilder sb = new StringBuilder(); + sb.append(losses[i]); + sb.append(" "); + sb.append(NAMES_BY_SIZE[sizes[i]]); + if (losses[i] != 1) + sb.append("s"); + typeDescription.add(sb.toString()); + } + System.out.println(String.join(", ", typeDescription)); + double ratioNum = ((double)misses)/hits; + String ratio = NumberFormat.getInstance().format(ratioNum); + System.out.println("Your current splash/hit ratio is " + ratio); + + if (lost == ships.size()) { + System.out.println("You have totally wiped out the bad guys' fleet"); + System.out.println("With a final splash/hit ratio of " + ratio); + + if (misses == 0) { + System.out.println("Congratulations - A direct hit every time."); + } + + System.out.println("\n****************************\n"); + } + } + } + } + } + } + catch (IOException e) { + } + } + + private static class Ship { + public static final int ORIENT_E=0; + public static final int ORIENT_SE=1; + public static final int ORIENT_S=2; + public static final int ORIENT_SW=3; + + private int id; + private int size; + private String type; + private boolean placed; + private boolean sunk; + private ArrayList hits; + + private int startX; + private int startY; + private int orientX; + private int orientY; + + public Ship(int i, String name, int sz) { + id = i; type = name; size = sz; + sunk = false; placed = false; + hits = new ArrayList<>(Collections.nCopies(size, false)); + } + + public int id() { return id; } + public int size() { return size; } + + public void hit(int x, int y) { + int offset; + if (orientX != 0) { + offset = (x - startX) / orientX; + } else { + offset = (y - startY) / orientY; + } + hits.set(offset, true); + + sunk = hits.stream().allMatch(Predicate.isEqual(true)); + } + + public boolean isSunk() { return sunk; } + + public boolean wasHit(int x, int y) { + int offset; + if (orientX != 0) { + offset = (x - startX) / orientX; + } else { + offset = (y - startY) / orientY; + } + return hits.get(offset); + }; + + public void placeRandom(Sea s) { + Random random = new Random(); + for (int tries = 0 ; tries < 1000 ; ++tries) { + int x = random.nextInt(s.size()); + int y = random.nextInt(s.size()); + int orient = random.nextInt(4); + + if (place(s, x, y, orient)) return; + } + + throw new RuntimeException("Could not place any more ships"); + } + + private boolean extendShip(Sea s, int fromX, int fromY, int toX, int toY) { + if (!s.isEmpty(toX, toY)) return false; // no space + if ((fromX == toX)||(fromY == toY)) return true; // horizontal or vertical + + // we can extend the ship without colliding, but we are going diagonally + // and it should not be possible for two ships to cross each other on + // opposite diagonals. + + // check the two tiles that would cross us here - if either is empty, we are OK + // if they both contain different ships, we are OK + // but if they both contain the same ship, we are crossing! + int corner1 = s.get(fromX, toY); + int corner2 = s.get(toX, fromY); + if ((corner1 == 0) || (corner1 != corner2)) return true; + return false; + } + + public boolean place(Sea s, int x, int y, int orient) { + if (placed) { + throw new RuntimeException("Program error - placed ship " + id + " twice"); + } + switch(orient) { + case ORIENT_E: + orientX = 1; orientY = 0; + break; + case ORIENT_SE: + orientX = 1; orientY = 1; + break; + case ORIENT_S: + orientX = 0; orientY = 1; + break; + case ORIENT_SW: + orientX = -1; orientY = 1; + break; + default: + throw new RuntimeException("Invalid orientation " + orient); + } + + if (!s.isEmpty(x, y)) return false; + startX = x; startY = y; + int tilesPlaced = 1; + int nextX = startX; + int nextY = startY; + while (tilesPlaced < size) { + if (extendShip(s, nextX, nextY, nextX + orientX, nextY + orientY)) { + tilesPlaced += 1; + nextX = nextX + orientX; + nextY = nextY + orientY; + } else { + int backX = startX - orientX; + int backY = startY - orientY; + + if (extendShip(s, startX, startY, backX, backY)) { + tilesPlaced +=1; + startX = backX; + startY = backY; + } else { + return false; + } + } + } + + for (int i = 0; i < size; ++i) { + int sx = startX + i * orientX; + int sy = startY + i * orientY; + s.set(sx, sy, id); + } + placed = true; + return true; + } + + } + + private static class Sea { + private int tiles[]; + private boolean hits[]; + + private int size; + public Sea(int make_size) { + size = make_size; + tiles = new int[size*size]; + } + + public int size() { return size; } + + public String encodedDump() { + StringBuilder out = new StringBuilder(); + for (int x = 0; x < size; ++x) { + for (int y = 0; y < size; ++y) + out.append(Integer.toString(get(x, y))); + out.append('\n'); + } + return out.toString(); + } + + /* return true if x,y is in the sea and empty + * return false if x,y is occupied or is out of range + */ + public boolean isEmpty(int x, int y) { + if ((x<0)||(x>=size)||(y<0)||(y>=size)) return false; + return (get(x,y) == 0); + } + + /* return the ship number, or zero if no ship */ + public int get(int x, int y) { + return tiles[index(x,y)]; + } + + public void set(int x, int y, int value) { + tiles[index(x, y)] = value; + } + + public int shipHit(int x, int y) { + if (hits[index(x,y)]) return get(x, y); + else return 0; + } + + public void recordHit(int x, int y) { + hits[index(x, y)] = true; + } + + private int index(int x, int y) { + if ((x < 0) || (x >= size)) + throw new ArrayIndexOutOfBoundsException("Program error: x cannot be " + x); + if ((y < 0) || (y >= size)) + throw new ArrayIndexOutOfBoundsException("Program error: y cannot be " + y); + + return y*size + x; + } + } +} From c074beaf42e0c0aeb91413c152a827ac48942417 Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 10 Jan 2022 19:38:23 +0000 Subject: [PATCH 053/337] pull out input parsing --- 09_Battle/java/Battle.java | 38 ++++---------------------------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/09_Battle/java/Battle.java b/09_Battle/java/Battle.java index aa53896c..b548292c 100644 --- a/09_Battle/java/Battle.java +++ b/09_Battle/java/Battle.java @@ -1,5 +1,3 @@ -import java.io.BufferedReader; -import java.io.InputStreamReader; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -79,43 +77,15 @@ public class Battle { int lost = 0; System.out.println("Start game"); + Input input = new Input(seaSize); try { - BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); - NumberFormat parser = NumberFormat.getIntegerInstance(); - while (lost < ships.size()) { - System.out.print("\nTarget x,y\n> "); - String inputLine = input.readLine(); - if (inputLine == null) { - System.out.println("Game quit\n"); + if (! input.readCoordinates()) { return; } - String[] coords = inputLine.split(","); - if (coords.length != 2) { - System.out.println("Need two coordinates separated by ','"); - continue; - } - int[] xy = new int[2]; - boolean error = false; - try { - for (int c = 0 ; c < 2; ++c ) { - int val = Integer.parseInt(coords[c].strip()); - if ((val < 1) || (val > seaSize)) { - System.out.println("Coordinates must be from 1 to " + seaSize); - error = true; - } else { - xy[c] = val; - } - } - } - catch (NumberFormatException ne) { - System.out.println("Coordinates must be numbers"); - error = true; - } - if (error) continue; - int row = seaSize - xy[1]; - int col = xy[0] - 1; + int row = seaSize - input.y(); + int col = input.x() - 1; if (sea.isEmpty(col, row)) { ++misses; From 8e88e25d6c3fbc9fd783aa39d834fb10105fc0ec Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 10 Jan 2022 19:46:37 +0000 Subject: [PATCH 054/337] Classes in own files --- 09_Battle/java/.gitignore | 1 + 09_Battle/java/Battle.java | 195 ------------------------------------- 09_Battle/java/Input.java | 58 +++++++++++ 09_Battle/java/Sea.java | 57 +++++++++++ 09_Battle/java/Ship.java | 142 +++++++++++++++++++++++++++ 5 files changed, 258 insertions(+), 195 deletions(-) create mode 100644 09_Battle/java/.gitignore create mode 100644 09_Battle/java/Input.java create mode 100644 09_Battle/java/Sea.java create mode 100644 09_Battle/java/Ship.java diff --git a/09_Battle/java/.gitignore b/09_Battle/java/.gitignore new file mode 100644 index 00000000..b25c15b8 --- /dev/null +++ b/09_Battle/java/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/09_Battle/java/Battle.java b/09_Battle/java/Battle.java index b548292c..627906d0 100644 --- a/09_Battle/java/Battle.java +++ b/09_Battle/java/Battle.java @@ -144,199 +144,4 @@ public class Battle { catch (IOException e) { } } - - private static class Ship { - public static final int ORIENT_E=0; - public static final int ORIENT_SE=1; - public static final int ORIENT_S=2; - public static final int ORIENT_SW=3; - - private int id; - private int size; - private String type; - private boolean placed; - private boolean sunk; - private ArrayList hits; - - private int startX; - private int startY; - private int orientX; - private int orientY; - - public Ship(int i, String name, int sz) { - id = i; type = name; size = sz; - sunk = false; placed = false; - hits = new ArrayList<>(Collections.nCopies(size, false)); - } - - public int id() { return id; } - public int size() { return size; } - - public void hit(int x, int y) { - int offset; - if (orientX != 0) { - offset = (x - startX) / orientX; - } else { - offset = (y - startY) / orientY; - } - hits.set(offset, true); - - sunk = hits.stream().allMatch(Predicate.isEqual(true)); - } - - public boolean isSunk() { return sunk; } - - public boolean wasHit(int x, int y) { - int offset; - if (orientX != 0) { - offset = (x - startX) / orientX; - } else { - offset = (y - startY) / orientY; - } - return hits.get(offset); - }; - - public void placeRandom(Sea s) { - Random random = new Random(); - for (int tries = 0 ; tries < 1000 ; ++tries) { - int x = random.nextInt(s.size()); - int y = random.nextInt(s.size()); - int orient = random.nextInt(4); - - if (place(s, x, y, orient)) return; - } - - throw new RuntimeException("Could not place any more ships"); - } - - private boolean extendShip(Sea s, int fromX, int fromY, int toX, int toY) { - if (!s.isEmpty(toX, toY)) return false; // no space - if ((fromX == toX)||(fromY == toY)) return true; // horizontal or vertical - - // we can extend the ship without colliding, but we are going diagonally - // and it should not be possible for two ships to cross each other on - // opposite diagonals. - - // check the two tiles that would cross us here - if either is empty, we are OK - // if they both contain different ships, we are OK - // but if they both contain the same ship, we are crossing! - int corner1 = s.get(fromX, toY); - int corner2 = s.get(toX, fromY); - if ((corner1 == 0) || (corner1 != corner2)) return true; - return false; - } - - public boolean place(Sea s, int x, int y, int orient) { - if (placed) { - throw new RuntimeException("Program error - placed ship " + id + " twice"); - } - switch(orient) { - case ORIENT_E: - orientX = 1; orientY = 0; - break; - case ORIENT_SE: - orientX = 1; orientY = 1; - break; - case ORIENT_S: - orientX = 0; orientY = 1; - break; - case ORIENT_SW: - orientX = -1; orientY = 1; - break; - default: - throw new RuntimeException("Invalid orientation " + orient); - } - - if (!s.isEmpty(x, y)) return false; - startX = x; startY = y; - int tilesPlaced = 1; - int nextX = startX; - int nextY = startY; - while (tilesPlaced < size) { - if (extendShip(s, nextX, nextY, nextX + orientX, nextY + orientY)) { - tilesPlaced += 1; - nextX = nextX + orientX; - nextY = nextY + orientY; - } else { - int backX = startX - orientX; - int backY = startY - orientY; - - if (extendShip(s, startX, startY, backX, backY)) { - tilesPlaced +=1; - startX = backX; - startY = backY; - } else { - return false; - } - } - } - - for (int i = 0; i < size; ++i) { - int sx = startX + i * orientX; - int sy = startY + i * orientY; - s.set(sx, sy, id); - } - placed = true; - return true; - } - - } - - private static class Sea { - private int tiles[]; - private boolean hits[]; - - private int size; - public Sea(int make_size) { - size = make_size; - tiles = new int[size*size]; - } - - public int size() { return size; } - - public String encodedDump() { - StringBuilder out = new StringBuilder(); - for (int x = 0; x < size; ++x) { - for (int y = 0; y < size; ++y) - out.append(Integer.toString(get(x, y))); - out.append('\n'); - } - return out.toString(); - } - - /* return true if x,y is in the sea and empty - * return false if x,y is occupied or is out of range - */ - public boolean isEmpty(int x, int y) { - if ((x<0)||(x>=size)||(y<0)||(y>=size)) return false; - return (get(x,y) == 0); - } - - /* return the ship number, or zero if no ship */ - public int get(int x, int y) { - return tiles[index(x,y)]; - } - - public void set(int x, int y, int value) { - tiles[index(x, y)] = value; - } - - public int shipHit(int x, int y) { - if (hits[index(x,y)]) return get(x, y); - else return 0; - } - - public void recordHit(int x, int y) { - hits[index(x, y)] = true; - } - - private int index(int x, int y) { - if ((x < 0) || (x >= size)) - throw new ArrayIndexOutOfBoundsException("Program error: x cannot be " + x); - if ((y < 0) || (y >= size)) - throw new ArrayIndexOutOfBoundsException("Program error: y cannot be " + y); - - return y*size + x; - } - } } diff --git a/09_Battle/java/Input.java b/09_Battle/java/Input.java new file mode 100644 index 00000000..8a782dba --- /dev/null +++ b/09_Battle/java/Input.java @@ -0,0 +1,58 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; +import java.text.NumberFormat; + +public class Input { + private BufferedReader reader; + private NumberFormat parser; + private int scale; + private boolean isQuit; + private int[] coords; + + public Input(int seaSize) { + scale = seaSize; + reader = new BufferedReader(new InputStreamReader(System.in)); + parser = NumberFormat.getIntegerInstance(); + } + + public boolean readCoordinates() throws IOException { + while (true) { + System.out.print("\nTarget x,y\n> "); + String inputLine = reader.readLine(); + if (inputLine == null) { + System.out.println("Game quit\n"); + isQuit = true; + return false; + } + + String[] fields = inputLine.split(","); + if (fields.length != 2) { + System.out.println("Need two coordinates separated by ','"); + continue; + } + + coords = new int[2]; + boolean error = false; + try { + for (int c = 0 ; c < 2; ++c ) { + int val = Integer.parseInt(fields[c].strip()); + if ((val < 1) || (val > scale)) { + System.out.println("Coordinates must be from 1 to " + scale); + error = true; + } else { + coords[c] = val; + } + } + } + catch (NumberFormatException ne) { + System.out.println("Coordinates must be numbers"); + error = true; + } + if (!error) return true; + } + } + + public int x() { return coords[0]; } + public int y() { return coords[1]; } +} diff --git a/09_Battle/java/Sea.java b/09_Battle/java/Sea.java new file mode 100644 index 00000000..d9987f34 --- /dev/null +++ b/09_Battle/java/Sea.java @@ -0,0 +1,57 @@ +class Sea { + private int tiles[]; + private boolean hits[]; + + private int size; + public Sea(int make_size) { + size = make_size; + tiles = new int[size*size]; + } + + public int size() { return size; } + + public String encodedDump() { + StringBuilder out = new StringBuilder(); + for (int x = 0; x < size; ++x) { + for (int y = 0; y < size; ++y) + out.append(Integer.toString(get(x, y))); + out.append('\n'); + } + return out.toString(); + } + + /* return true if x,y is in the sea and empty + * return false if x,y is occupied or is out of range + */ + public boolean isEmpty(int x, int y) { + if ((x<0)||(x>=size)||(y<0)||(y>=size)) return false; + return (get(x,y) == 0); + } + + /* return the ship number, or zero if no ship */ + public int get(int x, int y) { + return tiles[index(x,y)]; + } + + public void set(int x, int y, int value) { + tiles[index(x, y)] = value; + } + + public int shipHit(int x, int y) { + if (hits[index(x,y)]) return get(x, y); + else return 0; + } + + public void recordHit(int x, int y) { + hits[index(x, y)] = true; + } + + private int index(int x, int y) { + if ((x < 0) || (x >= size)) + throw new ArrayIndexOutOfBoundsException("Program error: x cannot be " + x); + if ((y < 0) || (y >= size)) + throw new ArrayIndexOutOfBoundsException("Program error: y cannot be " + y); + + return y*size + x; + } +} diff --git a/09_Battle/java/Ship.java b/09_Battle/java/Ship.java new file mode 100644 index 00000000..e3fb4f44 --- /dev/null +++ b/09_Battle/java/Ship.java @@ -0,0 +1,142 @@ +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Random; +import java.util.function.Predicate; + +class Ship { + public static final int ORIENT_E=0; + public static final int ORIENT_SE=1; + public static final int ORIENT_S=2; + public static final int ORIENT_SW=3; + + private int id; + private int size; + private String type; + private boolean placed; + private boolean sunk; + private ArrayList hits; + + private int startX; + private int startY; + private int orientX; + private int orientY; + + public Ship(int i, String name, int sz) { + id = i; type = name; size = sz; + sunk = false; placed = false; + hits = new ArrayList<>(Collections.nCopies(size, false)); + } + + public int id() { return id; } + public int size() { return size; } + + public void hit(int x, int y) { + int offset; + if (orientX != 0) { + offset = (x - startX) / orientX; + } else { + offset = (y - startY) / orientY; + } + hits.set(offset, true); + + sunk = hits.stream().allMatch(Predicate.isEqual(true)); + } + + public boolean isSunk() { return sunk; } + + public boolean wasHit(int x, int y) { + int offset; + if (orientX != 0) { + offset = (x - startX) / orientX; + } else { + offset = (y - startY) / orientY; + } + return hits.get(offset); + }; + + public void placeRandom(Sea s) { + Random random = new Random(); + for (int tries = 0 ; tries < 1000 ; ++tries) { + int x = random.nextInt(s.size()); + int y = random.nextInt(s.size()); + int orient = random.nextInt(4); + + if (place(s, x, y, orient)) return; + } + + throw new RuntimeException("Could not place any more ships"); + } + + private boolean extendShip(Sea s, int fromX, int fromY, int toX, int toY) { + if (!s.isEmpty(toX, toY)) return false; // no space + if ((fromX == toX)||(fromY == toY)) return true; // horizontal or vertical + + // we can extend the ship without colliding, but we are going diagonally + // and it should not be possible for two ships to cross each other on + // opposite diagonals. + + // check the two tiles that would cross us here - if either is empty, we are OK + // if they both contain different ships, we are OK + // but if they both contain the same ship, we are crossing! + int corner1 = s.get(fromX, toY); + int corner2 = s.get(toX, fromY); + if ((corner1 == 0) || (corner1 != corner2)) return true; + return false; + } + + public boolean place(Sea s, int x, int y, int orient) { + if (placed) { + throw new RuntimeException("Program error - placed ship " + id + " twice"); + } + switch(orient) { + case ORIENT_E: + orientX = 1; orientY = 0; + break; + case ORIENT_SE: + orientX = 1; orientY = 1; + break; + case ORIENT_S: + orientX = 0; orientY = 1; + break; + case ORIENT_SW: + orientX = -1; orientY = 1; + break; + default: + throw new RuntimeException("Invalid orientation " + orient); + } + + if (!s.isEmpty(x, y)) return false; + startX = x; startY = y; + int tilesPlaced = 1; + int nextX = startX; + int nextY = startY; + while (tilesPlaced < size) { + if (extendShip(s, nextX, nextY, nextX + orientX, nextY + orientY)) { + tilesPlaced += 1; + nextX = nextX + orientX; + nextY = nextY + orientY; + } else { + int backX = startX - orientX; + int backY = startY - orientY; + + if (extendShip(s, startX, startY, backX, backY)) { + tilesPlaced +=1; + startX = backX; + startY = backY; + } else { + return false; + } + } + } + + for (int i = 0; i < size; ++i) { + int sx = startX + i * orientX; + int sy = startY + i * orientY; + s.set(sx, sy, id); + } + placed = true; + return true; + } +} + From 49be31b8e2f1086ed72565715ed3b3ee407b366f Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 10 Jan 2022 20:15:15 +0000 Subject: [PATCH 055/337] Add some comments --- 09_Battle/java/Battle.java | 49 +++++++---- 09_Battle/java/Ship.java | 166 ++++++++++++++++++++++--------------- 2 files changed, 132 insertions(+), 83 deletions(-) diff --git a/09_Battle/java/Battle.java b/09_Battle/java/Battle.java index 627906d0..c0b27906 100644 --- a/09_Battle/java/Battle.java +++ b/09_Battle/java/Battle.java @@ -7,18 +7,26 @@ import java.util.Random; import java.util.function.Predicate; import java.text.NumberFormat; + +/* This class holds the game state and the game logic */ public class Battle { + + /* parameters of the game */ private int seaSize; private int[] sizes; private int[] counts; - + + /* The game setup - the ships and the sea */ private ArrayList ships; private Sea sea; - private int[] losses; - private int hits; - private int misses; + /* game state counts */ + private int[] losses; // how many of each type of ship have been sunk + private int hits; // how many hits the player has made + private int misses; // how many misses the player has made + // Names of ships of each size. The game as written has ships of size 3, 4 and 5 but + // can easily be modified. It makes no sense to have a ship of size zero though. private static String NAMES_BY_SIZE[] = { "error", "size1", @@ -27,10 +35,11 @@ public class Battle { "aircraft carrier", "size5" }; + // Entrypoint public static void main(String args[]) { - Battle game = new Battle(6, - new int[] { 2, 3, 4 }, - new int[] { 2, 2, 2 }); + Battle game = new Battle(6, // Sea is 6 x 6 tiles + new int[] { 2, 3, 4 }, // Ships are of sizes 2, 3, and 4 + new int[] { 2, 2, 2 }); // there are two ships of each size game.play(); } @@ -39,7 +48,7 @@ public class Battle { sizes = shipSizes; counts = shipCounts; - /* validate parameters */ + // validate parameters if (seaSize < 4) throw new RuntimeException("Sea Size " + seaSize + " invalid, must be at least 4"); for (int sz : sizes) { @@ -51,20 +60,25 @@ public class Battle { throw new RuntimeException("Ship counts must match"); } - sea = new Sea(seaSize); - ships = new ArrayList(); - losses = new int[counts.length]; + // Initialize game state + sea = new Sea(seaSize); // holds what ship if any occupies each tile + ships = new ArrayList(); // positions and states of all the ships + losses = new int[counts.length]; // how many ships of each type have been sunk + // Build up the list of all the ships int shipNumber = 1; for (int type = 0; type < counts.length; ++type) { for (int i = 0; i < counts[i]; ++i) { - ships.add(new Ship(shipNumber++, "Ship", sizes[type])); + ships.add(new Ship(shipNumber++, sizes[type])); } } + // When we put the ships in the sea, we put the biggest ones in first, or they might + // not fit ArrayList largestFirst = new ArrayList<>(ships); Collections.sort(largestFirst, Comparator.comparingInt((Ship ship) -> ship.size()).reversed()); + // place each ship into the sea for (Ship ship : largestFirst) { ship.placeRandom(sea); } @@ -79,11 +93,13 @@ public class Battle { System.out.println("Start game"); Input input = new Input(seaSize); try { - while (lost < ships.size()) { - if (! input.readCoordinates()) { + while (lost < ships.size()) { // the game continues while some ships remain unsunk + if (! input.readCoordinates()) { // ... unless there is no more input from the user return; } + // The computer thinks of the sea as a grid of rows, from top to bottom. + // However, the user will use X and Y coordinates, with Y going bottom to top int row = seaSize - input.y(); int col = input.x() - 1; @@ -104,6 +120,9 @@ public class Battle { ship.hit(col, row); ++hits; System.out.println("A direct hit on ship number " + ship.id()); + + // If a ship was hit, we need to know whether it was sunk. + // If so, tell the player and update our counts if (ship.isSunk()) { ++lost; System.out.println("And you sunk it. Hurrah for the good guys."); @@ -142,6 +161,8 @@ public class Battle { } } catch (IOException e) { + // This should not happen running from console, but java requires us to check for it + System.err.println("System error.\n" + e); } } } diff --git a/09_Battle/java/Ship.java b/09_Battle/java/Ship.java index e3fb4f44..23605e5c 100644 --- a/09_Battle/java/Ship.java +++ b/09_Battle/java/Ship.java @@ -4,34 +4,41 @@ import java.util.Comparator; import java.util.Random; import java.util.function.Predicate; +/** A single ship, with its position and where it has been hit */ class Ship { - public static final int ORIENT_E=0; - public static final int ORIENT_SE=1; - public static final int ORIENT_S=2; - public static final int ORIENT_SW=3; + // These are the four directions that ships can be in + public static final int ORIENT_E=0; // goes East from starting position + public static final int ORIENT_SE=1; // goes SouthEast from starting position + public static final int ORIENT_S=2; // goes South from starting position + public static final int ORIENT_SW=3; // goes SouthWest from starting position - private int id; - private int size; - private String type; - private boolean placed; - private boolean sunk; - private ArrayList hits; + private int id; // ship number + private int size; // how many tiles it occupies + private boolean placed; // whether this ship is in the sea yet + private boolean sunk; // whether this ship has been sunk + private ArrayList hits; // which tiles of the ship have been hit - private int startX; + private int startX; // starting position coordinates private int startY; - private int orientX; + private int orientX; // x and y deltas from each tile occupied to the next private int orientY; - public Ship(int i, String name, int sz) { - id = i; type = name; size = sz; + public Ship(int i, int sz) { + id = i; size = sz; sunk = false; placed = false; hits = new ArrayList<>(Collections.nCopies(size, false)); } + /** @returns the ship number */ public int id() { return id; } + /** @returns the ship size */ public int size() { return size; } + /* record the ship as having been hit at the given coordinates */ public void hit(int x, int y) { + // need to work out how many tiles from the ship's starting position the hit is at + // that can be worked out from the difference between the starting X coord and this one + // unless the ship runs N-S, in which case use the Y coord instead int offset; if (orientX != 0) { offset = (x - startX) / orientX; @@ -40,11 +47,13 @@ class Ship { } hits.set(offset, true); + // if every tile of the ship has been hit, the ship is sunk sunk = hits.stream().allMatch(Predicate.isEqual(true)); } public boolean isSunk() { return sunk; } + // whether the ship has already been hit at the given coordinates public boolean wasHit(int x, int y) { int offset; if (orientX != 0) { @@ -55,6 +64,9 @@ class Ship { return hits.get(offset); }; + // Place the ship in the sea. + // choose a random starting position, and a random direction + // if that doesn't fit, keep picking different positions and directions public void placeRandom(Sea s) { Random random = new Random(); for (int tries = 0 ; tries < 1000 ; ++tries) { @@ -68,6 +80,77 @@ class Ship { throw new RuntimeException("Could not place any more ships"); } + // Attempt to fit the ship into the sea, starting from a given position and + // in a given direction + // This is by far the most complicated part of the program. + // It will start at the position provided, and attempt to occupy tiles in the + // requested direction. If it does not fit, either because of the edge of the + // sea, or because of ships already in place, it will try to extend the ship + // in the opposite direction instead. If that is not possible, it fails. + public boolean place(Sea s, int x, int y, int orient) { + if (placed) { + throw new RuntimeException("Program error - placed ship " + id + " twice"); + } + switch(orient) { + case ORIENT_E: // east is increasing X coordinate + orientX = 1; orientY = 0; + break; + case ORIENT_SE: // southeast is increasing X and Y + orientX = 1; orientY = 1; + break; + case ORIENT_S: // south is increasing Y + orientX = 0; orientY = 1; + break; + case ORIENT_SW: // southwest is increasing Y but decreasing X + orientX = -1; orientY = 1; + break; + default: + throw new RuntimeException("Invalid orientation " + orient); + } + + if (!s.isEmpty(x, y)) return false; // starting position is occupied - placing fails + + startX = x; startY = y; + int tilesPlaced = 1; + int nextX = startX; + int nextY = startY; + while (tilesPlaced < size) { + if (extendShip(s, nextX, nextY, nextX + orientX, nextY + orientY)) { + // It is clear to extend the ship forwards + tilesPlaced += 1; + nextX = nextX + orientX; + nextY = nextY + orientY; + } else { + int backX = startX - orientX; + int backY = startY - orientY; + + if (extendShip(s, startX, startY, backX, backY)) { + // We can move the ship backwards, so it can be one tile longer + tilesPlaced +=1; + startX = backX; + startY = backY; + } else { + // Could not make it longer or move it backwards + return false; + } + } + } + + // Mark in the sea which tiles this ship occupies + for (int i = 0; i < size; ++i) { + int sx = startX + i * orientX; + int sy = startY + i * orientY; + s.set(sx, sy, id); + } + + placed = true; + return true; + } + + // Check whether a ship which already occupies the "from" coordinates, + // can also occupy the "to" coordinates. + // They must be within the sea area, empty, and not cause the ship to cross + // over another ship private boolean extendShip(Sea s, int fromX, int fromY, int toX, int toY) { if (!s.isEmpty(toX, toY)) return false; // no space if ((fromX == toX)||(fromY == toY)) return true; // horizontal or vertical @@ -84,59 +167,4 @@ class Ship { if ((corner1 == 0) || (corner1 != corner2)) return true; return false; } - - public boolean place(Sea s, int x, int y, int orient) { - if (placed) { - throw new RuntimeException("Program error - placed ship " + id + " twice"); - } - switch(orient) { - case ORIENT_E: - orientX = 1; orientY = 0; - break; - case ORIENT_SE: - orientX = 1; orientY = 1; - break; - case ORIENT_S: - orientX = 0; orientY = 1; - break; - case ORIENT_SW: - orientX = -1; orientY = 1; - break; - default: - throw new RuntimeException("Invalid orientation " + orient); - } - - if (!s.isEmpty(x, y)) return false; - startX = x; startY = y; - int tilesPlaced = 1; - int nextX = startX; - int nextY = startY; - while (tilesPlaced < size) { - if (extendShip(s, nextX, nextY, nextX + orientX, nextY + orientY)) { - tilesPlaced += 1; - nextX = nextX + orientX; - nextY = nextY + orientY; - } else { - int backX = startX - orientX; - int backY = startY - orientY; - - if (extendShip(s, startX, startY, backX, backY)) { - tilesPlaced +=1; - startX = backX; - startY = backY; - } else { - return false; - } - } - } - - for (int i = 0; i < size; ++i) { - int sx = startX + i * orientX; - int sy = startY + i * orientY; - s.set(sx, sy, id); - } - placed = true; - return true; - } } - From f7f10d52f35e89dc5db764ea571c4e3f57d830c0 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Mon, 10 Jan 2022 15:18:46 -0500 Subject: [PATCH 056/337] Formatted "Totals" output Slowly going through and making output true to the original BASIC code --- 75_Roulette/java/src/Roulette.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/src/Roulette.java index c6e46152..84986db1 100644 --- a/75_Roulette/java/src/Roulette.java +++ b/75_Roulette/java/src/Roulette.java @@ -63,10 +63,9 @@ public class Roulette { betResults(bets,result); out.println(); - - out.println("TOTALS:"); - out.println("\tME: " + houseBalance); - out.println("\tYOU " + playerBalance); + + out.println("TOTALS:\tME\tYOU"); + out.println("\t\t" + houseBalance + "\t" + playerBalance); } while(playAgain()); if(playerBalance <= 0) { From 0614831f460cf286e698b177296e5862fdad39b9 Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 10 Jan 2022 20:22:14 +0000 Subject: [PATCH 057/337] Add comments to the sea class --- 09_Battle/java/Sea.java | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/09_Battle/java/Sea.java b/09_Battle/java/Sea.java index d9987f34..f0c31fac 100644 --- a/09_Battle/java/Sea.java +++ b/09_Battle/java/Sea.java @@ -1,8 +1,13 @@ +// Track the content of the sea class Sea { + // the sea is a square grid of tiles. It is a one-dimensional array, and this + // class maps x and y coordinates to an array index + // Each tile is either empty (value of tiles at index is 0) + // or contains a ship (value of tiles at index is the ship number) private int tiles[]; - private boolean hits[]; private int size; + public Sea(int make_size) { size = make_size; tiles = new int[size*size]; @@ -10,6 +15,8 @@ class Sea { public int size() { return size; } + // This writes out a representation of the sea, but in a funny order + // The idea is to give the player the job of working it out public String encodedDump() { StringBuilder out = new StringBuilder(); for (int x = 0; x < size; ++x) { @@ -22,13 +29,17 @@ class Sea { /* return true if x,y is in the sea and empty * return false if x,y is occupied or is out of range + * Doing this in one method makes placing ships much easier */ public boolean isEmpty(int x, int y) { if ((x<0)||(x>=size)||(y<0)||(y>=size)) return false; return (get(x,y) == 0); } - /* return the ship number, or zero if no ship */ + /* return the ship number, or zero if no ship. + * Unlike isEmpty(x,y), these other methods require that the + * coordinates passed be valid + */ public int get(int x, int y) { return tiles[index(x,y)]; } @@ -37,15 +48,7 @@ class Sea { tiles[index(x, y)] = value; } - public int shipHit(int x, int y) { - if (hits[index(x,y)]) return get(x, y); - else return 0; - } - - public void recordHit(int x, int y) { - hits[index(x, y)] = true; - } - + // map the coordinates to the array index private int index(int x, int y) { if ((x < 0) || (x >= size)) throw new ArrayIndexOutOfBoundsException("Program error: x cannot be " + x); From ea5c2cf72d3164654894431acb741ec971ea8a3b Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 10 Jan 2022 20:26:50 +0000 Subject: [PATCH 058/337] Comment the input class --- 09_Battle/java/Input.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/09_Battle/java/Input.java b/09_Battle/java/Input.java index 8a782dba..ee87465f 100644 --- a/09_Battle/java/Input.java +++ b/09_Battle/java/Input.java @@ -3,12 +3,15 @@ import java.io.InputStreamReader; import java.io.IOException; import java.text.NumberFormat; +// This class handles reading input from the player +// Each input is an x and y coordinate +// e.g. 5,3 public class Input { private BufferedReader reader; private NumberFormat parser; - private int scale; - private boolean isQuit; - private int[] coords; + private int scale; // size of the sea, needed to validate input + private boolean isQuit; // whether the input has ended + private int[] coords; // the last coordinates read public Input(int seaSize) { scale = seaSize; @@ -18,22 +21,27 @@ public class Input { public boolean readCoordinates() throws IOException { while (true) { + // Write a prompt System.out.print("\nTarget x,y\n> "); String inputLine = reader.readLine(); if (inputLine == null) { - System.out.println("Game quit\n"); + // If the input stream is ended, there is no way to continue the game + System.out.println("\nGame quit\n"); isQuit = true; return false; } + // split the input into two fields String[] fields = inputLine.split(","); if (fields.length != 2) { + // has to be exactly two System.out.println("Need two coordinates separated by ','"); continue; } coords = new int[2]; boolean error = false; + // each field should contain an integer from 1 to the size of the sea try { for (int c = 0 ; c < 2; ++c ) { int val = Integer.parseInt(fields[c].strip()); @@ -46,6 +54,7 @@ public class Input { } } catch (NumberFormatException ne) { + // this happens if the field is not a valid number System.out.println("Coordinates must be numbers"); error = true; } From 00a8bf8983b0cc36a8b364908ce559d3f387e249 Mon Sep 17 00:00:00 2001 From: Josh Gribbon Date: Mon, 10 Jan 2022 15:42:08 -0500 Subject: [PATCH 059/337] Move file --- .../find-missing-implementations.js | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) rename find-missing-implementations.js => 00_Utilities/find-missing-implementations.js (79%) diff --git a/find-missing-implementations.js b/00_Utilities/find-missing-implementations.js similarity index 79% rename from find-missing-implementations.js rename to 00_Utilities/find-missing-implementations.js index 04cf3f84..1f998444 100644 --- a/find-missing-implementations.js +++ b/00_Utilities/find-missing-implementations.js @@ -15,7 +15,7 @@ const ROOT_PATH = "."; const languages = [ { name: "csharp", extension: "cs" }, { name: "java", extension: "java" }, - { name: "javascript", extension: "js" }, + { name: "javascript", extension: "html" }, { name: "pascal", extension: "pas" }, { name: "perl", extension: "pl" }, { name: "python", extension: "py" }, @@ -45,6 +45,7 @@ const getPuzzleFolders = () => { (async () => { let missingGames = {}; let missingLanguageCounts = {}; + languages.forEach((l) => (missingLanguageCounts[l.name] = 0)); const puzzles = getPuzzleFolders(); for (const puzzle of puzzles) { for (const { name: language, extension } of languages) { @@ -53,12 +54,8 @@ const getPuzzleFolders = () => { extension ); if (files.length === 0) { - if (!missingGames[puzzle]) { - missingGames[puzzle] = []; - } - if (!missingLanguageCounts[language]) { - missingLanguageCounts[language] = 0; - } + if (!missingGames[puzzle]) missingGames[puzzle] = []; + missingGames[puzzle].push(language); missingLanguageCounts[language]++; } @@ -70,15 +67,14 @@ const getPuzzleFolders = () => { } else { console.log(`Missing ${missingCount} implementations:`); - console.log(`\nMissing languages by game:`); - for (const [puzzle, languages] of Object.entries(missingGames)) { - console.log(`${puzzle}: ${languages.join(", ")}`); - } + Object.entries(missingGames).forEach( + ([p, ls]) => (missingGames[p] = ls.join(", ")) + ); + console.log(`\nMissing languages by game:`); + console.table(missingGames); console.log(`\nBy language:`); - for (const [language, count] of Object.entries(missingLanguageCounts)) { - console.log(`${language}: ${count} missing`); - } + console.table(missingLanguageCounts); } })(); From 2d2df367491a06003a9f5147cc1a80fc2e9ea1e5 Mon Sep 17 00:00:00 2001 From: Josh Gribbon Date: Mon, 10 Jan 2022 15:44:23 -0500 Subject: [PATCH 060/337] Fix relative path --- 00_Utilities/find-missing-implementations.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/00_Utilities/find-missing-implementations.js b/00_Utilities/find-missing-implementations.js index 1f998444..bd92bd79 100644 --- a/00_Utilities/find-missing-implementations.js +++ b/00_Utilities/find-missing-implementations.js @@ -10,7 +10,7 @@ const fs = require("fs"); const glob = require("glob"); // relative path to the repository root -const ROOT_PATH = "."; +const ROOT_PATH = "../."; const languages = [ { name: "csharp", extension: "cs" }, From 01fb3bd5009102e5bff45395981d047eccbb8756 Mon Sep 17 00:00:00 2001 From: Josh Gribbon Date: Mon, 10 Jan 2022 15:46:51 -0500 Subject: [PATCH 061/337] Skip utilities folder --- 00_Utilities/find-missing-implementations.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/00_Utilities/find-missing-implementations.js b/00_Utilities/find-missing-implementations.js index bd92bd79..61d849fe 100644 --- a/00_Utilities/find-missing-implementations.js +++ b/00_Utilities/find-missing-implementations.js @@ -38,7 +38,10 @@ const getPuzzleFolders = () => { return fs .readdirSync(ROOT_PATH, { withFileTypes: true }) .filter((dirEntry) => dirEntry.isDirectory()) - .filter((dirEntry) => ![".git", "node_modules"].includes(dirEntry.name)) + .filter( + (dirEntry) => + ![".git", "node_modules", "00_Utilities"].includes(dirEntry.name) + ) .map((dirEntry) => dirEntry.name); }; From 5c9443c5222519ab976864b570171f4ba58208c6 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Tue, 11 Jan 2022 11:43:27 +1100 Subject: [PATCH 062/337] Copying Mistale forgot to add 'clean' to the targets for the initial build --- buildJvm/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildJvm/README.md b/buildJvm/README.md index a5169abd..e2b9da0b 100644 --- a/buildJvm/README.md +++ b/buildJvm/README.md @@ -7,7 +7,7 @@ We should be using version 17 anyway, because anything less than 17 is deprecate Build all the games: ```shell cd buildJvm - ./gradlew -q assemble installDist distributeBin distributeLib + ./gradlew -q clean assemble installDist distributeBin distributeLib ``` Then, run a game From 7f14b42c73a481e8a3be14649a9c653f26b4949e Mon Sep 17 00:00:00 2001 From: Rob Miller Date: Tue, 11 Jan 2022 17:47:53 +0000 Subject: [PATCH 063/337] Depth Charge: use more idiomatic Ruby Refactor the Depth Charge game (#31) to use more Ruby idioms, without changing its structure, method names, etc. --- 31_Depth_Charge/ruby/depthcharge.rb | 139 ++++++++++++++-------------- 1 file changed, 69 insertions(+), 70 deletions(-) diff --git a/31_Depth_Charge/ruby/depthcharge.rb b/31_Depth_Charge/ruby/depthcharge.rb index ba2a5d83..67ab7cc8 100755 --- a/31_Depth_Charge/ruby/depthcharge.rb +++ b/31_Depth_Charge/ruby/depthcharge.rb @@ -1,59 +1,60 @@ #!/usr/bin/ruby class DepthCharge - def run_game - output_title() - while true - printf("----------\n") - print_instructions() - setup_game() - printf("\n") - game_loop() - break if ! get_input_another_game() + output_title + + loop do + puts "----------" + print_instructions + setup_game + puts + game_loop + break unless get_input_another_game end - printf("OK. HOPE YOU ENJOYED YOURSELF.\n") + puts "OK. HOPE YOU ENJOYED YOURSELF." end def output_title - printf("--- DEPTH CHARGE ---\n") - printf("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n") - printf("\n") + puts "--- DEPTH CHARGE ---" + puts "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" + puts end def get_input_y_or_n(message) - while true - print(message) + loop do + print message value = gets.chomp - if (value == 'Y' || value == 'y') + if value.downcase == "y" return true - elsif value == 'N' || value == 'n' + elsif value.downcase == "n" return false end - printf("PLEASE ENTER Y/y OR N/n...\n\n") + puts "PLEASE ENTER Y/y OR N/n..." + puts end end def get_input_positive_integer(message) - - while true - print(message) + loop do + print message value = gets.chomp - if (value == 'd') - debug_game() + + if value == "d" + debug_game next end - the_input = Integer(value) rescue nil + the_input = Integer(value) rescue 0 - if the_input == nil || the_input < 1 - printf("PLEASE ENTER A POSITIVE NUMBER\n\n") + if the_input < 1 + puts "PLEASE ENTER A POSITIVE NUMBER" + puts next - end return the_input @@ -61,42 +62,39 @@ class DepthCharge end def print_instructions - printf( <<~INSTRUCTIONS -YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER -AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE. YOUR -MISSION IS TO DESTROY IT. + puts <<~INSTRUCTIONS + YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER + AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE. YOUR + MISSION IS TO DESTROY IT. -SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A -TRIO OF NUMBERS -- THE FIRST TWO ARE THE -SURFACE COORDINATES (X, Y): - WEST < X < EAST - SOUTH < Y < NORTH + SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A + TRIO OF NUMBERS -- THE FIRST TWO ARE THE + SURFACE COORDINATES (X, Y): + WEST < X < EAST + SOUTH < Y < NORTH -THE THIRD IS THE DEPTH (Z): - SHALLOW < Z < DEEP + THE THIRD IS THE DEPTH (Z): + SHALLOW < Z < DEEP -GOOD LUCK ! + GOOD LUCK ! INSTRUCTIONS - ) end def debug_game - printf("@enemy_x: %d\n", @enemy_x) - printf("@enemy_y: %d\n", @enemy_y) - printf("@enemy_z: %d\n", @enemy_z) - printf("@num_tries: %d\n", @num_tries) - printf("@trial: %d\n", @trial) - printf("\n") + puts "@enemy_x: %d" % @enemy_x + puts "@enemy_y: %d" % @enemy_y + puts "@enemy_z: %d" % @enemy_z + puts "@num_tries: %d" % @num_tries + puts "@trial: %d" % @trial + puts end def setup_game @search_area_dimension = get_input_positive_integer("DIMENSION OF SEARCH AREA: ") - @num_tries = Integer( - Math.log(@search_area_dimension)/Math.log(2) + 1 - ) - setup_enemy() + @num_tries = Integer(Math.log(@search_area_dimension) / Math.log(2) + 1) + setup_enemy end def setup_enemy @@ -113,32 +111,34 @@ GOOD LUCK ! @shot_y = get_input_positive_integer("Y: ") @shot_z = get_input_positive_integer("Z: ") - if ( - (@enemy_x - @shot_x).abs \ - + (@enemy_y - @shot_y).abs \ - + (@enemy_z - @shot_z).abs \ - == 0 - ) - you_win() + + distance = (@enemy_x - @shot_x).abs + + (@enemy_y - @shot_y).abs + + (@enemy_z - @shot_z).abs + + if distance == 0 + you_win return else - missed_shot() + missed_shot end end - printf("\n") - - you_lose() + puts + you_lose end def output_game_status - printf("YOU HAVE %d SHOTS REMAINING.\n", @num_tries - @trial + 1) - printf("TRIAL \#%d\n", @trial) + puts "YOU HAVE %d SHOTS REMAINING." % @num_tries - @trial + 1 + puts "TRIAL \#%d" % @trial end + def you_win - printf("\nB O O M ! ! YOU FOUND IT IN %d TRIES!\n\n", @trial ) + puts "\nB O O M ! ! YOU FOUND IT IN %d TRIES!" % @trial + puts end + def missed_shot missed_directions = [] @@ -160,14 +160,13 @@ GOOD LUCK ! missed_directions.push('TOO SHALLOW') end - printf("SONAR REPORTS SHOT WAS: \n") - printf("%s\n", "\t" + missed_directions.join("\n\t")) + puts "SONAR REPORTS SHOT WAS: " + puts "\t#{missed_directions.join("\n\t")}" end def you_lose - printf("YOU HAVE BEEN TORPEDOED! ABANDON SHIP!\n") - printf("THE SUBMARINE WAS AT %d %d %d\n", @enemy_x, @enemy_y, @enemy_z) - + puts "YOU HAVE BEEN TORPEDOED! ABANDON SHIP!" + puts "THE SUBMARINE WAS AT %d %d %d" % [@enemy_x, @enemy_y, @enemy_z] end def get_input_another_game @@ -176,4 +175,4 @@ GOOD LUCK ! end game = DepthCharge.new -game.run_game() +game.run_game From 2885acd95195bcb167e0866d107cfd471de3d6e3 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 11 Jan 2022 14:10:42 -0500 Subject: [PATCH 064/337] Match Formatting to Original Program --- 75_Roulette/java/src/Roulette.java | 174 +++++++++++++++-------------- 1 file changed, 91 insertions(+), 83 deletions(-) diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/src/Roulette.java index 84986db1..3bb042a5 100644 --- a/75_Roulette/java/src/Roulette.java +++ b/75_Roulette/java/src/Roulette.java @@ -1,7 +1,7 @@ import java.io.InputStream; import java.io.PrintStream; -import java.lang.management.PlatformLoggingMXBean; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.*; public class Roulette { @@ -35,135 +35,143 @@ public class Roulette { out.println(" ROULETTE"); out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); out.println("WELCOME TO THE ROULETTE TABLE\n"); - out.println("DO YOU WANT INSTRUCTIONS"); + out.print("DO YOU WANT INSTRUCTIONS? "); if(scanner.nextLine().toLowerCase().charAt(0) != 'n') { printInstructions(); } + do { Bet[] bets = queryBets(); - out.println("SPINNING...\n\n\n"); + out.print("SPINNING...\n\n"); int result = random.nextInt(1,39); /* Equivalent to following line - if(RED_NUMBERS.contains(result)) { + if(result == 37) { + out.println("00"); + } else if(result == 38) { + out.println("0"); + } else if(RED_NUMBERS.contains(result)) { out.println(result + " RED"); } else { out.println(result + " BLACK"); } */ - switch(result) { - case 37 -> out.print("00"); - case 38 -> out.print("0"); - default -> out.println(result + (RED_NUMBERS.contains(result) ? " RED\n" : " BLACK\n")); - } + out.println(switch(result) { + case 37 -> "00"; + case 38 -> "0"; + default -> result + (RED_NUMBERS.contains(result) ? " RED" : " BLACK"); + }); betResults(bets,result); out.println(); - out.println("TOTALS:\tME\tYOU"); - out.println("\t\t" + houseBalance + "\t" + playerBalance); + out.println("TOTALS:\tME\t\tYOU"); + out.format("\t\t%5d\t%d\n",houseBalance,playerBalance); } while(playAgain()); if(playerBalance <= 0) { out.println("THANKS FOR YOUR MONEY\nI'LL USE IT TO BUY A SOLID GOLD ROULETTE WHEEL"); - } else if(houseBalance <= 0) { - out.println("TO WHOM SHALL I MAKE THE CHECK"); - String name = scanner.nextLine(); - out.println(); - for(int i = 0; i < 72; i++) { - out.print("-"); - } - out.println(); - for(int i = 0; i < 50; i++) { - out.print(" "); - } - out.println("CHECK NO. " + random.nextInt(0,1000)); - out.println(); - for(int i = 0; i < 40; i++) { - out.print(" "); - } - out.println(LocalDateTime.now()); - out.println("\n"); - out.println("PAY TO THE ORDER OF----- " + name + "------$" + (playerBalance - 1000)); - out.println("\n"); - for(int i = 0; i < 10; i++) { - out.print(" "); - } - out.println("THE MEMORY BANK OF NEW YORK"); - for(int i = 0; i < 40; i++) { - out.print(" "); - } - out.println("THE COMPUTER"); - for(int i = 0; i < 40; i++) { - out.print(" "); - } - out.println("----------X-----"); - for(int i = 0; i < 72; i++) { - out.print("-"); - } - out.println("\n"); - out.println("COME BACK SOON"); + } else { + printCheck(); } + out.println("COME BACK SOON!"); + } + + private void printCheck() { + out.print("TO WHOM SHALL I MAKE THE CHECK? "); + String name = scanner.nextLine(); + + out.println(); + for(int i = 0; i < 72; i++) { + out.print("-"); + } + out.println(); + + for(int i = 0; i < 50; i++) { + out.print(" "); + } + out.println("CHECK NO. " + random.nextInt(0,100)); + + for(int i = 0; i< 40; i++) { + out.print(" "); + } + out.println(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE)); + out.println(); + + out.println("PAY TO THE ORDER OF -----" + name + "----- $" + (playerBalance)); + out.println(); + + for(int i = 0; i < 40; i++) { + out.print(" "); + } + out.println("THE MEMORY BANK OF NEW YORK"); + + for(int i = 0; i < 40; i++) { + out.print(" "); + } + out.println("THE COMPUTER"); + + for(int i = 0; i < 40; i++) { + out.print(" "); + } + out.println("----------X-----"); + + for(int i = 0; i < 72; i++) { + out.print("-"); + } + out.println(); } private boolean playAgain() { - if(playerBalance > 0) { - if(houseBalance <= 0) { - out.println("YOU BROKE THE HOUSE!"); - //using default values - playerBalance = 101000; - } + + if(playerBalance <= 0) { + out.println("OOPS! YOU JUST SPENT YOUR LAST DOLLAR!"); + return false; + } else if(houseBalance <= 0) { + out.println("YOU BROKE THE HOUSE!"); + playerBalance = 10100; + houseBalance = 0; + return false; + } else { out.println("PLAY AGAIN?"); return scanner.nextLine().toLowerCase().charAt(0) == 'y'; - } else { - return false; } } private Bet[] queryBets() { int numBets = -1; while(numBets < 1) { - out.println("HOW MANY BETS"); + out.print("HOW MANY BETS? "); try { numBets = Integer.parseInt(scanner.nextLine()); - } catch(NumberFormatException exception) { - out.println("THAT IS NOT A NUMBER"); - } + } catch(NumberFormatException ignored) {} } Bet[] bets = new Bet[numBets]; for(int i = 0; i < numBets; i++) { - try { - out.println("BET NUMBER " + (i + 1) + ":"); - String[] values = scanner.nextLine().split(","); - int betNumber = Integer.parseInt(values[0]); - int betValue = Integer.parseInt(values[1]); + while(bets[i] == null) { + try { + out.print("NUMBER" + (i + 1) + "? "); + String[] values = scanner.nextLine().split(","); + int betNumber = Integer.parseInt(values[0]); + int betValue = Integer.parseInt(values[1]); - for(int j = 0; j < i; j++) { - if(bets[j].num == betNumber) { - out.println("YOU MADE THAT BET ONCE ALREADY,DUM-DUM"); - throw new Exception(); + for(int j = 0; j < i; j++) { + if(bets[j].num == betNumber) { + out.println("YOU MADE THAT BET ONCE ALREADY,DUM-DUM"); + betNumber = -1; //Since -1 is out of the range, this will throw it out at the end + } } - } - if(betNumber < 1 || betNumber > 50 || betValue < 5 || betValue > 500) { - out.println("INVALID VALUE, TRY AGAIN"); - i--; - continue; - } - - bets[i] = new Bet(betNumber,betValue); - - } catch(Exception exception) { - if(exception instanceof NumberFormatException) { - out.println("SYNTAX ERROR, TRY AGAIN"); - } - i--; + if(betNumber > 0 && betNumber <= 50 && betValue >= 5 && betValue <= 500) { + bets[i] = new Bet(betValue,betNumber); + } + } catch(Exception ignored) {} } } return bets; From f43e31fb83cdb7ca47e59ca3514da82bbf0ca25d Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 11 Jan 2022 14:15:37 -0500 Subject: [PATCH 065/337] Re-Formatted Code --- 75_Roulette/java/src/Roulette.java | 263 +++++++++++++++-------------- 1 file changed, 132 insertions(+), 131 deletions(-) diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/src/Roulette.java index 3bb042a5..5fed5c65 100644 --- a/75_Roulette/java/src/Roulette.java +++ b/75_Roulette/java/src/Roulette.java @@ -2,26 +2,22 @@ import java.io.InputStream; import java.io.PrintStream; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.Random; +import java.util.Scanner; +import java.util.Set; public class Roulette { - private PrintStream out; - private Scanner scanner; - - private int houseBalance, playerBalance; - - private Random random; - private static Set RED_NUMBERS; static { RED_NUMBERS = Set.of(1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36); } - public static void main(String[] args) { - new Roulette(System.out, System.in).play(); - } + private PrintStream out; + private Scanner scanner; + private int houseBalance, playerBalance; + private Random random; public Roulette(PrintStream out, InputStream in) { this.out = out; @@ -31,22 +27,25 @@ public class Roulette { random = new Random(); } + public static void main(String[] args) { + new Roulette(System.out, System.in).play(); + } + public void play() { out.println(" ROULETTE"); out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); out.println("WELCOME TO THE ROULETTE TABLE\n"); out.print("DO YOU WANT INSTRUCTIONS? "); - if(scanner.nextLine().toLowerCase().charAt(0) != 'n') { + if (scanner.nextLine().toLowerCase().charAt(0) != 'n') { printInstructions(); } - do { Bet[] bets = queryBets(); out.print("SPINNING...\n\n"); - int result = random.nextInt(1,39); + int result = random.nextInt(1, 39); /* Equivalent to following line @@ -60,20 +59,19 @@ public class Roulette { out.println(result + " BLACK"); } */ - out.println(switch(result) { + out.println(switch (result) { case 37 -> "00"; case 38 -> "0"; - default -> result + (RED_NUMBERS.contains(result) ? " RED" : " BLACK"); + default -> result + (RED_NUMBERS.contains(result) ? " RED" : " BLACK"); }); - betResults(bets,result); + betResults(bets, result); out.println(); - - out.println("TOTALS:\tME\t\tYOU"); - out.format("\t\t%5d\t%d\n",houseBalance,playerBalance); - } while(playAgain()); - if(playerBalance <= 0) { + out.println("TOTALS:\tME\t\tYOU"); + out.format("\t\t%5d\t%d\n", houseBalance, playerBalance); + } while (playAgain()); + if (playerBalance <= 0) { out.println("THANKS FOR YOUR MONEY\nI'LL USE IT TO BUY A SOLID GOLD ROULETTE WHEEL"); } else { printCheck(); @@ -81,110 +79,101 @@ public class Roulette { out.println("COME BACK SOON!"); } - private void printCheck() { - out.print("TO WHOM SHALL I MAKE THE CHECK? "); - String name = scanner.nextLine(); - + public void printInstructions() { out.println(); - for(int i = 0; i < 72; i++) { - out.print("-"); - } + out.println("THIS IS THE BETTING LAYOUT"); + out.println(" (*=RED)"); out.println(); - - for(int i = 0; i < 50; i++) { - out.print(" "); - } - out.println("CHECK NO. " + random.nextInt(0,100)); - - for(int i = 0; i< 40; i++) { - out.print(" "); - } - out.println(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE)); + out.println(" 1* 2 3*"); + out.println(" 4 5* 6 "); + out.println(" 7* 8 9*"); + out.println("10 11 12*"); + out.println("---------------"); + out.println("13 14* 15 "); + out.println("16* 17 18*"); + out.println("19* 20 21*"); + out.println("22 23* 24 "); + out.println("---------------"); + out.println("25* 26 27*"); + out.println("28 29 30*"); + out.println("31 32* 33 "); + out.println("34* 35 36*"); + out.println("---------------"); + out.println(" 00 0 "); out.println(); - - out.println("PAY TO THE ORDER OF -----" + name + "----- $" + (playerBalance)); + out.println("TYPES OF BETS"); out.println(); - - for(int i = 0; i < 40; i++) { - out.print(" "); - } - out.println("THE MEMORY BANK OF NEW YORK"); - - for(int i = 0; i < 40; i++) { - out.print(" "); - } - out.println("THE COMPUTER"); - - for(int i = 0; i < 40; i++) { - out.print(" "); - } - out.println("----------X-----"); - - for(int i = 0; i < 72; i++) { - out.print("-"); - } + out.println("THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET"); + out.println("ON THAT NUMBER."); + out.println("THESE PAY OFF 35:1"); out.println(); - } - - private boolean playAgain() { - - if(playerBalance <= 0) { - out.println("OOPS! YOU JUST SPENT YOUR LAST DOLLAR!"); - return false; - } else if(houseBalance <= 0) { - out.println("YOU BROKE THE HOUSE!"); - playerBalance = 10100; - houseBalance = 0; - return false; - } else { - out.println("PLAY AGAIN?"); - return scanner.nextLine().toLowerCase().charAt(0) == 'y'; - } + out.println("THE 2:1 BETS ARE:"); + out.println(" 37) 1-12 40) FIRST COLUMN"); + out.println(" 38) 13-24 41) SECOND COLUMN"); + out.println(" 39) 25-36 42) THIRD COLUMN"); + out.println(); + out.println("THE EVEN MONEY BETS ARE:"); + out.println(" 43) 1-18 46) ODD"); + out.println(" 44) 19-36 47) RED"); + out.println(" 45) EVEN 48) BLACK"); + out.println(); + out.println(" 49)0 AND 50)00 PAY OFF 35:1"); + out.println(" NOTE: 0 AND 00 DO NOT COUNT UNDER ANY"); + out.println(" BETS EXCEPT THEIR OWN."); + out.println(); + out.println("WHEN I ASK FOR EACH BET, TYPE THE NUMBER"); + out.println("AND THE AMOUNT, SEPARATED BY A COMMA."); + out.println("FOR EXAMPLE: TO BET $500 ON BLACK, TYPE 48,500"); + out.println("WHEN I ASK FOR A BET."); + out.println(); + out.println("THE MINIMUM BET IS $5, THE MAXIMUM IS $500."); } private Bet[] queryBets() { int numBets = -1; - while(numBets < 1) { + while (numBets < 1) { out.print("HOW MANY BETS? "); try { numBets = Integer.parseInt(scanner.nextLine()); - } catch(NumberFormatException ignored) {} + } catch (NumberFormatException ignored) { + } } Bet[] bets = new Bet[numBets]; - for(int i = 0; i < numBets; i++) { - while(bets[i] == null) { + for (int i = 0; i < numBets; i++) { + while (bets[i] == null) { try { out.print("NUMBER" + (i + 1) + "? "); String[] values = scanner.nextLine().split(","); int betNumber = Integer.parseInt(values[0]); int betValue = Integer.parseInt(values[1]); - for(int j = 0; j < i; j++) { - if(bets[j].num == betNumber) { + for (int j = 0; j < i; j++) { + if (bets[j].num == betNumber) { out.println("YOU MADE THAT BET ONCE ALREADY,DUM-DUM"); betNumber = -1; //Since -1 is out of the range, this will throw it out at the end } } - if(betNumber > 0 && betNumber <= 50 && betValue >= 5 && betValue <= 500) { - bets[i] = new Bet(betValue,betNumber); + if (betNumber > 0 && betNumber <= 50 && betValue >= 5 && betValue <= 500) { + bets[i] = new Bet(betValue, betNumber); } - } catch(Exception ignored) {} + } catch (Exception ignored) { + } } } return bets; } private void betResults(Bet[] bets, int num) { - for(int i = 0; i < bets.length; i++) { + for (int i = 0; i < bets.length; i++) { Bet bet = bets[i]; /* Using a switch statement of ternary operators that check if a certain condition is met based on the bet value Returns the coefficient that the bet amount should be multiplied by to get the resulting value */ - int coefficient = switch(bet.num) { + int coefficient = switch (bet.num) { case 37 -> (num <= 12) ? 2 : -1; case 38 -> (num > 12 && num <= 24) ? 2 : -1; case 39 -> (num > 24 && num < 37) ? 2 : -1; @@ -204,7 +193,7 @@ public class Roulette { int betResult = bet.amount * coefficient; - if(betResult < 0) { + if (betResult < 0) { out.println("YOU LOSE " + -betResult + " DOLLARS ON BET " + (i + 1)); } else { out.println("YOU WIN " + betResult + " DOLLARS ON BET " + (i + 1)); @@ -215,57 +204,69 @@ public class Roulette { } } - public void printInstructions() { + private boolean playAgain() { + + if (playerBalance <= 0) { + out.println("OOPS! YOU JUST SPENT YOUR LAST DOLLAR!"); + return false; + } else if (houseBalance <= 0) { + out.println("YOU BROKE THE HOUSE!"); + playerBalance = 10100; + houseBalance = 0; + return false; + } else { + out.println("PLAY AGAIN?"); + return scanner.nextLine().toLowerCase().charAt(0) == 'y'; + } + } + + private void printCheck() { + out.print("TO WHOM SHALL I MAKE THE CHECK? "); + String name = scanner.nextLine(); + out.println(); - out.println( "THIS IS THE BETTING LAYOUT"); - out.println( " (*=RED)"); + for (int i = 0; i < 72; i++) { + out.print("-"); + } out.println(); - out.println( " 1* 2 3*"); - out.println( " 4 5* 6 "); - out.println( " 7* 8 9*"); - out.println( "10 11 12*"); - out.println( "---------------"); - out.println( "13 14* 15 "); - out.println( "16* 17 18*"); - out.println( "19* 20 21*"); - out.println( "22 23* 24 "); - out.println( "---------------"); - out.println( "25* 26 27*"); - out.println( "28 29 30*"); - out.println( "31 32* 33 "); - out.println( "34* 35 36*"); - out.println( "---------------"); - out.println( " 00 0 "); + + for (int i = 0; i < 50; i++) { + out.print(" "); + } + out.println("CHECK NO. " + random.nextInt(0, 100)); + + for (int i = 0; i < 40; i++) { + out.print(" "); + } + out.println(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE)); out.println(); - out.println( "TYPES OF BETS"); + + out.println("PAY TO THE ORDER OF -----" + name + "----- $" + (playerBalance)); out.println(); - out.println( "THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET"); - out.println( "ON THAT NUMBER."); - out.println( "THESE PAY OFF 35:1"); + + for (int i = 0; i < 40; i++) { + out.print(" "); + } + out.println("THE MEMORY BANK OF NEW YORK"); + + for (int i = 0; i < 40; i++) { + out.print(" "); + } + out.println("THE COMPUTER"); + + for (int i = 0; i < 40; i++) { + out.print(" "); + } + out.println("----------X-----"); + + for (int i = 0; i < 72; i++) { + out.print("-"); + } out.println(); - out.println( "THE 2:1 BETS ARE:"); - out.println( " 37) 1-12 40) FIRST COLUMN"); - out.println( " 38) 13-24 41) SECOND COLUMN"); - out.println( " 39) 25-36 42) THIRD COLUMN"); - out.println(); - out.println( "THE EVEN MONEY BETS ARE:"); - out.println( " 43) 1-18 46) ODD"); - out.println( " 44) 19-36 47) RED"); - out.println( " 45) EVEN 48) BLACK"); - out.println(); - out.println( " 49)0 AND 50)00 PAY OFF 35:1"); - out.println( " NOTE: 0 AND 00 DO NOT COUNT UNDER ANY"); - out.println( " BETS EXCEPT THEIR OWN."); - out.println(); - out.println( "WHEN I ASK FOR EACH BET, TYPE THE NUMBER"); - out.println( "AND THE AMOUNT, SEPARATED BY A COMMA."); - out.println( "FOR EXAMPLE: TO BET $500 ON BLACK, TYPE 48,500"); - out.println( "WHEN I ASK FOR A BET."); - out.println(); - out.println( "THE MINIMUM BET IS $5, THE MAXIMUM IS $500."); } public class Bet { + final int num, amount; public Bet(int num, int amount) { From 74a3cb72aca72719cd9fc1c16fb9cf784ad8bb64 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 11 Jan 2022 15:09:03 -0500 Subject: [PATCH 066/337] Started Roulette in Python --- 75_Roulette/python/roulette.py | 130 +++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/75_Roulette/python/roulette.py b/75_Roulette/python/roulette.py index 8b137891..db1f5639 100644 --- a/75_Roulette/python/roulette.py +++ b/75_Roulette/python/roulette.py @@ -1 +1,131 @@ + +global RED_NUMBERS +RED_NUMBERS = [1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36] + +def print_instructions(): + print(""" +THIS IS THE BETTING LAYOUT + (*=RED) + + 1* 2 3* + 4 5* 6 + 7* 8 9* +10 11 12* +--------------- +13 14* 15 +16* 17 18* +19* 20 21* +22 23* 24 +--------------- +25* 26 27* +28 29 30* +31 32* 33 +34* 35 36* +--------------- + 00 0 + +TYPES OF BETS + +THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET +ON THAT NUMBER. +THESE PAY OFF 35:1 + +THE 2:1 BETS ARE: +37) 1-12 40) FIRST COLUMN +38) 13-24 41) SECOND COLUMN +39) 25-36 42) THIRD COLUMN + +THE EVEN MONEY BETS ARE: +43) 1-18 46) ODD +44) 19-36 47) RED +45) EVEN 48) BLACK + + 49)0 AND 50)00 PAY OFF 35:1 +NOTE: 0 AND 00 DO NOT COUNT UNDER ANY + BETS EXCEPT THEIR OWN. + +WHEN I ASK FOR EACH BET, TYPE THE NUMBER +AND THE AMOUNT, SEPARATED BY A COMMA. +FOR EXAMPLE: TO BET $500 ON BLACK, TYPE 48,500 +WHEN I ASK FOR A BET. + +THE MINIMUM BET IS $5, THE MAXIMUM IS $500. + + """) + +def query_bets(): + betCount = -1 + while betCount <= 0: + try: + betCount = int(input("HOW MANY BETS? ")) + except: + ... + + bet_IDs = [-1] * betCount + bet_Values = [0] * betCount + + for i in range(betCount): + while(bet_IDs[i] == -1): + try: + inString = input("NUMBER " + str(i + 1) + "? ").split(',') + id,val = int(inString[0]),int(inString[1]) + + # check other bet_IDs + for j in range(i): + if id != -1 and bet_IDs[j] == id: + id = -1 + print("YOU ALREADY MADE THAT BET ONCE, DUM-DUM") + break + + if id > 0 and id <= 50 and val >= 5 and val <= 500: + bet_IDs[i] = id + bet_Values[i] = val + except: + ... + return bet_IDs,bet_Values + +def bet_results(bet_IDs,bet_Values,result): + def get_modifier(id,num): + if id == 37 and num <= 12: + return 2 + elif id == 38 and num > 12 and num <= 24: + return 2 + elif id == 39 and num > 24 and num < 37: + return 2 + elif id == 40 and num < 37 and num % 3 == 1: + return 2 + elif id == 41 and num < 37 and num % 3 == 2: + return 2 + elif id == 42 and num < 37 and num % 3 == 0: + return 2 + elif id == 43 and num <= 18: + return 1 + elif id == 44 and num > 18 and num <= 36: + return 1 + elif id == 45 and num % 2 == 0: + return 1 + elif id == 46 and num % 2 == 1: + return 1 + elif id == 47 and num in RED_NUMBERS: + return 1 + elif id == 48 and num not in RED_NUMBERS: + return 1 + elif id < 37 and id == num: + return 35 + else: + return -1 + + for i in range(len(bet_IDs)): + winnings = bet_Values[i] * get_modifier(bet_IDs[i],result) + + if winnings >= 0: + print("YOU WIN " + str(winnings) + " DOLLARS ON BET " + str(i + 1)) + else: + print("YOU LOSE " + str(winnings * -1) + " DOLLARS ON BET " + str(i + 1)) + +def main(): + ... + +a,b = query_bets() +bet_results(a,b,5) From 614e4740a97008751bf4d11e6a051e07f3cf65a7 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 11 Jan 2022 15:26:53 -0500 Subject: [PATCH 067/337] Added check --- 75_Roulette/python/roulette.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/75_Roulette/python/roulette.py b/75_Roulette/python/roulette.py index db1f5639..c4cb6ccd 100644 --- a/75_Roulette/python/roulette.py +++ b/75_Roulette/python/roulette.py @@ -1,4 +1,5 @@ - +from datetime import date +import random global RED_NUMBERS RED_NUMBERS = [1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36] @@ -124,8 +125,23 @@ def bet_results(bet_IDs,bet_Values,result): else: print("YOU LOSE " + str(winnings * -1) + " DOLLARS ON BET " + str(i + 1)) +def print_check(amount): + name = input("TO WHOM SHALL I MAKE THE CHECK? ") + + print("-" * 72) + print() + print(" " * 40 + "CHECK NO. " + str(random.randint(0,100))) + print(" " * 40 + str(date.today())) + print() + print("PAY TO THE ORDER OF -----" + name + "----- $" + str(amount)) + print() + print(" " * 40 + "THE MEMORY BANK OF NEW YORK") + print(" " * 40 + "THE COMPUTER") + print(" " * 40 + "----------X-----") + print("-" * 72) + def main(): ... -a,b = query_bets() -bet_results(a,b,5) +# a,b = query_bets() +print_check(5) From 5dff7851296a53d73d4d1e2e5f56604de7cc0d6a Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 11 Jan 2022 15:56:31 -0500 Subject: [PATCH 068/337] Fixed numerical typo --- 75_Roulette/java/src/Roulette.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/src/Roulette.java index 5fed5c65..77ea2703 100644 --- a/75_Roulette/java/src/Roulette.java +++ b/75_Roulette/java/src/Roulette.java @@ -211,7 +211,7 @@ public class Roulette { return false; } else if (houseBalance <= 0) { out.println("YOU BROKE THE HOUSE!"); - playerBalance = 10100; + playerBalance = 101000; houseBalance = 0; return false; } else { From ea16d14a9ddb7d72287b9da7c91b6cf9b9563645 Mon Sep 17 00:00:00 2001 From: LittleTealeaf Date: Tue, 11 Jan 2022 16:01:38 -0500 Subject: [PATCH 069/337] Implemented more Roulette.py --- 75_Roulette/python/roulette.py | 66 ++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/75_Roulette/python/roulette.py b/75_Roulette/python/roulette.py index c4cb6ccd..cca991dd 100644 --- a/75_Roulette/python/roulette.py +++ b/75_Roulette/python/roulette.py @@ -87,6 +87,7 @@ def query_bets(): return bet_IDs,bet_Values def bet_results(bet_IDs,bet_Values,result): + total_winnings = 0 def get_modifier(id,num): if id == 37 and num <= 12: return 2 @@ -119,12 +120,15 @@ def bet_results(bet_IDs,bet_Values,result): for i in range(len(bet_IDs)): winnings = bet_Values[i] * get_modifier(bet_IDs[i],result) + total_winnings += winnings if winnings >= 0: print("YOU WIN " + str(winnings) + " DOLLARS ON BET " + str(i + 1)) else: print("YOU LOSE " + str(winnings * -1) + " DOLLARS ON BET " + str(i + 1)) + return winnings + def print_check(amount): name = input("TO WHOM SHALL I MAKE THE CHECK? ") @@ -141,7 +145,65 @@ def print_check(amount): print("-" * 72) def main(): - ... + player_balance = 1000 + host_balance = 100000 + + print(" " * 32 + "ROULETTE") + print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + print() + print() + print() + + if stringtobool(input("DO YOU WANT INSTRUCTIONS? ")): + print_instructions() + + while True: + bet_IDs,bet_Values = query_bets() + + print("SPINNING") + print() + print() + + val = random.randint(0,38) + if val == 38: + print("0") + elif val == 37: + print("00") + elif val in RED_NUMBERS: + print(str(val) + " RED") + else: + print(str(val) + " BLACK") + + print() + total_winnings = bet_results(bet_IDs,bet_Values,val) + player_balance += total_winnings + host_balance -= total_winnings + + print() + print("TOTALS:\tME\t\tYOU") + print("\t\t" + str(host_balance) + "\t" + str(player_balance)) + + if player_balance <= 0: + print("OOPS! YOU JUST SPENT YOUR LAST DOLLAR!") + break + elif host_balance <= 0: + print("YOU BROKE THE HOUSE!") + player_balance = 101000 + break + if not stringtobool(input("PLAY AGAIN? ")): + break + + + if player_balance <= 0: + print("THANKS FOR YOUR MONEY") + print("I'LL USE IT TO BUY A SOLID GOLD ROULETTE WHEEL") + else: + print_check(player_balance) + print("COME BACK SOON!") + + +def stringtobool(string): + return string.lower() in ("yes","y","true","t","yes") # a,b = query_bets() -print_check(5) +main() From 1317d9ee16b15b4f1221955e15e3b7c71d8044f9 Mon Sep 17 00:00:00 2001 From: LittleTealeaf Date: Tue, 11 Jan 2022 16:04:44 -0500 Subject: [PATCH 070/337] Player balance is now deducted on bets --- 75_Roulette/java/src/Roulette.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/src/Roulette.java index 5fed5c65..56bcb1e5 100644 --- a/75_Roulette/java/src/Roulette.java +++ b/75_Roulette/java/src/Roulette.java @@ -157,7 +157,8 @@ public class Roulette { } if (betNumber > 0 && betNumber <= 50 && betValue >= 5 && betValue <= 500) { - bets[i] = new Bet(betValue, betNumber); + bets[i] = new Bet(betNumber,betValue); + playerBalance -= betValue; } } catch (Exception ignored) { } From 5c3a7e67fa2ad872eeeff3d094b31602785dec6d Mon Sep 17 00:00:00 2001 From: LittleTealeaf Date: Tue, 11 Jan 2022 16:05:16 -0500 Subject: [PATCH 071/337] Reverting previous commit --- 75_Roulette/java/src/Roulette.java | 1 - 1 file changed, 1 deletion(-) diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/src/Roulette.java index 56bcb1e5..30c25091 100644 --- a/75_Roulette/java/src/Roulette.java +++ b/75_Roulette/java/src/Roulette.java @@ -158,7 +158,6 @@ public class Roulette { if (betNumber > 0 && betNumber <= 50 && betValue >= 5 && betValue <= 500) { bets[i] = new Bet(betNumber,betValue); - playerBalance -= betValue; } } catch (Exception ignored) { } From 11fb8f778fab60218f33071068c3cc1141051d7b Mon Sep 17 00:00:00 2001 From: LittleTealeaf Date: Tue, 11 Jan 2022 16:11:10 -0500 Subject: [PATCH 072/337] Added comments --- 75_Roulette/python/roulette.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/75_Roulette/python/roulette.py b/75_Roulette/python/roulette.py index cca991dd..c839adc7 100644 --- a/75_Roulette/python/roulette.py +++ b/75_Roulette/python/roulette.py @@ -56,6 +56,7 @@ THE MINIMUM BET IS $5, THE MAXIMUM IS $500. """) def query_bets(): + """Queries the user to input their bets""" betCount = -1 while betCount <= 0: try: @@ -87,6 +88,7 @@ def query_bets(): return bet_IDs,bet_Values def bet_results(bet_IDs,bet_Values,result): + """Computes the results, prints them, and returns the total net winnings""" total_winnings = 0 def get_modifier(id,num): if id == 37 and num <= 12: @@ -130,6 +132,7 @@ def bet_results(bet_IDs,bet_Values,result): return winnings def print_check(amount): + """Prints a check of a given amount""" name = input("TO WHOM SHALL I MAKE THE CHECK? ") print("-" * 72) @@ -203,7 +206,8 @@ def main(): def stringtobool(string): + """Converts a string to a bool""" return string.lower() in ("yes","y","true","t","yes") -# a,b = query_bets() -main() +if __name__ == '__main__': + main() From 5c632b2d7eada3dab2f28e8ef4f2b603809c3fbf Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 11 Jan 2022 21:14:23 +0000 Subject: [PATCH 073/337] 75_Roulette in java --- 75_Roulette/java/Bet.java | 65 +++++++++ 75_Roulette/java/Roulette.java | 234 +++++++++++++++++++++++++++++++++ 75_Roulette/java/Wheel.java | 69 ++++++++++ 3 files changed, 368 insertions(+) create mode 100644 75_Roulette/java/Bet.java create mode 100644 75_Roulette/java/Roulette.java create mode 100644 75_Roulette/java/Wheel.java diff --git a/75_Roulette/java/Bet.java b/75_Roulette/java/Bet.java new file mode 100644 index 00000000..6d9ea48a --- /dev/null +++ b/75_Roulette/java/Bet.java @@ -0,0 +1,65 @@ +/* A bet has a target (the code entered, which is 1-36, or special values for + * the various groups, zero and double-zero), and an amount in dollars + */ + +public class Bet { + public int target; + public int amount; + + /* bet on a target, of an amount */ + public Bet(int on, int of) { + target = on; amount = of; + } + + /* check if this is a valid bet - on a real target and of a valid amount */ + public boolean isValid() { + return ((target > 0) && (target <= 50) && + (amount >= 5) && (amount <= 500)); + } + + /* utility to return either the odds amount in the case of a win, or zero for a loss */ + private int m(boolean isWon, int odds) { + return isWon? odds: 0; + } + + /* look at the wheel to see if this bet won. + * returns 0 if it didn't, or the odds if it did + */ + public int winsOn(Wheel w) { + if (target < 37) { + // A number bet 1-36 wins at odds of 35 if it is the exact number + return m(w.isNumber() && (w.number() == target), 35); + } else + switch (target) { + case 37: // 1-12, odds of 2 + return m(w.isNumber() && (w.number() <= 12), 2); + case 38: // 13-24, odds of 2 + return m(w.isNumber() && (w.number() > 12) && (w.number() <= 24), 2); + case 39: // 25-36, odds of 2 + return m(w.isNumber() && (w.number() > 24), 2); + case 40: // Column 1, odds of 2 + return m(w.isNumber() && ((w.number() % 3) == 1), 2); + case 41: // Column 2, odds of 2 + return m(w.isNumber() && ((w.number() % 3) == 2), 2); + case 42: // Column 3, odds of 2 + return m(w.isNumber() && ((w.number() % 3) == 0), 2); + case 43: // 1-18, odds of 1 + return m(w.isNumber() && (w.number() <= 18), 1); + case 44: // 19-36, odds of 1 + return m(w.isNumber() && (w.number() > 18), 1); + case 45: // even, odds of 1 + return m(w.isNumber() && ((w.number() %2) == 0), 1); + case 46: // odd, odds of 1 + return m(w.isNumber() && ((w.number() %2) == 1), 1); + case 47: // red, odds of 1 + return m(w.isNumber() && (w.color() == Wheel.BLACK), 1); + case 48: // black, odds of 1 + return m(w.isNumber() && (w.color() == Wheel.RED), 1); + case 49: // single zero, odds of 35 + return m(w.value().equals("0"), 35); + case 50: // double zero, odds of 35 + return m(w.value().equals("00"), 35); + } + throw new RuntimeException("Program Error - invalid bet"); + } +} diff --git a/75_Roulette/java/Roulette.java b/75_Roulette/java/Roulette.java new file mode 100644 index 00000000..77ae3463 --- /dev/null +++ b/75_Roulette/java/Roulette.java @@ -0,0 +1,234 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; + +public class Roulette { + public static void main(String args[]) throws Exception { + Roulette r = new Roulette(); + r.play(); + } + + private BufferedReader reader; + private PrintStream writer; + + private int house; // how much money does the house have + private int player; // how much money does the player have + private Wheel wheel = new Wheel(); + + public Roulette() { + reader = new BufferedReader(new InputStreamReader(System.in)); + writer = System.out; + house = 100000; + player = 1000; + } + + // for a test / cheat mode -- set the random number generator to a known value + private void setSeed(long l) { + wheel.setSeed(l); + } + + public void play() { + try { + intro(); + writer.println("WELCOME TO THE ROULETTE TABLE\n" + + "DO YOU WANT INSTRUCTIONS"); + String instr = reader.readLine(); + if (!instr.toUpperCase().startsWith("N")) + instructions(); + + while (betAndSpin()) { // returns true if the game is to continue + } + + if (player <= 0) { + // player ran out of money + writer.println("THANKS FOR YOUR MONEY.\nI'LL USE IT TO BUY A SOLID GOLD ROULETTE WHEEL"); + } else { + // player has money -- print them a check + writer.println("TO WHOM SHALL I MAKE THE CHECK"); + + String payee = reader.readLine(); + + writer.println("-".repeat(72)); + tab(50); writer.println("CHECK NO. " + (new Random().nextInt(100) + 1)); + writer.println(); + tab(40); writer.println(LocalDate.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG))); + writer.println("\n\nPAY TO THE ORDER OF-----" + payee + "-----$ " + player); + writer.print("\n\n"); + tab(10); writer.println("THE MEMORY BANK OF NEW YORK\n"); + tab(40); writer.println("THE COMPUTER"); + tab(40); writer.println("----------X-----\n"); + writer.println("-".repeat(72)); + writer.println("COME BACK SOON!\n"); + } + } + catch (IOException e) { + // this should not happen + System.err.println("System error:\n" + e); + } + } + + /* Write the starting introduction */ + private void intro() throws IOException { + tab(32); writer.println("ROULETTE"); + tab(15); writer.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n"); + } + + /* Display the game instructions */ + private void instructions() { + String[] instLines = new String[] { + "THIS IS THE BETTING LAYOUT", + " (*=RED)", + "" , + " 1* 2 3*", + " 4 5* 6 ", + " 7* 8 9*", + "10 11 12*", + "---------------", + "13 14* 15 ", + "16* 17 18*", + "19* 20 21*", + "22 23* 24 ", + "---------------", + "25* 26 27*", + "28 29 30*", + "31 32* 33 ", + "34* 35 36*", + "---------------", + " 00 0 ", + "" , + "TYPES OF BETS", + "" , + "THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET", + "ON THAT NUMBER.", + "THESE PAY OFF 35:1", + "" , + "THE 2:1 BETS ARE:", + " 37) 1-12 40) FIRST COLUMN", + " 38) 13-24 41) SECOND COLUMN", + " 39) 25-36 42) THIRD COLUMN", + "" , + "THE EVEN MONEY BETS ARE:", + " 43) 1-18 46) ODD", + " 44) 19-36 47) RED", + " 45) EVEN 48) BLACK", + "", + " 49)0 AND 50)00 PAY OFF 35:1", + " NOTE: 0 AND 00 DO NOT COUNT UNDER ANY", + " BETS EXCEPT THEIR OWN.", + "", + "WHEN I ASK FOR EACH BET, TYPE THE NUMBER", + "AND THE AMOUNT, SEPARATED BY A COMMA.", + "FOR EXAMPLE: TO BET $500 ON BLACK, TYPE 48,500", + "WHEN I ASK FOR A BET.", + "", + "THE MINIMUM BET IS $5, THE MAXIMUM IS $500.", + "" }; + writer.println(String.join("\n", instLines)); + } + + /* Take a set of bets from the player, then spin the wheel and work out the winnings * + * This returns true if the game is to continue afterwards + */ + private boolean betAndSpin() throws IOException { + int betCount = 0; + + while (betCount == 0) { // keep asking how many bets until we get a good answer + try { + writer.println("HOW MANY BETS"); + String howMany = reader.readLine(); + betCount = Integer.parseInt(howMany.strip()); + + if ((betCount < 1) || (betCount > 100)) betCount = 0; // bad -- set zero and ask again + } + catch (NumberFormatException e) { + // this happens if the input is not a number + writer.println("INPUT ERROR"); + } + } + + HashSet betsMade = new HashSet<>(); // Bet targets already made, so we can spot repeats + ArrayList bets = new ArrayList<>(); // All the bets for this round + + while (bets.size() < betCount) { + Bet bet = new Bet(0, 0); // an invalid bet to hold the place + while (!bet.isValid()) { // keep asking until it is valid + try { + writer.println("NUMBER " + (bets.size() + 1)); + String fields[] = reader.readLine().split(","); + if (fields.length == 2) { + bet = new Bet(Integer.parseInt(fields[0].strip()), + Integer.parseInt(fields[1].strip())); + } + } + catch (NumberFormatException e) { + writer.println("INPUT ERROR"); + } + } + + // Check if there is already a bet on the same target + if (betsMade.contains(bet.target)) { + writer.println("YOU MADE THAT BET ONCE ALREADY,DUM-DUM"); + } else { + betsMade.add(bet.target); // note this target has now been bet on + bets.add(bet); + } + } + + writer.println("SPINNING\n\n"); + + wheel.spin(); // this deliberately takes some random amount of time + + writer.println(wheel.value()); + + // go through the bets, and evaluate each one + int betNumber = 1; + for (Bet b : bets) { + int multiplier = b.winsOn(wheel); + if (multiplier == 0) { + // lost the amount of the bet + writer.println("YOU LOSE " + b.amount + " DOLLARS ON BET " + betNumber); + house += b.amount; + player -= b.amount; + } else { + // won the amount of the bet, multiplied by the odds + int winnings = b.amount * multiplier; + writer.println("YOU WIN " + winnings + " DOLLARS ON BET " + betNumber); + house -= winnings; + player += winnings; + } + ++betNumber; + } + + writer.println("\nTOTALS:\tME\tYOU\n\t" + house + "\t" + player); + + if (player <= 0) { + writer.println("OOPS! YOU JUST SPENT YOUR LAST DOLLAR"); + return false; // do not repeat since the player has no more money + } + if (house <= 0) { + writer.println("YOU BROKE THE HOUSE!"); + player = 101000; // can't win more than the house started with + return false; // do not repeat since the house has no more money + } + + // player still has money, and the house still has money, so ask the player + // if they want to continue + writer.println("AGAIN"); + String doContinue = reader.readLine(); + + // repeat if the answer was not "n" or "no" + return (!doContinue.toUpperCase().startsWith("N")); + } + + // utility to print n spaces for formatting + private void tab(int n) { + writer.print(" ".repeat(n)); + } +} diff --git a/75_Roulette/java/Wheel.java b/75_Roulette/java/Wheel.java new file mode 100644 index 00000000..497c8b53 --- /dev/null +++ b/75_Roulette/java/Wheel.java @@ -0,0 +1,69 @@ +import java.util.Arrays; +import java.util.HashSet; +import java.util.Random; + +// The roulette wheel +public class Wheel { + // List the numbers which are black + private HashSet black = new HashSet<>(Arrays.asList(new Integer[] { 1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36 })); + + private Random random = new Random(); + private int pocket = 38; + + public static final int ZERO=0; + public static final int BLACK=1; + public static final int RED=2; + + // Set up a wheel. You call "spin", and then can check the result. + public Wheel() { + } + + // Cheat / test mode + void setSeed(long l) { + random.setSeed(l); + } + + // Spin the wheel onto a new random value. + public void spin() { + // keep spinning for a while + do { + try { + // 1 second delay. Where it stops, nobody knows + Thread.sleep(1000); + } + catch (InterruptedException e) {} + + pocket = random.nextInt(38) + 1; + } while (random.nextInt(4) > 0); // keep spinning until it stops + } + + // The string representation of the number; 1-36, 0, or 00 + public String value() { + if (pocket == 37) return "0"; + else if (pocket == 38) return "00"; + else return String.valueOf(pocket); + } + + // True if either 0 or 00 is hit + public boolean zero() { + return (pocket > 36); + } + + // True if anything other than 0 or 00 is hit + public boolean isNumber() { + return (pocket < 37); + } + + // The number rolled + public int number() { + if (zero()) return 0; + else return pocket; + } + + // Either ZERO, BLACK, or RED + public int color() { + if (zero()) return ZERO; + else if (black.contains(pocket)) return BLACK; + else return RED; + } +} From 3d46e147f553868eca2b6c854e4eeb106e77d250 Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 11 Jan 2022 21:40:31 +0000 Subject: [PATCH 074/337] readme --- 75_Roulette/java/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/75_Roulette/java/README.md b/75_Roulette/java/README.md index 51edd8d4..2f9c97ca 100644 --- a/75_Roulette/java/README.md +++ b/75_Roulette/java/README.md @@ -1,3 +1,6 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Oracle Java](https://openjdk.java.net/) + +Conversion by Andrew McGuinness (andrew@arobeia.co.uk) + From 09b0e972cdf6b2cab7547396685569a0fc4364d4 Mon Sep 17 00:00:00 2001 From: Tom Wyant Date: Tue, 11 Jan 2022 17:00:28 -0500 Subject: [PATCH 075/337] Port 75_Roulette to Perl. The directory includes a Perl script to test the port (roulette-test.t) and a Perl script to generate the test based on output from the BASIC implementation (make-roulette-test.pl). --- 75_Roulette/perl/README.md | 12 + 75_Roulette/perl/make-roulette-test.pl | 263 ++++ 75_Roulette/perl/roulette-test.t | 1967 ++++++++++++++++++++++++ 75_Roulette/perl/roulette.pl | 319 ++++ 4 files changed, 2561 insertions(+) create mode 100755 75_Roulette/perl/make-roulette-test.pl create mode 100644 75_Roulette/perl/roulette-test.t create mode 100755 75_Roulette/perl/roulette.pl diff --git a/75_Roulette/perl/README.md b/75_Roulette/perl/README.md index e69c8b81..e7dcb811 100644 --- a/75_Roulette/perl/README.md +++ b/75_Roulette/perl/README.md @@ -1,3 +1,15 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Perl](https://www.perl.org/) + +This conversion consists of three files in `75_Roulette/perl/`: + +- `roulette.pl` is the port of the BASIC to Perl; +- `roulette-test.t` is a Perl test for correctness of display and payout; +- `make-roulette-test.pl` generates roulette-test.t from roulette.bas. + +The ported version of the game numbers the slots from 0 rather than 1, and uses a dispatch table to figure out the payout. + +The Perl test loads `roulette.pl` and verifies the Perl slot display and payout logic against the BASIC for all combinations of slots and bets. If any tests fail that fact will be noted at the end of the output. + +The test code is generated by reading the BASIC, retaining only the slot display and payout logic (based on line numbers), and wrapping this in code that generates all combinations of bet and spin result. The result is run, and the result is captured and parsed to produce `roulette-test.t`. `make-roulette-test.pl` has some command-line options that may be of interest. `--help` will display the documentation. diff --git a/75_Roulette/perl/make-roulette-test.pl b/75_Roulette/perl/make-roulette-test.pl new file mode 100755 index 00000000..100fd8d7 --- /dev/null +++ b/75_Roulette/perl/make-roulette-test.pl @@ -0,0 +1,263 @@ +#!/usr/bin/env perl + +use 5.014; # For s///r + +use strict; +use warnings; + +use File::Temp; +use Getopt::Long 2.33 qw{ :config auto_version }; +use IPC::Cmd qw{ can_run }; # Core as of Perl 5.9.5. +use Pod::Usage; + +our $VERSION = '0.000_01'; + +my %opt = ( + program => find_basic(), + output => make_default_output(), +); + +GetOptions( \%opt, + qw{ output=s program=s }, + help => sub { pod2usage( { -verbose => 2 } ) }, +) or pod2usage( { -verbose => 0 } ); + +die "No default BASIC found; you must specify --program\n" + unless defined $opt{program}; + +my $game_dir = ( File::Spec->splitdir( $0 ) )[0]; +my $basic_file = File::Spec->catfile( $game_dir, 'roulette.bas' ); +open my $basic_handle, '<', $basic_file + or die "Unable to open $basic_file: $!\n"; + +my $munged = File::Temp->new(); + +print { $munged } <<'EOD'; +1000 Y=50 +1010 DIM B(100),C(100),T(100) +1090 FOR S=1 TO 38 +1095 PRINT "SPIN ";S +1100 FOR C=1 TO Y +1110 B(C)=1 +1120 T(C)=C +1130 NEXT C +EOD + +transcribe( $basic_file, $basic_handle, $munged, 1860, 2810 ); +transcribe( $basic_file, $basic_handle, $munged, 2950 ); + +say { $munged } '4000 NEXT S'; + +$munged->flush(); + +if ( $opt{output} ne '-' ) { + my $dir = ( File::Spec->splitpath( $0 ) )[1]; + my $fn = File::Spec->rel2abs( $opt{output}, $dir ); + $fn = File::Spec->abs2rel( $fn ); + open my $fh, '>', $fn + or die "Unable to open $fn: $!\n"; + warn "Writing $fn\n"; + select $fh; +} + +print <<'EOD'; +package main; + +use 5.010; + +use strict; +use warnings; + +use File::Spec; +use Test::More 0.88; # Because of done_testing(); + +EOD + +print <<"EOD"; +# NOTE: This file is generated by $0. +# Any edits made to it will be lost the next time it is regenerated. +# Caveat coder. + +EOD + +print <<'EOD'; +my $dir = ( File::Spec->splitpath( $0 ) )[1]; +my $script = File::Spec->catfile( $dir, 'roulette.pl' ); +{ + # Modern Perls do not have . in @INC, but we need it there to load a + # relative path. + local @INC = ( File::Spec->curdir(), @INC ); + require $script; # Load game as module +} + +EOD + +my $spin; +my $name; +foreach ( `$opt{program} @{[ $munged->filename() ]}` ) { + s/\N{U+1D}/ /smxg; # Artifact of the BASIC I'm using. + s/ \s+ \z //smx; + s/ \A \s+ //smx; + if ( $_ eq '' ) { + # Ignore empty lines. + } elsif ( m/ \A SPIN \s* ( [0-9]+ ) /smx ) { + $spin = $1 - 1; # BASIC is 1-based, but Perl is 0-based + } elsif ( m/ \A YOU \s+ WIN \s* ( [0-9]+ ) \s* + DOLLARS \s+ ON \s+ BET \s* ( [0-9]+ ) /smx ) { + say "is payout( $spin, $2 ), $1, 'Spin $spin ($name), bet $2 pays $1';"; + } elsif ( m/ \A YOU \s+ LOSE \s* ( [0-9]+ ) \s* + DOLLARS \s+ ON \s+ BET \s* ( [0-9]+ ) /smx ) { + say "is payout( $spin, $2 ), -$1, 'Spin $spin ($name), bet $2 pays -$1';"; + } elsif ( m/ \A \s* ( [0-9]+ ) (?: \s* ( [[:alpha:]]+ ) )? \z /smx ) { + $name = $2 ? sprintf( '%d %s', $1, ucfirst lc $2 ) : $1; + say "is format_spin( $spin ), '$name', 'Spin $spin is $name';"; + } else { + die "Unexpected input $_"; + } +} + +print <<'EOD'; + +done_testing; + +1; + +# ex: set textwidth=72 : +EOD + +sub find_basic { + # yabasic seems not to work + foreach my $prog ( qw{ basic cbmbasic } ) { + return $prog if can_run( $prog ) + } + return undef; +} + +sub make_default_output { + ( my $rslt = $0 ) =~ s/ [.] pl \z /.t/smx; + $rslt =~ s/ .* \b make- //smx; + return $rslt; +} + +sub transcribe { + my ( $in_file, $in_handle, $out_handle, $first_line, $last_line ) = @_; + $last_line //= $first_line; + + while ( <$in_handle> ) { + m/ \A \s* ( [0-9]+ )+ \s /smx + or next; + $1 < $first_line + and next; + say { $out_handle } sprintf '%04d REM BEGIN VERBATIM FROM %s', + $first_line - 10, $in_file; + print { $out_handle } $_; + last; + } + while ( <$in_handle> ) { + m/ \A \s* ( [0-9]+ )+ \s /smx + and $1 > $last_line + and last; + print { $out_handle } $_; + } + say { $out_handle } sprintf '%04d REM END VERBATIM FROM %s', + $last_line + 10, $in_file; + + return; +} + +__END__ + +=head1 TITLE + +make-roulette-test.pl - Generate the tests for 75_Roulette/perl/roulette.pl + +=head1 SYNOPSIS + + perl 75_Roulette/perl/make-roulette-test.pl + perl 75_Roulette/perl/make-roulette-test.pl --program mybasic + perl 75_Roulette/perl/make-roulette-test.pl --help + perl 75_Roulette/perl/make-roulette-test.pl --version + +=head1 OPTIONS + +<<< replace boiler plate >>> + +=head2 --help + +This option displays the documentation for this script. The script then +exits. + +=head2 --output + + --output fubar.t + +This option specifies the output file. This needs to be in the same +directory as F, and defaults to that directory. A single +dash (C<'-'>) is special-cased to send the output to standard out. + +The default is C<--output=test-roulette.t>. + +=head2 --program + + --program my_basic + +This option specifies the name of your BASIC interpreter. This must be +the name of an executable file in your PATH (aliases do not work). + +The default is the first-found in the list C. + +=head2 --version + +This option displays the version of this script. The script then exits. + +=head1 DETAILS + +This Perl script generates F, which tests +F. The latter is expected to be written as a modulino. + +This script assumes that: + +=over + +=item * it is in the same directory as F; + +=item * F is in the first-level subdirectory under the current directory; + +=back + +The generated test assumes that it is in the same directory as +F. + +This script works by abstracting the internals of F and +wrapping them in a loop that generates all possible spins, and places +all possible bets on each spin. The generated BASIC is written to a +temporary file, and executed by a BASIC interpreter. The output is +parsed and used to generate the output. + +Obviously there is some ad-hocery going on, and this script has only +been tested under C, which was what I had on hand. + +B the abstraction process is driven by BASIC line numbers. Any +change of these puts the ad-hocery at risk. + +=head1 AUTHOR + +Thomas R. Wyant, III F + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2022 by Thomas R. Wyant, III + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl 5.10.0. For more details, see the Artistic +License 1.0 at +L, and/or the +Gnu GPL at L. + +This program is distributed in the hope that it will be useful, but +without any warranty; without even the implied warranty of +merchantability or fitness for a particular purpose. + +=cut + +# ex: set textwidth=72 : diff --git a/75_Roulette/perl/roulette-test.t b/75_Roulette/perl/roulette-test.t new file mode 100644 index 00000000..6fe43fa7 --- /dev/null +++ b/75_Roulette/perl/roulette-test.t @@ -0,0 +1,1967 @@ +package main; + +use 5.010; + +use strict; +use warnings; + +use File::Spec; +use Test::More 0.88; # Because of done_testing(); + +# NOTE: This file is generated by 75_Roulette/perl/make-roulette-test.pl. +# Any edits made to it will be lost the next time it is regenerated. +# Caveat coder. + +my $dir = ( File::Spec->splitpath( $0 ) )[1]; +my $script = File::Spec->catfile( $dir, 'roulette.pl' ); +{ + # Modern Perls do not have . in @INC, but we need it there to load a + # relative path. + local @INC = ( File::Spec->curdir(), @INC ); + require $script; # Load game as module +} + +is format_spin( 0 ), '1 Red', 'Spin 0 is 1 Red'; +is payout( 0, 1 ), 35, 'Spin 0 (1 Red), bet 1 pays 35'; +is payout( 0, 2 ), -1, 'Spin 0 (1 Red), bet 2 pays -1'; +is payout( 0, 3 ), -1, 'Spin 0 (1 Red), bet 3 pays -1'; +is payout( 0, 4 ), -1, 'Spin 0 (1 Red), bet 4 pays -1'; +is payout( 0, 5 ), -1, 'Spin 0 (1 Red), bet 5 pays -1'; +is payout( 0, 6 ), -1, 'Spin 0 (1 Red), bet 6 pays -1'; +is payout( 0, 7 ), -1, 'Spin 0 (1 Red), bet 7 pays -1'; +is payout( 0, 8 ), -1, 'Spin 0 (1 Red), bet 8 pays -1'; +is payout( 0, 9 ), -1, 'Spin 0 (1 Red), bet 9 pays -1'; +is payout( 0, 10 ), -1, 'Spin 0 (1 Red), bet 10 pays -1'; +is payout( 0, 11 ), -1, 'Spin 0 (1 Red), bet 11 pays -1'; +is payout( 0, 12 ), -1, 'Spin 0 (1 Red), bet 12 pays -1'; +is payout( 0, 13 ), -1, 'Spin 0 (1 Red), bet 13 pays -1'; +is payout( 0, 14 ), -1, 'Spin 0 (1 Red), bet 14 pays -1'; +is payout( 0, 15 ), -1, 'Spin 0 (1 Red), bet 15 pays -1'; +is payout( 0, 16 ), -1, 'Spin 0 (1 Red), bet 16 pays -1'; +is payout( 0, 17 ), -1, 'Spin 0 (1 Red), bet 17 pays -1'; +is payout( 0, 18 ), -1, 'Spin 0 (1 Red), bet 18 pays -1'; +is payout( 0, 19 ), -1, 'Spin 0 (1 Red), bet 19 pays -1'; +is payout( 0, 20 ), -1, 'Spin 0 (1 Red), bet 20 pays -1'; +is payout( 0, 21 ), -1, 'Spin 0 (1 Red), bet 21 pays -1'; +is payout( 0, 22 ), -1, 'Spin 0 (1 Red), bet 22 pays -1'; +is payout( 0, 23 ), -1, 'Spin 0 (1 Red), bet 23 pays -1'; +is payout( 0, 24 ), -1, 'Spin 0 (1 Red), bet 24 pays -1'; +is payout( 0, 25 ), -1, 'Spin 0 (1 Red), bet 25 pays -1'; +is payout( 0, 26 ), -1, 'Spin 0 (1 Red), bet 26 pays -1'; +is payout( 0, 27 ), -1, 'Spin 0 (1 Red), bet 27 pays -1'; +is payout( 0, 28 ), -1, 'Spin 0 (1 Red), bet 28 pays -1'; +is payout( 0, 29 ), -1, 'Spin 0 (1 Red), bet 29 pays -1'; +is payout( 0, 30 ), -1, 'Spin 0 (1 Red), bet 30 pays -1'; +is payout( 0, 31 ), -1, 'Spin 0 (1 Red), bet 31 pays -1'; +is payout( 0, 32 ), -1, 'Spin 0 (1 Red), bet 32 pays -1'; +is payout( 0, 33 ), -1, 'Spin 0 (1 Red), bet 33 pays -1'; +is payout( 0, 34 ), -1, 'Spin 0 (1 Red), bet 34 pays -1'; +is payout( 0, 35 ), -1, 'Spin 0 (1 Red), bet 35 pays -1'; +is payout( 0, 36 ), -1, 'Spin 0 (1 Red), bet 36 pays -1'; +is payout( 0, 37 ), 2, 'Spin 0 (1 Red), bet 37 pays 2'; +is payout( 0, 38 ), -1, 'Spin 0 (1 Red), bet 38 pays -1'; +is payout( 0, 39 ), -1, 'Spin 0 (1 Red), bet 39 pays -1'; +is payout( 0, 40 ), 2, 'Spin 0 (1 Red), bet 40 pays 2'; +is payout( 0, 41 ), -1, 'Spin 0 (1 Red), bet 41 pays -1'; +is payout( 0, 42 ), -1, 'Spin 0 (1 Red), bet 42 pays -1'; +is payout( 0, 43 ), 1, 'Spin 0 (1 Red), bet 43 pays 1'; +is payout( 0, 44 ), -1, 'Spin 0 (1 Red), bet 44 pays -1'; +is payout( 0, 45 ), -1, 'Spin 0 (1 Red), bet 45 pays -1'; +is payout( 0, 46 ), 1, 'Spin 0 (1 Red), bet 46 pays 1'; +is payout( 0, 47 ), 1, 'Spin 0 (1 Red), bet 47 pays 1'; +is payout( 0, 48 ), -1, 'Spin 0 (1 Red), bet 48 pays -1'; +is payout( 0, 49 ), -1, 'Spin 0 (1 Red), bet 49 pays -1'; +is payout( 0, 50 ), -1, 'Spin 0 (1 Red), bet 50 pays -1'; +is format_spin( 1 ), '2 Black', 'Spin 1 is 2 Black'; +is payout( 1, 1 ), -1, 'Spin 1 (2 Black), bet 1 pays -1'; +is payout( 1, 2 ), 35, 'Spin 1 (2 Black), bet 2 pays 35'; +is payout( 1, 3 ), -1, 'Spin 1 (2 Black), bet 3 pays -1'; +is payout( 1, 4 ), -1, 'Spin 1 (2 Black), bet 4 pays -1'; +is payout( 1, 5 ), -1, 'Spin 1 (2 Black), bet 5 pays -1'; +is payout( 1, 6 ), -1, 'Spin 1 (2 Black), bet 6 pays -1'; +is payout( 1, 7 ), -1, 'Spin 1 (2 Black), bet 7 pays -1'; +is payout( 1, 8 ), -1, 'Spin 1 (2 Black), bet 8 pays -1'; +is payout( 1, 9 ), -1, 'Spin 1 (2 Black), bet 9 pays -1'; +is payout( 1, 10 ), -1, 'Spin 1 (2 Black), bet 10 pays -1'; +is payout( 1, 11 ), -1, 'Spin 1 (2 Black), bet 11 pays -1'; +is payout( 1, 12 ), -1, 'Spin 1 (2 Black), bet 12 pays -1'; +is payout( 1, 13 ), -1, 'Spin 1 (2 Black), bet 13 pays -1'; +is payout( 1, 14 ), -1, 'Spin 1 (2 Black), bet 14 pays -1'; +is payout( 1, 15 ), -1, 'Spin 1 (2 Black), bet 15 pays -1'; +is payout( 1, 16 ), -1, 'Spin 1 (2 Black), bet 16 pays -1'; +is payout( 1, 17 ), -1, 'Spin 1 (2 Black), bet 17 pays -1'; +is payout( 1, 18 ), -1, 'Spin 1 (2 Black), bet 18 pays -1'; +is payout( 1, 19 ), -1, 'Spin 1 (2 Black), bet 19 pays -1'; +is payout( 1, 20 ), -1, 'Spin 1 (2 Black), bet 20 pays -1'; +is payout( 1, 21 ), -1, 'Spin 1 (2 Black), bet 21 pays -1'; +is payout( 1, 22 ), -1, 'Spin 1 (2 Black), bet 22 pays -1'; +is payout( 1, 23 ), -1, 'Spin 1 (2 Black), bet 23 pays -1'; +is payout( 1, 24 ), -1, 'Spin 1 (2 Black), bet 24 pays -1'; +is payout( 1, 25 ), -1, 'Spin 1 (2 Black), bet 25 pays -1'; +is payout( 1, 26 ), -1, 'Spin 1 (2 Black), bet 26 pays -1'; +is payout( 1, 27 ), -1, 'Spin 1 (2 Black), bet 27 pays -1'; +is payout( 1, 28 ), -1, 'Spin 1 (2 Black), bet 28 pays -1'; +is payout( 1, 29 ), -1, 'Spin 1 (2 Black), bet 29 pays -1'; +is payout( 1, 30 ), -1, 'Spin 1 (2 Black), bet 30 pays -1'; +is payout( 1, 31 ), -1, 'Spin 1 (2 Black), bet 31 pays -1'; +is payout( 1, 32 ), -1, 'Spin 1 (2 Black), bet 32 pays -1'; +is payout( 1, 33 ), -1, 'Spin 1 (2 Black), bet 33 pays -1'; +is payout( 1, 34 ), -1, 'Spin 1 (2 Black), bet 34 pays -1'; +is payout( 1, 35 ), -1, 'Spin 1 (2 Black), bet 35 pays -1'; +is payout( 1, 36 ), -1, 'Spin 1 (2 Black), bet 36 pays -1'; +is payout( 1, 37 ), 2, 'Spin 1 (2 Black), bet 37 pays 2'; +is payout( 1, 38 ), -1, 'Spin 1 (2 Black), bet 38 pays -1'; +is payout( 1, 39 ), -1, 'Spin 1 (2 Black), bet 39 pays -1'; +is payout( 1, 40 ), -1, 'Spin 1 (2 Black), bet 40 pays -1'; +is payout( 1, 41 ), 2, 'Spin 1 (2 Black), bet 41 pays 2'; +is payout( 1, 42 ), -1, 'Spin 1 (2 Black), bet 42 pays -1'; +is payout( 1, 43 ), 1, 'Spin 1 (2 Black), bet 43 pays 1'; +is payout( 1, 44 ), -1, 'Spin 1 (2 Black), bet 44 pays -1'; +is payout( 1, 45 ), 1, 'Spin 1 (2 Black), bet 45 pays 1'; +is payout( 1, 46 ), -1, 'Spin 1 (2 Black), bet 46 pays -1'; +is payout( 1, 47 ), -1, 'Spin 1 (2 Black), bet 47 pays -1'; +is payout( 1, 48 ), 1, 'Spin 1 (2 Black), bet 48 pays 1'; +is payout( 1, 49 ), -1, 'Spin 1 (2 Black), bet 49 pays -1'; +is payout( 1, 50 ), -1, 'Spin 1 (2 Black), bet 50 pays -1'; +is format_spin( 2 ), '3 Red', 'Spin 2 is 3 Red'; +is payout( 2, 1 ), -1, 'Spin 2 (3 Red), bet 1 pays -1'; +is payout( 2, 2 ), -1, 'Spin 2 (3 Red), bet 2 pays -1'; +is payout( 2, 3 ), 35, 'Spin 2 (3 Red), bet 3 pays 35'; +is payout( 2, 4 ), -1, 'Spin 2 (3 Red), bet 4 pays -1'; +is payout( 2, 5 ), -1, 'Spin 2 (3 Red), bet 5 pays -1'; +is payout( 2, 6 ), -1, 'Spin 2 (3 Red), bet 6 pays -1'; +is payout( 2, 7 ), -1, 'Spin 2 (3 Red), bet 7 pays -1'; +is payout( 2, 8 ), -1, 'Spin 2 (3 Red), bet 8 pays -1'; +is payout( 2, 9 ), -1, 'Spin 2 (3 Red), bet 9 pays -1'; +is payout( 2, 10 ), -1, 'Spin 2 (3 Red), bet 10 pays -1'; +is payout( 2, 11 ), -1, 'Spin 2 (3 Red), bet 11 pays -1'; +is payout( 2, 12 ), -1, 'Spin 2 (3 Red), bet 12 pays -1'; +is payout( 2, 13 ), -1, 'Spin 2 (3 Red), bet 13 pays -1'; +is payout( 2, 14 ), -1, 'Spin 2 (3 Red), bet 14 pays -1'; +is payout( 2, 15 ), -1, 'Spin 2 (3 Red), bet 15 pays -1'; +is payout( 2, 16 ), -1, 'Spin 2 (3 Red), bet 16 pays -1'; +is payout( 2, 17 ), -1, 'Spin 2 (3 Red), bet 17 pays -1'; +is payout( 2, 18 ), -1, 'Spin 2 (3 Red), bet 18 pays -1'; +is payout( 2, 19 ), -1, 'Spin 2 (3 Red), bet 19 pays -1'; +is payout( 2, 20 ), -1, 'Spin 2 (3 Red), bet 20 pays -1'; +is payout( 2, 21 ), -1, 'Spin 2 (3 Red), bet 21 pays -1'; +is payout( 2, 22 ), -1, 'Spin 2 (3 Red), bet 22 pays -1'; +is payout( 2, 23 ), -1, 'Spin 2 (3 Red), bet 23 pays -1'; +is payout( 2, 24 ), -1, 'Spin 2 (3 Red), bet 24 pays -1'; +is payout( 2, 25 ), -1, 'Spin 2 (3 Red), bet 25 pays -1'; +is payout( 2, 26 ), -1, 'Spin 2 (3 Red), bet 26 pays -1'; +is payout( 2, 27 ), -1, 'Spin 2 (3 Red), bet 27 pays -1'; +is payout( 2, 28 ), -1, 'Spin 2 (3 Red), bet 28 pays -1'; +is payout( 2, 29 ), -1, 'Spin 2 (3 Red), bet 29 pays -1'; +is payout( 2, 30 ), -1, 'Spin 2 (3 Red), bet 30 pays -1'; +is payout( 2, 31 ), -1, 'Spin 2 (3 Red), bet 31 pays -1'; +is payout( 2, 32 ), -1, 'Spin 2 (3 Red), bet 32 pays -1'; +is payout( 2, 33 ), -1, 'Spin 2 (3 Red), bet 33 pays -1'; +is payout( 2, 34 ), -1, 'Spin 2 (3 Red), bet 34 pays -1'; +is payout( 2, 35 ), -1, 'Spin 2 (3 Red), bet 35 pays -1'; +is payout( 2, 36 ), -1, 'Spin 2 (3 Red), bet 36 pays -1'; +is payout( 2, 37 ), 2, 'Spin 2 (3 Red), bet 37 pays 2'; +is payout( 2, 38 ), -1, 'Spin 2 (3 Red), bet 38 pays -1'; +is payout( 2, 39 ), -1, 'Spin 2 (3 Red), bet 39 pays -1'; +is payout( 2, 40 ), -1, 'Spin 2 (3 Red), bet 40 pays -1'; +is payout( 2, 41 ), -1, 'Spin 2 (3 Red), bet 41 pays -1'; +is payout( 2, 42 ), 2, 'Spin 2 (3 Red), bet 42 pays 2'; +is payout( 2, 43 ), 1, 'Spin 2 (3 Red), bet 43 pays 1'; +is payout( 2, 44 ), -1, 'Spin 2 (3 Red), bet 44 pays -1'; +is payout( 2, 45 ), -1, 'Spin 2 (3 Red), bet 45 pays -1'; +is payout( 2, 46 ), 1, 'Spin 2 (3 Red), bet 46 pays 1'; +is payout( 2, 47 ), 1, 'Spin 2 (3 Red), bet 47 pays 1'; +is payout( 2, 48 ), -1, 'Spin 2 (3 Red), bet 48 pays -1'; +is payout( 2, 49 ), -1, 'Spin 2 (3 Red), bet 49 pays -1'; +is payout( 2, 50 ), -1, 'Spin 2 (3 Red), bet 50 pays -1'; +is format_spin( 3 ), '4 Black', 'Spin 3 is 4 Black'; +is payout( 3, 1 ), -1, 'Spin 3 (4 Black), bet 1 pays -1'; +is payout( 3, 2 ), -1, 'Spin 3 (4 Black), bet 2 pays -1'; +is payout( 3, 3 ), -1, 'Spin 3 (4 Black), bet 3 pays -1'; +is payout( 3, 4 ), 35, 'Spin 3 (4 Black), bet 4 pays 35'; +is payout( 3, 5 ), -1, 'Spin 3 (4 Black), bet 5 pays -1'; +is payout( 3, 6 ), -1, 'Spin 3 (4 Black), bet 6 pays -1'; +is payout( 3, 7 ), -1, 'Spin 3 (4 Black), bet 7 pays -1'; +is payout( 3, 8 ), -1, 'Spin 3 (4 Black), bet 8 pays -1'; +is payout( 3, 9 ), -1, 'Spin 3 (4 Black), bet 9 pays -1'; +is payout( 3, 10 ), -1, 'Spin 3 (4 Black), bet 10 pays -1'; +is payout( 3, 11 ), -1, 'Spin 3 (4 Black), bet 11 pays -1'; +is payout( 3, 12 ), -1, 'Spin 3 (4 Black), bet 12 pays -1'; +is payout( 3, 13 ), -1, 'Spin 3 (4 Black), bet 13 pays -1'; +is payout( 3, 14 ), -1, 'Spin 3 (4 Black), bet 14 pays -1'; +is payout( 3, 15 ), -1, 'Spin 3 (4 Black), bet 15 pays -1'; +is payout( 3, 16 ), -1, 'Spin 3 (4 Black), bet 16 pays -1'; +is payout( 3, 17 ), -1, 'Spin 3 (4 Black), bet 17 pays -1'; +is payout( 3, 18 ), -1, 'Spin 3 (4 Black), bet 18 pays -1'; +is payout( 3, 19 ), -1, 'Spin 3 (4 Black), bet 19 pays -1'; +is payout( 3, 20 ), -1, 'Spin 3 (4 Black), bet 20 pays -1'; +is payout( 3, 21 ), -1, 'Spin 3 (4 Black), bet 21 pays -1'; +is payout( 3, 22 ), -1, 'Spin 3 (4 Black), bet 22 pays -1'; +is payout( 3, 23 ), -1, 'Spin 3 (4 Black), bet 23 pays -1'; +is payout( 3, 24 ), -1, 'Spin 3 (4 Black), bet 24 pays -1'; +is payout( 3, 25 ), -1, 'Spin 3 (4 Black), bet 25 pays -1'; +is payout( 3, 26 ), -1, 'Spin 3 (4 Black), bet 26 pays -1'; +is payout( 3, 27 ), -1, 'Spin 3 (4 Black), bet 27 pays -1'; +is payout( 3, 28 ), -1, 'Spin 3 (4 Black), bet 28 pays -1'; +is payout( 3, 29 ), -1, 'Spin 3 (4 Black), bet 29 pays -1'; +is payout( 3, 30 ), -1, 'Spin 3 (4 Black), bet 30 pays -1'; +is payout( 3, 31 ), -1, 'Spin 3 (4 Black), bet 31 pays -1'; +is payout( 3, 32 ), -1, 'Spin 3 (4 Black), bet 32 pays -1'; +is payout( 3, 33 ), -1, 'Spin 3 (4 Black), bet 33 pays -1'; +is payout( 3, 34 ), -1, 'Spin 3 (4 Black), bet 34 pays -1'; +is payout( 3, 35 ), -1, 'Spin 3 (4 Black), bet 35 pays -1'; +is payout( 3, 36 ), -1, 'Spin 3 (4 Black), bet 36 pays -1'; +is payout( 3, 37 ), 2, 'Spin 3 (4 Black), bet 37 pays 2'; +is payout( 3, 38 ), -1, 'Spin 3 (4 Black), bet 38 pays -1'; +is payout( 3, 39 ), -1, 'Spin 3 (4 Black), bet 39 pays -1'; +is payout( 3, 40 ), 2, 'Spin 3 (4 Black), bet 40 pays 2'; +is payout( 3, 41 ), -1, 'Spin 3 (4 Black), bet 41 pays -1'; +is payout( 3, 42 ), -1, 'Spin 3 (4 Black), bet 42 pays -1'; +is payout( 3, 43 ), 1, 'Spin 3 (4 Black), bet 43 pays 1'; +is payout( 3, 44 ), -1, 'Spin 3 (4 Black), bet 44 pays -1'; +is payout( 3, 45 ), 1, 'Spin 3 (4 Black), bet 45 pays 1'; +is payout( 3, 46 ), -1, 'Spin 3 (4 Black), bet 46 pays -1'; +is payout( 3, 47 ), -1, 'Spin 3 (4 Black), bet 47 pays -1'; +is payout( 3, 48 ), 1, 'Spin 3 (4 Black), bet 48 pays 1'; +is payout( 3, 49 ), -1, 'Spin 3 (4 Black), bet 49 pays -1'; +is payout( 3, 50 ), -1, 'Spin 3 (4 Black), bet 50 pays -1'; +is format_spin( 4 ), '5 Red', 'Spin 4 is 5 Red'; +is payout( 4, 1 ), -1, 'Spin 4 (5 Red), bet 1 pays -1'; +is payout( 4, 2 ), -1, 'Spin 4 (5 Red), bet 2 pays -1'; +is payout( 4, 3 ), -1, 'Spin 4 (5 Red), bet 3 pays -1'; +is payout( 4, 4 ), -1, 'Spin 4 (5 Red), bet 4 pays -1'; +is payout( 4, 5 ), 35, 'Spin 4 (5 Red), bet 5 pays 35'; +is payout( 4, 6 ), -1, 'Spin 4 (5 Red), bet 6 pays -1'; +is payout( 4, 7 ), -1, 'Spin 4 (5 Red), bet 7 pays -1'; +is payout( 4, 8 ), -1, 'Spin 4 (5 Red), bet 8 pays -1'; +is payout( 4, 9 ), -1, 'Spin 4 (5 Red), bet 9 pays -1'; +is payout( 4, 10 ), -1, 'Spin 4 (5 Red), bet 10 pays -1'; +is payout( 4, 11 ), -1, 'Spin 4 (5 Red), bet 11 pays -1'; +is payout( 4, 12 ), -1, 'Spin 4 (5 Red), bet 12 pays -1'; +is payout( 4, 13 ), -1, 'Spin 4 (5 Red), bet 13 pays -1'; +is payout( 4, 14 ), -1, 'Spin 4 (5 Red), bet 14 pays -1'; +is payout( 4, 15 ), -1, 'Spin 4 (5 Red), bet 15 pays -1'; +is payout( 4, 16 ), -1, 'Spin 4 (5 Red), bet 16 pays -1'; +is payout( 4, 17 ), -1, 'Spin 4 (5 Red), bet 17 pays -1'; +is payout( 4, 18 ), -1, 'Spin 4 (5 Red), bet 18 pays -1'; +is payout( 4, 19 ), -1, 'Spin 4 (5 Red), bet 19 pays -1'; +is payout( 4, 20 ), -1, 'Spin 4 (5 Red), bet 20 pays -1'; +is payout( 4, 21 ), -1, 'Spin 4 (5 Red), bet 21 pays -1'; +is payout( 4, 22 ), -1, 'Spin 4 (5 Red), bet 22 pays -1'; +is payout( 4, 23 ), -1, 'Spin 4 (5 Red), bet 23 pays -1'; +is payout( 4, 24 ), -1, 'Spin 4 (5 Red), bet 24 pays -1'; +is payout( 4, 25 ), -1, 'Spin 4 (5 Red), bet 25 pays -1'; +is payout( 4, 26 ), -1, 'Spin 4 (5 Red), bet 26 pays -1'; +is payout( 4, 27 ), -1, 'Spin 4 (5 Red), bet 27 pays -1'; +is payout( 4, 28 ), -1, 'Spin 4 (5 Red), bet 28 pays -1'; +is payout( 4, 29 ), -1, 'Spin 4 (5 Red), bet 29 pays -1'; +is payout( 4, 30 ), -1, 'Spin 4 (5 Red), bet 30 pays -1'; +is payout( 4, 31 ), -1, 'Spin 4 (5 Red), bet 31 pays -1'; +is payout( 4, 32 ), -1, 'Spin 4 (5 Red), bet 32 pays -1'; +is payout( 4, 33 ), -1, 'Spin 4 (5 Red), bet 33 pays -1'; +is payout( 4, 34 ), -1, 'Spin 4 (5 Red), bet 34 pays -1'; +is payout( 4, 35 ), -1, 'Spin 4 (5 Red), bet 35 pays -1'; +is payout( 4, 36 ), -1, 'Spin 4 (5 Red), bet 36 pays -1'; +is payout( 4, 37 ), 2, 'Spin 4 (5 Red), bet 37 pays 2'; +is payout( 4, 38 ), -1, 'Spin 4 (5 Red), bet 38 pays -1'; +is payout( 4, 39 ), -1, 'Spin 4 (5 Red), bet 39 pays -1'; +is payout( 4, 40 ), -1, 'Spin 4 (5 Red), bet 40 pays -1'; +is payout( 4, 41 ), 2, 'Spin 4 (5 Red), bet 41 pays 2'; +is payout( 4, 42 ), -1, 'Spin 4 (5 Red), bet 42 pays -1'; +is payout( 4, 43 ), 1, 'Spin 4 (5 Red), bet 43 pays 1'; +is payout( 4, 44 ), -1, 'Spin 4 (5 Red), bet 44 pays -1'; +is payout( 4, 45 ), -1, 'Spin 4 (5 Red), bet 45 pays -1'; +is payout( 4, 46 ), 1, 'Spin 4 (5 Red), bet 46 pays 1'; +is payout( 4, 47 ), 1, 'Spin 4 (5 Red), bet 47 pays 1'; +is payout( 4, 48 ), -1, 'Spin 4 (5 Red), bet 48 pays -1'; +is payout( 4, 49 ), -1, 'Spin 4 (5 Red), bet 49 pays -1'; +is payout( 4, 50 ), -1, 'Spin 4 (5 Red), bet 50 pays -1'; +is format_spin( 5 ), '6 Black', 'Spin 5 is 6 Black'; +is payout( 5, 1 ), -1, 'Spin 5 (6 Black), bet 1 pays -1'; +is payout( 5, 2 ), -1, 'Spin 5 (6 Black), bet 2 pays -1'; +is payout( 5, 3 ), -1, 'Spin 5 (6 Black), bet 3 pays -1'; +is payout( 5, 4 ), -1, 'Spin 5 (6 Black), bet 4 pays -1'; +is payout( 5, 5 ), -1, 'Spin 5 (6 Black), bet 5 pays -1'; +is payout( 5, 6 ), 35, 'Spin 5 (6 Black), bet 6 pays 35'; +is payout( 5, 7 ), -1, 'Spin 5 (6 Black), bet 7 pays -1'; +is payout( 5, 8 ), -1, 'Spin 5 (6 Black), bet 8 pays -1'; +is payout( 5, 9 ), -1, 'Spin 5 (6 Black), bet 9 pays -1'; +is payout( 5, 10 ), -1, 'Spin 5 (6 Black), bet 10 pays -1'; +is payout( 5, 11 ), -1, 'Spin 5 (6 Black), bet 11 pays -1'; +is payout( 5, 12 ), -1, 'Spin 5 (6 Black), bet 12 pays -1'; +is payout( 5, 13 ), -1, 'Spin 5 (6 Black), bet 13 pays -1'; +is payout( 5, 14 ), -1, 'Spin 5 (6 Black), bet 14 pays -1'; +is payout( 5, 15 ), -1, 'Spin 5 (6 Black), bet 15 pays -1'; +is payout( 5, 16 ), -1, 'Spin 5 (6 Black), bet 16 pays -1'; +is payout( 5, 17 ), -1, 'Spin 5 (6 Black), bet 17 pays -1'; +is payout( 5, 18 ), -1, 'Spin 5 (6 Black), bet 18 pays -1'; +is payout( 5, 19 ), -1, 'Spin 5 (6 Black), bet 19 pays -1'; +is payout( 5, 20 ), -1, 'Spin 5 (6 Black), bet 20 pays -1'; +is payout( 5, 21 ), -1, 'Spin 5 (6 Black), bet 21 pays -1'; +is payout( 5, 22 ), -1, 'Spin 5 (6 Black), bet 22 pays -1'; +is payout( 5, 23 ), -1, 'Spin 5 (6 Black), bet 23 pays -1'; +is payout( 5, 24 ), -1, 'Spin 5 (6 Black), bet 24 pays -1'; +is payout( 5, 25 ), -1, 'Spin 5 (6 Black), bet 25 pays -1'; +is payout( 5, 26 ), -1, 'Spin 5 (6 Black), bet 26 pays -1'; +is payout( 5, 27 ), -1, 'Spin 5 (6 Black), bet 27 pays -1'; +is payout( 5, 28 ), -1, 'Spin 5 (6 Black), bet 28 pays -1'; +is payout( 5, 29 ), -1, 'Spin 5 (6 Black), bet 29 pays -1'; +is payout( 5, 30 ), -1, 'Spin 5 (6 Black), bet 30 pays -1'; +is payout( 5, 31 ), -1, 'Spin 5 (6 Black), bet 31 pays -1'; +is payout( 5, 32 ), -1, 'Spin 5 (6 Black), bet 32 pays -1'; +is payout( 5, 33 ), -1, 'Spin 5 (6 Black), bet 33 pays -1'; +is payout( 5, 34 ), -1, 'Spin 5 (6 Black), bet 34 pays -1'; +is payout( 5, 35 ), -1, 'Spin 5 (6 Black), bet 35 pays -1'; +is payout( 5, 36 ), -1, 'Spin 5 (6 Black), bet 36 pays -1'; +is payout( 5, 37 ), 2, 'Spin 5 (6 Black), bet 37 pays 2'; +is payout( 5, 38 ), -1, 'Spin 5 (6 Black), bet 38 pays -1'; +is payout( 5, 39 ), -1, 'Spin 5 (6 Black), bet 39 pays -1'; +is payout( 5, 40 ), -1, 'Spin 5 (6 Black), bet 40 pays -1'; +is payout( 5, 41 ), -1, 'Spin 5 (6 Black), bet 41 pays -1'; +is payout( 5, 42 ), 2, 'Spin 5 (6 Black), bet 42 pays 2'; +is payout( 5, 43 ), 1, 'Spin 5 (6 Black), bet 43 pays 1'; +is payout( 5, 44 ), -1, 'Spin 5 (6 Black), bet 44 pays -1'; +is payout( 5, 45 ), 1, 'Spin 5 (6 Black), bet 45 pays 1'; +is payout( 5, 46 ), -1, 'Spin 5 (6 Black), bet 46 pays -1'; +is payout( 5, 47 ), -1, 'Spin 5 (6 Black), bet 47 pays -1'; +is payout( 5, 48 ), 1, 'Spin 5 (6 Black), bet 48 pays 1'; +is payout( 5, 49 ), -1, 'Spin 5 (6 Black), bet 49 pays -1'; +is payout( 5, 50 ), -1, 'Spin 5 (6 Black), bet 50 pays -1'; +is format_spin( 6 ), '7 Red', 'Spin 6 is 7 Red'; +is payout( 6, 1 ), -1, 'Spin 6 (7 Red), bet 1 pays -1'; +is payout( 6, 2 ), -1, 'Spin 6 (7 Red), bet 2 pays -1'; +is payout( 6, 3 ), -1, 'Spin 6 (7 Red), bet 3 pays -1'; +is payout( 6, 4 ), -1, 'Spin 6 (7 Red), bet 4 pays -1'; +is payout( 6, 5 ), -1, 'Spin 6 (7 Red), bet 5 pays -1'; +is payout( 6, 6 ), -1, 'Spin 6 (7 Red), bet 6 pays -1'; +is payout( 6, 7 ), 35, 'Spin 6 (7 Red), bet 7 pays 35'; +is payout( 6, 8 ), -1, 'Spin 6 (7 Red), bet 8 pays -1'; +is payout( 6, 9 ), -1, 'Spin 6 (7 Red), bet 9 pays -1'; +is payout( 6, 10 ), -1, 'Spin 6 (7 Red), bet 10 pays -1'; +is payout( 6, 11 ), -1, 'Spin 6 (7 Red), bet 11 pays -1'; +is payout( 6, 12 ), -1, 'Spin 6 (7 Red), bet 12 pays -1'; +is payout( 6, 13 ), -1, 'Spin 6 (7 Red), bet 13 pays -1'; +is payout( 6, 14 ), -1, 'Spin 6 (7 Red), bet 14 pays -1'; +is payout( 6, 15 ), -1, 'Spin 6 (7 Red), bet 15 pays -1'; +is payout( 6, 16 ), -1, 'Spin 6 (7 Red), bet 16 pays -1'; +is payout( 6, 17 ), -1, 'Spin 6 (7 Red), bet 17 pays -1'; +is payout( 6, 18 ), -1, 'Spin 6 (7 Red), bet 18 pays -1'; +is payout( 6, 19 ), -1, 'Spin 6 (7 Red), bet 19 pays -1'; +is payout( 6, 20 ), -1, 'Spin 6 (7 Red), bet 20 pays -1'; +is payout( 6, 21 ), -1, 'Spin 6 (7 Red), bet 21 pays -1'; +is payout( 6, 22 ), -1, 'Spin 6 (7 Red), bet 22 pays -1'; +is payout( 6, 23 ), -1, 'Spin 6 (7 Red), bet 23 pays -1'; +is payout( 6, 24 ), -1, 'Spin 6 (7 Red), bet 24 pays -1'; +is payout( 6, 25 ), -1, 'Spin 6 (7 Red), bet 25 pays -1'; +is payout( 6, 26 ), -1, 'Spin 6 (7 Red), bet 26 pays -1'; +is payout( 6, 27 ), -1, 'Spin 6 (7 Red), bet 27 pays -1'; +is payout( 6, 28 ), -1, 'Spin 6 (7 Red), bet 28 pays -1'; +is payout( 6, 29 ), -1, 'Spin 6 (7 Red), bet 29 pays -1'; +is payout( 6, 30 ), -1, 'Spin 6 (7 Red), bet 30 pays -1'; +is payout( 6, 31 ), -1, 'Spin 6 (7 Red), bet 31 pays -1'; +is payout( 6, 32 ), -1, 'Spin 6 (7 Red), bet 32 pays -1'; +is payout( 6, 33 ), -1, 'Spin 6 (7 Red), bet 33 pays -1'; +is payout( 6, 34 ), -1, 'Spin 6 (7 Red), bet 34 pays -1'; +is payout( 6, 35 ), -1, 'Spin 6 (7 Red), bet 35 pays -1'; +is payout( 6, 36 ), -1, 'Spin 6 (7 Red), bet 36 pays -1'; +is payout( 6, 37 ), 2, 'Spin 6 (7 Red), bet 37 pays 2'; +is payout( 6, 38 ), -1, 'Spin 6 (7 Red), bet 38 pays -1'; +is payout( 6, 39 ), -1, 'Spin 6 (7 Red), bet 39 pays -1'; +is payout( 6, 40 ), 2, 'Spin 6 (7 Red), bet 40 pays 2'; +is payout( 6, 41 ), -1, 'Spin 6 (7 Red), bet 41 pays -1'; +is payout( 6, 42 ), -1, 'Spin 6 (7 Red), bet 42 pays -1'; +is payout( 6, 43 ), 1, 'Spin 6 (7 Red), bet 43 pays 1'; +is payout( 6, 44 ), -1, 'Spin 6 (7 Red), bet 44 pays -1'; +is payout( 6, 45 ), -1, 'Spin 6 (7 Red), bet 45 pays -1'; +is payout( 6, 46 ), 1, 'Spin 6 (7 Red), bet 46 pays 1'; +is payout( 6, 47 ), 1, 'Spin 6 (7 Red), bet 47 pays 1'; +is payout( 6, 48 ), -1, 'Spin 6 (7 Red), bet 48 pays -1'; +is payout( 6, 49 ), -1, 'Spin 6 (7 Red), bet 49 pays -1'; +is payout( 6, 50 ), -1, 'Spin 6 (7 Red), bet 50 pays -1'; +is format_spin( 7 ), '8 Black', 'Spin 7 is 8 Black'; +is payout( 7, 1 ), -1, 'Spin 7 (8 Black), bet 1 pays -1'; +is payout( 7, 2 ), -1, 'Spin 7 (8 Black), bet 2 pays -1'; +is payout( 7, 3 ), -1, 'Spin 7 (8 Black), bet 3 pays -1'; +is payout( 7, 4 ), -1, 'Spin 7 (8 Black), bet 4 pays -1'; +is payout( 7, 5 ), -1, 'Spin 7 (8 Black), bet 5 pays -1'; +is payout( 7, 6 ), -1, 'Spin 7 (8 Black), bet 6 pays -1'; +is payout( 7, 7 ), -1, 'Spin 7 (8 Black), bet 7 pays -1'; +is payout( 7, 8 ), 35, 'Spin 7 (8 Black), bet 8 pays 35'; +is payout( 7, 9 ), -1, 'Spin 7 (8 Black), bet 9 pays -1'; +is payout( 7, 10 ), -1, 'Spin 7 (8 Black), bet 10 pays -1'; +is payout( 7, 11 ), -1, 'Spin 7 (8 Black), bet 11 pays -1'; +is payout( 7, 12 ), -1, 'Spin 7 (8 Black), bet 12 pays -1'; +is payout( 7, 13 ), -1, 'Spin 7 (8 Black), bet 13 pays -1'; +is payout( 7, 14 ), -1, 'Spin 7 (8 Black), bet 14 pays -1'; +is payout( 7, 15 ), -1, 'Spin 7 (8 Black), bet 15 pays -1'; +is payout( 7, 16 ), -1, 'Spin 7 (8 Black), bet 16 pays -1'; +is payout( 7, 17 ), -1, 'Spin 7 (8 Black), bet 17 pays -1'; +is payout( 7, 18 ), -1, 'Spin 7 (8 Black), bet 18 pays -1'; +is payout( 7, 19 ), -1, 'Spin 7 (8 Black), bet 19 pays -1'; +is payout( 7, 20 ), -1, 'Spin 7 (8 Black), bet 20 pays -1'; +is payout( 7, 21 ), -1, 'Spin 7 (8 Black), bet 21 pays -1'; +is payout( 7, 22 ), -1, 'Spin 7 (8 Black), bet 22 pays -1'; +is payout( 7, 23 ), -1, 'Spin 7 (8 Black), bet 23 pays -1'; +is payout( 7, 24 ), -1, 'Spin 7 (8 Black), bet 24 pays -1'; +is payout( 7, 25 ), -1, 'Spin 7 (8 Black), bet 25 pays -1'; +is payout( 7, 26 ), -1, 'Spin 7 (8 Black), bet 26 pays -1'; +is payout( 7, 27 ), -1, 'Spin 7 (8 Black), bet 27 pays -1'; +is payout( 7, 28 ), -1, 'Spin 7 (8 Black), bet 28 pays -1'; +is payout( 7, 29 ), -1, 'Spin 7 (8 Black), bet 29 pays -1'; +is payout( 7, 30 ), -1, 'Spin 7 (8 Black), bet 30 pays -1'; +is payout( 7, 31 ), -1, 'Spin 7 (8 Black), bet 31 pays -1'; +is payout( 7, 32 ), -1, 'Spin 7 (8 Black), bet 32 pays -1'; +is payout( 7, 33 ), -1, 'Spin 7 (8 Black), bet 33 pays -1'; +is payout( 7, 34 ), -1, 'Spin 7 (8 Black), bet 34 pays -1'; +is payout( 7, 35 ), -1, 'Spin 7 (8 Black), bet 35 pays -1'; +is payout( 7, 36 ), -1, 'Spin 7 (8 Black), bet 36 pays -1'; +is payout( 7, 37 ), 2, 'Spin 7 (8 Black), bet 37 pays 2'; +is payout( 7, 38 ), -1, 'Spin 7 (8 Black), bet 38 pays -1'; +is payout( 7, 39 ), -1, 'Spin 7 (8 Black), bet 39 pays -1'; +is payout( 7, 40 ), -1, 'Spin 7 (8 Black), bet 40 pays -1'; +is payout( 7, 41 ), 2, 'Spin 7 (8 Black), bet 41 pays 2'; +is payout( 7, 42 ), -1, 'Spin 7 (8 Black), bet 42 pays -1'; +is payout( 7, 43 ), 1, 'Spin 7 (8 Black), bet 43 pays 1'; +is payout( 7, 44 ), -1, 'Spin 7 (8 Black), bet 44 pays -1'; +is payout( 7, 45 ), 1, 'Spin 7 (8 Black), bet 45 pays 1'; +is payout( 7, 46 ), -1, 'Spin 7 (8 Black), bet 46 pays -1'; +is payout( 7, 47 ), -1, 'Spin 7 (8 Black), bet 47 pays -1'; +is payout( 7, 48 ), 1, 'Spin 7 (8 Black), bet 48 pays 1'; +is payout( 7, 49 ), -1, 'Spin 7 (8 Black), bet 49 pays -1'; +is payout( 7, 50 ), -1, 'Spin 7 (8 Black), bet 50 pays -1'; +is format_spin( 8 ), '9 Red', 'Spin 8 is 9 Red'; +is payout( 8, 1 ), -1, 'Spin 8 (9 Red), bet 1 pays -1'; +is payout( 8, 2 ), -1, 'Spin 8 (9 Red), bet 2 pays -1'; +is payout( 8, 3 ), -1, 'Spin 8 (9 Red), bet 3 pays -1'; +is payout( 8, 4 ), -1, 'Spin 8 (9 Red), bet 4 pays -1'; +is payout( 8, 5 ), -1, 'Spin 8 (9 Red), bet 5 pays -1'; +is payout( 8, 6 ), -1, 'Spin 8 (9 Red), bet 6 pays -1'; +is payout( 8, 7 ), -1, 'Spin 8 (9 Red), bet 7 pays -1'; +is payout( 8, 8 ), -1, 'Spin 8 (9 Red), bet 8 pays -1'; +is payout( 8, 9 ), 35, 'Spin 8 (9 Red), bet 9 pays 35'; +is payout( 8, 10 ), -1, 'Spin 8 (9 Red), bet 10 pays -1'; +is payout( 8, 11 ), -1, 'Spin 8 (9 Red), bet 11 pays -1'; +is payout( 8, 12 ), -1, 'Spin 8 (9 Red), bet 12 pays -1'; +is payout( 8, 13 ), -1, 'Spin 8 (9 Red), bet 13 pays -1'; +is payout( 8, 14 ), -1, 'Spin 8 (9 Red), bet 14 pays -1'; +is payout( 8, 15 ), -1, 'Spin 8 (9 Red), bet 15 pays -1'; +is payout( 8, 16 ), -1, 'Spin 8 (9 Red), bet 16 pays -1'; +is payout( 8, 17 ), -1, 'Spin 8 (9 Red), bet 17 pays -1'; +is payout( 8, 18 ), -1, 'Spin 8 (9 Red), bet 18 pays -1'; +is payout( 8, 19 ), -1, 'Spin 8 (9 Red), bet 19 pays -1'; +is payout( 8, 20 ), -1, 'Spin 8 (9 Red), bet 20 pays -1'; +is payout( 8, 21 ), -1, 'Spin 8 (9 Red), bet 21 pays -1'; +is payout( 8, 22 ), -1, 'Spin 8 (9 Red), bet 22 pays -1'; +is payout( 8, 23 ), -1, 'Spin 8 (9 Red), bet 23 pays -1'; +is payout( 8, 24 ), -1, 'Spin 8 (9 Red), bet 24 pays -1'; +is payout( 8, 25 ), -1, 'Spin 8 (9 Red), bet 25 pays -1'; +is payout( 8, 26 ), -1, 'Spin 8 (9 Red), bet 26 pays -1'; +is payout( 8, 27 ), -1, 'Spin 8 (9 Red), bet 27 pays -1'; +is payout( 8, 28 ), -1, 'Spin 8 (9 Red), bet 28 pays -1'; +is payout( 8, 29 ), -1, 'Spin 8 (9 Red), bet 29 pays -1'; +is payout( 8, 30 ), -1, 'Spin 8 (9 Red), bet 30 pays -1'; +is payout( 8, 31 ), -1, 'Spin 8 (9 Red), bet 31 pays -1'; +is payout( 8, 32 ), -1, 'Spin 8 (9 Red), bet 32 pays -1'; +is payout( 8, 33 ), -1, 'Spin 8 (9 Red), bet 33 pays -1'; +is payout( 8, 34 ), -1, 'Spin 8 (9 Red), bet 34 pays -1'; +is payout( 8, 35 ), -1, 'Spin 8 (9 Red), bet 35 pays -1'; +is payout( 8, 36 ), -1, 'Spin 8 (9 Red), bet 36 pays -1'; +is payout( 8, 37 ), 2, 'Spin 8 (9 Red), bet 37 pays 2'; +is payout( 8, 38 ), -1, 'Spin 8 (9 Red), bet 38 pays -1'; +is payout( 8, 39 ), -1, 'Spin 8 (9 Red), bet 39 pays -1'; +is payout( 8, 40 ), -1, 'Spin 8 (9 Red), bet 40 pays -1'; +is payout( 8, 41 ), -1, 'Spin 8 (9 Red), bet 41 pays -1'; +is payout( 8, 42 ), 2, 'Spin 8 (9 Red), bet 42 pays 2'; +is payout( 8, 43 ), 1, 'Spin 8 (9 Red), bet 43 pays 1'; +is payout( 8, 44 ), -1, 'Spin 8 (9 Red), bet 44 pays -1'; +is payout( 8, 45 ), -1, 'Spin 8 (9 Red), bet 45 pays -1'; +is payout( 8, 46 ), 1, 'Spin 8 (9 Red), bet 46 pays 1'; +is payout( 8, 47 ), 1, 'Spin 8 (9 Red), bet 47 pays 1'; +is payout( 8, 48 ), -1, 'Spin 8 (9 Red), bet 48 pays -1'; +is payout( 8, 49 ), -1, 'Spin 8 (9 Red), bet 49 pays -1'; +is payout( 8, 50 ), -1, 'Spin 8 (9 Red), bet 50 pays -1'; +is format_spin( 9 ), '10 Black', 'Spin 9 is 10 Black'; +is payout( 9, 1 ), -1, 'Spin 9 (10 Black), bet 1 pays -1'; +is payout( 9, 2 ), -1, 'Spin 9 (10 Black), bet 2 pays -1'; +is payout( 9, 3 ), -1, 'Spin 9 (10 Black), bet 3 pays -1'; +is payout( 9, 4 ), -1, 'Spin 9 (10 Black), bet 4 pays -1'; +is payout( 9, 5 ), -1, 'Spin 9 (10 Black), bet 5 pays -1'; +is payout( 9, 6 ), -1, 'Spin 9 (10 Black), bet 6 pays -1'; +is payout( 9, 7 ), -1, 'Spin 9 (10 Black), bet 7 pays -1'; +is payout( 9, 8 ), -1, 'Spin 9 (10 Black), bet 8 pays -1'; +is payout( 9, 9 ), -1, 'Spin 9 (10 Black), bet 9 pays -1'; +is payout( 9, 10 ), 35, 'Spin 9 (10 Black), bet 10 pays 35'; +is payout( 9, 11 ), -1, 'Spin 9 (10 Black), bet 11 pays -1'; +is payout( 9, 12 ), -1, 'Spin 9 (10 Black), bet 12 pays -1'; +is payout( 9, 13 ), -1, 'Spin 9 (10 Black), bet 13 pays -1'; +is payout( 9, 14 ), -1, 'Spin 9 (10 Black), bet 14 pays -1'; +is payout( 9, 15 ), -1, 'Spin 9 (10 Black), bet 15 pays -1'; +is payout( 9, 16 ), -1, 'Spin 9 (10 Black), bet 16 pays -1'; +is payout( 9, 17 ), -1, 'Spin 9 (10 Black), bet 17 pays -1'; +is payout( 9, 18 ), -1, 'Spin 9 (10 Black), bet 18 pays -1'; +is payout( 9, 19 ), -1, 'Spin 9 (10 Black), bet 19 pays -1'; +is payout( 9, 20 ), -1, 'Spin 9 (10 Black), bet 20 pays -1'; +is payout( 9, 21 ), -1, 'Spin 9 (10 Black), bet 21 pays -1'; +is payout( 9, 22 ), -1, 'Spin 9 (10 Black), bet 22 pays -1'; +is payout( 9, 23 ), -1, 'Spin 9 (10 Black), bet 23 pays -1'; +is payout( 9, 24 ), -1, 'Spin 9 (10 Black), bet 24 pays -1'; +is payout( 9, 25 ), -1, 'Spin 9 (10 Black), bet 25 pays -1'; +is payout( 9, 26 ), -1, 'Spin 9 (10 Black), bet 26 pays -1'; +is payout( 9, 27 ), -1, 'Spin 9 (10 Black), bet 27 pays -1'; +is payout( 9, 28 ), -1, 'Spin 9 (10 Black), bet 28 pays -1'; +is payout( 9, 29 ), -1, 'Spin 9 (10 Black), bet 29 pays -1'; +is payout( 9, 30 ), -1, 'Spin 9 (10 Black), bet 30 pays -1'; +is payout( 9, 31 ), -1, 'Spin 9 (10 Black), bet 31 pays -1'; +is payout( 9, 32 ), -1, 'Spin 9 (10 Black), bet 32 pays -1'; +is payout( 9, 33 ), -1, 'Spin 9 (10 Black), bet 33 pays -1'; +is payout( 9, 34 ), -1, 'Spin 9 (10 Black), bet 34 pays -1'; +is payout( 9, 35 ), -1, 'Spin 9 (10 Black), bet 35 pays -1'; +is payout( 9, 36 ), -1, 'Spin 9 (10 Black), bet 36 pays -1'; +is payout( 9, 37 ), 2, 'Spin 9 (10 Black), bet 37 pays 2'; +is payout( 9, 38 ), -1, 'Spin 9 (10 Black), bet 38 pays -1'; +is payout( 9, 39 ), -1, 'Spin 9 (10 Black), bet 39 pays -1'; +is payout( 9, 40 ), 2, 'Spin 9 (10 Black), bet 40 pays 2'; +is payout( 9, 41 ), -1, 'Spin 9 (10 Black), bet 41 pays -1'; +is payout( 9, 42 ), -1, 'Spin 9 (10 Black), bet 42 pays -1'; +is payout( 9, 43 ), 1, 'Spin 9 (10 Black), bet 43 pays 1'; +is payout( 9, 44 ), -1, 'Spin 9 (10 Black), bet 44 pays -1'; +is payout( 9, 45 ), 1, 'Spin 9 (10 Black), bet 45 pays 1'; +is payout( 9, 46 ), -1, 'Spin 9 (10 Black), bet 46 pays -1'; +is payout( 9, 47 ), -1, 'Spin 9 (10 Black), bet 47 pays -1'; +is payout( 9, 48 ), 1, 'Spin 9 (10 Black), bet 48 pays 1'; +is payout( 9, 49 ), -1, 'Spin 9 (10 Black), bet 49 pays -1'; +is payout( 9, 50 ), -1, 'Spin 9 (10 Black), bet 50 pays -1'; +is format_spin( 10 ), '11 Black', 'Spin 10 is 11 Black'; +is payout( 10, 1 ), -1, 'Spin 10 (11 Black), bet 1 pays -1'; +is payout( 10, 2 ), -1, 'Spin 10 (11 Black), bet 2 pays -1'; +is payout( 10, 3 ), -1, 'Spin 10 (11 Black), bet 3 pays -1'; +is payout( 10, 4 ), -1, 'Spin 10 (11 Black), bet 4 pays -1'; +is payout( 10, 5 ), -1, 'Spin 10 (11 Black), bet 5 pays -1'; +is payout( 10, 6 ), -1, 'Spin 10 (11 Black), bet 6 pays -1'; +is payout( 10, 7 ), -1, 'Spin 10 (11 Black), bet 7 pays -1'; +is payout( 10, 8 ), -1, 'Spin 10 (11 Black), bet 8 pays -1'; +is payout( 10, 9 ), -1, 'Spin 10 (11 Black), bet 9 pays -1'; +is payout( 10, 10 ), -1, 'Spin 10 (11 Black), bet 10 pays -1'; +is payout( 10, 11 ), 35, 'Spin 10 (11 Black), bet 11 pays 35'; +is payout( 10, 12 ), -1, 'Spin 10 (11 Black), bet 12 pays -1'; +is payout( 10, 13 ), -1, 'Spin 10 (11 Black), bet 13 pays -1'; +is payout( 10, 14 ), -1, 'Spin 10 (11 Black), bet 14 pays -1'; +is payout( 10, 15 ), -1, 'Spin 10 (11 Black), bet 15 pays -1'; +is payout( 10, 16 ), -1, 'Spin 10 (11 Black), bet 16 pays -1'; +is payout( 10, 17 ), -1, 'Spin 10 (11 Black), bet 17 pays -1'; +is payout( 10, 18 ), -1, 'Spin 10 (11 Black), bet 18 pays -1'; +is payout( 10, 19 ), -1, 'Spin 10 (11 Black), bet 19 pays -1'; +is payout( 10, 20 ), -1, 'Spin 10 (11 Black), bet 20 pays -1'; +is payout( 10, 21 ), -1, 'Spin 10 (11 Black), bet 21 pays -1'; +is payout( 10, 22 ), -1, 'Spin 10 (11 Black), bet 22 pays -1'; +is payout( 10, 23 ), -1, 'Spin 10 (11 Black), bet 23 pays -1'; +is payout( 10, 24 ), -1, 'Spin 10 (11 Black), bet 24 pays -1'; +is payout( 10, 25 ), -1, 'Spin 10 (11 Black), bet 25 pays -1'; +is payout( 10, 26 ), -1, 'Spin 10 (11 Black), bet 26 pays -1'; +is payout( 10, 27 ), -1, 'Spin 10 (11 Black), bet 27 pays -1'; +is payout( 10, 28 ), -1, 'Spin 10 (11 Black), bet 28 pays -1'; +is payout( 10, 29 ), -1, 'Spin 10 (11 Black), bet 29 pays -1'; +is payout( 10, 30 ), -1, 'Spin 10 (11 Black), bet 30 pays -1'; +is payout( 10, 31 ), -1, 'Spin 10 (11 Black), bet 31 pays -1'; +is payout( 10, 32 ), -1, 'Spin 10 (11 Black), bet 32 pays -1'; +is payout( 10, 33 ), -1, 'Spin 10 (11 Black), bet 33 pays -1'; +is payout( 10, 34 ), -1, 'Spin 10 (11 Black), bet 34 pays -1'; +is payout( 10, 35 ), -1, 'Spin 10 (11 Black), bet 35 pays -1'; +is payout( 10, 36 ), -1, 'Spin 10 (11 Black), bet 36 pays -1'; +is payout( 10, 37 ), 2, 'Spin 10 (11 Black), bet 37 pays 2'; +is payout( 10, 38 ), -1, 'Spin 10 (11 Black), bet 38 pays -1'; +is payout( 10, 39 ), -1, 'Spin 10 (11 Black), bet 39 pays -1'; +is payout( 10, 40 ), -1, 'Spin 10 (11 Black), bet 40 pays -1'; +is payout( 10, 41 ), 2, 'Spin 10 (11 Black), bet 41 pays 2'; +is payout( 10, 42 ), -1, 'Spin 10 (11 Black), bet 42 pays -1'; +is payout( 10, 43 ), 1, 'Spin 10 (11 Black), bet 43 pays 1'; +is payout( 10, 44 ), -1, 'Spin 10 (11 Black), bet 44 pays -1'; +is payout( 10, 45 ), -1, 'Spin 10 (11 Black), bet 45 pays -1'; +is payout( 10, 46 ), 1, 'Spin 10 (11 Black), bet 46 pays 1'; +is payout( 10, 47 ), -1, 'Spin 10 (11 Black), bet 47 pays -1'; +is payout( 10, 48 ), 1, 'Spin 10 (11 Black), bet 48 pays 1'; +is payout( 10, 49 ), -1, 'Spin 10 (11 Black), bet 49 pays -1'; +is payout( 10, 50 ), -1, 'Spin 10 (11 Black), bet 50 pays -1'; +is format_spin( 11 ), '12 Red', 'Spin 11 is 12 Red'; +is payout( 11, 1 ), -1, 'Spin 11 (12 Red), bet 1 pays -1'; +is payout( 11, 2 ), -1, 'Spin 11 (12 Red), bet 2 pays -1'; +is payout( 11, 3 ), -1, 'Spin 11 (12 Red), bet 3 pays -1'; +is payout( 11, 4 ), -1, 'Spin 11 (12 Red), bet 4 pays -1'; +is payout( 11, 5 ), -1, 'Spin 11 (12 Red), bet 5 pays -1'; +is payout( 11, 6 ), -1, 'Spin 11 (12 Red), bet 6 pays -1'; +is payout( 11, 7 ), -1, 'Spin 11 (12 Red), bet 7 pays -1'; +is payout( 11, 8 ), -1, 'Spin 11 (12 Red), bet 8 pays -1'; +is payout( 11, 9 ), -1, 'Spin 11 (12 Red), bet 9 pays -1'; +is payout( 11, 10 ), -1, 'Spin 11 (12 Red), bet 10 pays -1'; +is payout( 11, 11 ), -1, 'Spin 11 (12 Red), bet 11 pays -1'; +is payout( 11, 12 ), 35, 'Spin 11 (12 Red), bet 12 pays 35'; +is payout( 11, 13 ), -1, 'Spin 11 (12 Red), bet 13 pays -1'; +is payout( 11, 14 ), -1, 'Spin 11 (12 Red), bet 14 pays -1'; +is payout( 11, 15 ), -1, 'Spin 11 (12 Red), bet 15 pays -1'; +is payout( 11, 16 ), -1, 'Spin 11 (12 Red), bet 16 pays -1'; +is payout( 11, 17 ), -1, 'Spin 11 (12 Red), bet 17 pays -1'; +is payout( 11, 18 ), -1, 'Spin 11 (12 Red), bet 18 pays -1'; +is payout( 11, 19 ), -1, 'Spin 11 (12 Red), bet 19 pays -1'; +is payout( 11, 20 ), -1, 'Spin 11 (12 Red), bet 20 pays -1'; +is payout( 11, 21 ), -1, 'Spin 11 (12 Red), bet 21 pays -1'; +is payout( 11, 22 ), -1, 'Spin 11 (12 Red), bet 22 pays -1'; +is payout( 11, 23 ), -1, 'Spin 11 (12 Red), bet 23 pays -1'; +is payout( 11, 24 ), -1, 'Spin 11 (12 Red), bet 24 pays -1'; +is payout( 11, 25 ), -1, 'Spin 11 (12 Red), bet 25 pays -1'; +is payout( 11, 26 ), -1, 'Spin 11 (12 Red), bet 26 pays -1'; +is payout( 11, 27 ), -1, 'Spin 11 (12 Red), bet 27 pays -1'; +is payout( 11, 28 ), -1, 'Spin 11 (12 Red), bet 28 pays -1'; +is payout( 11, 29 ), -1, 'Spin 11 (12 Red), bet 29 pays -1'; +is payout( 11, 30 ), -1, 'Spin 11 (12 Red), bet 30 pays -1'; +is payout( 11, 31 ), -1, 'Spin 11 (12 Red), bet 31 pays -1'; +is payout( 11, 32 ), -1, 'Spin 11 (12 Red), bet 32 pays -1'; +is payout( 11, 33 ), -1, 'Spin 11 (12 Red), bet 33 pays -1'; +is payout( 11, 34 ), -1, 'Spin 11 (12 Red), bet 34 pays -1'; +is payout( 11, 35 ), -1, 'Spin 11 (12 Red), bet 35 pays -1'; +is payout( 11, 36 ), -1, 'Spin 11 (12 Red), bet 36 pays -1'; +is payout( 11, 37 ), 2, 'Spin 11 (12 Red), bet 37 pays 2'; +is payout( 11, 38 ), -1, 'Spin 11 (12 Red), bet 38 pays -1'; +is payout( 11, 39 ), -1, 'Spin 11 (12 Red), bet 39 pays -1'; +is payout( 11, 40 ), -1, 'Spin 11 (12 Red), bet 40 pays -1'; +is payout( 11, 41 ), -1, 'Spin 11 (12 Red), bet 41 pays -1'; +is payout( 11, 42 ), 2, 'Spin 11 (12 Red), bet 42 pays 2'; +is payout( 11, 43 ), 1, 'Spin 11 (12 Red), bet 43 pays 1'; +is payout( 11, 44 ), -1, 'Spin 11 (12 Red), bet 44 pays -1'; +is payout( 11, 45 ), 1, 'Spin 11 (12 Red), bet 45 pays 1'; +is payout( 11, 46 ), -1, 'Spin 11 (12 Red), bet 46 pays -1'; +is payout( 11, 47 ), 1, 'Spin 11 (12 Red), bet 47 pays 1'; +is payout( 11, 48 ), -1, 'Spin 11 (12 Red), bet 48 pays -1'; +is payout( 11, 49 ), -1, 'Spin 11 (12 Red), bet 49 pays -1'; +is payout( 11, 50 ), -1, 'Spin 11 (12 Red), bet 50 pays -1'; +is format_spin( 12 ), '13 Black', 'Spin 12 is 13 Black'; +is payout( 12, 1 ), -1, 'Spin 12 (13 Black), bet 1 pays -1'; +is payout( 12, 2 ), -1, 'Spin 12 (13 Black), bet 2 pays -1'; +is payout( 12, 3 ), -1, 'Spin 12 (13 Black), bet 3 pays -1'; +is payout( 12, 4 ), -1, 'Spin 12 (13 Black), bet 4 pays -1'; +is payout( 12, 5 ), -1, 'Spin 12 (13 Black), bet 5 pays -1'; +is payout( 12, 6 ), -1, 'Spin 12 (13 Black), bet 6 pays -1'; +is payout( 12, 7 ), -1, 'Spin 12 (13 Black), bet 7 pays -1'; +is payout( 12, 8 ), -1, 'Spin 12 (13 Black), bet 8 pays -1'; +is payout( 12, 9 ), -1, 'Spin 12 (13 Black), bet 9 pays -1'; +is payout( 12, 10 ), -1, 'Spin 12 (13 Black), bet 10 pays -1'; +is payout( 12, 11 ), -1, 'Spin 12 (13 Black), bet 11 pays -1'; +is payout( 12, 12 ), -1, 'Spin 12 (13 Black), bet 12 pays -1'; +is payout( 12, 13 ), 35, 'Spin 12 (13 Black), bet 13 pays 35'; +is payout( 12, 14 ), -1, 'Spin 12 (13 Black), bet 14 pays -1'; +is payout( 12, 15 ), -1, 'Spin 12 (13 Black), bet 15 pays -1'; +is payout( 12, 16 ), -1, 'Spin 12 (13 Black), bet 16 pays -1'; +is payout( 12, 17 ), -1, 'Spin 12 (13 Black), bet 17 pays -1'; +is payout( 12, 18 ), -1, 'Spin 12 (13 Black), bet 18 pays -1'; +is payout( 12, 19 ), -1, 'Spin 12 (13 Black), bet 19 pays -1'; +is payout( 12, 20 ), -1, 'Spin 12 (13 Black), bet 20 pays -1'; +is payout( 12, 21 ), -1, 'Spin 12 (13 Black), bet 21 pays -1'; +is payout( 12, 22 ), -1, 'Spin 12 (13 Black), bet 22 pays -1'; +is payout( 12, 23 ), -1, 'Spin 12 (13 Black), bet 23 pays -1'; +is payout( 12, 24 ), -1, 'Spin 12 (13 Black), bet 24 pays -1'; +is payout( 12, 25 ), -1, 'Spin 12 (13 Black), bet 25 pays -1'; +is payout( 12, 26 ), -1, 'Spin 12 (13 Black), bet 26 pays -1'; +is payout( 12, 27 ), -1, 'Spin 12 (13 Black), bet 27 pays -1'; +is payout( 12, 28 ), -1, 'Spin 12 (13 Black), bet 28 pays -1'; +is payout( 12, 29 ), -1, 'Spin 12 (13 Black), bet 29 pays -1'; +is payout( 12, 30 ), -1, 'Spin 12 (13 Black), bet 30 pays -1'; +is payout( 12, 31 ), -1, 'Spin 12 (13 Black), bet 31 pays -1'; +is payout( 12, 32 ), -1, 'Spin 12 (13 Black), bet 32 pays -1'; +is payout( 12, 33 ), -1, 'Spin 12 (13 Black), bet 33 pays -1'; +is payout( 12, 34 ), -1, 'Spin 12 (13 Black), bet 34 pays -1'; +is payout( 12, 35 ), -1, 'Spin 12 (13 Black), bet 35 pays -1'; +is payout( 12, 36 ), -1, 'Spin 12 (13 Black), bet 36 pays -1'; +is payout( 12, 37 ), -1, 'Spin 12 (13 Black), bet 37 pays -1'; +is payout( 12, 38 ), 2, 'Spin 12 (13 Black), bet 38 pays 2'; +is payout( 12, 39 ), -1, 'Spin 12 (13 Black), bet 39 pays -1'; +is payout( 12, 40 ), 2, 'Spin 12 (13 Black), bet 40 pays 2'; +is payout( 12, 41 ), -1, 'Spin 12 (13 Black), bet 41 pays -1'; +is payout( 12, 42 ), -1, 'Spin 12 (13 Black), bet 42 pays -1'; +is payout( 12, 43 ), 1, 'Spin 12 (13 Black), bet 43 pays 1'; +is payout( 12, 44 ), -1, 'Spin 12 (13 Black), bet 44 pays -1'; +is payout( 12, 45 ), -1, 'Spin 12 (13 Black), bet 45 pays -1'; +is payout( 12, 46 ), 1, 'Spin 12 (13 Black), bet 46 pays 1'; +is payout( 12, 47 ), -1, 'Spin 12 (13 Black), bet 47 pays -1'; +is payout( 12, 48 ), 1, 'Spin 12 (13 Black), bet 48 pays 1'; +is payout( 12, 49 ), -1, 'Spin 12 (13 Black), bet 49 pays -1'; +is payout( 12, 50 ), -1, 'Spin 12 (13 Black), bet 50 pays -1'; +is format_spin( 13 ), '14 Red', 'Spin 13 is 14 Red'; +is payout( 13, 1 ), -1, 'Spin 13 (14 Red), bet 1 pays -1'; +is payout( 13, 2 ), -1, 'Spin 13 (14 Red), bet 2 pays -1'; +is payout( 13, 3 ), -1, 'Spin 13 (14 Red), bet 3 pays -1'; +is payout( 13, 4 ), -1, 'Spin 13 (14 Red), bet 4 pays -1'; +is payout( 13, 5 ), -1, 'Spin 13 (14 Red), bet 5 pays -1'; +is payout( 13, 6 ), -1, 'Spin 13 (14 Red), bet 6 pays -1'; +is payout( 13, 7 ), -1, 'Spin 13 (14 Red), bet 7 pays -1'; +is payout( 13, 8 ), -1, 'Spin 13 (14 Red), bet 8 pays -1'; +is payout( 13, 9 ), -1, 'Spin 13 (14 Red), bet 9 pays -1'; +is payout( 13, 10 ), -1, 'Spin 13 (14 Red), bet 10 pays -1'; +is payout( 13, 11 ), -1, 'Spin 13 (14 Red), bet 11 pays -1'; +is payout( 13, 12 ), -1, 'Spin 13 (14 Red), bet 12 pays -1'; +is payout( 13, 13 ), -1, 'Spin 13 (14 Red), bet 13 pays -1'; +is payout( 13, 14 ), 35, 'Spin 13 (14 Red), bet 14 pays 35'; +is payout( 13, 15 ), -1, 'Spin 13 (14 Red), bet 15 pays -1'; +is payout( 13, 16 ), -1, 'Spin 13 (14 Red), bet 16 pays -1'; +is payout( 13, 17 ), -1, 'Spin 13 (14 Red), bet 17 pays -1'; +is payout( 13, 18 ), -1, 'Spin 13 (14 Red), bet 18 pays -1'; +is payout( 13, 19 ), -1, 'Spin 13 (14 Red), bet 19 pays -1'; +is payout( 13, 20 ), -1, 'Spin 13 (14 Red), bet 20 pays -1'; +is payout( 13, 21 ), -1, 'Spin 13 (14 Red), bet 21 pays -1'; +is payout( 13, 22 ), -1, 'Spin 13 (14 Red), bet 22 pays -1'; +is payout( 13, 23 ), -1, 'Spin 13 (14 Red), bet 23 pays -1'; +is payout( 13, 24 ), -1, 'Spin 13 (14 Red), bet 24 pays -1'; +is payout( 13, 25 ), -1, 'Spin 13 (14 Red), bet 25 pays -1'; +is payout( 13, 26 ), -1, 'Spin 13 (14 Red), bet 26 pays -1'; +is payout( 13, 27 ), -1, 'Spin 13 (14 Red), bet 27 pays -1'; +is payout( 13, 28 ), -1, 'Spin 13 (14 Red), bet 28 pays -1'; +is payout( 13, 29 ), -1, 'Spin 13 (14 Red), bet 29 pays -1'; +is payout( 13, 30 ), -1, 'Spin 13 (14 Red), bet 30 pays -1'; +is payout( 13, 31 ), -1, 'Spin 13 (14 Red), bet 31 pays -1'; +is payout( 13, 32 ), -1, 'Spin 13 (14 Red), bet 32 pays -1'; +is payout( 13, 33 ), -1, 'Spin 13 (14 Red), bet 33 pays -1'; +is payout( 13, 34 ), -1, 'Spin 13 (14 Red), bet 34 pays -1'; +is payout( 13, 35 ), -1, 'Spin 13 (14 Red), bet 35 pays -1'; +is payout( 13, 36 ), -1, 'Spin 13 (14 Red), bet 36 pays -1'; +is payout( 13, 37 ), -1, 'Spin 13 (14 Red), bet 37 pays -1'; +is payout( 13, 38 ), 2, 'Spin 13 (14 Red), bet 38 pays 2'; +is payout( 13, 39 ), -1, 'Spin 13 (14 Red), bet 39 pays -1'; +is payout( 13, 40 ), -1, 'Spin 13 (14 Red), bet 40 pays -1'; +is payout( 13, 41 ), 2, 'Spin 13 (14 Red), bet 41 pays 2'; +is payout( 13, 42 ), -1, 'Spin 13 (14 Red), bet 42 pays -1'; +is payout( 13, 43 ), 1, 'Spin 13 (14 Red), bet 43 pays 1'; +is payout( 13, 44 ), -1, 'Spin 13 (14 Red), bet 44 pays -1'; +is payout( 13, 45 ), 1, 'Spin 13 (14 Red), bet 45 pays 1'; +is payout( 13, 46 ), -1, 'Spin 13 (14 Red), bet 46 pays -1'; +is payout( 13, 47 ), 1, 'Spin 13 (14 Red), bet 47 pays 1'; +is payout( 13, 48 ), -1, 'Spin 13 (14 Red), bet 48 pays -1'; +is payout( 13, 49 ), -1, 'Spin 13 (14 Red), bet 49 pays -1'; +is payout( 13, 50 ), -1, 'Spin 13 (14 Red), bet 50 pays -1'; +is format_spin( 14 ), '15 Black', 'Spin 14 is 15 Black'; +is payout( 14, 1 ), -1, 'Spin 14 (15 Black), bet 1 pays -1'; +is payout( 14, 2 ), -1, 'Spin 14 (15 Black), bet 2 pays -1'; +is payout( 14, 3 ), -1, 'Spin 14 (15 Black), bet 3 pays -1'; +is payout( 14, 4 ), -1, 'Spin 14 (15 Black), bet 4 pays -1'; +is payout( 14, 5 ), -1, 'Spin 14 (15 Black), bet 5 pays -1'; +is payout( 14, 6 ), -1, 'Spin 14 (15 Black), bet 6 pays -1'; +is payout( 14, 7 ), -1, 'Spin 14 (15 Black), bet 7 pays -1'; +is payout( 14, 8 ), -1, 'Spin 14 (15 Black), bet 8 pays -1'; +is payout( 14, 9 ), -1, 'Spin 14 (15 Black), bet 9 pays -1'; +is payout( 14, 10 ), -1, 'Spin 14 (15 Black), bet 10 pays -1'; +is payout( 14, 11 ), -1, 'Spin 14 (15 Black), bet 11 pays -1'; +is payout( 14, 12 ), -1, 'Spin 14 (15 Black), bet 12 pays -1'; +is payout( 14, 13 ), -1, 'Spin 14 (15 Black), bet 13 pays -1'; +is payout( 14, 14 ), -1, 'Spin 14 (15 Black), bet 14 pays -1'; +is payout( 14, 15 ), 35, 'Spin 14 (15 Black), bet 15 pays 35'; +is payout( 14, 16 ), -1, 'Spin 14 (15 Black), bet 16 pays -1'; +is payout( 14, 17 ), -1, 'Spin 14 (15 Black), bet 17 pays -1'; +is payout( 14, 18 ), -1, 'Spin 14 (15 Black), bet 18 pays -1'; +is payout( 14, 19 ), -1, 'Spin 14 (15 Black), bet 19 pays -1'; +is payout( 14, 20 ), -1, 'Spin 14 (15 Black), bet 20 pays -1'; +is payout( 14, 21 ), -1, 'Spin 14 (15 Black), bet 21 pays -1'; +is payout( 14, 22 ), -1, 'Spin 14 (15 Black), bet 22 pays -1'; +is payout( 14, 23 ), -1, 'Spin 14 (15 Black), bet 23 pays -1'; +is payout( 14, 24 ), -1, 'Spin 14 (15 Black), bet 24 pays -1'; +is payout( 14, 25 ), -1, 'Spin 14 (15 Black), bet 25 pays -1'; +is payout( 14, 26 ), -1, 'Spin 14 (15 Black), bet 26 pays -1'; +is payout( 14, 27 ), -1, 'Spin 14 (15 Black), bet 27 pays -1'; +is payout( 14, 28 ), -1, 'Spin 14 (15 Black), bet 28 pays -1'; +is payout( 14, 29 ), -1, 'Spin 14 (15 Black), bet 29 pays -1'; +is payout( 14, 30 ), -1, 'Spin 14 (15 Black), bet 30 pays -1'; +is payout( 14, 31 ), -1, 'Spin 14 (15 Black), bet 31 pays -1'; +is payout( 14, 32 ), -1, 'Spin 14 (15 Black), bet 32 pays -1'; +is payout( 14, 33 ), -1, 'Spin 14 (15 Black), bet 33 pays -1'; +is payout( 14, 34 ), -1, 'Spin 14 (15 Black), bet 34 pays -1'; +is payout( 14, 35 ), -1, 'Spin 14 (15 Black), bet 35 pays -1'; +is payout( 14, 36 ), -1, 'Spin 14 (15 Black), bet 36 pays -1'; +is payout( 14, 37 ), -1, 'Spin 14 (15 Black), bet 37 pays -1'; +is payout( 14, 38 ), 2, 'Spin 14 (15 Black), bet 38 pays 2'; +is payout( 14, 39 ), -1, 'Spin 14 (15 Black), bet 39 pays -1'; +is payout( 14, 40 ), -1, 'Spin 14 (15 Black), bet 40 pays -1'; +is payout( 14, 41 ), -1, 'Spin 14 (15 Black), bet 41 pays -1'; +is payout( 14, 42 ), 2, 'Spin 14 (15 Black), bet 42 pays 2'; +is payout( 14, 43 ), 1, 'Spin 14 (15 Black), bet 43 pays 1'; +is payout( 14, 44 ), -1, 'Spin 14 (15 Black), bet 44 pays -1'; +is payout( 14, 45 ), -1, 'Spin 14 (15 Black), bet 45 pays -1'; +is payout( 14, 46 ), 1, 'Spin 14 (15 Black), bet 46 pays 1'; +is payout( 14, 47 ), -1, 'Spin 14 (15 Black), bet 47 pays -1'; +is payout( 14, 48 ), 1, 'Spin 14 (15 Black), bet 48 pays 1'; +is payout( 14, 49 ), -1, 'Spin 14 (15 Black), bet 49 pays -1'; +is payout( 14, 50 ), -1, 'Spin 14 (15 Black), bet 50 pays -1'; +is format_spin( 15 ), '16 Red', 'Spin 15 is 16 Red'; +is payout( 15, 1 ), -1, 'Spin 15 (16 Red), bet 1 pays -1'; +is payout( 15, 2 ), -1, 'Spin 15 (16 Red), bet 2 pays -1'; +is payout( 15, 3 ), -1, 'Spin 15 (16 Red), bet 3 pays -1'; +is payout( 15, 4 ), -1, 'Spin 15 (16 Red), bet 4 pays -1'; +is payout( 15, 5 ), -1, 'Spin 15 (16 Red), bet 5 pays -1'; +is payout( 15, 6 ), -1, 'Spin 15 (16 Red), bet 6 pays -1'; +is payout( 15, 7 ), -1, 'Spin 15 (16 Red), bet 7 pays -1'; +is payout( 15, 8 ), -1, 'Spin 15 (16 Red), bet 8 pays -1'; +is payout( 15, 9 ), -1, 'Spin 15 (16 Red), bet 9 pays -1'; +is payout( 15, 10 ), -1, 'Spin 15 (16 Red), bet 10 pays -1'; +is payout( 15, 11 ), -1, 'Spin 15 (16 Red), bet 11 pays -1'; +is payout( 15, 12 ), -1, 'Spin 15 (16 Red), bet 12 pays -1'; +is payout( 15, 13 ), -1, 'Spin 15 (16 Red), bet 13 pays -1'; +is payout( 15, 14 ), -1, 'Spin 15 (16 Red), bet 14 pays -1'; +is payout( 15, 15 ), -1, 'Spin 15 (16 Red), bet 15 pays -1'; +is payout( 15, 16 ), 35, 'Spin 15 (16 Red), bet 16 pays 35'; +is payout( 15, 17 ), -1, 'Spin 15 (16 Red), bet 17 pays -1'; +is payout( 15, 18 ), -1, 'Spin 15 (16 Red), bet 18 pays -1'; +is payout( 15, 19 ), -1, 'Spin 15 (16 Red), bet 19 pays -1'; +is payout( 15, 20 ), -1, 'Spin 15 (16 Red), bet 20 pays -1'; +is payout( 15, 21 ), -1, 'Spin 15 (16 Red), bet 21 pays -1'; +is payout( 15, 22 ), -1, 'Spin 15 (16 Red), bet 22 pays -1'; +is payout( 15, 23 ), -1, 'Spin 15 (16 Red), bet 23 pays -1'; +is payout( 15, 24 ), -1, 'Spin 15 (16 Red), bet 24 pays -1'; +is payout( 15, 25 ), -1, 'Spin 15 (16 Red), bet 25 pays -1'; +is payout( 15, 26 ), -1, 'Spin 15 (16 Red), bet 26 pays -1'; +is payout( 15, 27 ), -1, 'Spin 15 (16 Red), bet 27 pays -1'; +is payout( 15, 28 ), -1, 'Spin 15 (16 Red), bet 28 pays -1'; +is payout( 15, 29 ), -1, 'Spin 15 (16 Red), bet 29 pays -1'; +is payout( 15, 30 ), -1, 'Spin 15 (16 Red), bet 30 pays -1'; +is payout( 15, 31 ), -1, 'Spin 15 (16 Red), bet 31 pays -1'; +is payout( 15, 32 ), -1, 'Spin 15 (16 Red), bet 32 pays -1'; +is payout( 15, 33 ), -1, 'Spin 15 (16 Red), bet 33 pays -1'; +is payout( 15, 34 ), -1, 'Spin 15 (16 Red), bet 34 pays -1'; +is payout( 15, 35 ), -1, 'Spin 15 (16 Red), bet 35 pays -1'; +is payout( 15, 36 ), -1, 'Spin 15 (16 Red), bet 36 pays -1'; +is payout( 15, 37 ), -1, 'Spin 15 (16 Red), bet 37 pays -1'; +is payout( 15, 38 ), 2, 'Spin 15 (16 Red), bet 38 pays 2'; +is payout( 15, 39 ), -1, 'Spin 15 (16 Red), bet 39 pays -1'; +is payout( 15, 40 ), 2, 'Spin 15 (16 Red), bet 40 pays 2'; +is payout( 15, 41 ), -1, 'Spin 15 (16 Red), bet 41 pays -1'; +is payout( 15, 42 ), -1, 'Spin 15 (16 Red), bet 42 pays -1'; +is payout( 15, 43 ), 1, 'Spin 15 (16 Red), bet 43 pays 1'; +is payout( 15, 44 ), -1, 'Spin 15 (16 Red), bet 44 pays -1'; +is payout( 15, 45 ), 1, 'Spin 15 (16 Red), bet 45 pays 1'; +is payout( 15, 46 ), -1, 'Spin 15 (16 Red), bet 46 pays -1'; +is payout( 15, 47 ), 1, 'Spin 15 (16 Red), bet 47 pays 1'; +is payout( 15, 48 ), -1, 'Spin 15 (16 Red), bet 48 pays -1'; +is payout( 15, 49 ), -1, 'Spin 15 (16 Red), bet 49 pays -1'; +is payout( 15, 50 ), -1, 'Spin 15 (16 Red), bet 50 pays -1'; +is format_spin( 16 ), '17 Black', 'Spin 16 is 17 Black'; +is payout( 16, 1 ), -1, 'Spin 16 (17 Black), bet 1 pays -1'; +is payout( 16, 2 ), -1, 'Spin 16 (17 Black), bet 2 pays -1'; +is payout( 16, 3 ), -1, 'Spin 16 (17 Black), bet 3 pays -1'; +is payout( 16, 4 ), -1, 'Spin 16 (17 Black), bet 4 pays -1'; +is payout( 16, 5 ), -1, 'Spin 16 (17 Black), bet 5 pays -1'; +is payout( 16, 6 ), -1, 'Spin 16 (17 Black), bet 6 pays -1'; +is payout( 16, 7 ), -1, 'Spin 16 (17 Black), bet 7 pays -1'; +is payout( 16, 8 ), -1, 'Spin 16 (17 Black), bet 8 pays -1'; +is payout( 16, 9 ), -1, 'Spin 16 (17 Black), bet 9 pays -1'; +is payout( 16, 10 ), -1, 'Spin 16 (17 Black), bet 10 pays -1'; +is payout( 16, 11 ), -1, 'Spin 16 (17 Black), bet 11 pays -1'; +is payout( 16, 12 ), -1, 'Spin 16 (17 Black), bet 12 pays -1'; +is payout( 16, 13 ), -1, 'Spin 16 (17 Black), bet 13 pays -1'; +is payout( 16, 14 ), -1, 'Spin 16 (17 Black), bet 14 pays -1'; +is payout( 16, 15 ), -1, 'Spin 16 (17 Black), bet 15 pays -1'; +is payout( 16, 16 ), -1, 'Spin 16 (17 Black), bet 16 pays -1'; +is payout( 16, 17 ), 35, 'Spin 16 (17 Black), bet 17 pays 35'; +is payout( 16, 18 ), -1, 'Spin 16 (17 Black), bet 18 pays -1'; +is payout( 16, 19 ), -1, 'Spin 16 (17 Black), bet 19 pays -1'; +is payout( 16, 20 ), -1, 'Spin 16 (17 Black), bet 20 pays -1'; +is payout( 16, 21 ), -1, 'Spin 16 (17 Black), bet 21 pays -1'; +is payout( 16, 22 ), -1, 'Spin 16 (17 Black), bet 22 pays -1'; +is payout( 16, 23 ), -1, 'Spin 16 (17 Black), bet 23 pays -1'; +is payout( 16, 24 ), -1, 'Spin 16 (17 Black), bet 24 pays -1'; +is payout( 16, 25 ), -1, 'Spin 16 (17 Black), bet 25 pays -1'; +is payout( 16, 26 ), -1, 'Spin 16 (17 Black), bet 26 pays -1'; +is payout( 16, 27 ), -1, 'Spin 16 (17 Black), bet 27 pays -1'; +is payout( 16, 28 ), -1, 'Spin 16 (17 Black), bet 28 pays -1'; +is payout( 16, 29 ), -1, 'Spin 16 (17 Black), bet 29 pays -1'; +is payout( 16, 30 ), -1, 'Spin 16 (17 Black), bet 30 pays -1'; +is payout( 16, 31 ), -1, 'Spin 16 (17 Black), bet 31 pays -1'; +is payout( 16, 32 ), -1, 'Spin 16 (17 Black), bet 32 pays -1'; +is payout( 16, 33 ), -1, 'Spin 16 (17 Black), bet 33 pays -1'; +is payout( 16, 34 ), -1, 'Spin 16 (17 Black), bet 34 pays -1'; +is payout( 16, 35 ), -1, 'Spin 16 (17 Black), bet 35 pays -1'; +is payout( 16, 36 ), -1, 'Spin 16 (17 Black), bet 36 pays -1'; +is payout( 16, 37 ), -1, 'Spin 16 (17 Black), bet 37 pays -1'; +is payout( 16, 38 ), 2, 'Spin 16 (17 Black), bet 38 pays 2'; +is payout( 16, 39 ), -1, 'Spin 16 (17 Black), bet 39 pays -1'; +is payout( 16, 40 ), -1, 'Spin 16 (17 Black), bet 40 pays -1'; +is payout( 16, 41 ), 2, 'Spin 16 (17 Black), bet 41 pays 2'; +is payout( 16, 42 ), -1, 'Spin 16 (17 Black), bet 42 pays -1'; +is payout( 16, 43 ), 1, 'Spin 16 (17 Black), bet 43 pays 1'; +is payout( 16, 44 ), -1, 'Spin 16 (17 Black), bet 44 pays -1'; +is payout( 16, 45 ), -1, 'Spin 16 (17 Black), bet 45 pays -1'; +is payout( 16, 46 ), 1, 'Spin 16 (17 Black), bet 46 pays 1'; +is payout( 16, 47 ), -1, 'Spin 16 (17 Black), bet 47 pays -1'; +is payout( 16, 48 ), 1, 'Spin 16 (17 Black), bet 48 pays 1'; +is payout( 16, 49 ), -1, 'Spin 16 (17 Black), bet 49 pays -1'; +is payout( 16, 50 ), -1, 'Spin 16 (17 Black), bet 50 pays -1'; +is format_spin( 17 ), '18 Red', 'Spin 17 is 18 Red'; +is payout( 17, 1 ), -1, 'Spin 17 (18 Red), bet 1 pays -1'; +is payout( 17, 2 ), -1, 'Spin 17 (18 Red), bet 2 pays -1'; +is payout( 17, 3 ), -1, 'Spin 17 (18 Red), bet 3 pays -1'; +is payout( 17, 4 ), -1, 'Spin 17 (18 Red), bet 4 pays -1'; +is payout( 17, 5 ), -1, 'Spin 17 (18 Red), bet 5 pays -1'; +is payout( 17, 6 ), -1, 'Spin 17 (18 Red), bet 6 pays -1'; +is payout( 17, 7 ), -1, 'Spin 17 (18 Red), bet 7 pays -1'; +is payout( 17, 8 ), -1, 'Spin 17 (18 Red), bet 8 pays -1'; +is payout( 17, 9 ), -1, 'Spin 17 (18 Red), bet 9 pays -1'; +is payout( 17, 10 ), -1, 'Spin 17 (18 Red), bet 10 pays -1'; +is payout( 17, 11 ), -1, 'Spin 17 (18 Red), bet 11 pays -1'; +is payout( 17, 12 ), -1, 'Spin 17 (18 Red), bet 12 pays -1'; +is payout( 17, 13 ), -1, 'Spin 17 (18 Red), bet 13 pays -1'; +is payout( 17, 14 ), -1, 'Spin 17 (18 Red), bet 14 pays -1'; +is payout( 17, 15 ), -1, 'Spin 17 (18 Red), bet 15 pays -1'; +is payout( 17, 16 ), -1, 'Spin 17 (18 Red), bet 16 pays -1'; +is payout( 17, 17 ), -1, 'Spin 17 (18 Red), bet 17 pays -1'; +is payout( 17, 18 ), 35, 'Spin 17 (18 Red), bet 18 pays 35'; +is payout( 17, 19 ), -1, 'Spin 17 (18 Red), bet 19 pays -1'; +is payout( 17, 20 ), -1, 'Spin 17 (18 Red), bet 20 pays -1'; +is payout( 17, 21 ), -1, 'Spin 17 (18 Red), bet 21 pays -1'; +is payout( 17, 22 ), -1, 'Spin 17 (18 Red), bet 22 pays -1'; +is payout( 17, 23 ), -1, 'Spin 17 (18 Red), bet 23 pays -1'; +is payout( 17, 24 ), -1, 'Spin 17 (18 Red), bet 24 pays -1'; +is payout( 17, 25 ), -1, 'Spin 17 (18 Red), bet 25 pays -1'; +is payout( 17, 26 ), -1, 'Spin 17 (18 Red), bet 26 pays -1'; +is payout( 17, 27 ), -1, 'Spin 17 (18 Red), bet 27 pays -1'; +is payout( 17, 28 ), -1, 'Spin 17 (18 Red), bet 28 pays -1'; +is payout( 17, 29 ), -1, 'Spin 17 (18 Red), bet 29 pays -1'; +is payout( 17, 30 ), -1, 'Spin 17 (18 Red), bet 30 pays -1'; +is payout( 17, 31 ), -1, 'Spin 17 (18 Red), bet 31 pays -1'; +is payout( 17, 32 ), -1, 'Spin 17 (18 Red), bet 32 pays -1'; +is payout( 17, 33 ), -1, 'Spin 17 (18 Red), bet 33 pays -1'; +is payout( 17, 34 ), -1, 'Spin 17 (18 Red), bet 34 pays -1'; +is payout( 17, 35 ), -1, 'Spin 17 (18 Red), bet 35 pays -1'; +is payout( 17, 36 ), -1, 'Spin 17 (18 Red), bet 36 pays -1'; +is payout( 17, 37 ), -1, 'Spin 17 (18 Red), bet 37 pays -1'; +is payout( 17, 38 ), 2, 'Spin 17 (18 Red), bet 38 pays 2'; +is payout( 17, 39 ), -1, 'Spin 17 (18 Red), bet 39 pays -1'; +is payout( 17, 40 ), -1, 'Spin 17 (18 Red), bet 40 pays -1'; +is payout( 17, 41 ), -1, 'Spin 17 (18 Red), bet 41 pays -1'; +is payout( 17, 42 ), 2, 'Spin 17 (18 Red), bet 42 pays 2'; +is payout( 17, 43 ), 1, 'Spin 17 (18 Red), bet 43 pays 1'; +is payout( 17, 44 ), -1, 'Spin 17 (18 Red), bet 44 pays -1'; +is payout( 17, 45 ), 1, 'Spin 17 (18 Red), bet 45 pays 1'; +is payout( 17, 46 ), -1, 'Spin 17 (18 Red), bet 46 pays -1'; +is payout( 17, 47 ), 1, 'Spin 17 (18 Red), bet 47 pays 1'; +is payout( 17, 48 ), -1, 'Spin 17 (18 Red), bet 48 pays -1'; +is payout( 17, 49 ), -1, 'Spin 17 (18 Red), bet 49 pays -1'; +is payout( 17, 50 ), -1, 'Spin 17 (18 Red), bet 50 pays -1'; +is format_spin( 18 ), '19 Red', 'Spin 18 is 19 Red'; +is payout( 18, 1 ), -1, 'Spin 18 (19 Red), bet 1 pays -1'; +is payout( 18, 2 ), -1, 'Spin 18 (19 Red), bet 2 pays -1'; +is payout( 18, 3 ), -1, 'Spin 18 (19 Red), bet 3 pays -1'; +is payout( 18, 4 ), -1, 'Spin 18 (19 Red), bet 4 pays -1'; +is payout( 18, 5 ), -1, 'Spin 18 (19 Red), bet 5 pays -1'; +is payout( 18, 6 ), -1, 'Spin 18 (19 Red), bet 6 pays -1'; +is payout( 18, 7 ), -1, 'Spin 18 (19 Red), bet 7 pays -1'; +is payout( 18, 8 ), -1, 'Spin 18 (19 Red), bet 8 pays -1'; +is payout( 18, 9 ), -1, 'Spin 18 (19 Red), bet 9 pays -1'; +is payout( 18, 10 ), -1, 'Spin 18 (19 Red), bet 10 pays -1'; +is payout( 18, 11 ), -1, 'Spin 18 (19 Red), bet 11 pays -1'; +is payout( 18, 12 ), -1, 'Spin 18 (19 Red), bet 12 pays -1'; +is payout( 18, 13 ), -1, 'Spin 18 (19 Red), bet 13 pays -1'; +is payout( 18, 14 ), -1, 'Spin 18 (19 Red), bet 14 pays -1'; +is payout( 18, 15 ), -1, 'Spin 18 (19 Red), bet 15 pays -1'; +is payout( 18, 16 ), -1, 'Spin 18 (19 Red), bet 16 pays -1'; +is payout( 18, 17 ), -1, 'Spin 18 (19 Red), bet 17 pays -1'; +is payout( 18, 18 ), -1, 'Spin 18 (19 Red), bet 18 pays -1'; +is payout( 18, 19 ), 35, 'Spin 18 (19 Red), bet 19 pays 35'; +is payout( 18, 20 ), -1, 'Spin 18 (19 Red), bet 20 pays -1'; +is payout( 18, 21 ), -1, 'Spin 18 (19 Red), bet 21 pays -1'; +is payout( 18, 22 ), -1, 'Spin 18 (19 Red), bet 22 pays -1'; +is payout( 18, 23 ), -1, 'Spin 18 (19 Red), bet 23 pays -1'; +is payout( 18, 24 ), -1, 'Spin 18 (19 Red), bet 24 pays -1'; +is payout( 18, 25 ), -1, 'Spin 18 (19 Red), bet 25 pays -1'; +is payout( 18, 26 ), -1, 'Spin 18 (19 Red), bet 26 pays -1'; +is payout( 18, 27 ), -1, 'Spin 18 (19 Red), bet 27 pays -1'; +is payout( 18, 28 ), -1, 'Spin 18 (19 Red), bet 28 pays -1'; +is payout( 18, 29 ), -1, 'Spin 18 (19 Red), bet 29 pays -1'; +is payout( 18, 30 ), -1, 'Spin 18 (19 Red), bet 30 pays -1'; +is payout( 18, 31 ), -1, 'Spin 18 (19 Red), bet 31 pays -1'; +is payout( 18, 32 ), -1, 'Spin 18 (19 Red), bet 32 pays -1'; +is payout( 18, 33 ), -1, 'Spin 18 (19 Red), bet 33 pays -1'; +is payout( 18, 34 ), -1, 'Spin 18 (19 Red), bet 34 pays -1'; +is payout( 18, 35 ), -1, 'Spin 18 (19 Red), bet 35 pays -1'; +is payout( 18, 36 ), -1, 'Spin 18 (19 Red), bet 36 pays -1'; +is payout( 18, 37 ), -1, 'Spin 18 (19 Red), bet 37 pays -1'; +is payout( 18, 38 ), 2, 'Spin 18 (19 Red), bet 38 pays 2'; +is payout( 18, 39 ), -1, 'Spin 18 (19 Red), bet 39 pays -1'; +is payout( 18, 40 ), 2, 'Spin 18 (19 Red), bet 40 pays 2'; +is payout( 18, 41 ), -1, 'Spin 18 (19 Red), bet 41 pays -1'; +is payout( 18, 42 ), -1, 'Spin 18 (19 Red), bet 42 pays -1'; +is payout( 18, 43 ), -1, 'Spin 18 (19 Red), bet 43 pays -1'; +is payout( 18, 44 ), 1, 'Spin 18 (19 Red), bet 44 pays 1'; +is payout( 18, 45 ), -1, 'Spin 18 (19 Red), bet 45 pays -1'; +is payout( 18, 46 ), 1, 'Spin 18 (19 Red), bet 46 pays 1'; +is payout( 18, 47 ), 1, 'Spin 18 (19 Red), bet 47 pays 1'; +is payout( 18, 48 ), -1, 'Spin 18 (19 Red), bet 48 pays -1'; +is payout( 18, 49 ), -1, 'Spin 18 (19 Red), bet 49 pays -1'; +is payout( 18, 50 ), -1, 'Spin 18 (19 Red), bet 50 pays -1'; +is format_spin( 19 ), '20 Black', 'Spin 19 is 20 Black'; +is payout( 19, 1 ), -1, 'Spin 19 (20 Black), bet 1 pays -1'; +is payout( 19, 2 ), -1, 'Spin 19 (20 Black), bet 2 pays -1'; +is payout( 19, 3 ), -1, 'Spin 19 (20 Black), bet 3 pays -1'; +is payout( 19, 4 ), -1, 'Spin 19 (20 Black), bet 4 pays -1'; +is payout( 19, 5 ), -1, 'Spin 19 (20 Black), bet 5 pays -1'; +is payout( 19, 6 ), -1, 'Spin 19 (20 Black), bet 6 pays -1'; +is payout( 19, 7 ), -1, 'Spin 19 (20 Black), bet 7 pays -1'; +is payout( 19, 8 ), -1, 'Spin 19 (20 Black), bet 8 pays -1'; +is payout( 19, 9 ), -1, 'Spin 19 (20 Black), bet 9 pays -1'; +is payout( 19, 10 ), -1, 'Spin 19 (20 Black), bet 10 pays -1'; +is payout( 19, 11 ), -1, 'Spin 19 (20 Black), bet 11 pays -1'; +is payout( 19, 12 ), -1, 'Spin 19 (20 Black), bet 12 pays -1'; +is payout( 19, 13 ), -1, 'Spin 19 (20 Black), bet 13 pays -1'; +is payout( 19, 14 ), -1, 'Spin 19 (20 Black), bet 14 pays -1'; +is payout( 19, 15 ), -1, 'Spin 19 (20 Black), bet 15 pays -1'; +is payout( 19, 16 ), -1, 'Spin 19 (20 Black), bet 16 pays -1'; +is payout( 19, 17 ), -1, 'Spin 19 (20 Black), bet 17 pays -1'; +is payout( 19, 18 ), -1, 'Spin 19 (20 Black), bet 18 pays -1'; +is payout( 19, 19 ), -1, 'Spin 19 (20 Black), bet 19 pays -1'; +is payout( 19, 20 ), 35, 'Spin 19 (20 Black), bet 20 pays 35'; +is payout( 19, 21 ), -1, 'Spin 19 (20 Black), bet 21 pays -1'; +is payout( 19, 22 ), -1, 'Spin 19 (20 Black), bet 22 pays -1'; +is payout( 19, 23 ), -1, 'Spin 19 (20 Black), bet 23 pays -1'; +is payout( 19, 24 ), -1, 'Spin 19 (20 Black), bet 24 pays -1'; +is payout( 19, 25 ), -1, 'Spin 19 (20 Black), bet 25 pays -1'; +is payout( 19, 26 ), -1, 'Spin 19 (20 Black), bet 26 pays -1'; +is payout( 19, 27 ), -1, 'Spin 19 (20 Black), bet 27 pays -1'; +is payout( 19, 28 ), -1, 'Spin 19 (20 Black), bet 28 pays -1'; +is payout( 19, 29 ), -1, 'Spin 19 (20 Black), bet 29 pays -1'; +is payout( 19, 30 ), -1, 'Spin 19 (20 Black), bet 30 pays -1'; +is payout( 19, 31 ), -1, 'Spin 19 (20 Black), bet 31 pays -1'; +is payout( 19, 32 ), -1, 'Spin 19 (20 Black), bet 32 pays -1'; +is payout( 19, 33 ), -1, 'Spin 19 (20 Black), bet 33 pays -1'; +is payout( 19, 34 ), -1, 'Spin 19 (20 Black), bet 34 pays -1'; +is payout( 19, 35 ), -1, 'Spin 19 (20 Black), bet 35 pays -1'; +is payout( 19, 36 ), -1, 'Spin 19 (20 Black), bet 36 pays -1'; +is payout( 19, 37 ), -1, 'Spin 19 (20 Black), bet 37 pays -1'; +is payout( 19, 38 ), 2, 'Spin 19 (20 Black), bet 38 pays 2'; +is payout( 19, 39 ), -1, 'Spin 19 (20 Black), bet 39 pays -1'; +is payout( 19, 40 ), -1, 'Spin 19 (20 Black), bet 40 pays -1'; +is payout( 19, 41 ), 2, 'Spin 19 (20 Black), bet 41 pays 2'; +is payout( 19, 42 ), -1, 'Spin 19 (20 Black), bet 42 pays -1'; +is payout( 19, 43 ), -1, 'Spin 19 (20 Black), bet 43 pays -1'; +is payout( 19, 44 ), 1, 'Spin 19 (20 Black), bet 44 pays 1'; +is payout( 19, 45 ), 1, 'Spin 19 (20 Black), bet 45 pays 1'; +is payout( 19, 46 ), -1, 'Spin 19 (20 Black), bet 46 pays -1'; +is payout( 19, 47 ), -1, 'Spin 19 (20 Black), bet 47 pays -1'; +is payout( 19, 48 ), 1, 'Spin 19 (20 Black), bet 48 pays 1'; +is payout( 19, 49 ), -1, 'Spin 19 (20 Black), bet 49 pays -1'; +is payout( 19, 50 ), -1, 'Spin 19 (20 Black), bet 50 pays -1'; +is format_spin( 20 ), '21 Red', 'Spin 20 is 21 Red'; +is payout( 20, 1 ), -1, 'Spin 20 (21 Red), bet 1 pays -1'; +is payout( 20, 2 ), -1, 'Spin 20 (21 Red), bet 2 pays -1'; +is payout( 20, 3 ), -1, 'Spin 20 (21 Red), bet 3 pays -1'; +is payout( 20, 4 ), -1, 'Spin 20 (21 Red), bet 4 pays -1'; +is payout( 20, 5 ), -1, 'Spin 20 (21 Red), bet 5 pays -1'; +is payout( 20, 6 ), -1, 'Spin 20 (21 Red), bet 6 pays -1'; +is payout( 20, 7 ), -1, 'Spin 20 (21 Red), bet 7 pays -1'; +is payout( 20, 8 ), -1, 'Spin 20 (21 Red), bet 8 pays -1'; +is payout( 20, 9 ), -1, 'Spin 20 (21 Red), bet 9 pays -1'; +is payout( 20, 10 ), -1, 'Spin 20 (21 Red), bet 10 pays -1'; +is payout( 20, 11 ), -1, 'Spin 20 (21 Red), bet 11 pays -1'; +is payout( 20, 12 ), -1, 'Spin 20 (21 Red), bet 12 pays -1'; +is payout( 20, 13 ), -1, 'Spin 20 (21 Red), bet 13 pays -1'; +is payout( 20, 14 ), -1, 'Spin 20 (21 Red), bet 14 pays -1'; +is payout( 20, 15 ), -1, 'Spin 20 (21 Red), bet 15 pays -1'; +is payout( 20, 16 ), -1, 'Spin 20 (21 Red), bet 16 pays -1'; +is payout( 20, 17 ), -1, 'Spin 20 (21 Red), bet 17 pays -1'; +is payout( 20, 18 ), -1, 'Spin 20 (21 Red), bet 18 pays -1'; +is payout( 20, 19 ), -1, 'Spin 20 (21 Red), bet 19 pays -1'; +is payout( 20, 20 ), -1, 'Spin 20 (21 Red), bet 20 pays -1'; +is payout( 20, 21 ), 35, 'Spin 20 (21 Red), bet 21 pays 35'; +is payout( 20, 22 ), -1, 'Spin 20 (21 Red), bet 22 pays -1'; +is payout( 20, 23 ), -1, 'Spin 20 (21 Red), bet 23 pays -1'; +is payout( 20, 24 ), -1, 'Spin 20 (21 Red), bet 24 pays -1'; +is payout( 20, 25 ), -1, 'Spin 20 (21 Red), bet 25 pays -1'; +is payout( 20, 26 ), -1, 'Spin 20 (21 Red), bet 26 pays -1'; +is payout( 20, 27 ), -1, 'Spin 20 (21 Red), bet 27 pays -1'; +is payout( 20, 28 ), -1, 'Spin 20 (21 Red), bet 28 pays -1'; +is payout( 20, 29 ), -1, 'Spin 20 (21 Red), bet 29 pays -1'; +is payout( 20, 30 ), -1, 'Spin 20 (21 Red), bet 30 pays -1'; +is payout( 20, 31 ), -1, 'Spin 20 (21 Red), bet 31 pays -1'; +is payout( 20, 32 ), -1, 'Spin 20 (21 Red), bet 32 pays -1'; +is payout( 20, 33 ), -1, 'Spin 20 (21 Red), bet 33 pays -1'; +is payout( 20, 34 ), -1, 'Spin 20 (21 Red), bet 34 pays -1'; +is payout( 20, 35 ), -1, 'Spin 20 (21 Red), bet 35 pays -1'; +is payout( 20, 36 ), -1, 'Spin 20 (21 Red), bet 36 pays -1'; +is payout( 20, 37 ), -1, 'Spin 20 (21 Red), bet 37 pays -1'; +is payout( 20, 38 ), 2, 'Spin 20 (21 Red), bet 38 pays 2'; +is payout( 20, 39 ), -1, 'Spin 20 (21 Red), bet 39 pays -1'; +is payout( 20, 40 ), -1, 'Spin 20 (21 Red), bet 40 pays -1'; +is payout( 20, 41 ), -1, 'Spin 20 (21 Red), bet 41 pays -1'; +is payout( 20, 42 ), 2, 'Spin 20 (21 Red), bet 42 pays 2'; +is payout( 20, 43 ), -1, 'Spin 20 (21 Red), bet 43 pays -1'; +is payout( 20, 44 ), 1, 'Spin 20 (21 Red), bet 44 pays 1'; +is payout( 20, 45 ), -1, 'Spin 20 (21 Red), bet 45 pays -1'; +is payout( 20, 46 ), 1, 'Spin 20 (21 Red), bet 46 pays 1'; +is payout( 20, 47 ), 1, 'Spin 20 (21 Red), bet 47 pays 1'; +is payout( 20, 48 ), -1, 'Spin 20 (21 Red), bet 48 pays -1'; +is payout( 20, 49 ), -1, 'Spin 20 (21 Red), bet 49 pays -1'; +is payout( 20, 50 ), -1, 'Spin 20 (21 Red), bet 50 pays -1'; +is format_spin( 21 ), '22 Black', 'Spin 21 is 22 Black'; +is payout( 21, 1 ), -1, 'Spin 21 (22 Black), bet 1 pays -1'; +is payout( 21, 2 ), -1, 'Spin 21 (22 Black), bet 2 pays -1'; +is payout( 21, 3 ), -1, 'Spin 21 (22 Black), bet 3 pays -1'; +is payout( 21, 4 ), -1, 'Spin 21 (22 Black), bet 4 pays -1'; +is payout( 21, 5 ), -1, 'Spin 21 (22 Black), bet 5 pays -1'; +is payout( 21, 6 ), -1, 'Spin 21 (22 Black), bet 6 pays -1'; +is payout( 21, 7 ), -1, 'Spin 21 (22 Black), bet 7 pays -1'; +is payout( 21, 8 ), -1, 'Spin 21 (22 Black), bet 8 pays -1'; +is payout( 21, 9 ), -1, 'Spin 21 (22 Black), bet 9 pays -1'; +is payout( 21, 10 ), -1, 'Spin 21 (22 Black), bet 10 pays -1'; +is payout( 21, 11 ), -1, 'Spin 21 (22 Black), bet 11 pays -1'; +is payout( 21, 12 ), -1, 'Spin 21 (22 Black), bet 12 pays -1'; +is payout( 21, 13 ), -1, 'Spin 21 (22 Black), bet 13 pays -1'; +is payout( 21, 14 ), -1, 'Spin 21 (22 Black), bet 14 pays -1'; +is payout( 21, 15 ), -1, 'Spin 21 (22 Black), bet 15 pays -1'; +is payout( 21, 16 ), -1, 'Spin 21 (22 Black), bet 16 pays -1'; +is payout( 21, 17 ), -1, 'Spin 21 (22 Black), bet 17 pays -1'; +is payout( 21, 18 ), -1, 'Spin 21 (22 Black), bet 18 pays -1'; +is payout( 21, 19 ), -1, 'Spin 21 (22 Black), bet 19 pays -1'; +is payout( 21, 20 ), -1, 'Spin 21 (22 Black), bet 20 pays -1'; +is payout( 21, 21 ), -1, 'Spin 21 (22 Black), bet 21 pays -1'; +is payout( 21, 22 ), 35, 'Spin 21 (22 Black), bet 22 pays 35'; +is payout( 21, 23 ), -1, 'Spin 21 (22 Black), bet 23 pays -1'; +is payout( 21, 24 ), -1, 'Spin 21 (22 Black), bet 24 pays -1'; +is payout( 21, 25 ), -1, 'Spin 21 (22 Black), bet 25 pays -1'; +is payout( 21, 26 ), -1, 'Spin 21 (22 Black), bet 26 pays -1'; +is payout( 21, 27 ), -1, 'Spin 21 (22 Black), bet 27 pays -1'; +is payout( 21, 28 ), -1, 'Spin 21 (22 Black), bet 28 pays -1'; +is payout( 21, 29 ), -1, 'Spin 21 (22 Black), bet 29 pays -1'; +is payout( 21, 30 ), -1, 'Spin 21 (22 Black), bet 30 pays -1'; +is payout( 21, 31 ), -1, 'Spin 21 (22 Black), bet 31 pays -1'; +is payout( 21, 32 ), -1, 'Spin 21 (22 Black), bet 32 pays -1'; +is payout( 21, 33 ), -1, 'Spin 21 (22 Black), bet 33 pays -1'; +is payout( 21, 34 ), -1, 'Spin 21 (22 Black), bet 34 pays -1'; +is payout( 21, 35 ), -1, 'Spin 21 (22 Black), bet 35 pays -1'; +is payout( 21, 36 ), -1, 'Spin 21 (22 Black), bet 36 pays -1'; +is payout( 21, 37 ), -1, 'Spin 21 (22 Black), bet 37 pays -1'; +is payout( 21, 38 ), 2, 'Spin 21 (22 Black), bet 38 pays 2'; +is payout( 21, 39 ), -1, 'Spin 21 (22 Black), bet 39 pays -1'; +is payout( 21, 40 ), 2, 'Spin 21 (22 Black), bet 40 pays 2'; +is payout( 21, 41 ), -1, 'Spin 21 (22 Black), bet 41 pays -1'; +is payout( 21, 42 ), -1, 'Spin 21 (22 Black), bet 42 pays -1'; +is payout( 21, 43 ), -1, 'Spin 21 (22 Black), bet 43 pays -1'; +is payout( 21, 44 ), 1, 'Spin 21 (22 Black), bet 44 pays 1'; +is payout( 21, 45 ), 1, 'Spin 21 (22 Black), bet 45 pays 1'; +is payout( 21, 46 ), -1, 'Spin 21 (22 Black), bet 46 pays -1'; +is payout( 21, 47 ), -1, 'Spin 21 (22 Black), bet 47 pays -1'; +is payout( 21, 48 ), 1, 'Spin 21 (22 Black), bet 48 pays 1'; +is payout( 21, 49 ), -1, 'Spin 21 (22 Black), bet 49 pays -1'; +is payout( 21, 50 ), -1, 'Spin 21 (22 Black), bet 50 pays -1'; +is format_spin( 22 ), '23 Red', 'Spin 22 is 23 Red'; +is payout( 22, 1 ), -1, 'Spin 22 (23 Red), bet 1 pays -1'; +is payout( 22, 2 ), -1, 'Spin 22 (23 Red), bet 2 pays -1'; +is payout( 22, 3 ), -1, 'Spin 22 (23 Red), bet 3 pays -1'; +is payout( 22, 4 ), -1, 'Spin 22 (23 Red), bet 4 pays -1'; +is payout( 22, 5 ), -1, 'Spin 22 (23 Red), bet 5 pays -1'; +is payout( 22, 6 ), -1, 'Spin 22 (23 Red), bet 6 pays -1'; +is payout( 22, 7 ), -1, 'Spin 22 (23 Red), bet 7 pays -1'; +is payout( 22, 8 ), -1, 'Spin 22 (23 Red), bet 8 pays -1'; +is payout( 22, 9 ), -1, 'Spin 22 (23 Red), bet 9 pays -1'; +is payout( 22, 10 ), -1, 'Spin 22 (23 Red), bet 10 pays -1'; +is payout( 22, 11 ), -1, 'Spin 22 (23 Red), bet 11 pays -1'; +is payout( 22, 12 ), -1, 'Spin 22 (23 Red), bet 12 pays -1'; +is payout( 22, 13 ), -1, 'Spin 22 (23 Red), bet 13 pays -1'; +is payout( 22, 14 ), -1, 'Spin 22 (23 Red), bet 14 pays -1'; +is payout( 22, 15 ), -1, 'Spin 22 (23 Red), bet 15 pays -1'; +is payout( 22, 16 ), -1, 'Spin 22 (23 Red), bet 16 pays -1'; +is payout( 22, 17 ), -1, 'Spin 22 (23 Red), bet 17 pays -1'; +is payout( 22, 18 ), -1, 'Spin 22 (23 Red), bet 18 pays -1'; +is payout( 22, 19 ), -1, 'Spin 22 (23 Red), bet 19 pays -1'; +is payout( 22, 20 ), -1, 'Spin 22 (23 Red), bet 20 pays -1'; +is payout( 22, 21 ), -1, 'Spin 22 (23 Red), bet 21 pays -1'; +is payout( 22, 22 ), -1, 'Spin 22 (23 Red), bet 22 pays -1'; +is payout( 22, 23 ), 35, 'Spin 22 (23 Red), bet 23 pays 35'; +is payout( 22, 24 ), -1, 'Spin 22 (23 Red), bet 24 pays -1'; +is payout( 22, 25 ), -1, 'Spin 22 (23 Red), bet 25 pays -1'; +is payout( 22, 26 ), -1, 'Spin 22 (23 Red), bet 26 pays -1'; +is payout( 22, 27 ), -1, 'Spin 22 (23 Red), bet 27 pays -1'; +is payout( 22, 28 ), -1, 'Spin 22 (23 Red), bet 28 pays -1'; +is payout( 22, 29 ), -1, 'Spin 22 (23 Red), bet 29 pays -1'; +is payout( 22, 30 ), -1, 'Spin 22 (23 Red), bet 30 pays -1'; +is payout( 22, 31 ), -1, 'Spin 22 (23 Red), bet 31 pays -1'; +is payout( 22, 32 ), -1, 'Spin 22 (23 Red), bet 32 pays -1'; +is payout( 22, 33 ), -1, 'Spin 22 (23 Red), bet 33 pays -1'; +is payout( 22, 34 ), -1, 'Spin 22 (23 Red), bet 34 pays -1'; +is payout( 22, 35 ), -1, 'Spin 22 (23 Red), bet 35 pays -1'; +is payout( 22, 36 ), -1, 'Spin 22 (23 Red), bet 36 pays -1'; +is payout( 22, 37 ), -1, 'Spin 22 (23 Red), bet 37 pays -1'; +is payout( 22, 38 ), 2, 'Spin 22 (23 Red), bet 38 pays 2'; +is payout( 22, 39 ), -1, 'Spin 22 (23 Red), bet 39 pays -1'; +is payout( 22, 40 ), -1, 'Spin 22 (23 Red), bet 40 pays -1'; +is payout( 22, 41 ), 2, 'Spin 22 (23 Red), bet 41 pays 2'; +is payout( 22, 42 ), -1, 'Spin 22 (23 Red), bet 42 pays -1'; +is payout( 22, 43 ), -1, 'Spin 22 (23 Red), bet 43 pays -1'; +is payout( 22, 44 ), 1, 'Spin 22 (23 Red), bet 44 pays 1'; +is payout( 22, 45 ), -1, 'Spin 22 (23 Red), bet 45 pays -1'; +is payout( 22, 46 ), 1, 'Spin 22 (23 Red), bet 46 pays 1'; +is payout( 22, 47 ), 1, 'Spin 22 (23 Red), bet 47 pays 1'; +is payout( 22, 48 ), -1, 'Spin 22 (23 Red), bet 48 pays -1'; +is payout( 22, 49 ), -1, 'Spin 22 (23 Red), bet 49 pays -1'; +is payout( 22, 50 ), -1, 'Spin 22 (23 Red), bet 50 pays -1'; +is format_spin( 23 ), '24 Black', 'Spin 23 is 24 Black'; +is payout( 23, 1 ), -1, 'Spin 23 (24 Black), bet 1 pays -1'; +is payout( 23, 2 ), -1, 'Spin 23 (24 Black), bet 2 pays -1'; +is payout( 23, 3 ), -1, 'Spin 23 (24 Black), bet 3 pays -1'; +is payout( 23, 4 ), -1, 'Spin 23 (24 Black), bet 4 pays -1'; +is payout( 23, 5 ), -1, 'Spin 23 (24 Black), bet 5 pays -1'; +is payout( 23, 6 ), -1, 'Spin 23 (24 Black), bet 6 pays -1'; +is payout( 23, 7 ), -1, 'Spin 23 (24 Black), bet 7 pays -1'; +is payout( 23, 8 ), -1, 'Spin 23 (24 Black), bet 8 pays -1'; +is payout( 23, 9 ), -1, 'Spin 23 (24 Black), bet 9 pays -1'; +is payout( 23, 10 ), -1, 'Spin 23 (24 Black), bet 10 pays -1'; +is payout( 23, 11 ), -1, 'Spin 23 (24 Black), bet 11 pays -1'; +is payout( 23, 12 ), -1, 'Spin 23 (24 Black), bet 12 pays -1'; +is payout( 23, 13 ), -1, 'Spin 23 (24 Black), bet 13 pays -1'; +is payout( 23, 14 ), -1, 'Spin 23 (24 Black), bet 14 pays -1'; +is payout( 23, 15 ), -1, 'Spin 23 (24 Black), bet 15 pays -1'; +is payout( 23, 16 ), -1, 'Spin 23 (24 Black), bet 16 pays -1'; +is payout( 23, 17 ), -1, 'Spin 23 (24 Black), bet 17 pays -1'; +is payout( 23, 18 ), -1, 'Spin 23 (24 Black), bet 18 pays -1'; +is payout( 23, 19 ), -1, 'Spin 23 (24 Black), bet 19 pays -1'; +is payout( 23, 20 ), -1, 'Spin 23 (24 Black), bet 20 pays -1'; +is payout( 23, 21 ), -1, 'Spin 23 (24 Black), bet 21 pays -1'; +is payout( 23, 22 ), -1, 'Spin 23 (24 Black), bet 22 pays -1'; +is payout( 23, 23 ), -1, 'Spin 23 (24 Black), bet 23 pays -1'; +is payout( 23, 24 ), 35, 'Spin 23 (24 Black), bet 24 pays 35'; +is payout( 23, 25 ), -1, 'Spin 23 (24 Black), bet 25 pays -1'; +is payout( 23, 26 ), -1, 'Spin 23 (24 Black), bet 26 pays -1'; +is payout( 23, 27 ), -1, 'Spin 23 (24 Black), bet 27 pays -1'; +is payout( 23, 28 ), -1, 'Spin 23 (24 Black), bet 28 pays -1'; +is payout( 23, 29 ), -1, 'Spin 23 (24 Black), bet 29 pays -1'; +is payout( 23, 30 ), -1, 'Spin 23 (24 Black), bet 30 pays -1'; +is payout( 23, 31 ), -1, 'Spin 23 (24 Black), bet 31 pays -1'; +is payout( 23, 32 ), -1, 'Spin 23 (24 Black), bet 32 pays -1'; +is payout( 23, 33 ), -1, 'Spin 23 (24 Black), bet 33 pays -1'; +is payout( 23, 34 ), -1, 'Spin 23 (24 Black), bet 34 pays -1'; +is payout( 23, 35 ), -1, 'Spin 23 (24 Black), bet 35 pays -1'; +is payout( 23, 36 ), -1, 'Spin 23 (24 Black), bet 36 pays -1'; +is payout( 23, 37 ), -1, 'Spin 23 (24 Black), bet 37 pays -1'; +is payout( 23, 38 ), 2, 'Spin 23 (24 Black), bet 38 pays 2'; +is payout( 23, 39 ), -1, 'Spin 23 (24 Black), bet 39 pays -1'; +is payout( 23, 40 ), -1, 'Spin 23 (24 Black), bet 40 pays -1'; +is payout( 23, 41 ), -1, 'Spin 23 (24 Black), bet 41 pays -1'; +is payout( 23, 42 ), 2, 'Spin 23 (24 Black), bet 42 pays 2'; +is payout( 23, 43 ), -1, 'Spin 23 (24 Black), bet 43 pays -1'; +is payout( 23, 44 ), 1, 'Spin 23 (24 Black), bet 44 pays 1'; +is payout( 23, 45 ), 1, 'Spin 23 (24 Black), bet 45 pays 1'; +is payout( 23, 46 ), -1, 'Spin 23 (24 Black), bet 46 pays -1'; +is payout( 23, 47 ), -1, 'Spin 23 (24 Black), bet 47 pays -1'; +is payout( 23, 48 ), 1, 'Spin 23 (24 Black), bet 48 pays 1'; +is payout( 23, 49 ), -1, 'Spin 23 (24 Black), bet 49 pays -1'; +is payout( 23, 50 ), -1, 'Spin 23 (24 Black), bet 50 pays -1'; +is format_spin( 24 ), '25 Red', 'Spin 24 is 25 Red'; +is payout( 24, 1 ), -1, 'Spin 24 (25 Red), bet 1 pays -1'; +is payout( 24, 2 ), -1, 'Spin 24 (25 Red), bet 2 pays -1'; +is payout( 24, 3 ), -1, 'Spin 24 (25 Red), bet 3 pays -1'; +is payout( 24, 4 ), -1, 'Spin 24 (25 Red), bet 4 pays -1'; +is payout( 24, 5 ), -1, 'Spin 24 (25 Red), bet 5 pays -1'; +is payout( 24, 6 ), -1, 'Spin 24 (25 Red), bet 6 pays -1'; +is payout( 24, 7 ), -1, 'Spin 24 (25 Red), bet 7 pays -1'; +is payout( 24, 8 ), -1, 'Spin 24 (25 Red), bet 8 pays -1'; +is payout( 24, 9 ), -1, 'Spin 24 (25 Red), bet 9 pays -1'; +is payout( 24, 10 ), -1, 'Spin 24 (25 Red), bet 10 pays -1'; +is payout( 24, 11 ), -1, 'Spin 24 (25 Red), bet 11 pays -1'; +is payout( 24, 12 ), -1, 'Spin 24 (25 Red), bet 12 pays -1'; +is payout( 24, 13 ), -1, 'Spin 24 (25 Red), bet 13 pays -1'; +is payout( 24, 14 ), -1, 'Spin 24 (25 Red), bet 14 pays -1'; +is payout( 24, 15 ), -1, 'Spin 24 (25 Red), bet 15 pays -1'; +is payout( 24, 16 ), -1, 'Spin 24 (25 Red), bet 16 pays -1'; +is payout( 24, 17 ), -1, 'Spin 24 (25 Red), bet 17 pays -1'; +is payout( 24, 18 ), -1, 'Spin 24 (25 Red), bet 18 pays -1'; +is payout( 24, 19 ), -1, 'Spin 24 (25 Red), bet 19 pays -1'; +is payout( 24, 20 ), -1, 'Spin 24 (25 Red), bet 20 pays -1'; +is payout( 24, 21 ), -1, 'Spin 24 (25 Red), bet 21 pays -1'; +is payout( 24, 22 ), -1, 'Spin 24 (25 Red), bet 22 pays -1'; +is payout( 24, 23 ), -1, 'Spin 24 (25 Red), bet 23 pays -1'; +is payout( 24, 24 ), -1, 'Spin 24 (25 Red), bet 24 pays -1'; +is payout( 24, 25 ), 35, 'Spin 24 (25 Red), bet 25 pays 35'; +is payout( 24, 26 ), -1, 'Spin 24 (25 Red), bet 26 pays -1'; +is payout( 24, 27 ), -1, 'Spin 24 (25 Red), bet 27 pays -1'; +is payout( 24, 28 ), -1, 'Spin 24 (25 Red), bet 28 pays -1'; +is payout( 24, 29 ), -1, 'Spin 24 (25 Red), bet 29 pays -1'; +is payout( 24, 30 ), -1, 'Spin 24 (25 Red), bet 30 pays -1'; +is payout( 24, 31 ), -1, 'Spin 24 (25 Red), bet 31 pays -1'; +is payout( 24, 32 ), -1, 'Spin 24 (25 Red), bet 32 pays -1'; +is payout( 24, 33 ), -1, 'Spin 24 (25 Red), bet 33 pays -1'; +is payout( 24, 34 ), -1, 'Spin 24 (25 Red), bet 34 pays -1'; +is payout( 24, 35 ), -1, 'Spin 24 (25 Red), bet 35 pays -1'; +is payout( 24, 36 ), -1, 'Spin 24 (25 Red), bet 36 pays -1'; +is payout( 24, 37 ), -1, 'Spin 24 (25 Red), bet 37 pays -1'; +is payout( 24, 38 ), -1, 'Spin 24 (25 Red), bet 38 pays -1'; +is payout( 24, 39 ), 2, 'Spin 24 (25 Red), bet 39 pays 2'; +is payout( 24, 40 ), 2, 'Spin 24 (25 Red), bet 40 pays 2'; +is payout( 24, 41 ), -1, 'Spin 24 (25 Red), bet 41 pays -1'; +is payout( 24, 42 ), -1, 'Spin 24 (25 Red), bet 42 pays -1'; +is payout( 24, 43 ), -1, 'Spin 24 (25 Red), bet 43 pays -1'; +is payout( 24, 44 ), 1, 'Spin 24 (25 Red), bet 44 pays 1'; +is payout( 24, 45 ), -1, 'Spin 24 (25 Red), bet 45 pays -1'; +is payout( 24, 46 ), 1, 'Spin 24 (25 Red), bet 46 pays 1'; +is payout( 24, 47 ), 1, 'Spin 24 (25 Red), bet 47 pays 1'; +is payout( 24, 48 ), -1, 'Spin 24 (25 Red), bet 48 pays -1'; +is payout( 24, 49 ), -1, 'Spin 24 (25 Red), bet 49 pays -1'; +is payout( 24, 50 ), -1, 'Spin 24 (25 Red), bet 50 pays -1'; +is format_spin( 25 ), '26 Black', 'Spin 25 is 26 Black'; +is payout( 25, 1 ), -1, 'Spin 25 (26 Black), bet 1 pays -1'; +is payout( 25, 2 ), -1, 'Spin 25 (26 Black), bet 2 pays -1'; +is payout( 25, 3 ), -1, 'Spin 25 (26 Black), bet 3 pays -1'; +is payout( 25, 4 ), -1, 'Spin 25 (26 Black), bet 4 pays -1'; +is payout( 25, 5 ), -1, 'Spin 25 (26 Black), bet 5 pays -1'; +is payout( 25, 6 ), -1, 'Spin 25 (26 Black), bet 6 pays -1'; +is payout( 25, 7 ), -1, 'Spin 25 (26 Black), bet 7 pays -1'; +is payout( 25, 8 ), -1, 'Spin 25 (26 Black), bet 8 pays -1'; +is payout( 25, 9 ), -1, 'Spin 25 (26 Black), bet 9 pays -1'; +is payout( 25, 10 ), -1, 'Spin 25 (26 Black), bet 10 pays -1'; +is payout( 25, 11 ), -1, 'Spin 25 (26 Black), bet 11 pays -1'; +is payout( 25, 12 ), -1, 'Spin 25 (26 Black), bet 12 pays -1'; +is payout( 25, 13 ), -1, 'Spin 25 (26 Black), bet 13 pays -1'; +is payout( 25, 14 ), -1, 'Spin 25 (26 Black), bet 14 pays -1'; +is payout( 25, 15 ), -1, 'Spin 25 (26 Black), bet 15 pays -1'; +is payout( 25, 16 ), -1, 'Spin 25 (26 Black), bet 16 pays -1'; +is payout( 25, 17 ), -1, 'Spin 25 (26 Black), bet 17 pays -1'; +is payout( 25, 18 ), -1, 'Spin 25 (26 Black), bet 18 pays -1'; +is payout( 25, 19 ), -1, 'Spin 25 (26 Black), bet 19 pays -1'; +is payout( 25, 20 ), -1, 'Spin 25 (26 Black), bet 20 pays -1'; +is payout( 25, 21 ), -1, 'Spin 25 (26 Black), bet 21 pays -1'; +is payout( 25, 22 ), -1, 'Spin 25 (26 Black), bet 22 pays -1'; +is payout( 25, 23 ), -1, 'Spin 25 (26 Black), bet 23 pays -1'; +is payout( 25, 24 ), -1, 'Spin 25 (26 Black), bet 24 pays -1'; +is payout( 25, 25 ), -1, 'Spin 25 (26 Black), bet 25 pays -1'; +is payout( 25, 26 ), 35, 'Spin 25 (26 Black), bet 26 pays 35'; +is payout( 25, 27 ), -1, 'Spin 25 (26 Black), bet 27 pays -1'; +is payout( 25, 28 ), -1, 'Spin 25 (26 Black), bet 28 pays -1'; +is payout( 25, 29 ), -1, 'Spin 25 (26 Black), bet 29 pays -1'; +is payout( 25, 30 ), -1, 'Spin 25 (26 Black), bet 30 pays -1'; +is payout( 25, 31 ), -1, 'Spin 25 (26 Black), bet 31 pays -1'; +is payout( 25, 32 ), -1, 'Spin 25 (26 Black), bet 32 pays -1'; +is payout( 25, 33 ), -1, 'Spin 25 (26 Black), bet 33 pays -1'; +is payout( 25, 34 ), -1, 'Spin 25 (26 Black), bet 34 pays -1'; +is payout( 25, 35 ), -1, 'Spin 25 (26 Black), bet 35 pays -1'; +is payout( 25, 36 ), -1, 'Spin 25 (26 Black), bet 36 pays -1'; +is payout( 25, 37 ), -1, 'Spin 25 (26 Black), bet 37 pays -1'; +is payout( 25, 38 ), -1, 'Spin 25 (26 Black), bet 38 pays -1'; +is payout( 25, 39 ), 2, 'Spin 25 (26 Black), bet 39 pays 2'; +is payout( 25, 40 ), -1, 'Spin 25 (26 Black), bet 40 pays -1'; +is payout( 25, 41 ), 2, 'Spin 25 (26 Black), bet 41 pays 2'; +is payout( 25, 42 ), -1, 'Spin 25 (26 Black), bet 42 pays -1'; +is payout( 25, 43 ), -1, 'Spin 25 (26 Black), bet 43 pays -1'; +is payout( 25, 44 ), 1, 'Spin 25 (26 Black), bet 44 pays 1'; +is payout( 25, 45 ), 1, 'Spin 25 (26 Black), bet 45 pays 1'; +is payout( 25, 46 ), -1, 'Spin 25 (26 Black), bet 46 pays -1'; +is payout( 25, 47 ), -1, 'Spin 25 (26 Black), bet 47 pays -1'; +is payout( 25, 48 ), 1, 'Spin 25 (26 Black), bet 48 pays 1'; +is payout( 25, 49 ), -1, 'Spin 25 (26 Black), bet 49 pays -1'; +is payout( 25, 50 ), -1, 'Spin 25 (26 Black), bet 50 pays -1'; +is format_spin( 26 ), '27 Red', 'Spin 26 is 27 Red'; +is payout( 26, 1 ), -1, 'Spin 26 (27 Red), bet 1 pays -1'; +is payout( 26, 2 ), -1, 'Spin 26 (27 Red), bet 2 pays -1'; +is payout( 26, 3 ), -1, 'Spin 26 (27 Red), bet 3 pays -1'; +is payout( 26, 4 ), -1, 'Spin 26 (27 Red), bet 4 pays -1'; +is payout( 26, 5 ), -1, 'Spin 26 (27 Red), bet 5 pays -1'; +is payout( 26, 6 ), -1, 'Spin 26 (27 Red), bet 6 pays -1'; +is payout( 26, 7 ), -1, 'Spin 26 (27 Red), bet 7 pays -1'; +is payout( 26, 8 ), -1, 'Spin 26 (27 Red), bet 8 pays -1'; +is payout( 26, 9 ), -1, 'Spin 26 (27 Red), bet 9 pays -1'; +is payout( 26, 10 ), -1, 'Spin 26 (27 Red), bet 10 pays -1'; +is payout( 26, 11 ), -1, 'Spin 26 (27 Red), bet 11 pays -1'; +is payout( 26, 12 ), -1, 'Spin 26 (27 Red), bet 12 pays -1'; +is payout( 26, 13 ), -1, 'Spin 26 (27 Red), bet 13 pays -1'; +is payout( 26, 14 ), -1, 'Spin 26 (27 Red), bet 14 pays -1'; +is payout( 26, 15 ), -1, 'Spin 26 (27 Red), bet 15 pays -1'; +is payout( 26, 16 ), -1, 'Spin 26 (27 Red), bet 16 pays -1'; +is payout( 26, 17 ), -1, 'Spin 26 (27 Red), bet 17 pays -1'; +is payout( 26, 18 ), -1, 'Spin 26 (27 Red), bet 18 pays -1'; +is payout( 26, 19 ), -1, 'Spin 26 (27 Red), bet 19 pays -1'; +is payout( 26, 20 ), -1, 'Spin 26 (27 Red), bet 20 pays -1'; +is payout( 26, 21 ), -1, 'Spin 26 (27 Red), bet 21 pays -1'; +is payout( 26, 22 ), -1, 'Spin 26 (27 Red), bet 22 pays -1'; +is payout( 26, 23 ), -1, 'Spin 26 (27 Red), bet 23 pays -1'; +is payout( 26, 24 ), -1, 'Spin 26 (27 Red), bet 24 pays -1'; +is payout( 26, 25 ), -1, 'Spin 26 (27 Red), bet 25 pays -1'; +is payout( 26, 26 ), -1, 'Spin 26 (27 Red), bet 26 pays -1'; +is payout( 26, 27 ), 35, 'Spin 26 (27 Red), bet 27 pays 35'; +is payout( 26, 28 ), -1, 'Spin 26 (27 Red), bet 28 pays -1'; +is payout( 26, 29 ), -1, 'Spin 26 (27 Red), bet 29 pays -1'; +is payout( 26, 30 ), -1, 'Spin 26 (27 Red), bet 30 pays -1'; +is payout( 26, 31 ), -1, 'Spin 26 (27 Red), bet 31 pays -1'; +is payout( 26, 32 ), -1, 'Spin 26 (27 Red), bet 32 pays -1'; +is payout( 26, 33 ), -1, 'Spin 26 (27 Red), bet 33 pays -1'; +is payout( 26, 34 ), -1, 'Spin 26 (27 Red), bet 34 pays -1'; +is payout( 26, 35 ), -1, 'Spin 26 (27 Red), bet 35 pays -1'; +is payout( 26, 36 ), -1, 'Spin 26 (27 Red), bet 36 pays -1'; +is payout( 26, 37 ), -1, 'Spin 26 (27 Red), bet 37 pays -1'; +is payout( 26, 38 ), -1, 'Spin 26 (27 Red), bet 38 pays -1'; +is payout( 26, 39 ), 2, 'Spin 26 (27 Red), bet 39 pays 2'; +is payout( 26, 40 ), -1, 'Spin 26 (27 Red), bet 40 pays -1'; +is payout( 26, 41 ), -1, 'Spin 26 (27 Red), bet 41 pays -1'; +is payout( 26, 42 ), 2, 'Spin 26 (27 Red), bet 42 pays 2'; +is payout( 26, 43 ), -1, 'Spin 26 (27 Red), bet 43 pays -1'; +is payout( 26, 44 ), 1, 'Spin 26 (27 Red), bet 44 pays 1'; +is payout( 26, 45 ), -1, 'Spin 26 (27 Red), bet 45 pays -1'; +is payout( 26, 46 ), 1, 'Spin 26 (27 Red), bet 46 pays 1'; +is payout( 26, 47 ), 1, 'Spin 26 (27 Red), bet 47 pays 1'; +is payout( 26, 48 ), -1, 'Spin 26 (27 Red), bet 48 pays -1'; +is payout( 26, 49 ), -1, 'Spin 26 (27 Red), bet 49 pays -1'; +is payout( 26, 50 ), -1, 'Spin 26 (27 Red), bet 50 pays -1'; +is format_spin( 27 ), '28 Black', 'Spin 27 is 28 Black'; +is payout( 27, 1 ), -1, 'Spin 27 (28 Black), bet 1 pays -1'; +is payout( 27, 2 ), -1, 'Spin 27 (28 Black), bet 2 pays -1'; +is payout( 27, 3 ), -1, 'Spin 27 (28 Black), bet 3 pays -1'; +is payout( 27, 4 ), -1, 'Spin 27 (28 Black), bet 4 pays -1'; +is payout( 27, 5 ), -1, 'Spin 27 (28 Black), bet 5 pays -1'; +is payout( 27, 6 ), -1, 'Spin 27 (28 Black), bet 6 pays -1'; +is payout( 27, 7 ), -1, 'Spin 27 (28 Black), bet 7 pays -1'; +is payout( 27, 8 ), -1, 'Spin 27 (28 Black), bet 8 pays -1'; +is payout( 27, 9 ), -1, 'Spin 27 (28 Black), bet 9 pays -1'; +is payout( 27, 10 ), -1, 'Spin 27 (28 Black), bet 10 pays -1'; +is payout( 27, 11 ), -1, 'Spin 27 (28 Black), bet 11 pays -1'; +is payout( 27, 12 ), -1, 'Spin 27 (28 Black), bet 12 pays -1'; +is payout( 27, 13 ), -1, 'Spin 27 (28 Black), bet 13 pays -1'; +is payout( 27, 14 ), -1, 'Spin 27 (28 Black), bet 14 pays -1'; +is payout( 27, 15 ), -1, 'Spin 27 (28 Black), bet 15 pays -1'; +is payout( 27, 16 ), -1, 'Spin 27 (28 Black), bet 16 pays -1'; +is payout( 27, 17 ), -1, 'Spin 27 (28 Black), bet 17 pays -1'; +is payout( 27, 18 ), -1, 'Spin 27 (28 Black), bet 18 pays -1'; +is payout( 27, 19 ), -1, 'Spin 27 (28 Black), bet 19 pays -1'; +is payout( 27, 20 ), -1, 'Spin 27 (28 Black), bet 20 pays -1'; +is payout( 27, 21 ), -1, 'Spin 27 (28 Black), bet 21 pays -1'; +is payout( 27, 22 ), -1, 'Spin 27 (28 Black), bet 22 pays -1'; +is payout( 27, 23 ), -1, 'Spin 27 (28 Black), bet 23 pays -1'; +is payout( 27, 24 ), -1, 'Spin 27 (28 Black), bet 24 pays -1'; +is payout( 27, 25 ), -1, 'Spin 27 (28 Black), bet 25 pays -1'; +is payout( 27, 26 ), -1, 'Spin 27 (28 Black), bet 26 pays -1'; +is payout( 27, 27 ), -1, 'Spin 27 (28 Black), bet 27 pays -1'; +is payout( 27, 28 ), 35, 'Spin 27 (28 Black), bet 28 pays 35'; +is payout( 27, 29 ), -1, 'Spin 27 (28 Black), bet 29 pays -1'; +is payout( 27, 30 ), -1, 'Spin 27 (28 Black), bet 30 pays -1'; +is payout( 27, 31 ), -1, 'Spin 27 (28 Black), bet 31 pays -1'; +is payout( 27, 32 ), -1, 'Spin 27 (28 Black), bet 32 pays -1'; +is payout( 27, 33 ), -1, 'Spin 27 (28 Black), bet 33 pays -1'; +is payout( 27, 34 ), -1, 'Spin 27 (28 Black), bet 34 pays -1'; +is payout( 27, 35 ), -1, 'Spin 27 (28 Black), bet 35 pays -1'; +is payout( 27, 36 ), -1, 'Spin 27 (28 Black), bet 36 pays -1'; +is payout( 27, 37 ), -1, 'Spin 27 (28 Black), bet 37 pays -1'; +is payout( 27, 38 ), -1, 'Spin 27 (28 Black), bet 38 pays -1'; +is payout( 27, 39 ), 2, 'Spin 27 (28 Black), bet 39 pays 2'; +is payout( 27, 40 ), 2, 'Spin 27 (28 Black), bet 40 pays 2'; +is payout( 27, 41 ), -1, 'Spin 27 (28 Black), bet 41 pays -1'; +is payout( 27, 42 ), -1, 'Spin 27 (28 Black), bet 42 pays -1'; +is payout( 27, 43 ), -1, 'Spin 27 (28 Black), bet 43 pays -1'; +is payout( 27, 44 ), 1, 'Spin 27 (28 Black), bet 44 pays 1'; +is payout( 27, 45 ), 1, 'Spin 27 (28 Black), bet 45 pays 1'; +is payout( 27, 46 ), -1, 'Spin 27 (28 Black), bet 46 pays -1'; +is payout( 27, 47 ), -1, 'Spin 27 (28 Black), bet 47 pays -1'; +is payout( 27, 48 ), 1, 'Spin 27 (28 Black), bet 48 pays 1'; +is payout( 27, 49 ), -1, 'Spin 27 (28 Black), bet 49 pays -1'; +is payout( 27, 50 ), -1, 'Spin 27 (28 Black), bet 50 pays -1'; +is format_spin( 28 ), '29 Black', 'Spin 28 is 29 Black'; +is payout( 28, 1 ), -1, 'Spin 28 (29 Black), bet 1 pays -1'; +is payout( 28, 2 ), -1, 'Spin 28 (29 Black), bet 2 pays -1'; +is payout( 28, 3 ), -1, 'Spin 28 (29 Black), bet 3 pays -1'; +is payout( 28, 4 ), -1, 'Spin 28 (29 Black), bet 4 pays -1'; +is payout( 28, 5 ), -1, 'Spin 28 (29 Black), bet 5 pays -1'; +is payout( 28, 6 ), -1, 'Spin 28 (29 Black), bet 6 pays -1'; +is payout( 28, 7 ), -1, 'Spin 28 (29 Black), bet 7 pays -1'; +is payout( 28, 8 ), -1, 'Spin 28 (29 Black), bet 8 pays -1'; +is payout( 28, 9 ), -1, 'Spin 28 (29 Black), bet 9 pays -1'; +is payout( 28, 10 ), -1, 'Spin 28 (29 Black), bet 10 pays -1'; +is payout( 28, 11 ), -1, 'Spin 28 (29 Black), bet 11 pays -1'; +is payout( 28, 12 ), -1, 'Spin 28 (29 Black), bet 12 pays -1'; +is payout( 28, 13 ), -1, 'Spin 28 (29 Black), bet 13 pays -1'; +is payout( 28, 14 ), -1, 'Spin 28 (29 Black), bet 14 pays -1'; +is payout( 28, 15 ), -1, 'Spin 28 (29 Black), bet 15 pays -1'; +is payout( 28, 16 ), -1, 'Spin 28 (29 Black), bet 16 pays -1'; +is payout( 28, 17 ), -1, 'Spin 28 (29 Black), bet 17 pays -1'; +is payout( 28, 18 ), -1, 'Spin 28 (29 Black), bet 18 pays -1'; +is payout( 28, 19 ), -1, 'Spin 28 (29 Black), bet 19 pays -1'; +is payout( 28, 20 ), -1, 'Spin 28 (29 Black), bet 20 pays -1'; +is payout( 28, 21 ), -1, 'Spin 28 (29 Black), bet 21 pays -1'; +is payout( 28, 22 ), -1, 'Spin 28 (29 Black), bet 22 pays -1'; +is payout( 28, 23 ), -1, 'Spin 28 (29 Black), bet 23 pays -1'; +is payout( 28, 24 ), -1, 'Spin 28 (29 Black), bet 24 pays -1'; +is payout( 28, 25 ), -1, 'Spin 28 (29 Black), bet 25 pays -1'; +is payout( 28, 26 ), -1, 'Spin 28 (29 Black), bet 26 pays -1'; +is payout( 28, 27 ), -1, 'Spin 28 (29 Black), bet 27 pays -1'; +is payout( 28, 28 ), -1, 'Spin 28 (29 Black), bet 28 pays -1'; +is payout( 28, 29 ), 35, 'Spin 28 (29 Black), bet 29 pays 35'; +is payout( 28, 30 ), -1, 'Spin 28 (29 Black), bet 30 pays -1'; +is payout( 28, 31 ), -1, 'Spin 28 (29 Black), bet 31 pays -1'; +is payout( 28, 32 ), -1, 'Spin 28 (29 Black), bet 32 pays -1'; +is payout( 28, 33 ), -1, 'Spin 28 (29 Black), bet 33 pays -1'; +is payout( 28, 34 ), -1, 'Spin 28 (29 Black), bet 34 pays -1'; +is payout( 28, 35 ), -1, 'Spin 28 (29 Black), bet 35 pays -1'; +is payout( 28, 36 ), -1, 'Spin 28 (29 Black), bet 36 pays -1'; +is payout( 28, 37 ), -1, 'Spin 28 (29 Black), bet 37 pays -1'; +is payout( 28, 38 ), -1, 'Spin 28 (29 Black), bet 38 pays -1'; +is payout( 28, 39 ), 2, 'Spin 28 (29 Black), bet 39 pays 2'; +is payout( 28, 40 ), -1, 'Spin 28 (29 Black), bet 40 pays -1'; +is payout( 28, 41 ), 2, 'Spin 28 (29 Black), bet 41 pays 2'; +is payout( 28, 42 ), -1, 'Spin 28 (29 Black), bet 42 pays -1'; +is payout( 28, 43 ), -1, 'Spin 28 (29 Black), bet 43 pays -1'; +is payout( 28, 44 ), 1, 'Spin 28 (29 Black), bet 44 pays 1'; +is payout( 28, 45 ), -1, 'Spin 28 (29 Black), bet 45 pays -1'; +is payout( 28, 46 ), 1, 'Spin 28 (29 Black), bet 46 pays 1'; +is payout( 28, 47 ), -1, 'Spin 28 (29 Black), bet 47 pays -1'; +is payout( 28, 48 ), 1, 'Spin 28 (29 Black), bet 48 pays 1'; +is payout( 28, 49 ), -1, 'Spin 28 (29 Black), bet 49 pays -1'; +is payout( 28, 50 ), -1, 'Spin 28 (29 Black), bet 50 pays -1'; +is format_spin( 29 ), '30 Red', 'Spin 29 is 30 Red'; +is payout( 29, 1 ), -1, 'Spin 29 (30 Red), bet 1 pays -1'; +is payout( 29, 2 ), -1, 'Spin 29 (30 Red), bet 2 pays -1'; +is payout( 29, 3 ), -1, 'Spin 29 (30 Red), bet 3 pays -1'; +is payout( 29, 4 ), -1, 'Spin 29 (30 Red), bet 4 pays -1'; +is payout( 29, 5 ), -1, 'Spin 29 (30 Red), bet 5 pays -1'; +is payout( 29, 6 ), -1, 'Spin 29 (30 Red), bet 6 pays -1'; +is payout( 29, 7 ), -1, 'Spin 29 (30 Red), bet 7 pays -1'; +is payout( 29, 8 ), -1, 'Spin 29 (30 Red), bet 8 pays -1'; +is payout( 29, 9 ), -1, 'Spin 29 (30 Red), bet 9 pays -1'; +is payout( 29, 10 ), -1, 'Spin 29 (30 Red), bet 10 pays -1'; +is payout( 29, 11 ), -1, 'Spin 29 (30 Red), bet 11 pays -1'; +is payout( 29, 12 ), -1, 'Spin 29 (30 Red), bet 12 pays -1'; +is payout( 29, 13 ), -1, 'Spin 29 (30 Red), bet 13 pays -1'; +is payout( 29, 14 ), -1, 'Spin 29 (30 Red), bet 14 pays -1'; +is payout( 29, 15 ), -1, 'Spin 29 (30 Red), bet 15 pays -1'; +is payout( 29, 16 ), -1, 'Spin 29 (30 Red), bet 16 pays -1'; +is payout( 29, 17 ), -1, 'Spin 29 (30 Red), bet 17 pays -1'; +is payout( 29, 18 ), -1, 'Spin 29 (30 Red), bet 18 pays -1'; +is payout( 29, 19 ), -1, 'Spin 29 (30 Red), bet 19 pays -1'; +is payout( 29, 20 ), -1, 'Spin 29 (30 Red), bet 20 pays -1'; +is payout( 29, 21 ), -1, 'Spin 29 (30 Red), bet 21 pays -1'; +is payout( 29, 22 ), -1, 'Spin 29 (30 Red), bet 22 pays -1'; +is payout( 29, 23 ), -1, 'Spin 29 (30 Red), bet 23 pays -1'; +is payout( 29, 24 ), -1, 'Spin 29 (30 Red), bet 24 pays -1'; +is payout( 29, 25 ), -1, 'Spin 29 (30 Red), bet 25 pays -1'; +is payout( 29, 26 ), -1, 'Spin 29 (30 Red), bet 26 pays -1'; +is payout( 29, 27 ), -1, 'Spin 29 (30 Red), bet 27 pays -1'; +is payout( 29, 28 ), -1, 'Spin 29 (30 Red), bet 28 pays -1'; +is payout( 29, 29 ), -1, 'Spin 29 (30 Red), bet 29 pays -1'; +is payout( 29, 30 ), 35, 'Spin 29 (30 Red), bet 30 pays 35'; +is payout( 29, 31 ), -1, 'Spin 29 (30 Red), bet 31 pays -1'; +is payout( 29, 32 ), -1, 'Spin 29 (30 Red), bet 32 pays -1'; +is payout( 29, 33 ), -1, 'Spin 29 (30 Red), bet 33 pays -1'; +is payout( 29, 34 ), -1, 'Spin 29 (30 Red), bet 34 pays -1'; +is payout( 29, 35 ), -1, 'Spin 29 (30 Red), bet 35 pays -1'; +is payout( 29, 36 ), -1, 'Spin 29 (30 Red), bet 36 pays -1'; +is payout( 29, 37 ), -1, 'Spin 29 (30 Red), bet 37 pays -1'; +is payout( 29, 38 ), -1, 'Spin 29 (30 Red), bet 38 pays -1'; +is payout( 29, 39 ), 2, 'Spin 29 (30 Red), bet 39 pays 2'; +is payout( 29, 40 ), -1, 'Spin 29 (30 Red), bet 40 pays -1'; +is payout( 29, 41 ), -1, 'Spin 29 (30 Red), bet 41 pays -1'; +is payout( 29, 42 ), 2, 'Spin 29 (30 Red), bet 42 pays 2'; +is payout( 29, 43 ), -1, 'Spin 29 (30 Red), bet 43 pays -1'; +is payout( 29, 44 ), 1, 'Spin 29 (30 Red), bet 44 pays 1'; +is payout( 29, 45 ), 1, 'Spin 29 (30 Red), bet 45 pays 1'; +is payout( 29, 46 ), -1, 'Spin 29 (30 Red), bet 46 pays -1'; +is payout( 29, 47 ), 1, 'Spin 29 (30 Red), bet 47 pays 1'; +is payout( 29, 48 ), -1, 'Spin 29 (30 Red), bet 48 pays -1'; +is payout( 29, 49 ), -1, 'Spin 29 (30 Red), bet 49 pays -1'; +is payout( 29, 50 ), -1, 'Spin 29 (30 Red), bet 50 pays -1'; +is format_spin( 30 ), '31 Black', 'Spin 30 is 31 Black'; +is payout( 30, 1 ), -1, 'Spin 30 (31 Black), bet 1 pays -1'; +is payout( 30, 2 ), -1, 'Spin 30 (31 Black), bet 2 pays -1'; +is payout( 30, 3 ), -1, 'Spin 30 (31 Black), bet 3 pays -1'; +is payout( 30, 4 ), -1, 'Spin 30 (31 Black), bet 4 pays -1'; +is payout( 30, 5 ), -1, 'Spin 30 (31 Black), bet 5 pays -1'; +is payout( 30, 6 ), -1, 'Spin 30 (31 Black), bet 6 pays -1'; +is payout( 30, 7 ), -1, 'Spin 30 (31 Black), bet 7 pays -1'; +is payout( 30, 8 ), -1, 'Spin 30 (31 Black), bet 8 pays -1'; +is payout( 30, 9 ), -1, 'Spin 30 (31 Black), bet 9 pays -1'; +is payout( 30, 10 ), -1, 'Spin 30 (31 Black), bet 10 pays -1'; +is payout( 30, 11 ), -1, 'Spin 30 (31 Black), bet 11 pays -1'; +is payout( 30, 12 ), -1, 'Spin 30 (31 Black), bet 12 pays -1'; +is payout( 30, 13 ), -1, 'Spin 30 (31 Black), bet 13 pays -1'; +is payout( 30, 14 ), -1, 'Spin 30 (31 Black), bet 14 pays -1'; +is payout( 30, 15 ), -1, 'Spin 30 (31 Black), bet 15 pays -1'; +is payout( 30, 16 ), -1, 'Spin 30 (31 Black), bet 16 pays -1'; +is payout( 30, 17 ), -1, 'Spin 30 (31 Black), bet 17 pays -1'; +is payout( 30, 18 ), -1, 'Spin 30 (31 Black), bet 18 pays -1'; +is payout( 30, 19 ), -1, 'Spin 30 (31 Black), bet 19 pays -1'; +is payout( 30, 20 ), -1, 'Spin 30 (31 Black), bet 20 pays -1'; +is payout( 30, 21 ), -1, 'Spin 30 (31 Black), bet 21 pays -1'; +is payout( 30, 22 ), -1, 'Spin 30 (31 Black), bet 22 pays -1'; +is payout( 30, 23 ), -1, 'Spin 30 (31 Black), bet 23 pays -1'; +is payout( 30, 24 ), -1, 'Spin 30 (31 Black), bet 24 pays -1'; +is payout( 30, 25 ), -1, 'Spin 30 (31 Black), bet 25 pays -1'; +is payout( 30, 26 ), -1, 'Spin 30 (31 Black), bet 26 pays -1'; +is payout( 30, 27 ), -1, 'Spin 30 (31 Black), bet 27 pays -1'; +is payout( 30, 28 ), -1, 'Spin 30 (31 Black), bet 28 pays -1'; +is payout( 30, 29 ), -1, 'Spin 30 (31 Black), bet 29 pays -1'; +is payout( 30, 30 ), -1, 'Spin 30 (31 Black), bet 30 pays -1'; +is payout( 30, 31 ), 35, 'Spin 30 (31 Black), bet 31 pays 35'; +is payout( 30, 32 ), -1, 'Spin 30 (31 Black), bet 32 pays -1'; +is payout( 30, 33 ), -1, 'Spin 30 (31 Black), bet 33 pays -1'; +is payout( 30, 34 ), -1, 'Spin 30 (31 Black), bet 34 pays -1'; +is payout( 30, 35 ), -1, 'Spin 30 (31 Black), bet 35 pays -1'; +is payout( 30, 36 ), -1, 'Spin 30 (31 Black), bet 36 pays -1'; +is payout( 30, 37 ), -1, 'Spin 30 (31 Black), bet 37 pays -1'; +is payout( 30, 38 ), -1, 'Spin 30 (31 Black), bet 38 pays -1'; +is payout( 30, 39 ), 2, 'Spin 30 (31 Black), bet 39 pays 2'; +is payout( 30, 40 ), 2, 'Spin 30 (31 Black), bet 40 pays 2'; +is payout( 30, 41 ), -1, 'Spin 30 (31 Black), bet 41 pays -1'; +is payout( 30, 42 ), -1, 'Spin 30 (31 Black), bet 42 pays -1'; +is payout( 30, 43 ), -1, 'Spin 30 (31 Black), bet 43 pays -1'; +is payout( 30, 44 ), 1, 'Spin 30 (31 Black), bet 44 pays 1'; +is payout( 30, 45 ), -1, 'Spin 30 (31 Black), bet 45 pays -1'; +is payout( 30, 46 ), 1, 'Spin 30 (31 Black), bet 46 pays 1'; +is payout( 30, 47 ), -1, 'Spin 30 (31 Black), bet 47 pays -1'; +is payout( 30, 48 ), 1, 'Spin 30 (31 Black), bet 48 pays 1'; +is payout( 30, 49 ), -1, 'Spin 30 (31 Black), bet 49 pays -1'; +is payout( 30, 50 ), -1, 'Spin 30 (31 Black), bet 50 pays -1'; +is format_spin( 31 ), '32 Red', 'Spin 31 is 32 Red'; +is payout( 31, 1 ), -1, 'Spin 31 (32 Red), bet 1 pays -1'; +is payout( 31, 2 ), -1, 'Spin 31 (32 Red), bet 2 pays -1'; +is payout( 31, 3 ), -1, 'Spin 31 (32 Red), bet 3 pays -1'; +is payout( 31, 4 ), -1, 'Spin 31 (32 Red), bet 4 pays -1'; +is payout( 31, 5 ), -1, 'Spin 31 (32 Red), bet 5 pays -1'; +is payout( 31, 6 ), -1, 'Spin 31 (32 Red), bet 6 pays -1'; +is payout( 31, 7 ), -1, 'Spin 31 (32 Red), bet 7 pays -1'; +is payout( 31, 8 ), -1, 'Spin 31 (32 Red), bet 8 pays -1'; +is payout( 31, 9 ), -1, 'Spin 31 (32 Red), bet 9 pays -1'; +is payout( 31, 10 ), -1, 'Spin 31 (32 Red), bet 10 pays -1'; +is payout( 31, 11 ), -1, 'Spin 31 (32 Red), bet 11 pays -1'; +is payout( 31, 12 ), -1, 'Spin 31 (32 Red), bet 12 pays -1'; +is payout( 31, 13 ), -1, 'Spin 31 (32 Red), bet 13 pays -1'; +is payout( 31, 14 ), -1, 'Spin 31 (32 Red), bet 14 pays -1'; +is payout( 31, 15 ), -1, 'Spin 31 (32 Red), bet 15 pays -1'; +is payout( 31, 16 ), -1, 'Spin 31 (32 Red), bet 16 pays -1'; +is payout( 31, 17 ), -1, 'Spin 31 (32 Red), bet 17 pays -1'; +is payout( 31, 18 ), -1, 'Spin 31 (32 Red), bet 18 pays -1'; +is payout( 31, 19 ), -1, 'Spin 31 (32 Red), bet 19 pays -1'; +is payout( 31, 20 ), -1, 'Spin 31 (32 Red), bet 20 pays -1'; +is payout( 31, 21 ), -1, 'Spin 31 (32 Red), bet 21 pays -1'; +is payout( 31, 22 ), -1, 'Spin 31 (32 Red), bet 22 pays -1'; +is payout( 31, 23 ), -1, 'Spin 31 (32 Red), bet 23 pays -1'; +is payout( 31, 24 ), -1, 'Spin 31 (32 Red), bet 24 pays -1'; +is payout( 31, 25 ), -1, 'Spin 31 (32 Red), bet 25 pays -1'; +is payout( 31, 26 ), -1, 'Spin 31 (32 Red), bet 26 pays -1'; +is payout( 31, 27 ), -1, 'Spin 31 (32 Red), bet 27 pays -1'; +is payout( 31, 28 ), -1, 'Spin 31 (32 Red), bet 28 pays -1'; +is payout( 31, 29 ), -1, 'Spin 31 (32 Red), bet 29 pays -1'; +is payout( 31, 30 ), -1, 'Spin 31 (32 Red), bet 30 pays -1'; +is payout( 31, 31 ), -1, 'Spin 31 (32 Red), bet 31 pays -1'; +is payout( 31, 32 ), 35, 'Spin 31 (32 Red), bet 32 pays 35'; +is payout( 31, 33 ), -1, 'Spin 31 (32 Red), bet 33 pays -1'; +is payout( 31, 34 ), -1, 'Spin 31 (32 Red), bet 34 pays -1'; +is payout( 31, 35 ), -1, 'Spin 31 (32 Red), bet 35 pays -1'; +is payout( 31, 36 ), -1, 'Spin 31 (32 Red), bet 36 pays -1'; +is payout( 31, 37 ), -1, 'Spin 31 (32 Red), bet 37 pays -1'; +is payout( 31, 38 ), -1, 'Spin 31 (32 Red), bet 38 pays -1'; +is payout( 31, 39 ), 2, 'Spin 31 (32 Red), bet 39 pays 2'; +is payout( 31, 40 ), -1, 'Spin 31 (32 Red), bet 40 pays -1'; +is payout( 31, 41 ), 2, 'Spin 31 (32 Red), bet 41 pays 2'; +is payout( 31, 42 ), -1, 'Spin 31 (32 Red), bet 42 pays -1'; +is payout( 31, 43 ), -1, 'Spin 31 (32 Red), bet 43 pays -1'; +is payout( 31, 44 ), 1, 'Spin 31 (32 Red), bet 44 pays 1'; +is payout( 31, 45 ), 1, 'Spin 31 (32 Red), bet 45 pays 1'; +is payout( 31, 46 ), -1, 'Spin 31 (32 Red), bet 46 pays -1'; +is payout( 31, 47 ), 1, 'Spin 31 (32 Red), bet 47 pays 1'; +is payout( 31, 48 ), -1, 'Spin 31 (32 Red), bet 48 pays -1'; +is payout( 31, 49 ), -1, 'Spin 31 (32 Red), bet 49 pays -1'; +is payout( 31, 50 ), -1, 'Spin 31 (32 Red), bet 50 pays -1'; +is format_spin( 32 ), '33 Black', 'Spin 32 is 33 Black'; +is payout( 32, 1 ), -1, 'Spin 32 (33 Black), bet 1 pays -1'; +is payout( 32, 2 ), -1, 'Spin 32 (33 Black), bet 2 pays -1'; +is payout( 32, 3 ), -1, 'Spin 32 (33 Black), bet 3 pays -1'; +is payout( 32, 4 ), -1, 'Spin 32 (33 Black), bet 4 pays -1'; +is payout( 32, 5 ), -1, 'Spin 32 (33 Black), bet 5 pays -1'; +is payout( 32, 6 ), -1, 'Spin 32 (33 Black), bet 6 pays -1'; +is payout( 32, 7 ), -1, 'Spin 32 (33 Black), bet 7 pays -1'; +is payout( 32, 8 ), -1, 'Spin 32 (33 Black), bet 8 pays -1'; +is payout( 32, 9 ), -1, 'Spin 32 (33 Black), bet 9 pays -1'; +is payout( 32, 10 ), -1, 'Spin 32 (33 Black), bet 10 pays -1'; +is payout( 32, 11 ), -1, 'Spin 32 (33 Black), bet 11 pays -1'; +is payout( 32, 12 ), -1, 'Spin 32 (33 Black), bet 12 pays -1'; +is payout( 32, 13 ), -1, 'Spin 32 (33 Black), bet 13 pays -1'; +is payout( 32, 14 ), -1, 'Spin 32 (33 Black), bet 14 pays -1'; +is payout( 32, 15 ), -1, 'Spin 32 (33 Black), bet 15 pays -1'; +is payout( 32, 16 ), -1, 'Spin 32 (33 Black), bet 16 pays -1'; +is payout( 32, 17 ), -1, 'Spin 32 (33 Black), bet 17 pays -1'; +is payout( 32, 18 ), -1, 'Spin 32 (33 Black), bet 18 pays -1'; +is payout( 32, 19 ), -1, 'Spin 32 (33 Black), bet 19 pays -1'; +is payout( 32, 20 ), -1, 'Spin 32 (33 Black), bet 20 pays -1'; +is payout( 32, 21 ), -1, 'Spin 32 (33 Black), bet 21 pays -1'; +is payout( 32, 22 ), -1, 'Spin 32 (33 Black), bet 22 pays -1'; +is payout( 32, 23 ), -1, 'Spin 32 (33 Black), bet 23 pays -1'; +is payout( 32, 24 ), -1, 'Spin 32 (33 Black), bet 24 pays -1'; +is payout( 32, 25 ), -1, 'Spin 32 (33 Black), bet 25 pays -1'; +is payout( 32, 26 ), -1, 'Spin 32 (33 Black), bet 26 pays -1'; +is payout( 32, 27 ), -1, 'Spin 32 (33 Black), bet 27 pays -1'; +is payout( 32, 28 ), -1, 'Spin 32 (33 Black), bet 28 pays -1'; +is payout( 32, 29 ), -1, 'Spin 32 (33 Black), bet 29 pays -1'; +is payout( 32, 30 ), -1, 'Spin 32 (33 Black), bet 30 pays -1'; +is payout( 32, 31 ), -1, 'Spin 32 (33 Black), bet 31 pays -1'; +is payout( 32, 32 ), -1, 'Spin 32 (33 Black), bet 32 pays -1'; +is payout( 32, 33 ), 35, 'Spin 32 (33 Black), bet 33 pays 35'; +is payout( 32, 34 ), -1, 'Spin 32 (33 Black), bet 34 pays -1'; +is payout( 32, 35 ), -1, 'Spin 32 (33 Black), bet 35 pays -1'; +is payout( 32, 36 ), -1, 'Spin 32 (33 Black), bet 36 pays -1'; +is payout( 32, 37 ), -1, 'Spin 32 (33 Black), bet 37 pays -1'; +is payout( 32, 38 ), -1, 'Spin 32 (33 Black), bet 38 pays -1'; +is payout( 32, 39 ), 2, 'Spin 32 (33 Black), bet 39 pays 2'; +is payout( 32, 40 ), -1, 'Spin 32 (33 Black), bet 40 pays -1'; +is payout( 32, 41 ), -1, 'Spin 32 (33 Black), bet 41 pays -1'; +is payout( 32, 42 ), 2, 'Spin 32 (33 Black), bet 42 pays 2'; +is payout( 32, 43 ), -1, 'Spin 32 (33 Black), bet 43 pays -1'; +is payout( 32, 44 ), 1, 'Spin 32 (33 Black), bet 44 pays 1'; +is payout( 32, 45 ), -1, 'Spin 32 (33 Black), bet 45 pays -1'; +is payout( 32, 46 ), 1, 'Spin 32 (33 Black), bet 46 pays 1'; +is payout( 32, 47 ), -1, 'Spin 32 (33 Black), bet 47 pays -1'; +is payout( 32, 48 ), 1, 'Spin 32 (33 Black), bet 48 pays 1'; +is payout( 32, 49 ), -1, 'Spin 32 (33 Black), bet 49 pays -1'; +is payout( 32, 50 ), -1, 'Spin 32 (33 Black), bet 50 pays -1'; +is format_spin( 33 ), '34 Red', 'Spin 33 is 34 Red'; +is payout( 33, 1 ), -1, 'Spin 33 (34 Red), bet 1 pays -1'; +is payout( 33, 2 ), -1, 'Spin 33 (34 Red), bet 2 pays -1'; +is payout( 33, 3 ), -1, 'Spin 33 (34 Red), bet 3 pays -1'; +is payout( 33, 4 ), -1, 'Spin 33 (34 Red), bet 4 pays -1'; +is payout( 33, 5 ), -1, 'Spin 33 (34 Red), bet 5 pays -1'; +is payout( 33, 6 ), -1, 'Spin 33 (34 Red), bet 6 pays -1'; +is payout( 33, 7 ), -1, 'Spin 33 (34 Red), bet 7 pays -1'; +is payout( 33, 8 ), -1, 'Spin 33 (34 Red), bet 8 pays -1'; +is payout( 33, 9 ), -1, 'Spin 33 (34 Red), bet 9 pays -1'; +is payout( 33, 10 ), -1, 'Spin 33 (34 Red), bet 10 pays -1'; +is payout( 33, 11 ), -1, 'Spin 33 (34 Red), bet 11 pays -1'; +is payout( 33, 12 ), -1, 'Spin 33 (34 Red), bet 12 pays -1'; +is payout( 33, 13 ), -1, 'Spin 33 (34 Red), bet 13 pays -1'; +is payout( 33, 14 ), -1, 'Spin 33 (34 Red), bet 14 pays -1'; +is payout( 33, 15 ), -1, 'Spin 33 (34 Red), bet 15 pays -1'; +is payout( 33, 16 ), -1, 'Spin 33 (34 Red), bet 16 pays -1'; +is payout( 33, 17 ), -1, 'Spin 33 (34 Red), bet 17 pays -1'; +is payout( 33, 18 ), -1, 'Spin 33 (34 Red), bet 18 pays -1'; +is payout( 33, 19 ), -1, 'Spin 33 (34 Red), bet 19 pays -1'; +is payout( 33, 20 ), -1, 'Spin 33 (34 Red), bet 20 pays -1'; +is payout( 33, 21 ), -1, 'Spin 33 (34 Red), bet 21 pays -1'; +is payout( 33, 22 ), -1, 'Spin 33 (34 Red), bet 22 pays -1'; +is payout( 33, 23 ), -1, 'Spin 33 (34 Red), bet 23 pays -1'; +is payout( 33, 24 ), -1, 'Spin 33 (34 Red), bet 24 pays -1'; +is payout( 33, 25 ), -1, 'Spin 33 (34 Red), bet 25 pays -1'; +is payout( 33, 26 ), -1, 'Spin 33 (34 Red), bet 26 pays -1'; +is payout( 33, 27 ), -1, 'Spin 33 (34 Red), bet 27 pays -1'; +is payout( 33, 28 ), -1, 'Spin 33 (34 Red), bet 28 pays -1'; +is payout( 33, 29 ), -1, 'Spin 33 (34 Red), bet 29 pays -1'; +is payout( 33, 30 ), -1, 'Spin 33 (34 Red), bet 30 pays -1'; +is payout( 33, 31 ), -1, 'Spin 33 (34 Red), bet 31 pays -1'; +is payout( 33, 32 ), -1, 'Spin 33 (34 Red), bet 32 pays -1'; +is payout( 33, 33 ), -1, 'Spin 33 (34 Red), bet 33 pays -1'; +is payout( 33, 34 ), 35, 'Spin 33 (34 Red), bet 34 pays 35'; +is payout( 33, 35 ), -1, 'Spin 33 (34 Red), bet 35 pays -1'; +is payout( 33, 36 ), -1, 'Spin 33 (34 Red), bet 36 pays -1'; +is payout( 33, 37 ), -1, 'Spin 33 (34 Red), bet 37 pays -1'; +is payout( 33, 38 ), -1, 'Spin 33 (34 Red), bet 38 pays -1'; +is payout( 33, 39 ), 2, 'Spin 33 (34 Red), bet 39 pays 2'; +is payout( 33, 40 ), 2, 'Spin 33 (34 Red), bet 40 pays 2'; +is payout( 33, 41 ), -1, 'Spin 33 (34 Red), bet 41 pays -1'; +is payout( 33, 42 ), -1, 'Spin 33 (34 Red), bet 42 pays -1'; +is payout( 33, 43 ), -1, 'Spin 33 (34 Red), bet 43 pays -1'; +is payout( 33, 44 ), 1, 'Spin 33 (34 Red), bet 44 pays 1'; +is payout( 33, 45 ), 1, 'Spin 33 (34 Red), bet 45 pays 1'; +is payout( 33, 46 ), -1, 'Spin 33 (34 Red), bet 46 pays -1'; +is payout( 33, 47 ), 1, 'Spin 33 (34 Red), bet 47 pays 1'; +is payout( 33, 48 ), -1, 'Spin 33 (34 Red), bet 48 pays -1'; +is payout( 33, 49 ), -1, 'Spin 33 (34 Red), bet 49 pays -1'; +is payout( 33, 50 ), -1, 'Spin 33 (34 Red), bet 50 pays -1'; +is format_spin( 34 ), '35 Black', 'Spin 34 is 35 Black'; +is payout( 34, 1 ), -1, 'Spin 34 (35 Black), bet 1 pays -1'; +is payout( 34, 2 ), -1, 'Spin 34 (35 Black), bet 2 pays -1'; +is payout( 34, 3 ), -1, 'Spin 34 (35 Black), bet 3 pays -1'; +is payout( 34, 4 ), -1, 'Spin 34 (35 Black), bet 4 pays -1'; +is payout( 34, 5 ), -1, 'Spin 34 (35 Black), bet 5 pays -1'; +is payout( 34, 6 ), -1, 'Spin 34 (35 Black), bet 6 pays -1'; +is payout( 34, 7 ), -1, 'Spin 34 (35 Black), bet 7 pays -1'; +is payout( 34, 8 ), -1, 'Spin 34 (35 Black), bet 8 pays -1'; +is payout( 34, 9 ), -1, 'Spin 34 (35 Black), bet 9 pays -1'; +is payout( 34, 10 ), -1, 'Spin 34 (35 Black), bet 10 pays -1'; +is payout( 34, 11 ), -1, 'Spin 34 (35 Black), bet 11 pays -1'; +is payout( 34, 12 ), -1, 'Spin 34 (35 Black), bet 12 pays -1'; +is payout( 34, 13 ), -1, 'Spin 34 (35 Black), bet 13 pays -1'; +is payout( 34, 14 ), -1, 'Spin 34 (35 Black), bet 14 pays -1'; +is payout( 34, 15 ), -1, 'Spin 34 (35 Black), bet 15 pays -1'; +is payout( 34, 16 ), -1, 'Spin 34 (35 Black), bet 16 pays -1'; +is payout( 34, 17 ), -1, 'Spin 34 (35 Black), bet 17 pays -1'; +is payout( 34, 18 ), -1, 'Spin 34 (35 Black), bet 18 pays -1'; +is payout( 34, 19 ), -1, 'Spin 34 (35 Black), bet 19 pays -1'; +is payout( 34, 20 ), -1, 'Spin 34 (35 Black), bet 20 pays -1'; +is payout( 34, 21 ), -1, 'Spin 34 (35 Black), bet 21 pays -1'; +is payout( 34, 22 ), -1, 'Spin 34 (35 Black), bet 22 pays -1'; +is payout( 34, 23 ), -1, 'Spin 34 (35 Black), bet 23 pays -1'; +is payout( 34, 24 ), -1, 'Spin 34 (35 Black), bet 24 pays -1'; +is payout( 34, 25 ), -1, 'Spin 34 (35 Black), bet 25 pays -1'; +is payout( 34, 26 ), -1, 'Spin 34 (35 Black), bet 26 pays -1'; +is payout( 34, 27 ), -1, 'Spin 34 (35 Black), bet 27 pays -1'; +is payout( 34, 28 ), -1, 'Spin 34 (35 Black), bet 28 pays -1'; +is payout( 34, 29 ), -1, 'Spin 34 (35 Black), bet 29 pays -1'; +is payout( 34, 30 ), -1, 'Spin 34 (35 Black), bet 30 pays -1'; +is payout( 34, 31 ), -1, 'Spin 34 (35 Black), bet 31 pays -1'; +is payout( 34, 32 ), -1, 'Spin 34 (35 Black), bet 32 pays -1'; +is payout( 34, 33 ), -1, 'Spin 34 (35 Black), bet 33 pays -1'; +is payout( 34, 34 ), -1, 'Spin 34 (35 Black), bet 34 pays -1'; +is payout( 34, 35 ), 35, 'Spin 34 (35 Black), bet 35 pays 35'; +is payout( 34, 36 ), -1, 'Spin 34 (35 Black), bet 36 pays -1'; +is payout( 34, 37 ), -1, 'Spin 34 (35 Black), bet 37 pays -1'; +is payout( 34, 38 ), -1, 'Spin 34 (35 Black), bet 38 pays -1'; +is payout( 34, 39 ), 2, 'Spin 34 (35 Black), bet 39 pays 2'; +is payout( 34, 40 ), -1, 'Spin 34 (35 Black), bet 40 pays -1'; +is payout( 34, 41 ), 2, 'Spin 34 (35 Black), bet 41 pays 2'; +is payout( 34, 42 ), -1, 'Spin 34 (35 Black), bet 42 pays -1'; +is payout( 34, 43 ), -1, 'Spin 34 (35 Black), bet 43 pays -1'; +is payout( 34, 44 ), 1, 'Spin 34 (35 Black), bet 44 pays 1'; +is payout( 34, 45 ), -1, 'Spin 34 (35 Black), bet 45 pays -1'; +is payout( 34, 46 ), 1, 'Spin 34 (35 Black), bet 46 pays 1'; +is payout( 34, 47 ), -1, 'Spin 34 (35 Black), bet 47 pays -1'; +is payout( 34, 48 ), 1, 'Spin 34 (35 Black), bet 48 pays 1'; +is payout( 34, 49 ), -1, 'Spin 34 (35 Black), bet 49 pays -1'; +is payout( 34, 50 ), -1, 'Spin 34 (35 Black), bet 50 pays -1'; +is format_spin( 35 ), '36 Red', 'Spin 35 is 36 Red'; +is payout( 35, 1 ), -1, 'Spin 35 (36 Red), bet 1 pays -1'; +is payout( 35, 2 ), -1, 'Spin 35 (36 Red), bet 2 pays -1'; +is payout( 35, 3 ), -1, 'Spin 35 (36 Red), bet 3 pays -1'; +is payout( 35, 4 ), -1, 'Spin 35 (36 Red), bet 4 pays -1'; +is payout( 35, 5 ), -1, 'Spin 35 (36 Red), bet 5 pays -1'; +is payout( 35, 6 ), -1, 'Spin 35 (36 Red), bet 6 pays -1'; +is payout( 35, 7 ), -1, 'Spin 35 (36 Red), bet 7 pays -1'; +is payout( 35, 8 ), -1, 'Spin 35 (36 Red), bet 8 pays -1'; +is payout( 35, 9 ), -1, 'Spin 35 (36 Red), bet 9 pays -1'; +is payout( 35, 10 ), -1, 'Spin 35 (36 Red), bet 10 pays -1'; +is payout( 35, 11 ), -1, 'Spin 35 (36 Red), bet 11 pays -1'; +is payout( 35, 12 ), -1, 'Spin 35 (36 Red), bet 12 pays -1'; +is payout( 35, 13 ), -1, 'Spin 35 (36 Red), bet 13 pays -1'; +is payout( 35, 14 ), -1, 'Spin 35 (36 Red), bet 14 pays -1'; +is payout( 35, 15 ), -1, 'Spin 35 (36 Red), bet 15 pays -1'; +is payout( 35, 16 ), -1, 'Spin 35 (36 Red), bet 16 pays -1'; +is payout( 35, 17 ), -1, 'Spin 35 (36 Red), bet 17 pays -1'; +is payout( 35, 18 ), -1, 'Spin 35 (36 Red), bet 18 pays -1'; +is payout( 35, 19 ), -1, 'Spin 35 (36 Red), bet 19 pays -1'; +is payout( 35, 20 ), -1, 'Spin 35 (36 Red), bet 20 pays -1'; +is payout( 35, 21 ), -1, 'Spin 35 (36 Red), bet 21 pays -1'; +is payout( 35, 22 ), -1, 'Spin 35 (36 Red), bet 22 pays -1'; +is payout( 35, 23 ), -1, 'Spin 35 (36 Red), bet 23 pays -1'; +is payout( 35, 24 ), -1, 'Spin 35 (36 Red), bet 24 pays -1'; +is payout( 35, 25 ), -1, 'Spin 35 (36 Red), bet 25 pays -1'; +is payout( 35, 26 ), -1, 'Spin 35 (36 Red), bet 26 pays -1'; +is payout( 35, 27 ), -1, 'Spin 35 (36 Red), bet 27 pays -1'; +is payout( 35, 28 ), -1, 'Spin 35 (36 Red), bet 28 pays -1'; +is payout( 35, 29 ), -1, 'Spin 35 (36 Red), bet 29 pays -1'; +is payout( 35, 30 ), -1, 'Spin 35 (36 Red), bet 30 pays -1'; +is payout( 35, 31 ), -1, 'Spin 35 (36 Red), bet 31 pays -1'; +is payout( 35, 32 ), -1, 'Spin 35 (36 Red), bet 32 pays -1'; +is payout( 35, 33 ), -1, 'Spin 35 (36 Red), bet 33 pays -1'; +is payout( 35, 34 ), -1, 'Spin 35 (36 Red), bet 34 pays -1'; +is payout( 35, 35 ), -1, 'Spin 35 (36 Red), bet 35 pays -1'; +is payout( 35, 36 ), 35, 'Spin 35 (36 Red), bet 36 pays 35'; +is payout( 35, 37 ), -1, 'Spin 35 (36 Red), bet 37 pays -1'; +is payout( 35, 38 ), -1, 'Spin 35 (36 Red), bet 38 pays -1'; +is payout( 35, 39 ), 2, 'Spin 35 (36 Red), bet 39 pays 2'; +is payout( 35, 40 ), -1, 'Spin 35 (36 Red), bet 40 pays -1'; +is payout( 35, 41 ), -1, 'Spin 35 (36 Red), bet 41 pays -1'; +is payout( 35, 42 ), 2, 'Spin 35 (36 Red), bet 42 pays 2'; +is payout( 35, 43 ), -1, 'Spin 35 (36 Red), bet 43 pays -1'; +is payout( 35, 44 ), 1, 'Spin 35 (36 Red), bet 44 pays 1'; +is payout( 35, 45 ), 1, 'Spin 35 (36 Red), bet 45 pays 1'; +is payout( 35, 46 ), -1, 'Spin 35 (36 Red), bet 46 pays -1'; +is payout( 35, 47 ), 1, 'Spin 35 (36 Red), bet 47 pays 1'; +is payout( 35, 48 ), -1, 'Spin 35 (36 Red), bet 48 pays -1'; +is payout( 35, 49 ), -1, 'Spin 35 (36 Red), bet 49 pays -1'; +is payout( 35, 50 ), -1, 'Spin 35 (36 Red), bet 50 pays -1'; +is format_spin( 36 ), '0', 'Spin 36 is 0'; +is payout( 36, 1 ), -1, 'Spin 36 (0), bet 1 pays -1'; +is payout( 36, 2 ), -1, 'Spin 36 (0), bet 2 pays -1'; +is payout( 36, 3 ), -1, 'Spin 36 (0), bet 3 pays -1'; +is payout( 36, 4 ), -1, 'Spin 36 (0), bet 4 pays -1'; +is payout( 36, 5 ), -1, 'Spin 36 (0), bet 5 pays -1'; +is payout( 36, 6 ), -1, 'Spin 36 (0), bet 6 pays -1'; +is payout( 36, 7 ), -1, 'Spin 36 (0), bet 7 pays -1'; +is payout( 36, 8 ), -1, 'Spin 36 (0), bet 8 pays -1'; +is payout( 36, 9 ), -1, 'Spin 36 (0), bet 9 pays -1'; +is payout( 36, 10 ), -1, 'Spin 36 (0), bet 10 pays -1'; +is payout( 36, 11 ), -1, 'Spin 36 (0), bet 11 pays -1'; +is payout( 36, 12 ), -1, 'Spin 36 (0), bet 12 pays -1'; +is payout( 36, 13 ), -1, 'Spin 36 (0), bet 13 pays -1'; +is payout( 36, 14 ), -1, 'Spin 36 (0), bet 14 pays -1'; +is payout( 36, 15 ), -1, 'Spin 36 (0), bet 15 pays -1'; +is payout( 36, 16 ), -1, 'Spin 36 (0), bet 16 pays -1'; +is payout( 36, 17 ), -1, 'Spin 36 (0), bet 17 pays -1'; +is payout( 36, 18 ), -1, 'Spin 36 (0), bet 18 pays -1'; +is payout( 36, 19 ), -1, 'Spin 36 (0), bet 19 pays -1'; +is payout( 36, 20 ), -1, 'Spin 36 (0), bet 20 pays -1'; +is payout( 36, 21 ), -1, 'Spin 36 (0), bet 21 pays -1'; +is payout( 36, 22 ), -1, 'Spin 36 (0), bet 22 pays -1'; +is payout( 36, 23 ), -1, 'Spin 36 (0), bet 23 pays -1'; +is payout( 36, 24 ), -1, 'Spin 36 (0), bet 24 pays -1'; +is payout( 36, 25 ), -1, 'Spin 36 (0), bet 25 pays -1'; +is payout( 36, 26 ), -1, 'Spin 36 (0), bet 26 pays -1'; +is payout( 36, 27 ), -1, 'Spin 36 (0), bet 27 pays -1'; +is payout( 36, 28 ), -1, 'Spin 36 (0), bet 28 pays -1'; +is payout( 36, 29 ), -1, 'Spin 36 (0), bet 29 pays -1'; +is payout( 36, 30 ), -1, 'Spin 36 (0), bet 30 pays -1'; +is payout( 36, 31 ), -1, 'Spin 36 (0), bet 31 pays -1'; +is payout( 36, 32 ), -1, 'Spin 36 (0), bet 32 pays -1'; +is payout( 36, 33 ), -1, 'Spin 36 (0), bet 33 pays -1'; +is payout( 36, 34 ), -1, 'Spin 36 (0), bet 34 pays -1'; +is payout( 36, 35 ), -1, 'Spin 36 (0), bet 35 pays -1'; +is payout( 36, 36 ), -1, 'Spin 36 (0), bet 36 pays -1'; +is payout( 36, 37 ), -1, 'Spin 36 (0), bet 37 pays -1'; +is payout( 36, 38 ), -1, 'Spin 36 (0), bet 38 pays -1'; +is payout( 36, 39 ), -1, 'Spin 36 (0), bet 39 pays -1'; +is payout( 36, 40 ), -1, 'Spin 36 (0), bet 40 pays -1'; +is payout( 36, 41 ), -1, 'Spin 36 (0), bet 41 pays -1'; +is payout( 36, 42 ), -1, 'Spin 36 (0), bet 42 pays -1'; +is payout( 36, 43 ), -1, 'Spin 36 (0), bet 43 pays -1'; +is payout( 36, 44 ), -1, 'Spin 36 (0), bet 44 pays -1'; +is payout( 36, 45 ), -1, 'Spin 36 (0), bet 45 pays -1'; +is payout( 36, 46 ), -1, 'Spin 36 (0), bet 46 pays -1'; +is payout( 36, 47 ), -1, 'Spin 36 (0), bet 47 pays -1'; +is payout( 36, 48 ), -1, 'Spin 36 (0), bet 48 pays -1'; +is payout( 36, 49 ), 35, 'Spin 36 (0), bet 49 pays 35'; +is payout( 36, 50 ), -1, 'Spin 36 (0), bet 50 pays -1'; +is format_spin( 37 ), '00', 'Spin 37 is 00'; +is payout( 37, 1 ), -1, 'Spin 37 (00), bet 1 pays -1'; +is payout( 37, 2 ), -1, 'Spin 37 (00), bet 2 pays -1'; +is payout( 37, 3 ), -1, 'Spin 37 (00), bet 3 pays -1'; +is payout( 37, 4 ), -1, 'Spin 37 (00), bet 4 pays -1'; +is payout( 37, 5 ), -1, 'Spin 37 (00), bet 5 pays -1'; +is payout( 37, 6 ), -1, 'Spin 37 (00), bet 6 pays -1'; +is payout( 37, 7 ), -1, 'Spin 37 (00), bet 7 pays -1'; +is payout( 37, 8 ), -1, 'Spin 37 (00), bet 8 pays -1'; +is payout( 37, 9 ), -1, 'Spin 37 (00), bet 9 pays -1'; +is payout( 37, 10 ), -1, 'Spin 37 (00), bet 10 pays -1'; +is payout( 37, 11 ), -1, 'Spin 37 (00), bet 11 pays -1'; +is payout( 37, 12 ), -1, 'Spin 37 (00), bet 12 pays -1'; +is payout( 37, 13 ), -1, 'Spin 37 (00), bet 13 pays -1'; +is payout( 37, 14 ), -1, 'Spin 37 (00), bet 14 pays -1'; +is payout( 37, 15 ), -1, 'Spin 37 (00), bet 15 pays -1'; +is payout( 37, 16 ), -1, 'Spin 37 (00), bet 16 pays -1'; +is payout( 37, 17 ), -1, 'Spin 37 (00), bet 17 pays -1'; +is payout( 37, 18 ), -1, 'Spin 37 (00), bet 18 pays -1'; +is payout( 37, 19 ), -1, 'Spin 37 (00), bet 19 pays -1'; +is payout( 37, 20 ), -1, 'Spin 37 (00), bet 20 pays -1'; +is payout( 37, 21 ), -1, 'Spin 37 (00), bet 21 pays -1'; +is payout( 37, 22 ), -1, 'Spin 37 (00), bet 22 pays -1'; +is payout( 37, 23 ), -1, 'Spin 37 (00), bet 23 pays -1'; +is payout( 37, 24 ), -1, 'Spin 37 (00), bet 24 pays -1'; +is payout( 37, 25 ), -1, 'Spin 37 (00), bet 25 pays -1'; +is payout( 37, 26 ), -1, 'Spin 37 (00), bet 26 pays -1'; +is payout( 37, 27 ), -1, 'Spin 37 (00), bet 27 pays -1'; +is payout( 37, 28 ), -1, 'Spin 37 (00), bet 28 pays -1'; +is payout( 37, 29 ), -1, 'Spin 37 (00), bet 29 pays -1'; +is payout( 37, 30 ), -1, 'Spin 37 (00), bet 30 pays -1'; +is payout( 37, 31 ), -1, 'Spin 37 (00), bet 31 pays -1'; +is payout( 37, 32 ), -1, 'Spin 37 (00), bet 32 pays -1'; +is payout( 37, 33 ), -1, 'Spin 37 (00), bet 33 pays -1'; +is payout( 37, 34 ), -1, 'Spin 37 (00), bet 34 pays -1'; +is payout( 37, 35 ), -1, 'Spin 37 (00), bet 35 pays -1'; +is payout( 37, 36 ), -1, 'Spin 37 (00), bet 36 pays -1'; +is payout( 37, 37 ), -1, 'Spin 37 (00), bet 37 pays -1'; +is payout( 37, 38 ), -1, 'Spin 37 (00), bet 38 pays -1'; +is payout( 37, 39 ), -1, 'Spin 37 (00), bet 39 pays -1'; +is payout( 37, 40 ), -1, 'Spin 37 (00), bet 40 pays -1'; +is payout( 37, 41 ), -1, 'Spin 37 (00), bet 41 pays -1'; +is payout( 37, 42 ), -1, 'Spin 37 (00), bet 42 pays -1'; +is payout( 37, 43 ), -1, 'Spin 37 (00), bet 43 pays -1'; +is payout( 37, 44 ), -1, 'Spin 37 (00), bet 44 pays -1'; +is payout( 37, 45 ), -1, 'Spin 37 (00), bet 45 pays -1'; +is payout( 37, 46 ), -1, 'Spin 37 (00), bet 46 pays -1'; +is payout( 37, 47 ), -1, 'Spin 37 (00), bet 47 pays -1'; +is payout( 37, 48 ), -1, 'Spin 37 (00), bet 48 pays -1'; +is payout( 37, 49 ), -1, 'Spin 37 (00), bet 49 pays -1'; +is payout( 37, 50 ), 35, 'Spin 37 (00), bet 50 pays 35'; + +done_testing; + +1; + +# ex: set textwidth=72 : diff --git a/75_Roulette/perl/roulette.pl b/75_Roulette/perl/roulette.pl new file mode 100755 index 00000000..ad3ce965 --- /dev/null +++ b/75_Roulette/perl/roulette.pl @@ -0,0 +1,319 @@ +#!/usr/bin/env perl + +use 5.010; # To get 'state' and 'say' + +use strict; # Require explicit declaration of variables +use warnings; # Enable optional compiler warnings + +use English; # Use more friendly names for Perl's magic variables +use POSIX qw{ strftime }; # Time formatting +use Term::ReadLine; # Prompt and return user input + +our $VERSION = '0.000_01'; + +# A main() function is not usual in Perl scripts. I have installed one +# here to make the script into a "modulino." The next line executes +# main() if and only if caller() returns false. It will do this if we +# were loaded by another Perl script but not otherwise. This was done so +# I could test the payout and spin formatting logic. +main() unless caller; + +sub main { + + print <<'EOD'; + ROULETTE + Creative Computing Morristown, New Jersey + + + + +Welcome to the roulette table. + +EOD + + if ( get_yes_no( 'Do you want instructions' ) ) { + print <<'EOD'; + +This is the betting layout + (*=red) + + 1* 2 3* + 4 5* 6 + 7* 8 9* +10 11 12* +--------------- +13 14* 15 +16* 17 18* +19* 20 21* +22 23* 24 +--------------- +25* 26 27* +28 29 30* +31 32* 33 +34* 35 36* +--------------- + 00 0 + +Types of bets: + +The numbers 1 to 36 signify a straight bet +on that number. +These pay off 35:1 + +The 2:1 bets are: + 37) 1-12 40) first column + 38) 13-24 41) second column + 39) 25-36 42) third column + +The even money bets are: + 43) 1-18 46) odd + 44) 19-36 47) red + 45) even 48) black + + 49) 0 and 50) 00 pay off 35:1 + Note: 0 and 00 do not count under any + bets except their own. + +When I ask for each bet, type the number +and the amount, separated by a comma. +For example: to bet $500 on black, type 48,500 +when I ask for a bet. + +The minimum bet is $5, the maximum is $500. + +EOD +} + + my $P = 1000; + my $D = 100000.; + + while ( 1 ) { # Iterate indefinitely + + my $Y = get_input( 'How many bets? ', + sub { m/ \A [0-9]+ \z /smx && $ARG > 0 && $ARG <= 50 }, + "Please enter a positive integer no greater than 50\n", + ); + my @B; + my @T; + foreach my $C ( 1 .. $Y ) { + my ( $X, $Z ) = split qr< , >smx, get_input( + "Number $C: ", + sub { m/ \A ( [0-9]+ ) , ( [0-9]+ ) \z /smx + && $1 > 0 && $1 <= 50 && $2 >= 5 && $2 <= 500 }, + "Please enter two comma-separated positive numbers\n", + ); + if ( $B[$X] ) { + say 'You made that bet once already, dum-dum.'; + redo; + } + $B[$X] = $Z; # BASIC does $B[$C] = $Z + $T[$C] = $X; + } + + print <<'EOD'; + + Spinning ... + +EOD + my $S = int rand 38; # Zero-based, versus 1-based in BASIC + + say format_spin( $S ); + + say ''; + + foreach my $C ( 1 .. $Y ) { + my $X = $T[$C]; + my $payout = payout( $S, $X ) * $B[$X]; + $D -= $payout; + $P += $payout; + if ( $payout > 0 ) { + say "You win $payout dollars on bet $C"; + } else { + $payout = -$payout; + say "You lose $payout dollars on bet $C"; + } + } + say "Totals\tMe\tYou"; + say "\t$D\t$P"; + say ''; + + + last unless get_yes_no( 'Again' ); + } + + say ''; + + if ( $P > 0 ) { + my $B = get_input( + 'To whom shall I make out the check? ', + ); + my $check_number = 1000 + int rand 9000; + my $todays_date = strftime( '%B %d, %Y', localtime ); + print <<"EOD"; + +------------------------------------------------------------ Check number $check_number + + $todays_date + +Pay to the order of ------ $B ----- \$$P + + The Memory Bank of New York + + The Computer + ---------X----- + +------------------------------------------------------------------------------- + +Come back soon! +EOD + } else { + print <<'EOD'; +Thanks for your money. +I'll use it to buy a solid gold roulette wheel +EOD + } +} + +{ + # Define the kind of each possible spin. 0 is '0' or '00', 1 is + # black, and 2 is red. We assign the values in a BEGIN block because + # execution never actually reaches this point in the script. + my @kind; + BEGIN { + @kind = ( 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 1, + 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 1, 2, 0, + 0 ); + } + + # Convert the spin (0-37) to its name on the wheel. + sub format_spin { + my ( $number ) = @_; + state $format = [ + sub { '0' x ( $_[0] - 35 ) }, + sub { sprintf '%s Black', $_[0] + 1 }, + sub { sprintf '%s Red', $_[0] + 1 }, + ]; + return $format->[$kind[$number]]( $number ); + } + + # Compute the payout given the spin (0-37) and the bet (1-50). + sub payout { + my ( $number, $bet ) = @_; + # We compute the payout on '0' and '00' directly, since under + # our rules they are only eligible for the 35-to-1 bet. + $kind[$number] + or return $number == $bet - 49 + 36 ? 35 : -1; + --$bet; # #bet is 1-based coming in + # Dispatch table for computing the payout for spins 0-36. + state $payout = [ + ( sub { $_[0] == $_[1] ? 35 : -1 } ) x 36, + ( sub { int( $_[0] / 12 ) == $_[1] - 36 ? 2 : -1 } ) x 3, + ( sub { $_[0] % 3 == $_[1] - 39 ? 2 : -1 } ) x 3, + ( sub { int( $_[0] / 18 ) == $_[1] - 42 ? 1 : -1 } ) x 2, + ( sub { $_[0] % 2 == 45 - $_[1] ? 1 : -1 } ) x 2, + ( sub { $kind[$_[0]] == 48 - $_[1] ? 1 : -1 } ) x 2, + ( sub { -1 } ) x 2, # Bet on '0' or '00' loses + ]; + return $payout->[$bet]->( $number, $bet ); + } +} + +# Get input from the user. The arguments are: +# * The prompt +# * A reference to validation code. This code receives the response in +# $ARG and returns true for a valid response. +# * A warning to print if the response is not valid. This must end in a +# return. +# The first valid response is returned. An end-of-file terminates the +# script. +sub get_input { + my ( $prompt, $validate, $warning ) = @ARG; + + # If no validator is passed, default to one that always returns + # true. + $validate ||= sub { 1 }; + + # Create the readline object. The 'state' causes the variable to be + # initialized only once, no matter how many times this subroutine is + # called. The do { ... } is a compound statement used because we + # need to tweak the created object before we store it. + state $term = do { + my $obj = Term::ReadLine->new( 'reverse' ); + $obj->ornaments( 0 ); + $obj; + }; + + while ( 1 ) { # Iterate indefinitely + + # Read the input into the topic variable, localized to prevent + # Spooky Action at a Distance. We exit on undef, which signals + # end-of-file. + exit unless defined( local $ARG = $term->readline( $prompt ) ); + + # Return the input if it is valid. + return $ARG if $validate->(); + + # Issue the warning, and go around the merry-go-round again. + warn $warning; + } +} + +# Get a yes-or-no answer. The argument is the prompt, which will have +# '? [y/n]: ' appended. The donkey work is done by get_input(), which is +# requested to validate the response as beginning with 'y' or 'n', +# case-insensitive. The return is a true value for 'y' and a false value +# for 'n'. +sub get_yes_no { + my ( $prompt ) = @ARG; + state $map_answer = { + n => 0, + y => 1, + }; + my $resp = lc get_input( + "$prompt? [y/n]: ", + sub { m/ \A [yn] /smxi }, + "Please respond 'y' or 'n'\n", + ); + return $map_answer->{ substr $resp, 0, 1 }; +} + +__END__ + +=head1 TITLE + +roulette - Play the game 'Roulette' from Basic Computer Games + +=head1 SYNOPSIS + + roulette.pl + +=head1 DETAILS + +This Perl script is a port of roulette, which is the 75th +entry in Basic Computer Games. + +The main internal changes are converting the roulette slot numbering to +0-based and replacing most of the payout logic with a dispatch table. +These changes were tested for correctness against the original BASIC. + +=head1 PORTED BY + +Thomas R. Wyant, III F + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2022 by Thomas R. Wyant, III + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl 5.10.0. For more details, see the Artistic +License 1.0 at +L, and/or the +Gnu GPL at L. + +This program is distributed in the hope that it will be useful, but +without any warranty; without even the implied warranty of +merchantability or fitness for a particular purpose. + +=cut + +# ex: set expandtab tabstop=4 textwidth=72 : From 71bc3b95f4ae936ef00b034a41d8dd07bb9edb15 Mon Sep 17 00:00:00 2001 From: Mark Wieder Date: Tue, 11 Jan 2022 15:12:06 -0800 Subject: [PATCH 076/337] Slot machine in ruby --- 80_Slots/ruby/slots.rb | 152 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 80_Slots/ruby/slots.rb diff --git a/80_Slots/ruby/slots.rb b/80_Slots/ruby/slots.rb new file mode 100644 index 00000000..a4c3e7ef --- /dev/null +++ b/80_Slots/ruby/slots.rb @@ -0,0 +1,152 @@ +$pot = 0 + +def greeting + puts "SLOTS".center(80) + puts "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY".center(80) + puts "\n\n" + + # PRODUCED BY FRED MIRABELLE AND BOB HARPER ON JAN 29, 1973 + # IT SIMULATES THE SLOT MACHINE. + + puts "You are in the H&M Casino, in front of one of our" + puts "one-arm bandits. You can bet from $1 to $100." + puts "To pull the arm, punch the return key after making your bet." + puts "\nBet zero to end the game." +end + +def overLimit + puts "House Limit is $100" +end + +def underMinimum + puts "Minimum Bet is $1" +end + +# bells don't work on my machine. YMMV +# I'm displaying dashes between the reels + +def tenBells + 10.times do + # beep if you can + print "-" + end +end + +def fiveBells + "-----" +end + +def goodbye + puts "\n\n\n" + # end the game + exit +end + +def payUp + puts "PAY UP! PLEASE LEAVE YOUR MONEY ON THE TERMINAL." +end + +def brokeEven + puts "HEY, YOU BROKE EVEN." +end + +def collectWinnings + puts "COLLECT YOUR WINNINGS FROM THE H&M CASHIER." +end + +def win winType, bet + case winType + when "jackpot" + winMessage = "***JACKPOT***" + winnings = 101 + when "topDollar" + winMessage = "**TOP DOLLAR**" + winnings = 11 + when "doubleBar" + winMessage = "*DOUBLE BAR!!*" + winnings = 6 + when "double" + winMessage = "DOUBLE!!" + winnings = 3 + end + puts "\nYou won: " + winMessage + $pot += (winnings * bet) +end + +greeting + +#$pot = 0 +while true + reelArray = ["BAR","BELL","ORANGE","LEMON","PLUM","CHERRY"] + print "\nYOUR BET? " + # get input, remove leading and trailing whitespace, cast to integer + bet = gets.strip.to_i + + if bet == 0 then + goodbye + elsif bet > 100 then + overLimit # error if more than $100 + elsif bet < 1 then + underMinimum # have to bet at least a dollar + else + # valid bet, continue + tenBells # ding + + # assign a random value from the array to each of the three reels + reel1 = reelArray[rand(5)] + reel2 = reelArray[rand(5)] + reel3 = reelArray[rand(5)] + + # print the slot machine reels + puts "\n\n" + reel1 + fiveBells + reel2 + fiveBells + reel3 + + # see if we have a match in the first two reels + if reel1 == reel2 then + if reel2 == reel3 then + if reel3 == "BAR" then + # all three reels are "BAR" + win "jackpot", bet + else + # all three reels match but aren't "BAR" + win "topDollar", bet + end + elsif reel2 == "BAR" then + # reels 1 and 2 are both "BAR" + win "doubleBar", bet + else + # reels 1 and 2 match but aren't "BAR" + win "double", bet + end + # otherwise see if there's a match in the remaining reels + elsif reel1 == reel3 or reel2 == reel3 then + if reel3 == "BAR" then + # two reels match, both "BAR" + win "doubleBar", bet + else + # two reels match, but not "BAR" + win "double", bet + end + else + # bad news - no matches + puts "\nYou lost" + # decrement your standings by the bet amount + $pot -= bet + end + + puts "Your standings are: " + $pot.to_s + print "\nAgain? " # YES to continue + # get input, remove leading and trailing whitespace, make uppercase + again = gets.strip.upcase + if again != "Y" && again != "YES" then + # that's enough... evaluate the pot and quit + if $pot < 0 then + payUp + elsif $pot == 0 then + brokeEven + else # yay! + collectWinnings + end + goodbye + end + end +end From 1c1276778b562850563d6391c0c89eb056844f30 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:40:05 -0300 Subject: [PATCH 077/337] Just starting out. --- 55_Life/csharp/.gitignore | 509 +++++++++++++++++++++++++++++++++++++ 55_Life/csharp/Life.csproj | 9 + 55_Life/csharp/Life.sln | 16 ++ 55_Life/csharp/Program.cs | 37 +++ 4 files changed, 571 insertions(+) create mode 100644 55_Life/csharp/.gitignore create mode 100644 55_Life/csharp/Life.csproj create mode 100644 55_Life/csharp/Life.sln create mode 100644 55_Life/csharp/Program.cs diff --git a/55_Life/csharp/.gitignore b/55_Life/csharp/.gitignore new file mode 100644 index 00000000..e96e7522 --- /dev/null +++ b/55_Life/csharp/.gitignore @@ -0,0 +1,509 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/dotnetcore,rider,visualstudio,visualstudiocode +# Edit at https://www.toptal.com/developers/gitignore?templates=dotnetcore,rider,visualstudio,visualstudiocode + +### DotnetCore ### +# .NET Core build folders +bin/ +obj/ + +# Common node modules locations +/node_modules +/wwwroot/node_modules + +### Rider ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# Support for Project snippet scope + +### VisualStudio ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +*.code-workspace + +# Local History for Visual Studio Code + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml + +### VisualStudio Patch ### +# Additional files built by Visual Studio + +# End of https://www.toptal.com/developers/gitignore/api/dotnetcore,rider,visualstudio,visualstudiocode diff --git a/55_Life/csharp/Life.csproj b/55_Life/csharp/Life.csproj new file mode 100644 index 00000000..7311ef16 --- /dev/null +++ b/55_Life/csharp/Life.csproj @@ -0,0 +1,9 @@ + + + + Exe + net6.0 + enable + + + diff --git a/55_Life/csharp/Life.sln b/55_Life/csharp/Life.sln new file mode 100644 index 00000000..1f6131b8 --- /dev/null +++ b/55_Life/csharp/Life.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Life", "Life.csproj", "{28B02688-78D1-4B3E-B998-BCC78C292D03}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {28B02688-78D1-4B3E-B998-BCC78C292D03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {28B02688-78D1-4B3E-B998-BCC78C292D03}.Debug|Any CPU.Build.0 = Debug|Any CPU + {28B02688-78D1-4B3E-B998-BCC78C292D03}.Release|Any CPU.ActiveCfg = Release|Any CPU + {28B02688-78D1-4B3E-B998-BCC78C292D03}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs new file mode 100644 index 00000000..e12d5b7d --- /dev/null +++ b/55_Life/csharp/Program.cs @@ -0,0 +1,37 @@ +// See https://aka.ms/new-console-template for more information + +const int MaxWidth = 70; +const int MaxHeight = 24; + +PrintHeader(); + +int x1 = 1, y1 = 1; +int x2 = 24, y2 = 70; +var a = new float[24, 70]; +var b = new string[24]; +var c = 1; + +Console.WriteLine("ENTER YOUR PATTERN:"); +b[c] = Console.ReadLine(); +if (b[c] == "DONE") + b[c] = "" + + +void PrintHeader() +{ + const int pageWidth = 64; + + void PrintCentered(string text) + { + var spaceCount = (pageWidth - text.Length) / 2; + Console.Write(new string(' ', spaceCount)); + Console.WriteLine(text); + } + + PrintCentered("LIFE"); + PrintCentered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine(); +} + From ade38d696998a222e693a37916132c2cdc8dbffd Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:40:50 -0300 Subject: [PATCH 078/337] Another step. --- 55_Life/csharp/Program.cs | 151 ++++++++++++++++++++++++++++++++++---- 1 file changed, 137 insertions(+), 14 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index e12d5b7d..6a8ed618 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -1,21 +1,23 @@ // See https://aka.ms/new-console-template for more information -const int MaxWidth = 70; -const int MaxHeight = 24; +IEnumerable ReadPattern(int limitHeight) +{ + for (var i = 0; i < limitHeight; i++) + { + var input = Console.ReadLine(); + if (input.ToUpper() == "DONE") + { + yield return string.Empty; + break; + } -PrintHeader(); - -int x1 = 1, y1 = 1; -int x2 = 24, y2 = 70; -var a = new float[24, 70]; -var b = new string[24]; -var c = 1; - -Console.WriteLine("ENTER YOUR PATTERN:"); -b[c] = Console.ReadLine(); -if (b[c] == "DONE") - b[c] = "" + // kept for compatibility + if (input.StartsWith('.')) + yield return input.Substring(1, input.Length - 2); + yield return input; + } +} void PrintHeader() { @@ -35,3 +37,124 @@ void PrintHeader() Console.WriteLine(); } +(int index, string value) GetLongestInput(IEnumerable strings) +{ + return strings + .Select((value, index) => (index, value)) + .OrderByDescending(input => input.value.Length) + .First(); +} + + +PrintHeader(); + +Console.WriteLine("ENTER YOUR PATTERN:"); +// var pattern = ReadPattern(limitHeight: MaxHeight).ToArray(); +var pattern = new string[] { "a", "bdc", "", "pattern" }; // FOR DEBUGGING PURPOSES +var (index, value) = GetLongestInput(pattern); +Console.WriteLine("" + index + ", " + value); + +// B = pattern + +int x1 = (11 - index / 2) - 1; +int y1 = (33 - value.Length / 2) - 1; +const int MaxWidth = 70; // Y2 +const int MaxHeight = 24; // X2 + +var a = new int[24, 70]; // TODO understand it +int population = 0; + +// count initial population? +for (var x = 0; x < pattern.Length; x++) +{ + for (var y = 0; y < pattern[x].Length; y++) + { + if (pattern[x][y] != ' ') + { + a[x1 + x, y1 + y] = 1; + population++; + } + } +} + +void ProcessGeneration() +{ + void PrintPopulation(int generation, int population) + { + Console.WriteLine($"GENERATION: {generation}\tPOPULATION: {population}"); + var i9 = false; // TODO understand + if (i9) + Console.WriteLine("INVALID!"); + } + int generation = 1; + PrintPopulation(generation, population); + + int x3 = MaxHeight, y3 = MaxWidth; + int x4 = 1, y4 = 1; + + for (int x = 0; x < x1; x++) + { + Console.WriteLine(); + } + + for (var x = x1; x < MaxHeight; x++) + { + Console.WriteLine(); + for (var y = y1; y < MaxWidth; y++) + { + if (a[x, y] == 2) + { + a[x, y] = 0; // birth? + continue; + } + + if (a[x, y] == 3) + { + a[x, y] = 1; + Console.WriteLine(new string('\t', y+1) + "*"); + continue; + } + + // TODO understand what it does + if (x < x3) x3 = x; + if (x > x4) x4 = x; + if (y < y3) y3 = y; + if (y < y4) y4 = y; + } + } + +} + +PrintMatrix(a); +void PrintMatrix(int[,] matrix) +{ + Console.WriteLine("Matrix:"); + for (int x = 0; x < matrix.GetLength(0); x++) + { + for (int y = 0; y < matrix.GetLength(1); y++) + { + Console.Write(matrix[x, y].ToString()); + } + Console.WriteLine(); + } +} + +Console.WriteLine(); +Console.WriteLine(); +Console.WriteLine(); +ProcessGeneration(); + + + + + + +// int x1 = 1, y1 = 1; +// int x2 = 24, y2 = 70; + +// var b = new string[24]; + + + + + From 53d2943f934dbbb38e78ae3e9d1d0d81e6fcfefd Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:41:28 -0300 Subject: [PATCH 079/337] Not working yet. --- 55_Life/csharp/Program.cs | 204 +++++++++++++++++++++++++++----------- 1 file changed, 148 insertions(+), 56 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 6a8ed618..ab995aa5 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -1,5 +1,7 @@ // See https://aka.ms/new-console-template for more information +using System.Xml; + IEnumerable ReadPattern(int limitHeight) { for (var i = 0; i < limitHeight; i++) @@ -50,82 +52,43 @@ PrintHeader(); Console.WriteLine("ENTER YOUR PATTERN:"); // var pattern = ReadPattern(limitHeight: MaxHeight).ToArray(); -var pattern = new string[] { "a", "bdc", "", "pattern" }; // FOR DEBUGGING PURPOSES +var pattern = new[] +{ + " ", + " * ", + " * ", + " * ", + " " +}; // FOR DEBUGGING PURPOSES var (index, value) = GetLongestInput(pattern); Console.WriteLine("" + index + ", " + value); // B = pattern -int x1 = (11 - index / 2) - 1; -int y1 = (33 - value.Length / 2) - 1; + const int MaxWidth = 70; // Y2 const int MaxHeight = 24; // X2 -var a = new int[24, 70]; // TODO understand it +var matrix = new int[24, 70]; // TODO understand it int population = 0; +var isInvalid = false; // TODO understand -// count initial population? + +int x1 = (11 - index / 2) - 1; // middle x +int y1 = (33 - value.Length / 2) - 1; // middle y for (var x = 0; x < pattern.Length; x++) { for (var y = 0; y < pattern[x].Length; y++) { if (pattern[x][y] != ' ') { - a[x1 + x, y1 + y] = 1; - population++; + matrix[x1 + x, y1 + y] = 1; // copy the pattern to the middle of the simulation + population++; // increments the population } } } -void ProcessGeneration() -{ - void PrintPopulation(int generation, int population) - { - Console.WriteLine($"GENERATION: {generation}\tPOPULATION: {population}"); - var i9 = false; // TODO understand - if (i9) - Console.WriteLine("INVALID!"); - } - int generation = 1; - PrintPopulation(generation, population); - - int x3 = MaxHeight, y3 = MaxWidth; - int x4 = 1, y4 = 1; - - for (int x = 0; x < x1; x++) - { - Console.WriteLine(); - } - - for (var x = x1; x < MaxHeight; x++) - { - Console.WriteLine(); - for (var y = y1; y < MaxWidth; y++) - { - if (a[x, y] == 2) - { - a[x, y] = 0; // birth? - continue; - } - - if (a[x, y] == 3) - { - a[x, y] = 1; - Console.WriteLine(new string('\t', y+1) + "*"); - continue; - } - - // TODO understand what it does - if (x < x3) x3 = x; - if (x > x4) x4 = x; - if (y < y3) y3 = y; - if (y < y4) y4 = y; - } - } - -} - -PrintMatrix(a); +PrintMatrix(matrix); void PrintMatrix(int[,] matrix) { Console.WriteLine("Matrix:"); @@ -139,6 +102,135 @@ void PrintMatrix(int[,] matrix) } } + + +int generation = 0; + +void ProcessGeneration() +{ + generation++; + void PrintPopulation(int generation, int population) + { + Console.WriteLine($"GENERATION: {generation}\tPOPULATION: {population}"); + if (isInvalid) + Console.WriteLine("INVALID!"); + } + PrintPopulation(generation, population); + + int nextMaxX = MaxHeight, nextMaxY = MaxWidth; + int nextMinX = 1, nextMinY = 1; + + for (int x = 0; x < x1; x++) + { + Console.WriteLine(); + } + + for (var x = x1; x < MaxHeight; x++) + { + Console.WriteLine(); + for (var y = y1; y < MaxWidth; y++) + { + if (matrix[x, y] == 2) + { + matrix[x, y] = 0; + continue; + } + + if (matrix[x, y] == 3) + { + matrix[x, y] = 1; // birth? + Console.WriteLine(new string(' ', y+1) + "*"); + continue; + } + + nextMinX = Math.Min(x, nextMinX); + nextMaxX = Math.Max(x, nextMaxX); + nextMinY = Math.Min(y, nextMinY); + nextMaxY = Math.Max(y, nextMaxY); + } + } + + var x2 = MaxHeight; + for (int x = x2 + 1; x < MaxHeight; x++) // TODO test +1 + { + Console.WriteLine(); + } + + x1 = nextMaxX; + x2 = nextMinX; + y1 = nextMaxY; + var y2 = nextMinY; + + // TODO boundaries? review + if (x1 < 3) + { + x1 = 3; + isInvalid = true; + } + + if (x2 > 22) + { + x2 = 22; + isInvalid = true; + } + + if (y1 < 3) + { + y1 = 3; + isInvalid = true; + } + + if (y2 > 68) + { + y2 = 68; + isInvalid = true; + } + + ProcessPopulation(); + // TODO line 635 + + void ProcessPopulation() + { + var population = 0; + for (int x = x1 - 1; x < x2 + 1; x++) // TODO review indices + { + for (int y = y1 - 1; y < y2 + 1; y++) // TODO review indices + { + var counter = 0; + for (int i = x - 1; i < x + 1; i++) + { + for (int j = y - 1; j < y + 1; j++) + { + if (matrix[i, j] == 1 || matrix[i, j] == 2) + counter++; + } + } + + if (matrix[x, y] == 0) + { + if (counter == 3) + { + matrix[x, y] = 2; + population++; + } + } + else if (counter is < 3 or > 4) + { + matrix[x, y] = 2; + } + else + { + population++; + } + } + } + } + PrintMatrix(matrix); + ProcessGeneration(); +} + + + Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); From be5e35f7e0c887b53304543d1a055326c12b9c3c Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:42:40 -0300 Subject: [PATCH 080/337] Got it working. --- 55_Life/csharp/Program.cs | 347 ++++++++++++++++++++++++-------------- 1 file changed, 216 insertions(+), 131 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index ab995aa5..0f78a6e4 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -1,6 +1,6 @@ // See https://aka.ms/new-console-template for more information -using System.Xml; +using System.Text; IEnumerable ReadPattern(int limitHeight) { @@ -47,6 +47,10 @@ void PrintHeader() .First(); } +try +{ + + PrintHeader(); @@ -54,11 +58,9 @@ Console.WriteLine("ENTER YOUR PATTERN:"); // var pattern = ReadPattern(limitHeight: MaxHeight).ToArray(); var pattern = new[] { - " ", - " * ", - " * ", - " * ", - " " + "*", + "*", + "*" }; // FOR DEBUGGING PURPOSES var (index, value) = GetLongestInput(pattern); Console.WriteLine("" + index + ", " + value); @@ -69,26 +71,42 @@ Console.WriteLine("" + index + ", " + value); const int MaxWidth = 70; // Y2 const int MaxHeight = 24; // X2 -var matrix = new int[24, 70]; // TODO understand it -int population = 0; +// var matrix = new int[24, 70]; // TODO understand it +var matrixSpace = new MatrixSpace(height: 24, width: 70); +// int population = 0; var isInvalid = false; // TODO understand -int x1 = (11 - index / 2) - 1; // middle x -int y1 = (33 - value.Length / 2) - 1; // middle y -for (var x = 0; x < pattern.Length; x++) -{ - for (var y = 0; y < pattern[x].Length; y++) + +int minX = (11 - index / 2) - 1; // middle x +int minY = (33 - value.Length / 2) - 1; // middle y +int maxX = MaxHeight; +int maxY = MaxWidth; +var simulation = InitializeSimulation(pattern, matrixSpace); + + + +Simulation InitializeSimulation(string[] inputPattern, MatrixSpace matrixToInitialize) { + var newSimulation = new Simulation(); + + for (var x = 0; x < inputPattern.Length; x++) { - if (pattern[x][y] != ' ') + for (var y = 0; y < inputPattern[x].Length; y++) { - matrix[x1 + x, y1 + y] = 1; // copy the pattern to the middle of the simulation - population++; // increments the population + if (inputPattern[x][y] != ' ') + { + matrixToInitialize.Matrix[minX + x, minY + y] = 1; // copy the pattern to the middle of the simulation + // population++; // increments the population + newSimulation.IncreasePopulation(); + } } } + + return newSimulation; } -PrintMatrix(matrix); + +// PrintMatrix(matrixSpace.Matrix); void PrintMatrix(int[,] matrix) { Console.WriteLine("Matrix:"); @@ -96,149 +114,191 @@ void PrintMatrix(int[,] matrix) { for (int y = 0; y < matrix.GetLength(1); y++) { - Console.Write(matrix[x, y].ToString()); + var character = matrix[x, y] == 0 ? ' ' : '*'; + Console.Write(character); } Console.WriteLine(); } } - - -int generation = 0; - -void ProcessGeneration() -{ - generation++; - void PrintPopulation(int generation, int population) + void ProcessGeneration() { - Console.WriteLine($"GENERATION: {generation}\tPOPULATION: {population}"); - if (isInvalid) - Console.WriteLine("INVALID!"); - } - PrintPopulation(generation, population); - - int nextMaxX = MaxHeight, nextMaxY = MaxWidth; - int nextMinX = 1, nextMinY = 1; - - for (int x = 0; x < x1; x++) - { - Console.WriteLine(); - } - - for (var x = x1; x < MaxHeight; x++) - { - Console.WriteLine(); - for (var y = y1; y < MaxWidth; y++) + var matrix = matrixSpace.Matrix; // TODO refactor + + // generation++; + + void PrintPopulation(int generation, int population) { - if (matrix[x, y] == 2) - { - matrix[x, y] = 0; - continue; - } - - if (matrix[x, y] == 3) - { - matrix[x, y] = 1; // birth? - Console.WriteLine(new string(' ', y+1) + "*"); - continue; - } - - nextMinX = Math.Min(x, nextMinX); - nextMaxX = Math.Max(x, nextMaxX); - nextMinY = Math.Min(y, nextMinY); - nextMaxY = Math.Max(y, nextMaxY); + Console.WriteLine($"GENERATION: {generation}\tPOPULATION: {population}"); + if (isInvalid) + Console.WriteLine("INVALID!"); } - } + PrintPopulation(simulation.Generation, simulation.Population); - var x2 = MaxHeight; - for (int x = x2 + 1; x < MaxHeight; x++) // TODO test +1 - { - Console.WriteLine(); - } + simulation.StartNewGeneration(); - x1 = nextMaxX; - x2 = nextMinX; - y1 = nextMaxY; - var y2 = nextMinY; - - // TODO boundaries? review - if (x1 < 3) - { - x1 = 3; - isInvalid = true; - } + // LINE 215 + // x3 = 24 = MaxHeight + // y3 = 70 = MaxWidth + // x4 = 1 + // y4 = 1 + // g = g + 1 - if (x2 > 22) - { - x2 = 22; - isInvalid = true; - } - - if (y1 < 3) - { - y1 = 3; - isInvalid = true; - } - - if (y2 > 68) - { - y2 = 68; - isInvalid = true; - } - - ProcessPopulation(); - // TODO line 635 - - void ProcessPopulation() - { - var population = 0; - for (int x = x1 - 1; x < x2 + 1; x++) // TODO review indices + int nextMinX = MaxHeight - 1; // x4 + int nextMinY = MaxWidth - 1; // y4 + int nextMaxX = 0; // x3 + int nextMaxY = 0; // y3 + + + // prints lines before + for (int x = 0; x < minX; x++) { - for (int y = y1 - 1; y < y2 + 1; y++) // TODO review indices + Console.WriteLine(); + } + + // prints matrix and + for (var x = minX; x < maxX; x++) + { + var printedLine = Enumerable.Repeat(' ', MaxWidth).ToList(); + for (var y = minY; y < maxY; y++) { - var counter = 0; - for (int i = x - 1; i < x + 1; i++) + if (matrix[x, y] == 2) { - for (int j = y - 1; j < y + 1; j++) - { - if (matrix[i, j] == 1 || matrix[i, j] == 2) - counter++; - } + matrix[x, y] = 0; + continue; + } + if (matrix[x, y] == 3) + { + matrix[x, y] = 1; + } + else if (matrix[x, y] != 1) + { + continue; } - if (matrix[x, y] == 0) + printedLine[y] = '*'; + + nextMinX = Math.Min(x, nextMinX); + nextMaxX = Math.Max(x+1, nextMaxX); + nextMinY = Math.Min(y, nextMinY); + nextMaxY = Math.Max(y+1, nextMaxY); + } + Console.WriteLine(string.Join(separator: null, values: printedLine)); + } + + // prints lines after + for (int x = maxX + 1; x < MaxHeight; x++) // TODO test +1 + { + Console.WriteLine(); + } + Console.WriteLine(); + + minX = nextMinX; + maxX = nextMaxX; + minY = nextMinY; + maxY = nextMaxY; + + // TODO boundaries? review + if (minX < 3) + { + minX = 3; + isInvalid = true; + } + if (maxX > 22) + { + maxX = 22; + isInvalid = true; + } + if (minY < 3) + { + minY = 3; + isInvalid = true; + } + if (maxY > 68) + { + maxY = 68; + isInvalid = true; + } + + // LINE 309 + ProcessPopulation(); + + void ProcessPopulation() + { + // var population = 0; + for (int x = minX - 1; x < maxX + 2; x++) // TODO review indices + { + for (int y = minY - 1; y < maxY + 2; y++) // TODO review indices { - if (counter == 3) + var neighbors = 0; + for (int i = x - 1; i < x + 2; i++) // TODO review indices + { + for (int j = y - 1; j < y + 2; j++) // TODO review indices + { + if (matrix[i, j] == 1 || matrix[i, j] == 2) + neighbors++; + } + } + // PrintMatrix(matrix); + if (matrix[x, y] == 0) + { + if (neighbors == 3) + { + matrix[x, y] = 3; + // population++; + simulation.IncreasePopulation(); + } + } + else if (neighbors is < 3 or > 4) { matrix[x, y] = 2; - population++; + } + else + { + // population++; + simulation.IncreasePopulation(); } } - else if (counter is < 3 or > 4) - { - matrix[x, y] = 2; - } - else - { - population++; - } } + + // LINE 635 + minX--; + minY--; + maxX++; + maxY++; } + // PrintMatrix(matrix); + ProcessGeneration(); } - PrintMatrix(matrix); + + + + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine(); ProcessGeneration(); } +catch (Exception e) +{ + Console.WriteLine(e); +} +public class Simulation +{ + public int Generation { get; private set; } + public int Population { get; private set; } + public void StartNewGeneration() + { + Generation++; + Population = 0; + } -Console.WriteLine(); -Console.WriteLine(); -Console.WriteLine(); -ProcessGeneration(); - - - - + public void IncreasePopulation() + { + Population++; + } +} // int x1 = 1, y1 = 1; @@ -250,3 +310,28 @@ ProcessGeneration(); +public class MatrixSpace +{ + public int[,] Matrix { get; } + + public MatrixSpace(int height, int width) + { + Matrix = new int[height, width]; + } + + public override string ToString() + { + var stringBuilder = new StringBuilder(); + for (var x = 0; x < Matrix.GetLength(0); x++) + { + for (var y = 0; y < Matrix.GetLength(1); y++) + { + var character = Matrix[x, y] == 0 ? " ": Matrix[x, y].ToString(); + stringBuilder.Append(character); + } + + stringBuilder.AppendLine(); + } + return stringBuilder.ToString(); + } +} From 44b1ada7d4882f59cd8b51b33c2deb221722de31 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:43:14 -0300 Subject: [PATCH 081/337] Eliminated StackOverflow bug. --- 55_Life/csharp/Program.cs | 66 +++++++++++++++------------------------ 1 file changed, 26 insertions(+), 40 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 0f78a6e4..0496fd91 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -47,10 +47,6 @@ void PrintHeader() .First(); } -try -{ - - PrintHeader(); @@ -106,33 +102,22 @@ Simulation InitializeSimulation(string[] inputPattern, MatrixSpace matrixToIniti } -// PrintMatrix(matrixSpace.Matrix); -void PrintMatrix(int[,] matrix) +void ProcessGeneration() { - Console.WriteLine("Matrix:"); - for (int x = 0; x < matrix.GetLength(0); x++) - { - for (int y = 0; y < matrix.GetLength(1); y++) - { - var character = matrix[x, y] == 0 ? ' ' : '*'; - Console.Write(character); - } - Console.WriteLine(); - } -} + var matrix = matrixSpace.Matrix; // TODO refactor - void ProcessGeneration() + while (true) { - var matrix = matrixSpace.Matrix; // TODO refactor - + // generation++; - + void PrintPopulation(int generation, int population) { Console.WriteLine($"GENERATION: {generation}\tPOPULATION: {population}"); if (isInvalid) Console.WriteLine("INVALID!"); } + PrintPopulation(simulation.Generation, simulation.Population); simulation.StartNewGeneration(); @@ -148,14 +133,14 @@ void PrintMatrix(int[,] matrix) int nextMinY = MaxWidth - 1; // y4 int nextMaxX = 0; // x3 int nextMaxY = 0; // y3 - - + + // prints lines before for (int x = 0; x < minX; x++) { Console.WriteLine(); } - + // prints matrix and for (var x = minX; x < maxX; x++) { @@ -164,9 +149,10 @@ void PrintMatrix(int[,] matrix) { if (matrix[x, y] == 2) { - matrix[x, y] = 0; + matrix[x, y] = 0; continue; } + if (matrix[x, y] == 3) { matrix[x, y] = 1; @@ -179,10 +165,11 @@ void PrintMatrix(int[,] matrix) printedLine[y] = '*'; nextMinX = Math.Min(x, nextMinX); - nextMaxX = Math.Max(x+1, nextMaxX); + nextMaxX = Math.Max(x + 1, nextMaxX); nextMinY = Math.Min(y, nextMinY); - nextMaxY = Math.Max(y+1, nextMaxY); + nextMaxY = Math.Max(y + 1, nextMaxY); } + Console.WriteLine(string.Join(separator: null, values: printedLine)); } @@ -191,29 +178,33 @@ void PrintMatrix(int[,] matrix) { Console.WriteLine(); } + Console.WriteLine(); minX = nextMinX; maxX = nextMaxX; minY = nextMinY; maxY = nextMaxY; - + // TODO boundaries? review if (minX < 3) { minX = 3; isInvalid = true; } + if (maxX > 22) { maxX = 22; isInvalid = true; } + if (minY < 3) { minY = 3; isInvalid = true; } + if (maxY > 68) { maxY = 68; @@ -239,6 +230,7 @@ void PrintMatrix(int[,] matrix) neighbors++; } } + // PrintMatrix(matrix); if (matrix[x, y] == 0) { @@ -268,20 +260,14 @@ void PrintMatrix(int[,] matrix) maxY++; } // PrintMatrix(matrix); - ProcessGeneration(); } - - - - Console.WriteLine(); - Console.WriteLine(); - Console.WriteLine(); - ProcessGeneration(); -} -catch (Exception e) -{ - Console.WriteLine(e); } + +Console.WriteLine(); +Console.WriteLine(); +Console.WriteLine(); +ProcessGeneration(); + public class Simulation { public int Generation { get; private set; } From d9ab235585aab5558a2c10d6211ad192bf9e7c27 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:43:44 -0300 Subject: [PATCH 082/337] Some initial refactorings. --- 55_Life/csharp/Program.cs | 201 +++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 111 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 0496fd91..ec925faa 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -39,16 +39,10 @@ void PrintHeader() Console.WriteLine(); } -(int index, string value) GetLongestInput(IEnumerable strings) -{ - return strings - .Select((value, index) => (index, value)) - .OrderByDescending(input => input.value.Length) - .First(); -} -PrintHeader(); + + Console.WriteLine("ENTER YOUR PATTERN:"); // var pattern = ReadPattern(limitHeight: MaxHeight).ToArray(); @@ -58,59 +52,59 @@ var pattern = new[] "*", "*" }; // FOR DEBUGGING PURPOSES +// var pattern = new[] +// { +// "**", +// "**", +// }; // FOR DEBUGGING PURPOSES +// var pattern = new[] +// { +// "***", +// "*", +// }; // FOR DEBUGGING PURPOSES + + +const int MaxWidth = 70; +const int MaxHeight = 24; + +var isInvalid = false; + var (index, value) = GetLongestInput(pattern); -Console.WriteLine("" + index + ", " + value); - -// B = pattern - - -const int MaxWidth = 70; // Y2 -const int MaxHeight = 24; // X2 - -// var matrix = new int[24, 70]; // TODO understand it -var matrixSpace = new MatrixSpace(height: 24, width: 70); -// int population = 0; -var isInvalid = false; // TODO understand - - - int minX = (11 - index / 2) - 1; // middle x int minY = (33 - value.Length / 2) - 1; // middle y int maxX = MaxHeight; int maxY = MaxWidth; -var simulation = InitializeSimulation(pattern, matrixSpace); +var matrix = new Matrix(height: MaxHeight, width: MaxWidth); +var simulation = InitializeSimulation(pattern, matrix); + +PrintHeader(); +Console.WriteLine(); +Console.WriteLine(); +Console.WriteLine(); +ProcessGeneration(); - -Simulation InitializeSimulation(string[] inputPattern, MatrixSpace matrixToInitialize) { +Simulation InitializeSimulation(IReadOnlyList inputPattern, Matrix matrixToInitialize) { var newSimulation = new Simulation(); - for (var x = 0; x < inputPattern.Length; x++) + for (var x = 0; x < inputPattern.Count; x++) { for (var y = 0; y < inputPattern[x].Length; y++) { - if (inputPattern[x][y] != ' ') - { - matrixToInitialize.Matrix[minX + x, minY + y] = 1; // copy the pattern to the middle of the simulation - // population++; // increments the population - newSimulation.IncreasePopulation(); - } + if (inputPattern[x][y] == ' ') continue; + + matrixToInitialize[minX + x, minY + y] = 1; // copy the pattern to the middle of the simulation + newSimulation.IncreasePopulation(); } } return newSimulation; } - void ProcessGeneration() { - var matrix = matrixSpace.Matrix; // TODO refactor - while (true) { - - // generation++; - void PrintPopulation(int generation, int population) { Console.WriteLine($"GENERATION: {generation}\tPOPULATION: {population}"); @@ -123,25 +117,18 @@ void ProcessGeneration() simulation.StartNewGeneration(); // LINE 215 - // x3 = 24 = MaxHeight - // y3 = 70 = MaxWidth - // x4 = 1 - // y4 = 1 - // g = g + 1 + var nextMinX = MaxHeight - 1; + var nextMinY = MaxWidth - 1; + var nextMaxX = 0; + var nextMaxY = 0; - int nextMinX = MaxHeight - 1; // x4 - int nextMinY = MaxWidth - 1; // y4 - int nextMaxX = 0; // x3 - int nextMaxY = 0; // y3 - - - // prints lines before - for (int x = 0; x < minX; x++) + // prints empty lines before alive cells + for (var x = 0; x < minX; x++) { Console.WriteLine(); } - // prints matrix and + // refreshes the matrix and updates search area for (var x = minX; x < maxX; x++) { var printedLine = Enumerable.Repeat(' ', MaxWidth).ToList(); @@ -152,7 +139,6 @@ void ProcessGeneration() matrix[x, y] = 0; continue; } - if (matrix[x, y] == 3) { matrix[x, y] = 1; @@ -173,12 +159,11 @@ void ProcessGeneration() Console.WriteLine(string.Join(separator: null, values: printedLine)); } - // prints lines after - for (int x = maxX + 1; x < MaxHeight; x++) // TODO test +1 + // prints empty lines after alive cells + for (int x = maxX + 1; x < MaxHeight; x++) { Console.WriteLine(); } - Console.WriteLine(); minX = nextMinX; @@ -211,62 +196,60 @@ void ProcessGeneration() isInvalid = true; } - // LINE 309 - ProcessPopulation(); - - void ProcessPopulation() + for (var x = minX - 1; x < maxX + 2; x++) { - // var population = 0; - for (int x = minX - 1; x < maxX + 2; x++) // TODO review indices + for (var y = minY - 1; y < maxY + 2; y++) { - for (int y = minY - 1; y < maxY + 2; y++) // TODO review indices + int CountNeighbors() { var neighbors = 0; - for (int i = x - 1; i < x + 2; i++) // TODO review indices + for (var i = x - 1; i < x + 2; i++) { - for (int j = y - 1; j < y + 2; j++) // TODO review indices + for (var j = y - 1; j < y + 2; j++) { if (matrix[i, j] == 1 || matrix[i, j] == 2) neighbors++; } } - // PrintMatrix(matrix); - if (matrix[x, y] == 0) + return neighbors; + } + + var neighbors = CountNeighbors(); + if (matrix[x, y] == 0) + { + if (neighbors == 3) { - if (neighbors == 3) - { - matrix[x, y] = 3; - // population++; - simulation.IncreasePopulation(); - } - } - else if (neighbors is < 3 or > 4) - { - matrix[x, y] = 2; - } - else - { - // population++; + matrix[x, y] = 3; simulation.IncreasePopulation(); } } + else if (neighbors is < 3 or > 4) + { + matrix[x, y] = 2; + } + else + { + simulation.IncreasePopulation(); + } } - - // LINE 635 - minX--; - minY--; - maxX++; - maxY++; } - // PrintMatrix(matrix); + + // expands search area to accommodate new cells + minX--; + minY--; + maxX++; + maxY++; } } -Console.WriteLine(); -Console.WriteLine(); -Console.WriteLine(); -ProcessGeneration(); +(int index, string value) GetLongestInput(IEnumerable strings) +{ + return strings + .Select((value, index) => (index, value)) + .OrderByDescending(input => input.value.Length) + .First(); +} public class Simulation { @@ -286,33 +269,29 @@ public class Simulation } } - -// int x1 = 1, y1 = 1; -// int x2 = 24, y2 = 70; - -// var b = new string[24]; - - - - - -public class MatrixSpace +class Matrix { - public int[,] Matrix { get; } + private readonly int[,] _matrix; - public MatrixSpace(int height, int width) + public Matrix(int height, int width) { - Matrix = new int[height, width]; + _matrix = new int[height, width]; } + public int this[int x, int y] + { + get => _matrix[x, y]; + set => _matrix[x, y] = value; + } + public override string ToString() { var stringBuilder = new StringBuilder(); - for (var x = 0; x < Matrix.GetLength(0); x++) + for (var x = 0; x < _matrix.GetLength(0); x++) { - for (var y = 0; y < Matrix.GetLength(1); y++) + for (var y = 0; y < _matrix.GetLength(1); y++) { - var character = Matrix[x, y] == 0 ? " ": Matrix[x, y].ToString(); + var character = _matrix[x, y] == 0 ? " ": _matrix[x, y].ToString(); stringBuilder.Append(character); } @@ -320,4 +299,4 @@ public class MatrixSpace } return stringBuilder.ToString(); } -} +} \ No newline at end of file From e53b9d9cf18fc89e6aa34130b5eb1b16cd8e782b Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:44:13 -0300 Subject: [PATCH 083/337] Further refactoring, naming procedures. --- 55_Life/csharp/Program.cs | 186 ++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 97 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index ec925faa..cc594435 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -2,47 +2,8 @@ using System.Text; -IEnumerable ReadPattern(int limitHeight) -{ - for (var i = 0; i < limitHeight; i++) - { - var input = Console.ReadLine(); - if (input.ToUpper() == "DONE") - { - yield return string.Empty; - break; - } - - // kept for compatibility - if (input.StartsWith('.')) - yield return input.Substring(1, input.Length - 2); - - yield return input; - } -} - -void PrintHeader() -{ - const int pageWidth = 64; - - void PrintCentered(string text) - { - var spaceCount = (pageWidth - text.Length) / 2; - Console.Write(new string(' ', spaceCount)); - Console.WriteLine(text); - } - - PrintCentered("LIFE"); - PrintCentered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); - Console.WriteLine(); - Console.WriteLine(); - Console.WriteLine(); -} - - - - - +const int MaxWidth = 70; +const int MaxHeight = 24; Console.WriteLine("ENTER YOUR PATTERN:"); // var pattern = ReadPattern(limitHeight: MaxHeight).ToArray(); @@ -63,26 +24,63 @@ var pattern = new[] // "*", // }; // FOR DEBUGGING PURPOSES - -const int MaxWidth = 70; -const int MaxHeight = 24; - var isInvalid = false; -var (index, value) = GetLongestInput(pattern); -int minX = (11 - index / 2) - 1; // middle x -int minY = (33 - value.Length / 2) - 1; // middle y -int maxX = MaxHeight; -int maxY = MaxWidth; +var (index, value) = FindLongestInput(pattern); +var minX = (11 - index / 2) - 1; // middle x +var minY = (33 - value.Length / 2) - 1; // middle y +var maxX = MaxHeight; +var maxY = MaxWidth; var matrix = new Matrix(height: MaxHeight, width: MaxWidth); var simulation = InitializeSimulation(pattern, matrix); PrintHeader(); -Console.WriteLine(); -Console.WriteLine(); -Console.WriteLine(); ProcessGeneration(); +IEnumerable ReadPattern(int limitHeight) +{ + for (var i = 0; i < limitHeight; i++) + { + var input = Console.ReadLine(); + if (input.ToUpper() == "DONE") + { + yield return string.Empty; + break; + } + + // kept for compatibility + if (input.StartsWith('.')) + yield return input.Substring(1, input.Length - 2); + + yield return input; + } +} + +(int index, string value) FindLongestInput(IEnumerable strings) +{ + return strings + .Select((value, index) => (index, value)) + .OrderByDescending(input => input.value.Length) + .First(); +} + +void PrintHeader() +{ + void PrintCentered(string text) + { + const int pageWidth = 64; + + var spaceCount = (pageWidth - text.Length) / 2; + Console.Write(new string(' ', spaceCount)); + Console.WriteLine(text); + } + + PrintCentered("LIFE"); + PrintCentered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine(); +} Simulation InitializeSimulation(IReadOnlyList inputPattern, Matrix matrixToInitialize) { var newSimulation = new Simulation(); @@ -103,26 +101,24 @@ Simulation InitializeSimulation(IReadOnlyList inputPattern, Matrix matri void ProcessGeneration() { + void PrintPopulation(int generation, int population) + { + Console.WriteLine($"GENERATION: {generation}\tPOPULATION: {population}"); + if (isInvalid) + Console.WriteLine("INVALID!"); + } + while (true) { - void PrintPopulation(int generation, int population) - { - Console.WriteLine($"GENERATION: {generation}\tPOPULATION: {population}"); - if (isInvalid) - Console.WriteLine("INVALID!"); - } - PrintPopulation(simulation.Generation, simulation.Population); - simulation.StartNewGeneration(); - // LINE 215 var nextMinX = MaxHeight - 1; var nextMinY = MaxWidth - 1; var nextMaxX = 0; var nextMaxY = 0; - // prints empty lines before alive cells + // prints the empty lines before search area for (var x = 0; x < minX; x++) { Console.WriteLine(); @@ -159,42 +155,46 @@ void ProcessGeneration() Console.WriteLine(string.Join(separator: null, values: printedLine)); } - // prints empty lines after alive cells - for (int x = maxX + 1; x < MaxHeight; x++) + // prints empty lines after search area + for (var x = maxX + 1; x < MaxHeight; x++) { Console.WriteLine(); } Console.WriteLine(); - minX = nextMinX; - maxX = nextMaxX; - minY = nextMinY; - maxY = nextMaxY; - - // TODO boundaries? review - if (minX < 3) + void UpdateSearchArea() { - minX = 3; - isInvalid = true; - } + minX = nextMinX; + maxX = nextMaxX; + minY = nextMinY; + maxY = nextMaxY; - if (maxX > 22) - { - maxX = 22; - isInvalid = true; - } + // TODO boundaries? review + if (minX < 3) + { + minX = 3; + isInvalid = true; + } - if (minY < 3) - { - minY = 3; - isInvalid = true; - } + if (maxX > 22) + { + maxX = 22; + isInvalid = true; + } - if (maxY > 68) - { - maxY = 68; - isInvalid = true; + if (minY < 3) + { + minY = 3; + isInvalid = true; + } + + if (maxY > 68) + { + maxY = 68; + isInvalid = true; + } } + UpdateSearchArea(); for (var x = minX - 1; x < maxX + 2; x++) { @@ -243,14 +243,6 @@ void ProcessGeneration() } } -(int index, string value) GetLongestInput(IEnumerable strings) -{ - return strings - .Select((value, index) => (index, value)) - .OrderByDescending(input => input.value.Length) - .First(); -} - public class Simulation { public int Generation { get; private set; } From 778af346d723fec512d30e451ad84a22ab1cb9a6 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:45:00 -0300 Subject: [PATCH 084/337] Added enum Cell to enhance clarity. --- 55_Life/csharp/Program.cs | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index cc594435..0abb68f1 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -1,10 +1,13 @@ // See https://aka.ms/new-console-template for more information +using System.Drawing; using System.Text; const int MaxWidth = 70; const int MaxHeight = 24; + + Console.WriteLine("ENTER YOUR PATTERN:"); // var pattern = ReadPattern(limitHeight: MaxHeight).ToArray(); var pattern = new[] @@ -91,7 +94,7 @@ Simulation InitializeSimulation(IReadOnlyList inputPattern, Matrix matri { if (inputPattern[x][y] == ' ') continue; - matrixToInitialize[minX + x, minY + y] = 1; // copy the pattern to the middle of the simulation + matrixToInitialize[minX + x, minY + y] = Cell.NeutralCell; // copy the pattern to the middle of the simulation newSimulation.IncreasePopulation(); } } @@ -130,16 +133,16 @@ void ProcessGeneration() var printedLine = Enumerable.Repeat(' ', MaxWidth).ToList(); for (var y = minY; y < maxY; y++) { - if (matrix[x, y] == 2) + if (matrix[x, y] == Cell.DyingCel) { matrix[x, y] = 0; continue; } - if (matrix[x, y] == 3) + if (matrix[x, y] == Cell.NewCell) { - matrix[x, y] = 1; + matrix[x, y] = Cell.NeutralCell; } - else if (matrix[x, y] != 1) + else if (matrix[x, y] != Cell.NeutralCell) { continue; } @@ -207,7 +210,7 @@ void ProcessGeneration() { for (var j = y - 1; j < y + 2; j++) { - if (matrix[i, j] == 1 || matrix[i, j] == 2) + if (matrix[i, j] == Cell.NeutralCell || matrix[i, j] == Cell.DyingCel) neighbors++; } } @@ -220,13 +223,13 @@ void ProcessGeneration() { if (neighbors == 3) { - matrix[x, y] = 3; + matrix[x, y] = Cell.NewCell; simulation.IncreasePopulation(); } } else if (neighbors is < 3 or > 4) { - matrix[x, y] = 2; + matrix[x, y] = Cell.DyingCel; } else { @@ -243,6 +246,14 @@ void ProcessGeneration() } } +internal enum Cell +{ + EmptyCell = 0, + NeutralCell = 1, + DyingCel = 2, + NewCell =3 +} + public class Simulation { public int Generation { get; private set; } @@ -263,14 +274,14 @@ public class Simulation class Matrix { - private readonly int[,] _matrix; + private readonly Cell[,] _matrix; public Matrix(int height, int width) { - _matrix = new int[height, width]; + _matrix = new Cell[height, width]; } - public int this[int x, int y] + public Cell this[int x, int y] { get => _matrix[x, y]; set => _matrix[x, y] = value; @@ -283,7 +294,7 @@ class Matrix { for (var y = 0; y < _matrix.GetLength(1); y++) { - var character = _matrix[x, y] == 0 ? " ": _matrix[x, y].ToString(); + var character = _matrix[x, y] == 0 ? " ": ((int)_matrix[x, y]).ToString(); stringBuilder.Append(character); } From 4870a14909b6055440c0445b5db1571004353518 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:45:34 -0300 Subject: [PATCH 085/337] Refactoring, plus adding real user input again. --- 55_Life/csharp/Program.cs | 72 ++++++++++++++------------------------- 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 0abb68f1..b9aef5dd 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -1,40 +1,16 @@ -// See https://aka.ms/new-console-template for more information - -using System.Drawing; -using System.Text; - -const int MaxWidth = 70; -const int MaxHeight = 24; - +using System.Text; +const int maxWidth = 70; +const int maxHeight = 24; Console.WriteLine("ENTER YOUR PATTERN:"); -// var pattern = ReadPattern(limitHeight: MaxHeight).ToArray(); -var pattern = new[] -{ - "*", - "*", - "*" -}; // FOR DEBUGGING PURPOSES -// var pattern = new[] -// { -// "**", -// "**", -// }; // FOR DEBUGGING PURPOSES -// var pattern = new[] -// { -// "***", -// "*", -// }; // FOR DEBUGGING PURPOSES +var pattern = ReadPattern(limitHeight: maxHeight).ToArray(); -var isInvalid = false; +var (minX, minY) = FindTopLeftCorner(pattern); +var maxX = maxHeight; +var maxY = maxWidth; -var (index, value) = FindLongestInput(pattern); -var minX = (11 - index / 2) - 1; // middle x -var minY = (33 - value.Length / 2) - 1; // middle y -var maxX = MaxHeight; -var maxY = MaxWidth; -var matrix = new Matrix(height: MaxHeight, width: MaxWidth); +var matrix = new Matrix(height: maxHeight, width: maxWidth); var simulation = InitializeSimulation(pattern, matrix); PrintHeader(); @@ -59,12 +35,15 @@ IEnumerable ReadPattern(int limitHeight) } } -(int index, string value) FindLongestInput(IEnumerable strings) +(int minX, int minY) FindTopLeftCorner(IEnumerable patternLines) { - return strings + var longestInput = patternLines .Select((value, index) => (index, value)) .OrderByDescending(input => input.value.Length) .First(); + var centerX = (11 - longestInput.index / 2) - 1; + var centerY = (33 - longestInput.value.Length / 2) - 1; + return (centerX, centerY); } void PrintHeader() @@ -88,13 +67,14 @@ void PrintHeader() Simulation InitializeSimulation(IReadOnlyList inputPattern, Matrix matrixToInitialize) { var newSimulation = new Simulation(); + // copies the pattern to the middle of the simulation and counts initial population for (var x = 0; x < inputPattern.Count; x++) { for (var y = 0; y < inputPattern[x].Length; y++) { if (inputPattern[x][y] == ' ') continue; - matrixToInitialize[minX + x, minY + y] = Cell.NeutralCell; // copy the pattern to the middle of the simulation + matrixToInitialize[minX + x, minY + y] = Cell.NeutralCell; newSimulation.IncreasePopulation(); } } @@ -104,20 +84,19 @@ Simulation InitializeSimulation(IReadOnlyList inputPattern, Matrix matri void ProcessGeneration() { - void PrintPopulation(int generation, int population) - { - Console.WriteLine($"GENERATION: {generation}\tPOPULATION: {population}"); - if (isInvalid) - Console.WriteLine("INVALID!"); - } + var isInvalid = false; while (true) { - PrintPopulation(simulation.Generation, simulation.Population); + // Thread.Sleep(millisecondsTimeout: 1000); + Console.WriteLine($"GENERATION: {simulation.Generation}\tPOPULATION: {simulation.Population}"); + if (isInvalid) + Console.WriteLine("INVALID!"); + simulation.StartNewGeneration(); - var nextMinX = MaxHeight - 1; - var nextMinY = MaxWidth - 1; + var nextMinX = maxHeight - 1; + var nextMinY = maxWidth - 1; var nextMaxX = 0; var nextMaxY = 0; @@ -130,7 +109,7 @@ void ProcessGeneration() // refreshes the matrix and updates search area for (var x = minX; x < maxX; x++) { - var printedLine = Enumerable.Repeat(' ', MaxWidth).ToList(); + var printedLine = Enumerable.Repeat(' ', maxWidth).ToList(); for (var y = minY; y < maxY; y++) { if (matrix[x, y] == Cell.DyingCel) @@ -159,7 +138,7 @@ void ProcessGeneration() } // prints empty lines after search area - for (var x = maxX + 1; x < MaxHeight; x++) + for (var x = maxX + 1; x < maxHeight; x++) { Console.WriteLine(); } @@ -172,7 +151,6 @@ void ProcessGeneration() minY = nextMinY; maxY = nextMaxY; - // TODO boundaries? review if (minX < 3) { minX = 3; From cd478a4a948d575ebb0ab55f34f555ac95c93bd8 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:46:07 -0300 Subject: [PATCH 086/337] Added argument to configure a pause in between iterations, allowing the player to enjoy watching the evolution of the game of life. --- 55_Life/csharp/Program.cs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index b9aef5dd..07a06eac 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -82,13 +82,32 @@ Simulation InitializeSimulation(IReadOnlyList inputPattern, Matrix matri return newSimulation; } +TimeSpan GetPauseBetweenIterations() +{ + if (args.Length == 2) + { + var parameter = args[0].ToLower(); + if (parameter.Contains("wait")) + { + var value = args[1]; + if (int.TryParse(value, out var sleepMilliseconds)) + return TimeSpan.FromMilliseconds(sleepMilliseconds); + } + } + + return TimeSpan.Zero; +} + void ProcessGeneration() { + var pauseBetweenIterations = GetPauseBetweenIterations(); var isInvalid = false; while (true) { - // Thread.Sleep(millisecondsTimeout: 1000); + if (pauseBetweenIterations > TimeSpan.Zero) + Thread.Sleep(pauseBetweenIterations); + Console.WriteLine($"GENERATION: {simulation.Generation}\tPOPULATION: {simulation.Population}"); if (isInvalid) Console.WriteLine("INVALID!"); From 3ffd2fdc520145d42b65becb51b6ae9cc87163aa Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:46:39 -0300 Subject: [PATCH 087/337] Refactoring and documenting the solution. --- 55_Life/csharp/Program.cs | 50 +++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 07a06eac..f2b66b88 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -14,7 +14,7 @@ var matrix = new Matrix(height: maxHeight, width: maxWidth); var simulation = InitializeSimulation(pattern, matrix); PrintHeader(); -ProcessGeneration(); +ProcessSimulation(); IEnumerable ReadPattern(int limitHeight) { @@ -27,7 +27,9 @@ IEnumerable ReadPattern(int limitHeight) break; } - // kept for compatibility + // In the original version, BASIC would trim the spaces in the beginning of an input, so the original + // game allowed you to input an '.' before the spaces to circumvent this limitation. This behavior was + // kept for compatibility. if (input.StartsWith('.')) yield return input.Substring(1, input.Length - 2); @@ -67,14 +69,14 @@ void PrintHeader() Simulation InitializeSimulation(IReadOnlyList inputPattern, Matrix matrixToInitialize) { var newSimulation = new Simulation(); - // copies the pattern to the middle of the simulation and counts initial population + // translates the pattern to the middle of the simulation and counts initial population for (var x = 0; x < inputPattern.Count; x++) { for (var y = 0; y < inputPattern[x].Length; y++) { if (inputPattern[x][y] == ' ') continue; - matrixToInitialize[minX + x, minY + y] = Cell.NeutralCell; + matrixToInitialize[minX + x, minY + y] = CellState.Stable; newSimulation.IncreasePopulation(); } } @@ -98,7 +100,7 @@ TimeSpan GetPauseBetweenIterations() return TimeSpan.Zero; } -void ProcessGeneration() +void ProcessSimulation() { var pauseBetweenIterations = GetPauseBetweenIterations(); var isInvalid = false; @@ -131,16 +133,16 @@ void ProcessGeneration() var printedLine = Enumerable.Repeat(' ', maxWidth).ToList(); for (var y = minY; y < maxY; y++) { - if (matrix[x, y] == Cell.DyingCel) + if (matrix[x, y] == CellState.Dying) { - matrix[x, y] = 0; + matrix[x, y] = CellState.Empty; continue; } - if (matrix[x, y] == Cell.NewCell) + if (matrix[x, y] == CellState.New) { - matrix[x, y] = Cell.NeutralCell; + matrix[x, y] = CellState.Stable; } - else if (matrix[x, y] != Cell.NeutralCell) + else if (matrix[x, y] != CellState.Stable) { continue; } @@ -207,7 +209,7 @@ void ProcessGeneration() { for (var j = y - 1; j < y + 2; j++) { - if (matrix[i, j] == Cell.NeutralCell || matrix[i, j] == Cell.DyingCel) + if (matrix[i, j] == CellState.Stable || matrix[i, j] == CellState.Dying) neighbors++; } } @@ -220,13 +222,13 @@ void ProcessGeneration() { if (neighbors == 3) { - matrix[x, y] = Cell.NewCell; + matrix[x, y] = CellState.New; simulation.IncreasePopulation(); } } else if (neighbors is < 3 or > 4) { - matrix[x, y] = Cell.DyingCel; + matrix[x, y] = CellState.Dying; } else { @@ -243,12 +245,15 @@ void ProcessGeneration() } } -internal enum Cell +/// +/// Indicates the state of a given cell in the simulation. +/// +internal enum CellState { - EmptyCell = 0, - NeutralCell = 1, - DyingCel = 2, - NewCell =3 + Empty = 0, + Stable = 1, + Dying = 2, + New = 3 } public class Simulation @@ -269,16 +274,19 @@ public class Simulation } } +/// +/// This class was created to aid debugging, through the implementation of the ToString() method. +/// class Matrix { - private readonly Cell[,] _matrix; + private readonly CellState[,] _matrix; public Matrix(int height, int width) { - _matrix = new Cell[height, width]; + _matrix = new CellState[height, width]; } - public Cell this[int x, int y] + public CellState this[int x, int y] { get => _matrix[x, y]; set => _matrix[x, y] = value; From c7c3d68a2eed69735ae4664f3c0d7925f9545464 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:47:08 -0300 Subject: [PATCH 088/337] Moving pause location to the end of iteration. --- 55_Life/csharp/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index f2b66b88..1c21b5f7 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -107,9 +107,6 @@ void ProcessSimulation() while (true) { - if (pauseBetweenIterations > TimeSpan.Zero) - Thread.Sleep(pauseBetweenIterations); - Console.WriteLine($"GENERATION: {simulation.Generation}\tPOPULATION: {simulation.Population}"); if (isInvalid) Console.WriteLine("INVALID!"); @@ -242,6 +239,9 @@ void ProcessSimulation() minY--; maxX++; maxY++; + + if (pauseBetweenIterations > TimeSpan.Zero) + Thread.Sleep(pauseBetweenIterations); } } From 985e1886ac32763896a363f585e7c7f5618b3a31 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:48:13 -0300 Subject: [PATCH 089/337] Adding comment about the port. --- 55_Life/csharp/Program.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 1c21b5f7..2ed1ec62 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -1,4 +1,16 @@ -using System.Text; +/* + * LIFE + * An implementation of John Conway's popular cellular automaton + * Ported by Dyego Alekssander Maas + * + * An example pattern would be: + * " * " + * "***" + * "DONE" (indicates that the simulation can start) + * + * You can find patterns to play with here: http://pi.math.cornell.edu/~lipa/mec/lesson6.html +*/ +using System.Text; const int maxWidth = 70; const int maxHeight = 24; From 8c02ea39d272a157613318a0884cea6fc734faca Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Tue, 11 Jan 2022 20:58:07 -0300 Subject: [PATCH 090/337] Documented the --wait argument. --- 55_Life/csharp/Program.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 2ed1ec62..47ed7386 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -9,6 +9,10 @@ * "DONE" (indicates that the simulation can start) * * You can find patterns to play with here: http://pi.math.cornell.edu/~lipa/mec/lesson6.html + * + * Optionally, you can run this program with the "--wait 1000" argument, the number being the time in milliseconds + * that the application will pause between each iteration. This is enables you to watch the simulation unfolding. + * By default, there is no pause between iterations. */ using System.Text; From b28a12f52afec5cd5955190dbd189015d8c05f78 Mon Sep 17 00:00:00 2001 From: Tim Buchalka <70119791+journich@users.noreply.github.com> Date: Wed, 12 Jan 2022 12:22:37 +1030 Subject: [PATCH 091/337] Document both contributions of this game Notes relating to both contributed versions of Acey Ducey for Java. --- 01_Acey_Ducey/java/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/01_Acey_Ducey/java/README.md b/01_Acey_Ducey/java/README.md index 51edd8d4..4153020a 100644 --- a/01_Acey_Ducey/java/README.md +++ b/01_Acey_Ducey/java/README.md @@ -1,3 +1,9 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Oracle Java](https://openjdk.java.net/) + +Two versions of Acey Ducey have been contributed. + +The original upload supported JDK 8/JDK 11 and uses multiple files and the second uses features in JDK 17 and is implemented in a single file AceyDucey17.java. + +Both are in the src folder. From daa06846bf2de4b3e57ba10c1e0c0b8491a0dae5 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 11 Jan 2022 20:59:56 -0500 Subject: [PATCH 092/337] moved implementations to individual folders --- 75_Roulette/java/{src => iterative}/Roulette.java | 0 75_Roulette/java/{ => oop}/Bet.java | 0 75_Roulette/java/{ => oop}/Roulette.java | 0 75_Roulette/java/{ => oop}/Wheel.java | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename 75_Roulette/java/{src => iterative}/Roulette.java (100%) rename 75_Roulette/java/{ => oop}/Bet.java (100%) rename 75_Roulette/java/{ => oop}/Roulette.java (100%) rename 75_Roulette/java/{ => oop}/Wheel.java (100%) diff --git a/75_Roulette/java/src/Roulette.java b/75_Roulette/java/iterative/Roulette.java similarity index 100% rename from 75_Roulette/java/src/Roulette.java rename to 75_Roulette/java/iterative/Roulette.java diff --git a/75_Roulette/java/Bet.java b/75_Roulette/java/oop/Bet.java similarity index 100% rename from 75_Roulette/java/Bet.java rename to 75_Roulette/java/oop/Bet.java diff --git a/75_Roulette/java/Roulette.java b/75_Roulette/java/oop/Roulette.java similarity index 100% rename from 75_Roulette/java/Roulette.java rename to 75_Roulette/java/oop/Roulette.java diff --git a/75_Roulette/java/Wheel.java b/75_Roulette/java/oop/Wheel.java similarity index 100% rename from 75_Roulette/java/Wheel.java rename to 75_Roulette/java/oop/Wheel.java From 76d5f2dde2dfc0422895aa6f9b93fc59ba9dd3ba Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 11 Jan 2022 21:03:33 -0500 Subject: [PATCH 093/337] Expanded README to describe different implementations --- 75_Roulette/java/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/75_Roulette/java/README.md b/75_Roulette/java/README.md index 2f9c97ca..8514a9ad 100644 --- a/75_Roulette/java/README.md +++ b/75_Roulette/java/README.md @@ -2,5 +2,7 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/gam Conversion to [Oracle Java](https://openjdk.java.net/) -Conversion by Andrew McGuinness (andrew@arobeia.co.uk) +Two versions of Roulette has been contributed. They are indicated within given sub-folders +- [oop](./oop) - Conversion by Andrew McGuinness (andrew@arobeia.co.uk) +- [iterative](./iterative) - Conversion by Thomas Kwashnak ([Github](https://github.com/LittleTealeaf)). Implements features from JDK 17 \ No newline at end of file From f87d306b0f5ba33047320c586dc7445d48bccf62 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Tue, 11 Jan 2022 21:05:35 -0500 Subject: [PATCH 094/337] Added some descriptors to iterative --- 75_Roulette/java/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/75_Roulette/java/README.md b/75_Roulette/java/README.md index 8514a9ad..bc05d92c 100644 --- a/75_Roulette/java/README.md +++ b/75_Roulette/java/README.md @@ -5,4 +5,6 @@ Conversion to [Oracle Java](https://openjdk.java.net/) Two versions of Roulette has been contributed. They are indicated within given sub-folders - [oop](./oop) - Conversion by Andrew McGuinness (andrew@arobeia.co.uk) -- [iterative](./iterative) - Conversion by Thomas Kwashnak ([Github](https://github.com/LittleTealeaf)). Implements features from JDK 17 \ No newline at end of file +- [iterative](./iterative) - Conversion by Thomas Kwashnak ([Github](https://github.com/LittleTealeaf)). + - Implements features from JDK 17. + - Does make use of some object oriented programming, but acts as a more iterative solution. \ No newline at end of file From f61148b2e4c7608c5d7cbbf08ddfcbfd9c5afebf Mon Sep 17 00:00:00 2001 From: Tom Wyant Date: Tue, 11 Jan 2022 21:19:47 -0500 Subject: [PATCH 095/337] Convert 21_Calendar to Perl. This is pretty much a complete rewrite. It displays the current year, but that can be changed by specifying the desired year on the command line. It MAY even be sensitive enough to locale to produce output in languages other than English. --- 21_Calendar/perl/README.md | 10 +++ 21_Calendar/perl/calendar.pl | 130 +++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100755 21_Calendar/perl/calendar.pl diff --git a/21_Calendar/perl/README.md b/21_Calendar/perl/README.md index e69c8b81..043be194 100644 --- a/21_Calendar/perl/README.md +++ b/21_Calendar/perl/README.md @@ -1,3 +1,13 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Perl](https://www.perl.org/) + +Actually, this is not so much a port as a complete rewrite, making use of +Perl's Posix time functionality. The calendar is for the current year (not +1979), but you can get another year by specifying it on the command line, e.g. + + `perl 21_Calendar/perl/calendar.pl 2001` + +It *may* even produce output in languages other than English. But the +leftmost column will still be Sunday, even in locales where it is +typically Monday. diff --git a/21_Calendar/perl/calendar.pl b/21_Calendar/perl/calendar.pl new file mode 100755 index 00000000..96ba387b --- /dev/null +++ b/21_Calendar/perl/calendar.pl @@ -0,0 +1,130 @@ +#!/usr/bin/env perl + +use 5.010; # To get 'state' and 'say' + +use strict; # Require explicit declaration of variables +use warnings; # Enable optional compiler warnings + +use English; # Use more friendly names for Perl's magic variables +use POSIX qw{ strftime }; +use Term::ReadLine; # Prompt and return user input +use Time::Local (); + +BEGIN { + *time_gm = + Time::Local->can( 'timegm_modern' ) || + Time::Local->can( 'timegm' ); +} + +our $VERSION = '0.000_01'; + +use constant COLUMN_WIDTH => 6; +use constant SECONDS_PER_DAY => 86400; + +binmode STDOUT, ':encoding(utf-8)'; + +my $year = @ARGV ? $ARGV[0] : ( localtime )[5] + 1900; +my $is_leap_year = is_leap_year( $year ); +my $year_len = 365 + $is_leap_year; +print <<'EOD'; + CALENDAR + Creative Computing Morristown, New Jersey + + +EOD + +my @mon_len = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); +$mon_len[1] += $is_leap_year; + +foreach my $month ( 0 .. 11 ) { + my $epoch = time_gm( 0, 0, 0, 1, $month, $year ); + my @start_time = gmtime( $epoch ); + my ( $week_day, $year_day ) = @start_time[ 6, 7 ]; + my $label = strftime( '%B %Y', @start_time ); + $label .= ' ' x ( ( 14 - length $label ) / 2 ); + printf "\n** %3d ****** %14s ****** %3d **\n", + $year_day, $label, $year_len - $year_day; + { + my $day = 1 + ( 7 - $week_day ) % 7; + foreach my $wd ( 0 .. 6 ) { + my $ep = time_gm( 0, 0, 0, $day + $wd, $month, $year ); + printf '%*s', COLUMN_WIDTH, strftime( '%a', gmtime $ep ); + } + print "\n"; + } + say '*' x ( COLUMN_WIDTH * 7 ); + print ' ' x ( COLUMN_WIDTH * $week_day ); + my $month_day = 1; + while ( $week_day < 7 ) { + printf '%*d', COLUMN_WIDTH, $month_day++; + $week_day++; + } + print "\n"; + $week_day = 0; + while ( $month_day <= $mon_len[$month] ) { + printf '%*d', COLUMN_WIDTH, $month_day++; + $week_day++; + unless ( $week_day % 7 ) { + print "\n"; + $week_day = 0; + } + } + print "\n" if $week_day; + +} + +sub is_leap_year { + my ( $year ) = 1; + return 0 if $year % 4; + return 1 if $year % 100; + return 0 if $year % 400; + return 1; +} + +__END__ + +=head1 TITLE + +calendar - Play the game 'Calendar' from Basic Computer Games + +=head1 SYNOPSIS + + calendar.pl + +=head1 DETAILS + +This Perl script is a port of calendar, which is the 21st +entry in Basic Computer Games. + +Actually, it is not so much a port as a complete rewrite, making use of +Perl's Posix time functionality. The calendar is for the current year +(not 1979), but you can get another year by specifying it on the command +line, e.g. + + perl 21_Calendar/perl/calendar.pl 2001 + +It B even produce output in languages other than English. But the +leftmost column will still be Sunday, even in locales where it is +typically Monday. + +=head1 PORTED BY + +Thomas R. Wyant, III F + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2022 by Thomas R. Wyant, III + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl 5.10.0. For more details, see the Artistic +License 1.0 at +L, and/or the +Gnu GPL at L. + +This program is distributed in the hope that it will be useful, but +without any warranty; without even the implied warranty of +merchantability or fitness for a particular purpose. + +=cut + +# ex: set expandtab tabstop=4 textwidth=72 : From 84d473d8f29e65b23ce12a859a45479974b5fe0c Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 17:56:26 +0800 Subject: [PATCH 096/337] Create reverser that reverses an array at a given position. --- .../Reverse.Tests/Reverse.Tests.csproj | 26 ++++++++++++ .../Reverse/Reverse.Tests/ReverserTests.cs | 41 +++++++++++++++++++ 73_Reverse/csharp/Reverse/Reverse.sln | 31 ++++++++++++++ 73_Reverse/csharp/Reverse/Reverse/Program.cs | 12 ++++++ .../csharp/Reverse/Reverse/Reverse.csproj | 8 ++++ 73_Reverse/csharp/Reverse/Reverse/Reverser.cs | 16 ++++++++ 6 files changed, 134 insertions(+) create mode 100644 73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj create mode 100644 73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs create mode 100644 73_Reverse/csharp/Reverse/Reverse.sln create mode 100644 73_Reverse/csharp/Reverse/Reverse/Program.cs create mode 100644 73_Reverse/csharp/Reverse/Reverse/Reverse.csproj create mode 100644 73_Reverse/csharp/Reverse/Reverse/Reverser.cs diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj b/73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj new file mode 100644 index 00000000..97b7bcce --- /dev/null +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj @@ -0,0 +1,26 @@ + + + + net5.0 + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs new file mode 100644 index 00000000..2ab52d69 --- /dev/null +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs @@ -0,0 +1,41 @@ +using System.Linq; +using Xunit; + +namespace Reverse.Tests +{ + public class ReverserTests + { + [Theory] + [InlineData(new int[] { 1 }, new int[] { 1 })] + [InlineData(new int[] { 1, 2 }, new int[] { 2, 1 })] + [InlineData(new int[] { 1, 2, 3 }, new int[] { 3, 2, 1 })] + public void ReverserReversesTheArray(int[] input, int[] output) + { + Reverser.Reverse(input, input.Length); + + Assert.True(input.SequenceEqual(output)); + } + + [Fact] + public void ReverserReversesTheArrayAtTheSpecifiedIndex() + { + var input = new int[] { 1, 2, 3, 4 }; + var output = new int[] { 2, 1, 3, 4 }; + + Reverser.Reverse(input, 2); + + Assert.True(input.SequenceEqual(output)); + } + + [Fact] + public void ReversingAtIndexOneDoesNotChangeTheArray() + { + var input = new int[] { 1, 2 }; + var output = new int[] { 1, 2 }; + + Reverser.Reverse(input, 1); + + Assert.True(input.SequenceEqual(output)); + } + } +} diff --git a/73_Reverse/csharp/Reverse/Reverse.sln b/73_Reverse/csharp/Reverse/Reverse.sln new file mode 100644 index 00000000..96c338be --- /dev/null +++ b/73_Reverse/csharp/Reverse/Reverse.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32002.261 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reverse", "Reverse\Reverse.csproj", "{39463B63-6A71-4DCF-A4F2-FAA74FDEEC01}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reverse.Tests", "Reverse.Tests\Reverse.Tests.csproj", "{96E824F8-0353-4FF2-9FEA-F850E2BE7312}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {39463B63-6A71-4DCF-A4F2-FAA74FDEEC01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {39463B63-6A71-4DCF-A4F2-FAA74FDEEC01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {39463B63-6A71-4DCF-A4F2-FAA74FDEEC01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {39463B63-6A71-4DCF-A4F2-FAA74FDEEC01}.Release|Any CPU.Build.0 = Release|Any CPU + {96E824F8-0353-4FF2-9FEA-F850E2BE7312}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96E824F8-0353-4FF2-9FEA-F850E2BE7312}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96E824F8-0353-4FF2-9FEA-F850E2BE7312}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96E824F8-0353-4FF2-9FEA-F850E2BE7312}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1DCA2723-D126-4B37-A698-D40DA03643A9} + EndGlobalSection +EndGlobal diff --git a/73_Reverse/csharp/Reverse/Reverse/Program.cs b/73_Reverse/csharp/Reverse/Reverse/Program.cs new file mode 100644 index 00000000..72ae99ef --- /dev/null +++ b/73_Reverse/csharp/Reverse/Reverse/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace Reverse +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverse.csproj b/73_Reverse/csharp/Reverse/Reverse/Reverse.csproj new file mode 100644 index 00000000..20827042 --- /dev/null +++ b/73_Reverse/csharp/Reverse/Reverse/Reverse.csproj @@ -0,0 +1,8 @@ + + + + Exe + net5.0 + + + diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs new file mode 100644 index 00000000..ed9b8748 --- /dev/null +++ b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs @@ -0,0 +1,16 @@ +namespace Reverse +{ + public class Reverser + { + public static void Reverse(int[] arrayToReverse, int indexToReverseTo) + { + for (int i = 0; i < indexToReverseTo / 2; i++) + { + int temp = arrayToReverse[i]; + int upperIndex = indexToReverseTo - 1 - i; + arrayToReverse[i] = arrayToReverse[upperIndex]; + arrayToReverse[upperIndex] = temp; + } + } + } +} From 2a809aabc99cb582bab93e259e1b3ec2d03a555b Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 18:09:57 +0800 Subject: [PATCH 097/337] Protect against index out of range exceptions --- .../csharp/Reverse/Reverse.Tests/ReverserTests.cs | 11 +++++++++++ 73_Reverse/csharp/Reverse/Reverse/Reverser.cs | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs index 2ab52d69..7320ef92 100644 --- a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs @@ -37,5 +37,16 @@ namespace Reverse.Tests Assert.True(input.SequenceEqual(output)); } + + [Fact] + public void Reverse_WithIndexGreaterThanArrayLength_DoesNothing() + { + var input = new int[] { 1, 2 }; + var output = new int[] { 1, 2 }; + + Reverser.Reverse(input, input.Length + 1); + + Assert.True(input.SequenceEqual(output)); + } } } diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs index ed9b8748..be3b194f 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs @@ -4,6 +4,11 @@ { public static void Reverse(int[] arrayToReverse, int indexToReverseTo) { + if (indexToReverseTo > arrayToReverse.Length) + { + return; + } + for (int i = 0; i < indexToReverseTo / 2; i++) { int temp = arrayToReverse[i]; From 8e54c0e930d87eef2ed0408591d73fcc9ce30541 Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 18:12:15 +0800 Subject: [PATCH 098/337] rename tests. --- 73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs index 7320ef92..c263dbe5 100644 --- a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs @@ -9,7 +9,7 @@ namespace Reverse.Tests [InlineData(new int[] { 1 }, new int[] { 1 })] [InlineData(new int[] { 1, 2 }, new int[] { 2, 1 })] [InlineData(new int[] { 1, 2, 3 }, new int[] { 3, 2, 1 })] - public void ReverserReversesTheArray(int[] input, int[] output) + public void Reverse_WillReverseEntireArray(int[] input, int[] output) { Reverser.Reverse(input, input.Length); @@ -17,7 +17,7 @@ namespace Reverse.Tests } [Fact] - public void ReverserReversesTheArrayAtTheSpecifiedIndex() + public void Reverse_WithSpecifiedIndex_ReversesItemsUpToThatIndex() { var input = new int[] { 1, 2, 3, 4 }; var output = new int[] { 2, 1, 3, 4 }; @@ -28,7 +28,7 @@ namespace Reverse.Tests } [Fact] - public void ReversingAtIndexOneDoesNotChangeTheArray() + public void Reverse_WithIndexOne_DoesNothing() { var input = new int[] { 1, 2 }; var output = new int[] { 1, 2 }; From b1cfa83ac56edcc867613064ee4496ea924d4084 Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 19:00:20 +0800 Subject: [PATCH 099/337] Add method for checking if a given array is in ascending order. --- .../Reverse/Reverse.Tests/ReverserTests.cs | 18 ++++++++++++++++++ 73_Reverse/csharp/Reverse/Reverse/Reverser.cs | 13 +++++++++++++ 2 files changed, 31 insertions(+) diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs index c263dbe5..d00640da 100644 --- a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs @@ -48,5 +48,23 @@ namespace Reverse.Tests Assert.True(input.SequenceEqual(output)); } + [Theory] + [InlineData(new int[] { 1 })] + [InlineData(new int[] { 1, 2 })] + [InlineData(new int[] { 1, 1 })] + public void IsArrayInAscendingOrder_WhenArrayElementsAreInNumericAscendingOrder_ReturnsTrue(int[] input) + { + var result = Reverser.IsArrayInAscendingOrder(input); + + Assert.True(result); + } + + [Fact] + public void IsArrayInOrder_WhenArrayElementsAreNotInNumericAscendingOrder_ReturnsFalse() + { + var result = Reverser.IsArrayInAscendingOrder(new int[] { 2, 1 }); + + Assert.False(result); + } } } diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs index be3b194f..e37e3d2f 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs @@ -17,5 +17,18 @@ arrayToReverse[upperIndex] = temp; } } + + public static bool IsArrayInAscendingOrder(int[] array) + { + for (int i = 1; i < array.Length; i++) + { + if (array[i] < array[i - 1]) + { + return false; + } + } + + return true; + } } } From 1d4651bfef143b766b7599f3e58086919390b8a1 Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 19:00:51 +0800 Subject: [PATCH 100/337] Add method for creating a random array of distinct values. --- .../Generators/PositiveIntegerGenerator.cs | 10 +++++++ .../Reverse.Tests/Reverse.Tests.csproj | 1 + .../Reverse/Reverse.Tests/ReverserTests.cs | 30 +++++++++++++++++++ 73_Reverse/csharp/Reverse/Reverse/Reverser.cs | 25 +++++++++++++++- 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 73_Reverse/csharp/Reverse/Reverse.Tests/Generators/PositiveIntegerGenerator.cs diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/Generators/PositiveIntegerGenerator.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/Generators/PositiveIntegerGenerator.cs new file mode 100644 index 00000000..66889bb5 --- /dev/null +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/Generators/PositiveIntegerGenerator.cs @@ -0,0 +1,10 @@ +using FsCheck; + +namespace Reverse.Tests.Generators +{ + public static class PositiveIntegerGenerator + { + public static Arbitrary Generate() => + Arb.Default.Int32().Filter(x => x > 0); + } +} diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj b/73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj index 97b7bcce..260de5e1 100644 --- a/73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj @@ -7,6 +7,7 @@ + diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs index d00640da..a6beeeb3 100644 --- a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs @@ -1,3 +1,5 @@ +using FsCheck.Xunit; +using Reverse.Tests.Generators; using System.Linq; using Xunit; @@ -48,6 +50,34 @@ namespace Reverse.Tests Assert.True(input.SequenceEqual(output)); } + + [Property(Arbitrary = new[] { typeof(PositiveIntegerGenerator) })] + public void CreateRandomArray_ReturnsRandomArrayOfSpecifiedLength() + { + var result = Reverser.CreateRandomArray(5); + + Assert.Equal(5, result.Length); + } + + [Property(Arbitrary = new[] { typeof(PositiveIntegerGenerator) })] + public void CreateRandomArray_MaxElementValueIsEqualToSize(int size) + { + var result = Reverser.CreateRandomArray(size); + + Assert.Equal(size, result.Max()); + } + + [Property(Arbitrary = new[] { typeof(PositiveIntegerGenerator) })] + public void CreateRandomArray_ReturnsRandomArrayWithDistinctElements(int size) + { + var array = Reverser.CreateRandomArray(size); + + var arrayGroup = array.GroupBy(x => x); + var duplicateFound = arrayGroup.Any(x => x.Count() > 1); + + Assert.False(duplicateFound); + } + [Theory] [InlineData(new int[] { 1 })] [InlineData(new int[] { 1, 2 })] diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs index e37e3d2f..62db79f1 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs @@ -1,4 +1,6 @@ -namespace Reverse +using System; + +namespace Reverse { public class Reverser { @@ -18,6 +20,27 @@ } } + public static int[] CreateRandomArray(int size) + { + var array = new int[size]; + for (int i = 1; i <= size; i++) + { + array[i - 1] = i; + } + + var rnd = new Random(); + + for (int i = size; i > 1;) + { + int k = rnd.Next(i); + --i; + int temp = array[i]; + array[i] = array[k]; + array[k] = temp; + } + return array; + } + public static bool IsArrayInAscendingOrder(int[] array) { for (int i = 1; i < array.Length; i++) From 08282e1a7dd45ed8ccfc8c234c4b10aade41d7db Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 19:29:09 +0800 Subject: [PATCH 101/337] Configure console app --- 73_Reverse/csharp/Reverse/Reverse/Program.cs | 95 +++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/73_Reverse/csharp/Reverse/Reverse/Program.cs b/73_Reverse/csharp/Reverse/Reverse/Program.cs index 72ae99ef..d1de060c 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Program.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Text; namespace Reverse { @@ -6,7 +7,99 @@ namespace Reverse { static void Main(string[] args) { - Console.WriteLine("Hello World!"); + PrintTitle(); + Console.Write("DO YOU WANT THE RULES? "); + var needRulesInput = Console.ReadLine(); + + if (string.Equals(needRulesInput, "YES", StringComparison.OrdinalIgnoreCase)) + { + DisplayRules(); + } + + var tryAgain = string.Empty; + while (!string.Equals(tryAgain, "NO", StringComparison.OrdinalIgnoreCase)) + { + var array = Reverser.CreateRandomArray(9); + Console.WriteLine(PrintArrayContents(array)); + var arrayIsNotInAscendingOrder = true; + var numberOfMoves = 0; + while (arrayIsNotInAscendingOrder) + { + int index = ReadNextInput(); + + if (index == 0) + { + break; + } + + Reverser.Reverse(array, index); + Console.WriteLine(PrintArrayContents(array)); + + if (Reverser.IsArrayInAscendingOrder(array)) + { + arrayIsNotInAscendingOrder = false; + Console.WriteLine($"YOU WON IT IN {numberOfMoves} MOVES!!!"); + } + numberOfMoves++; + } + + Console.Write("TRY AGAIN (YES OR NO)"); + tryAgain = Console.ReadLine(); + } + + Console.WriteLine("OK HOPE YOU HAD FUN"); + } + + private static int ReadNextInput() + { + Console.Write("HOW MANY SHALL I REVERSE? "); + var input = ReadIntegerInput(); + while (input > 9 || input < 0) + { + if (input > 9) + { + Console.WriteLine("OOPS! TOO MANY! I CAN REVERSE AT MOST THIS MANY"); + } + + if (input < 0) + { + Console.WriteLine("OOPS! TOO FEW! I CAN REVERSE BETWEEN 1 AND THIS MANY"); + } + Console.Write("HOW MANY SHALL I REVERSE? "); + input = ReadIntegerInput(); + } + + return input; + } + + private static int ReadIntegerInput() + { + var input = Console.ReadLine(); + int.TryParse(input, out var index); + return index; + } + + private static string PrintArrayContents(int[] arr) + { + var sb = new StringBuilder(); + + foreach (int i in arr) + { + sb.Append(" " + i + " "); + } + + return sb.ToString(); + } + + private static void PrintTitle() + { + Console.WriteLine("REVERSE"); + Console.WriteLine("CREATIVE COMPUTING MORRISTON, NEW JERSEY"); + } + + private static void DisplayRules() + { + Console.WriteLine("RULES"); } } } From a819a535bb0b4d35c947d0845eca474ea67b0e42 Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 20:00:59 +0800 Subject: [PATCH 102/337] Define instance methods for reverser. --- .../Reverse/Reverse.Tests/ReverserTests.cs | 89 +++++++++++-------- .../Reverse/Reverse.Tests/TestReverser.cs | 17 ++++ 73_Reverse/csharp/Reverse/Reverse/Reverser.cs | 17 ++++ 3 files changed, 86 insertions(+), 37 deletions(-) create mode 100644 73_Reverse/csharp/Reverse/Reverse.Tests/TestReverser.cs diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs index a6beeeb3..9df7d3d5 100644 --- a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs @@ -7,15 +7,45 @@ namespace Reverse.Tests { public class ReverserTests { + [Property(Arbitrary = new[] { typeof(PositiveIntegerGenerator) })] + public void Constructor_CreatesRandomArrayOfSpecifiedLength(int size) + { + var sut = new TestReverser(size); + + Assert.Equal(size, sut.GetArray().Length); + } + + [Property(Arbitrary = new[] { typeof(PositiveIntegerGenerator) })] + public void ConstructorArray_MaxElementValueIsEqualToSize(int size) + { + var sut = new TestReverser(size); + + Assert.Equal(size, sut.GetArray().Max()); + } + + [Property(Arbitrary = new[] { typeof(PositiveIntegerGenerator) })] + public void ConstructorArray_ReturnsRandomArrayWithDistinctElements(int size) + { + var sut = new TestReverser(size); + var array = sut.GetArray(); + var arrayGroup = array.GroupBy(x => x); + var duplicateFound = arrayGroup.Any(x => x.Count() > 1); + + Assert.False(duplicateFound); + } + [Theory] [InlineData(new int[] { 1 }, new int[] { 1 })] [InlineData(new int[] { 1, 2 }, new int[] { 2, 1 })] [InlineData(new int[] { 1, 2, 3 }, new int[] { 3, 2, 1 })] public void Reverse_WillReverseEntireArray(int[] input, int[] output) { - Reverser.Reverse(input, input.Length); + var sut = new TestReverser(1); + sut.SetArray(input); - Assert.True(input.SequenceEqual(output)); + sut.Reverse(input.Length); + + Assert.True(sut.GetArray().SequenceEqual(output)); } [Fact] @@ -23,10 +53,12 @@ namespace Reverse.Tests { var input = new int[] { 1, 2, 3, 4 }; var output = new int[] { 2, 1, 3, 4 }; + var sut = new TestReverser(1); + sut.SetArray(input); - Reverser.Reverse(input, 2); + sut.Reverse(2); - Assert.True(input.SequenceEqual(output)); + Assert.True(sut.GetArray().SequenceEqual(output)); } [Fact] @@ -34,10 +66,12 @@ namespace Reverse.Tests { var input = new int[] { 1, 2 }; var output = new int[] { 1, 2 }; + var sut = new TestReverser(1); + sut.SetArray(input); - Reverser.Reverse(input, 1); + sut.Reverse(1); - Assert.True(input.SequenceEqual(output)); + Assert.True(sut.GetArray().SequenceEqual(output)); } [Fact] @@ -45,37 +79,12 @@ namespace Reverse.Tests { var input = new int[] { 1, 2 }; var output = new int[] { 1, 2 }; + var sut = new TestReverser(1); + sut.SetArray(input); - Reverser.Reverse(input, input.Length + 1); + sut.Reverse(sut.GetArray().Length + 1); - Assert.True(input.SequenceEqual(output)); - } - - [Property(Arbitrary = new[] { typeof(PositiveIntegerGenerator) })] - public void CreateRandomArray_ReturnsRandomArrayOfSpecifiedLength() - { - var result = Reverser.CreateRandomArray(5); - - Assert.Equal(5, result.Length); - } - - [Property(Arbitrary = new[] { typeof(PositiveIntegerGenerator) })] - public void CreateRandomArray_MaxElementValueIsEqualToSize(int size) - { - var result = Reverser.CreateRandomArray(size); - - Assert.Equal(size, result.Max()); - } - - [Property(Arbitrary = new[] { typeof(PositiveIntegerGenerator) })] - public void CreateRandomArray_ReturnsRandomArrayWithDistinctElements(int size) - { - var array = Reverser.CreateRandomArray(size); - - var arrayGroup = array.GroupBy(x => x); - var duplicateFound = arrayGroup.Any(x => x.Count() > 1); - - Assert.False(duplicateFound); + Assert.True(sut.GetArray().SequenceEqual(output)); } [Theory] @@ -84,7 +93,10 @@ namespace Reverse.Tests [InlineData(new int[] { 1, 1 })] public void IsArrayInAscendingOrder_WhenArrayElementsAreInNumericAscendingOrder_ReturnsTrue(int[] input) { - var result = Reverser.IsArrayInAscendingOrder(input); + var sut = new TestReverser(1); + sut.SetArray(input); + + var result = sut.IsArrayInAscendingOrder(); Assert.True(result); } @@ -92,7 +104,10 @@ namespace Reverse.Tests [Fact] public void IsArrayInOrder_WhenArrayElementsAreNotInNumericAscendingOrder_ReturnsFalse() { - var result = Reverser.IsArrayInAscendingOrder(new int[] { 2, 1 }); + var sut = new TestReverser(1); + sut.SetArray(new int[] { 2, 1 }); + + var result = sut.IsArrayInAscendingOrder(); Assert.False(result); } diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/TestReverser.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/TestReverser.cs new file mode 100644 index 00000000..a53004e1 --- /dev/null +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/TestReverser.cs @@ -0,0 +1,17 @@ +namespace Reverse.Tests +{ + internal class TestReverser : Reverser + { + public TestReverser(int arraySize) : base(arraySize) { } + + public int[] GetArray() + { + return _array; + } + + public void SetArray(int[] array) + { + _array = array; + } + } +} diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs index 62db79f1..426713c4 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs @@ -4,6 +4,23 @@ namespace Reverse { public class Reverser { + protected int[] _array; + + public Reverser(int arraySize) + { + _array = CreateRandomArray(arraySize); + } + + public void Reverse(int index) + { + Reverse(_array, index); + } + + public bool IsArrayInAscendingOrder() + { + return IsArrayInAscendingOrder(_array); + } + public static void Reverse(int[] arrayToReverse, int indexToReverseTo) { if (indexToReverseTo > arrayToReverse.Length) From eb27f8612ea3c89f40a1e8f61430798e8800656e Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 20:05:17 +0800 Subject: [PATCH 103/337] Add GetArrayString method. --- .../csharp/Reverse/Reverse.Tests/ReverserTests.cs | 11 +++++++++++ 73_Reverse/csharp/Reverse/Reverse/Reverser.cs | 13 +++++++++++++ 2 files changed, 24 insertions(+) diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs index 9df7d3d5..bd00436f 100644 --- a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs @@ -111,5 +111,16 @@ namespace Reverse.Tests Assert.False(result); } + + [Fact] + public void GetArrayString_ReturnsSpaceSeparatedElementsOfArrayInStringFormat() + { + var sut = new TestReverser(1); + sut.SetArray(new int[] { 1, 2 }); + + var result = sut.GetArrayString(); + + Assert.Equal(" 1 2 ", result); + } } } diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs index 426713c4..f2d720b4 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs @@ -1,4 +1,5 @@ using System; +using System.Text; namespace Reverse { @@ -70,5 +71,17 @@ namespace Reverse return true; } + + public string GetArrayString() + { + var sb = new StringBuilder(); + + foreach (int i in _array) + { + sb.Append(" " + i + " "); + } + + return sb.ToString(); + } } } From 67d1c84f2e76693e54782eb3608f027fca9eee3b Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 20:13:03 +0800 Subject: [PATCH 104/337] Update program to reference instance of reverser. --- 73_Reverse/csharp/Reverse/Reverse/Program.cs | 30 +++++++------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/73_Reverse/csharp/Reverse/Reverse/Program.cs b/73_Reverse/csharp/Reverse/Reverse/Program.cs index d1de060c..7beee62b 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Program.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Program.cs @@ -1,10 +1,10 @@ using System; -using System.Text; namespace Reverse { class Program { + private static int arrayLength = 9; static void Main(string[] args) { PrintTitle(); @@ -19,8 +19,10 @@ namespace Reverse var tryAgain = string.Empty; while (!string.Equals(tryAgain, "NO", StringComparison.OrdinalIgnoreCase)) { - var array = Reverser.CreateRandomArray(9); - Console.WriteLine(PrintArrayContents(array)); + var reverser = new Reverser(arrayLength); + + Console.WriteLine(reverser.GetArrayString()); + var arrayIsNotInAscendingOrder = true; var numberOfMoves = 0; while (arrayIsNotInAscendingOrder) @@ -32,10 +34,10 @@ namespace Reverse break; } - Reverser.Reverse(array, index); - Console.WriteLine(PrintArrayContents(array)); + reverser.Reverse(index); + Console.WriteLine(reverser.GetArrayString()); - if (Reverser.IsArrayInAscendingOrder(array)) + if (reverser.IsArrayInAscendingOrder()) { arrayIsNotInAscendingOrder = false; Console.WriteLine($"YOU WON IT IN {numberOfMoves} MOVES!!!"); @@ -58,12 +60,12 @@ namespace Reverse { if (input > 9) { - Console.WriteLine("OOPS! TOO MANY! I CAN REVERSE AT MOST THIS MANY"); + Console.WriteLine($"OOPS! TOO MANY! I CAN REVERSE AT MOST {arrayLength}"); } if (input < 0) { - Console.WriteLine("OOPS! TOO FEW! I CAN REVERSE BETWEEN 1 AND THIS MANY"); + Console.WriteLine($"OOPS! TOO FEW! I CAN REVERSE BETWEEN 1 AND {arrayLength}"); } Console.Write("HOW MANY SHALL I REVERSE? "); input = ReadIntegerInput(); @@ -79,18 +81,6 @@ namespace Reverse return index; } - private static string PrintArrayContents(int[] arr) - { - var sb = new StringBuilder(); - - foreach (int i in arr) - { - sb.Append(" " + i + " "); - } - - return sb.ToString(); - } - private static void PrintTitle() { Console.WriteLine("REVERSE"); From 0a7e386c366038a43620ad02d5a2f82eb75ca301 Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 20:13:57 +0800 Subject: [PATCH 105/337] Remove static method. --- 73_Reverse/csharp/Reverse/Reverse/Reverser.cs | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs index f2d720b4..cd94bf4f 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs @@ -19,7 +19,15 @@ namespace Reverse public bool IsArrayInAscendingOrder() { - return IsArrayInAscendingOrder(_array); + for (int i = 1; i < _array.Length; i++) + { + if (_array[i] < _array[i - 1]) + { + return false; + } + } + + return true; } public static void Reverse(int[] arrayToReverse, int indexToReverseTo) @@ -59,19 +67,6 @@ namespace Reverse return array; } - public static bool IsArrayInAscendingOrder(int[] array) - { - for (int i = 1; i < array.Length; i++) - { - if (array[i] < array[i - 1]) - { - return false; - } - } - - return true; - } - public string GetArrayString() { var sb = new StringBuilder(); From 4dc1e57789cec996479ac90c4466e996e2702c9e Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 20:14:33 +0800 Subject: [PATCH 106/337] Make static method private. --- 73_Reverse/csharp/Reverse/Reverse/Reverser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs index cd94bf4f..99e60ea4 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs @@ -46,7 +46,7 @@ namespace Reverse } } - public static int[] CreateRandomArray(int size) + private int[] CreateRandomArray(int size) { var array = new int[size]; for (int i = 1; i <= size; i++) From 2758c3375cd204b0dce26f661fedf1ee011565ce Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 20:15:37 +0800 Subject: [PATCH 107/337] Remove static method. --- 73_Reverse/csharp/Reverse/Reverse/Reverser.cs | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs index 99e60ea4..2d2ea700 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs @@ -14,7 +14,18 @@ namespace Reverse public void Reverse(int index) { - Reverse(_array, index); + if (index > _array.Length) + { + return; + } + + for (int i = 0; i < index / 2; i++) + { + int temp = _array[i]; + int upperIndex = index - 1 - i; + _array[i] = _array[upperIndex]; + _array[upperIndex] = temp; + } } public bool IsArrayInAscendingOrder() @@ -30,22 +41,6 @@ namespace Reverse return true; } - public static void Reverse(int[] arrayToReverse, int indexToReverseTo) - { - if (indexToReverseTo > arrayToReverse.Length) - { - return; - } - - for (int i = 0; i < indexToReverseTo / 2; i++) - { - int temp = arrayToReverse[i]; - int upperIndex = indexToReverseTo - 1 - i; - arrayToReverse[i] = arrayToReverse[upperIndex]; - arrayToReverse[upperIndex] = temp; - } - } - private int[] CreateRandomArray(int size) { var array = new int[size]; From 3e9f1354b3de2b202c4fd8f0861c1fc0ae687f55 Mon Sep 17 00:00:00 2001 From: "Brax Antti (Oy Samlink Ab)" Date: Wed, 12 Jan 2022 14:26:18 +0200 Subject: [PATCH 108/337] Convert 20_Buzzword to Java The original version was a straight forward monolithic BASIC-to-Java conversion. Updated to use common Java coding conventions. - Split the single static main method into classes. The static part only contains the bootstrap code for the game. - Split the word list into three arrays so that there is no need to use error-prone calculations when choosing the random words. - Placed the Scanner in a try-with-resources block to ensure that the scanner gets closed when it is no longer needed. --- 20_Buzzword/java/src/Buzzword.java | 44 ++++------------- 20_Buzzword/java/src/BuzzwordSupplier.java | 39 +++++++++++++++ 20_Buzzword/java/src/UserInterface.java | 57 ++++++++++++++++++++++ 3 files changed, 106 insertions(+), 34 deletions(-) create mode 100644 20_Buzzword/java/src/BuzzwordSupplier.java create mode 100644 20_Buzzword/java/src/UserInterface.java diff --git a/20_Buzzword/java/src/Buzzword.java b/20_Buzzword/java/src/Buzzword.java index 82ed9100..248b4a77 100755 --- a/20_Buzzword/java/src/Buzzword.java +++ b/20_Buzzword/java/src/Buzzword.java @@ -1,41 +1,17 @@ import java.util.Scanner; -import static java.lang.System.out; -// This is very close to the original BASIC. Changes: -// 1) the array indexing is adjusted by 1 -// 2) the user can enter a lower case "y" -// 3) moved the word list to the top 8~) public class Buzzword { - private static final String[] A = { - "ABILITY","BASAL","BEHAVIORAL","CHILD-CENTERED", - "DIFFERENTIATED","DISCOVERY","FLEXIBLE","HETEROGENEOUS", - "HOMOGENEOUS","MANIPULATIVE","MODULAR","TAVISTOCK", - "INDIVIDUALIZED","LEARNING","EVALUATIVE","OBJECTIVE", - "COGNITIVE","ENRICHMENT","SCHEDULING","HUMANISTIC", - "INTEGRATED","NON-GRADED","TRAINING","VERTICAL AGE", - "MOTIVATIONAL","CREATIVE","GROUPING","MODIFICATION", - "ACCOUNTABILITY","PROCESS","CORE CURRICULUM","ALGORITHM", - "PERFORMANCE","REINFORCEMENT","OPEN CLASSROOM","RESOURCE", - "STRUCTURE","FACILITY","ENVIRONMENT" - }; - private static Scanner scanner = new Scanner( System.in ); - public static void main( final String [] args ) { - out.println( " BUZZWORD GENERATOR" ); - out.println( " CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" ); - out.println();out.println();out.println(); - out.println( "THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN" ); - out.println( "'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS" ); - out.println( "AND SPEECHES. WHENEVER A QUESTION MARK IS PRINTED," ); - out.println( "TYPE A 'Y' FOR ANOTHER PHRASE OR 'N' TO QUIT." ); - out.println();out.println();out.println( "HERE'S THE FIRST PHRASE:" ); - do { - out.print( A[ (int)( 13 * Math.random() ) ] + " " ); - out.print( A[ (int)( 13 * Math.random() + 13 ) ] + " " ); - out.print( A[ (int)( 13 * Math.random() + 26 ) ] ); out.println(); - out.print( "?" ); + public static void main(final String[] args) { + try ( + // Scanner is a Closeable so it must be closed + // before the program ends. + final Scanner scanner = new Scanner(System.in); + ) { + final BuzzwordSupplier buzzwords = new BuzzwordSupplier(); + final UserInterface userInterface = new UserInterface( + scanner, buzzwords); + userInterface.run(); } - while ( "Y".equals( scanner.nextLine().toUpperCase() ) ); - out.println( "COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!" ); } } diff --git a/20_Buzzword/java/src/BuzzwordSupplier.java b/20_Buzzword/java/src/BuzzwordSupplier.java new file mode 100644 index 00000000..679969f9 --- /dev/null +++ b/20_Buzzword/java/src/BuzzwordSupplier.java @@ -0,0 +1,39 @@ +import java.util.Random; +import java.util.function.Supplier; + +/** + * A string supplier that provides an endless stream of random buzzwords. + */ +public class BuzzwordSupplier implements Supplier { + + private static final String[] SET_1 = { + "ABILITY","BASAL","BEHAVIORAL","CHILD-CENTERED", + "DIFFERENTIATED","DISCOVERY","FLEXIBLE","HETEROGENEOUS", + "HOMOGENEOUS","MANIPULATIVE","MODULAR","TAVISTOCK", + "INDIVIDUALIZED" }; + + private static final String[] SET_2 = { + "LEARNING","EVALUATIVE","OBJECTIVE", + "COGNITIVE","ENRICHMENT","SCHEDULING","HUMANISTIC", + "INTEGRATED","NON-GRADED","TRAINING","VERTICAL AGE", + "MOTIVATIONAL","CREATIVE" }; + + private static final String[] SET_3 = { + "GROUPING","MODIFICATION", "ACCOUNTABILITY","PROCESS", + "CORE CURRICULUM","ALGORITHM", "PERFORMANCE", + "REINFORCEMENT","OPEN CLASSROOM","RESOURCE", "STRUCTURE", + "FACILITY","ENVIRONMENT" }; + + private final Random random = new Random(); + + /** + * Create a buzzword by concatenating a random word from each of the + * three word sets. + */ + @Override + public String get() { + return SET_1[random.nextInt(SET_1.length)] + ' ' + + SET_2[random.nextInt(SET_2.length)] + ' ' + + SET_3[random.nextInt(SET_3.length)]; + } +} diff --git a/20_Buzzword/java/src/UserInterface.java b/20_Buzzword/java/src/UserInterface.java new file mode 100644 index 00000000..cbfbe3eb --- /dev/null +++ b/20_Buzzword/java/src/UserInterface.java @@ -0,0 +1,57 @@ +import static java.lang.System.out; + +import java.util.Scanner; +import java.util.function.Supplier; + +/** + * A command line user interface that outputs a buzzword every + * time the user requests a new one. + */ +public class UserInterface implements Runnable { + + /** + * Input from the user. + */ + private final Scanner input; + + /** + * The buzzword generator. + */ + private final Supplier buzzwords; + + /** + * Create a new user interface. + * + * @param input The input scanner with which the user gives commands. + * @param buzzwords The buzzword supplier. + */ + public UserInterface(final Scanner input, + final Supplier buzzwords) { + this.input = input; + this.buzzwords = buzzwords; + } + + @Override + public void run() { + out.println(" BUZZWORD GENERATOR"); + out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + out.println(); + out.println(); + out.println(); + out.println("THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN"); + out.println("'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS"); + out.println("AND SPEECHES. WHENEVER A QUESTION MARK IS PRINTED,"); + out.println("TYPE A 'Y' FOR ANOTHER PHRASE OR 'N' TO QUIT."); + out.println(); + out.println(); + out.println("HERE'S THE FIRST PHRASE:"); + + do { + out.println(buzzwords.get()); + out.println(); + out.print("?"); + } while ("Y".equals(input.nextLine().toUpperCase())); + + out.println("COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!"); + } +} From 329fe3137c4b2a5400cc76a11ef31dd3829fe7a0 Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Wed, 12 Jan 2022 20:26:18 +0800 Subject: [PATCH 109/337] Add rules. --- 73_Reverse/csharp/Reverse/Reverse/Program.cs | 35 +++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/73_Reverse/csharp/Reverse/Reverse/Program.cs b/73_Reverse/csharp/Reverse/Reverse/Program.cs index 7beee62b..2f95cc55 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Program.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Program.cs @@ -10,7 +10,7 @@ namespace Reverse PrintTitle(); Console.Write("DO YOU WANT THE RULES? "); var needRulesInput = Console.ReadLine(); - + Console.WriteLine(); if (string.Equals(needRulesInput, "YES", StringComparison.OrdinalIgnoreCase)) { DisplayRules(); @@ -21,8 +21,8 @@ namespace Reverse { var reverser = new Reverser(arrayLength); - Console.WriteLine(reverser.GetArrayString()); - + Console.WriteLine("HERE WE GO ... THE LIST IS:\n"); + PrintList(reverser.GetArrayString()); var arrayIsNotInAscendingOrder = true; var numberOfMoves = 0; while (arrayIsNotInAscendingOrder) @@ -35,7 +35,7 @@ namespace Reverse } reverser.Reverse(index); - Console.WriteLine(reverser.GetArrayString()); + PrintList(reverser.GetArrayString()); if (reverser.IsArrayInAscendingOrder()) { @@ -81,6 +81,13 @@ namespace Reverse return index; } + private static void PrintList(string list) + { + Console.WriteLine(); + Console.WriteLine(list); + Console.WriteLine(); + } + private static void PrintTitle() { Console.WriteLine("REVERSE"); @@ -89,7 +96,25 @@ namespace Reverse private static void DisplayRules() { - Console.WriteLine("RULES"); + Console.WriteLine("THIS IS THE GAME OF 'REVERSE'. TO WIN, ALL YOU HAVE"); + Console.WriteLine("TO DO IS ARRANGE A LIST OF NUMBERS (1 THOUGH 9 )"); + Console.WriteLine("IN NUMBERICAL ORDER FROM LEFT TO RIGHT. TO MOVE, YOU"); + Console.WriteLine("TELL ME HOW MANY NUMBERS (COUNTING FROM THE LEFT) TO"); + Console.WriteLine("REVERSE. FOR EXAMPLE, IF THE CURRENT LIST IS:"); + Console.WriteLine(); + Console.WriteLine(" 2 3 4 5 1 6 7 8 9"); + Console.WriteLine(); + Console.WriteLine("AND YOU REVERSE 4, THE RESULT WILL BE:"); + Console.WriteLine(); + Console.WriteLine(" 5 4 3 2 1 6 7 8 9"); + Console.WriteLine(); + Console.WriteLine("NOW IF YOU REVERSE 5, YOU WIN!"); + Console.WriteLine(); + Console.WriteLine(" 1 2 3 4 5 6 7 8 9"); + Console.WriteLine(); + Console.WriteLine("NO DOUBT YOU WILL LIKE THIS GAME, BUT "); + Console.WriteLine("IF YOU WANT TO QUIT, REVERSE 0 (ZERO)"); + Console.WriteLine(); } } } From c8633c6051a665bcaaae6a69eec20b14b2adf5fe Mon Sep 17 00:00:00 2001 From: "Brax Antti (Oy Samlink Ab)" Date: Wed, 12 Jan 2022 14:33:55 +0200 Subject: [PATCH 110/337] Convert 20_Buzzword to Java Provide the output PrintStream dependency to UserInterface in the constructor instead of have it hard coded to System.out. --- 20_Buzzword/java/src/Buzzword.java | 2 +- 20_Buzzword/java/src/UserInterface.java | 45 ++++++++++++++----------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/20_Buzzword/java/src/Buzzword.java b/20_Buzzword/java/src/Buzzword.java index 248b4a77..85fecfd3 100755 --- a/20_Buzzword/java/src/Buzzword.java +++ b/20_Buzzword/java/src/Buzzword.java @@ -10,7 +10,7 @@ public class Buzzword { ) { final BuzzwordSupplier buzzwords = new BuzzwordSupplier(); final UserInterface userInterface = new UserInterface( - scanner, buzzwords); + scanner, System.out, buzzwords); userInterface.run(); } } diff --git a/20_Buzzword/java/src/UserInterface.java b/20_Buzzword/java/src/UserInterface.java index cbfbe3eb..103e88c8 100644 --- a/20_Buzzword/java/src/UserInterface.java +++ b/20_Buzzword/java/src/UserInterface.java @@ -1,5 +1,4 @@ -import static java.lang.System.out; - +import java.io.PrintStream; import java.util.Scanner; import java.util.function.Supplier; @@ -14,6 +13,11 @@ public class UserInterface implements Runnable { */ private final Scanner input; + /** + * Output to the user. + */ + private final PrintStream output; + /** * The buzzword generator. */ @@ -23,35 +27,38 @@ public class UserInterface implements Runnable { * Create a new user interface. * * @param input The input scanner with which the user gives commands. + * @param output The output to show messages to the user. * @param buzzwords The buzzword supplier. */ public UserInterface(final Scanner input, - final Supplier buzzwords) { + final PrintStream output, + final Supplier buzzwords) { this.input = input; + this.output = output; this.buzzwords = buzzwords; } @Override public void run() { - out.println(" BUZZWORD GENERATOR"); - out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); - out.println(); - out.println(); - out.println(); - out.println("THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN"); - out.println("'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS"); - out.println("AND SPEECHES. WHENEVER A QUESTION MARK IS PRINTED,"); - out.println("TYPE A 'Y' FOR ANOTHER PHRASE OR 'N' TO QUIT."); - out.println(); - out.println(); - out.println("HERE'S THE FIRST PHRASE:"); + output.println(" BUZZWORD GENERATOR"); + output.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + output.println(); + output.println(); + output.println(); + output.println("THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN"); + output.println("'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS"); + output.println("AND SPEECHES. WHENEVER A QUESTION MARK IS PRINTED,"); + output.println("TYPE A 'Y' FOR ANOTHER PHRASE OR 'N' TO QUIT."); + output.println(); + output.println(); + output.println("HERE'S THE FIRST PHRASE:"); do { - out.println(buzzwords.get()); - out.println(); - out.print("?"); + output.println(buzzwords.get()); + output.println(); + output.print("?"); } while ("Y".equals(input.nextLine().toUpperCase())); - out.println("COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!"); + output.println("COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!"); } } From 337e7976d13b1aea8ac8282c6bf440c2abbf202a Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 09:50:35 -0300 Subject: [PATCH 111/337] Performance optimization, reducing the amount of writes to the console necessary to output each iteration's matrix. --- 55_Life/csharp/Program.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 47ed7386..17e6fb18 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -132,12 +132,14 @@ void ProcessSimulation() var nextMinX = maxHeight - 1; var nextMinY = maxWidth - 1; var nextMaxX = 0; - var nextMaxY = 0; + var nextMaxY = 0; + + var matrixOutput = new StringBuilder(); // prints the empty lines before search area for (var x = 0; x < minX; x++) { - Console.WriteLine(); + matrixOutput.AppendLine(); } // refreshes the matrix and updates search area @@ -168,14 +170,15 @@ void ProcessSimulation() nextMaxY = Math.Max(y + 1, nextMaxY); } - Console.WriteLine(string.Join(separator: null, values: printedLine)); + matrixOutput.AppendLine(string.Join(separator: null, values: printedLine)); } // prints empty lines after search area for (var x = maxX + 1; x < maxHeight; x++) { - Console.WriteLine(); + matrixOutput.AppendLine(); } + Console.WriteLine(matrixOutput); Console.WriteLine(); void UpdateSearchArea() From f3d63355df68b53aaa31808b71cd690371235eaa Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 10:09:31 -0300 Subject: [PATCH 112/337] Adding instructions on how to run the example. --- 55_Life/csharp/Program.cs | 18 +----------------- 55_Life/csharp/README.md | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 17e6fb18..1b70ed3a 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -1,20 +1,4 @@ -/* - * LIFE - * An implementation of John Conway's popular cellular automaton - * Ported by Dyego Alekssander Maas - * - * An example pattern would be: - * " * " - * "***" - * "DONE" (indicates that the simulation can start) - * - * You can find patterns to play with here: http://pi.math.cornell.edu/~lipa/mec/lesson6.html - * - * Optionally, you can run this program with the "--wait 1000" argument, the number being the time in milliseconds - * that the application will pause between each iteration. This is enables you to watch the simulation unfolding. - * By default, there is no pause between iterations. -*/ -using System.Text; +using System.Text; const int maxWidth = 70; const int maxHeight = 24; diff --git a/55_Life/csharp/README.md b/55_Life/csharp/README.md index 4daabb5c..3bf2d48a 100644 --- a/55_Life/csharp/README.md +++ b/55_Life/csharp/README.md @@ -1,3 +1,26 @@ +# Life + +An implementation of John Conway's popular cellular automaton, also know as **Conway's Game of Life**. The original source was downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html). + +Ported by Dyego Alekssander Maas. + +## How to run + +This program requires you to install [.NET 6 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/6.0). After installed, you just need to run `dotnet run` from this directory in the terminal. + +## Know more about Conway's Game of Life + +You can find more about Conway's Game of Life on this page of the [Cornell Math Explorers' Club](http://pi.math.cornell.edu/~lipa/mec/lesson6.html), alongside many examples of patterns you can try. + +### Optional parameters + +Optionally, you can run this program with the `--wait 1000` argument, the number being the time in milliseconds +that the application will pause between each iteration. This is enables you to watch the simulation unfolding. By default, there is no pause between iterations. + +The complete command would be `dotnet run --wait 1000`. + +## Instructions to the port + Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Microsoft C#](https://docs.microsoft.com/en-us/dotnet/csharp/) From f62111606403a5914cedcdfa07b03a984ed11073 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 10:50:36 -0300 Subject: [PATCH 113/337] Adding instructions on how to enter patterns, and also some examples. --- 55_Life/csharp/README.md | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/55_Life/csharp/README.md b/55_Life/csharp/README.md index 3bf2d48a..5b4ffe62 100644 --- a/55_Life/csharp/README.md +++ b/55_Life/csharp/README.md @@ -19,6 +19,51 @@ that the application will pause between each iteration. This is enables you to w The complete command would be `dotnet run --wait 1000`. +## Entering patterns + +Once running the game, you are expected to enter a pattern. This pattern consists of multiple lines of text with either **spaces** or **some character**, usually an asterisk (`*`). + +Spaces represent empty cells. Asterisks represent alive cells. + +After entering the pattern, you need to enter the word "DONE". It is not case sensitive. An example of pattern would be: + +``` + * +*** +DONE +``` + +### Some patterns you could try + +``` + * +*** +``` + +``` +* +*** +``` + +``` +** +** +``` + +``` + * + * +* +``` + +This one is known as **glider**: + +``` +*** +* + * +``` + ## Instructions to the port Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) From d0ab16bac2fae9eee3f8b932fca56b442bb11f53 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Wed, 12 Jan 2022 13:07:07 -0500 Subject: [PATCH 114/337] Fixed formatting of tabs into spaces --- 48_High_IQ/python/High_IQ.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 1f32e300..cbb5960b 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -56,8 +56,8 @@ def play_game(): def main(): # if input("Do you want instrunctions?\n").lower().startswith("y"): - print("\t" * 33 + "H-I-Q") - print("\t" * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + print(" " * 33 + "H-I-Q") + print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") print_instructions() play_game() From 4485faa7e32ff91bb21b67715dc94d39e1afa9ed Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Wed, 12 Jan 2022 13:22:32 -0500 Subject: [PATCH 115/337] Update High_IQ.py --- 48_High_IQ/python/High_IQ.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index cbb5960b..b2e71b6c 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -47,12 +47,30 @@ def print_board(board): print(" " * 2 + board[67] + board[68] + board[69]) def play_game(): - print("Lets play a game") board = new_board() while not is_game_finished(board): print_board(board) + while not move(board): + print("ILLEGAL MOVE! TRY AGAIN") +def move(board): + try: + start = int(input("MOVE WHICH PIECE? ")) + if not (board[start] == "'!'): + return False + + end = int(input("TO WHERE? ")) + if not (board[end] == 'O'): + return False + difference = abs(end - start) + if difference != 2 and difference != 18: + return False + center = (end + start) / 2 + + except: + return False + return True def main(): # if input("Do you want instrunctions?\n").lower().startswith("y"): From b0da05a04e1b83ae1857cb41d81470c6253ccc08 Mon Sep 17 00:00:00 2001 From: Jeff Atwood Date: Wed, 12 Jan 2022 10:27:50 -0800 Subject: [PATCH 116/337] Update README.md add Emulation and Bugfixes section --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 266aaac8..6ed7cb51 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ Each project has subfolders corresponding to the languages we'd like to see the - Delphi / Object Pascal - Perl + + ### Project goals Feel free to begin converting these classic games into the above list of modern, memory safe languages. But first, a few guidelines: @@ -39,6 +41,16 @@ Feel free to begin converting these classic games into the above list of modern, - **Don't get _too_ fancy**. Definitely use the most recent versions and features of the target language, but also try to keep the code samples simple and explainable -- the goal is to teach programming in the target language, not necessarily demonstrate the cleverest one-line tricks. +### Emulation and Bugfixes + +We want the general behavior of the original programs to be preserved, _however_, we also want to update them, specifically: + +- allow both UPPERCASE and lowercase input and display +- incorporate any bugfixes to the original programs; see the `readme.md` in the game folder +- improved error handling for bad or erroneous input + +Please note that on the back of the Basic Computer Games book it says **Microsoft 8K Basic, Rev 4.0 was the version David Ahl used to test**, so that is the level of compatibility we are looking for.  QBasic on the DOS emulation is a later version of Basic but one that retains downwards compatibility so far in our testing. We're working on a recommended emulation to verify behavior. + ### Have fun! Thank you for taking part in this project to update a classic programming book -- one of the most influential programming books in computing history -- for 2022 and beyond! From 159aa46e2126799991e4229c78076ef3fcc994b3 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 16:04:14 -0300 Subject: [PATCH 117/337] Fixed pattern reading when inputing DONE, which would lead to incorrect sizing of the pattern transcribed to the matrix and caused drifting in relation to the original. --- 55_Life/csharp/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 1b70ed3a..ffdf1799 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -23,7 +23,6 @@ IEnumerable ReadPattern(int limitHeight) var input = Console.ReadLine(); if (input.ToUpper() == "DONE") { - yield return string.Empty; break; } From 73665d8b091f4dbf8bee2101d572c99c75909cb7 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 16:04:57 -0300 Subject: [PATCH 118/337] Fixes cropping that would happen when using an dot (.) in the beggining of the text. --- 55_Life/csharp/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index ffdf1799..f5bb7f38 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -30,7 +30,7 @@ IEnumerable ReadPattern(int limitHeight) // game allowed you to input an '.' before the spaces to circumvent this limitation. This behavior was // kept for compatibility. if (input.StartsWith('.')) - yield return input.Substring(1, input.Length - 2); + yield return input.Substring(1, input.Length - 1); yield return input; } From f25adca07a0f50619835097ae460ef97af46f078 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 16:07:35 -0300 Subject: [PATCH 119/337] Fix the initialization of the matrix, which was displacing the pattern in the initial position onto the matrix, which caused the evolution of the simulation to variate in relation with the original game in Basic when once the cells reached the boarder (invalid cases). --- 55_Life/csharp/Program.cs | 48 +++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index f5bb7f38..3aeb088e 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -4,11 +4,12 @@ const int maxWidth = 70; const int maxHeight = 24; Console.WriteLine("ENTER YOUR PATTERN:"); -var pattern = ReadPattern(limitHeight: maxHeight).ToArray(); +var pattern = new Pattern(ReadPattern(limitHeight: maxHeight).ToArray()); -var (minX, minY) = FindTopLeftCorner(pattern); -var maxX = maxHeight; -var maxY = maxWidth; +var minX = 10 - pattern.Height / 2; // was 11 +var minY = 32 - pattern.Width / 2; // was 33 +var maxX = maxHeight - 1; +var maxY = maxWidth - 1; var matrix = new Matrix(height: maxHeight, width: maxWidth); var simulation = InitializeSimulation(pattern, matrix); @@ -36,17 +37,6 @@ IEnumerable ReadPattern(int limitHeight) } } -(int minX, int minY) FindTopLeftCorner(IEnumerable patternLines) -{ - var longestInput = patternLines - .Select((value, index) => (index, value)) - .OrderByDescending(input => input.value.Length) - .First(); - var centerX = (11 - longestInput.index / 2) - 1; - var centerY = (33 - longestInput.value.Length / 2) - 1; - return (centerX, centerY); -} - void PrintHeader() { void PrintCentered(string text) @@ -65,15 +55,16 @@ void PrintHeader() Console.WriteLine(); } -Simulation InitializeSimulation(IReadOnlyList inputPattern, Matrix matrixToInitialize) { +Simulation InitializeSimulation(Pattern pattern, Matrix matrixToInitialize) { var newSimulation = new Simulation(); - // translates the pattern to the middle of the simulation and counts initial population - for (var x = 0; x < inputPattern.Count; x++) + // transcribes the pattern to the middle of the simulation and counts initial population + for (var x = 0; x < pattern.Height; x++) { - for (var y = 0; y < inputPattern[x].Length; y++) + for (var y = 0; y < pattern.Width; y++) { - if (inputPattern[x][y] == ' ') continue; + if (pattern.Content[x][y] == ' ') + continue; matrixToInitialize[minX + x, minY + y] = CellState.Stable; newSimulation.IncreasePopulation(); @@ -247,6 +238,23 @@ void ProcessSimulation() } } +public class Pattern +{ + public string[] Content { get; } + public int Height { get; } + public int Width { get; } + + public Pattern(IReadOnlyCollection patternLines) + { + Height = patternLines.Count; + Width = patternLines.Max(x => x.Length); + + Content = patternLines + .Select(x => x.PadRight(Width, ' ')) + .ToArray(); + } +} + /// /// Indicates the state of a given cell in the simulation. /// From 6a3f0b3259112a3fd8589c66ad249805cbae68f9 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 16:09:10 -0300 Subject: [PATCH 120/337] Fix various indexing problems that caused drifting. Now, the application behaves exactly like the original, even in "invalid" generations. --- 55_Life/csharp/Program.cs | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 3aeb088e..a6fb0d98 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -117,10 +117,10 @@ void ProcessSimulation() } // refreshes the matrix and updates search area - for (var x = minX; x < maxX; x++) + for (var x = minX; x <= maxX; x++) { var printedLine = Enumerable.Repeat(' ', maxWidth).ToList(); - for (var y = minY; y < maxY; y++) + for (var y = minY; y <= maxY; y++) { if (matrix[x, y] == CellState.Dying) { @@ -139,9 +139,9 @@ void ProcessSimulation() printedLine[y] = '*'; nextMinX = Math.Min(x, nextMinX); - nextMaxX = Math.Max(x + 1, nextMaxX); + nextMaxX = Math.Max(x, nextMaxX); nextMinY = Math.Min(y, nextMinY); - nextMaxY = Math.Max(y + 1, nextMaxY); + nextMaxY = Math.Max(y, nextMaxY); } matrixOutput.AppendLine(string.Join(separator: null, values: printedLine)); @@ -162,42 +162,45 @@ void ProcessSimulation() minY = nextMinY; maxY = nextMaxY; - if (minX < 3) + if (minX < 2) // was 3 { - minX = 3; + minX = 2; // was 3 isInvalid = true; } - if (maxX > 22) + const int limitX = 22; //maxHeight - 2; // was 22 + const int limitY = 68; //maxWidth - 2; // was 68 + + if (maxX > limitX) // was 22 { - maxX = 22; + maxX = limitX; // was 22 isInvalid = true; } - if (minY < 3) + if (minY < 2) // was 3 { - minY = 3; + minY = 2; // was 3 isInvalid = true; } - if (maxY > 68) + if (maxY > limitY) // was 68 { - maxY = 68; + maxY = limitY; // was 68 isInvalid = true; } } UpdateSearchArea(); - for (var x = minX - 1; x < maxX + 2; x++) + for (var x = minX - 1; x <= maxX + 1; x++) { - for (var y = minY - 1; y < maxY + 2; y++) + for (var y = minY - 1; y <= maxY + 1; y++) { int CountNeighbors() { var neighbors = 0; - for (var i = x - 1; i < x + 2; i++) + for (var i = x - 1; i <= x + 1; i++) { - for (var j = y - 1; j < y + 2; j++) + for (var j = y - 1; j <= y + 1; j++) { if (matrix[i, j] == CellState.Stable || matrix[i, j] == CellState.Dying) neighbors++; @@ -208,7 +211,7 @@ void ProcessSimulation() } var neighbors = CountNeighbors(); - if (matrix[x, y] == 0) + if (matrix[x, y] == CellState.Empty) { if (neighbors == 3) { From eaa20ba52bf76ea8bac49f901ba341b0d9126dd3 Mon Sep 17 00:00:00 2001 From: Alex Gomez Date: Wed, 12 Jan 2022 16:47:45 -0600 Subject: [PATCH 121/337] Carriage return removed --- 62_Mugwump/perl/mugwump.pl | 192 ++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/62_Mugwump/perl/mugwump.pl b/62_Mugwump/perl/mugwump.pl index d02a9036..33835b77 100755 --- a/62_Mugwump/perl/mugwump.pl +++ b/62_Mugwump/perl/mugwump.pl @@ -1,96 +1,96 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -# global variables defined here -my(@MUGWUMP) = (); - -# subroutines defined here - -# init_mugwump: pick the random places for the Mugwumps -sub init_mugwump() { - @MUGWUMP = (); - for (1 .. 4) { - push @MUGWUMP, [ int(rand 10), int(rand 10) ]; - } -} - - -# main code starts here - -# print introductory text -print <); - my($M,$N) = split(/,/,$in); - $M = int($M); - $N = int($N); - - for my $i (0 .. $#MUGWUMP) { - # -1 indicates a Mugwump that was already found - next if $MUGWUMP[$i]->[0] == -1; - - if ($MUGWUMP[$i]->[0] == $M && $MUGWUMP[$i]->[1] == $N) { - $MUGWUMP[$i]->[0] = -1; - printf("You have found Mugwump %d\n", $i+1); - } else { - my $d = sqrt(($MUGWUMP[$i]->[0] - $M) ** 2 + ($MUGWUMP[$i]->[1] - $N) ** 2); - printf("You are %.1f units away from Mugwump %d\n", $d, $i+1); - } - } - - # If a Mugwump still has not been found, - # go to the next turn - for my $j (0 .. $#MUGWUMP) { - if ($MUGWUMP[$j]->[0] != -1) { - next TURN; - } - } - # You win! - printf("You got all of them in %d %s!\n\n", $turn, ($turn == 1 ? 'turn' : 'turns')); - # Pass execution down to the continue block - next PLAY; - - } # end of TURN loop - - print "\nSorry, that's 10 tries. Here's where they're hiding:\n"; - for my $i (0 .. $#MUGWUMP) { - printf("Mugwump %d is at (%d, %d)\n", $i+1, $MUGWUMP[$i]->[0], $MUGWUMP[$i]->[1]) - if $MUGWUMP[$i]->[0] != -1; - } -} -continue { - print "\nThat was fun! Let's play again.......\n"; - print "Four more Mugwumps are now in hiding.\n\n"; -} - +#!/usr/bin/perl + +use strict; +use warnings; + +# global variables defined here +my(@MUGWUMP) = (); + +# subroutines defined here + +# init_mugwump: pick the random places for the Mugwumps +sub init_mugwump() { + @MUGWUMP = (); + for (1 .. 4) { + push @MUGWUMP, [ int(rand 10), int(rand 10) ]; + } +} + + +# main code starts here + +# print introductory text +print <); + my($M,$N) = split(/,/,$in); + $M = int($M); + $N = int($N); + + for my $i (0 .. $#MUGWUMP) { + # -1 indicates a Mugwump that was already found + next if $MUGWUMP[$i]->[0] == -1; + + if ($MUGWUMP[$i]->[0] == $M && $MUGWUMP[$i]->[1] == $N) { + $MUGWUMP[$i]->[0] = -1; + printf("You have found Mugwump %d\n", $i+1); + } else { + my $d = sqrt(($MUGWUMP[$i]->[0] - $M) ** 2 + ($MUGWUMP[$i]->[1] - $N) ** 2); + printf("You are %.1f units away from Mugwump %d\n", $d, $i+1); + } + } + + # If a Mugwump still has not been found, + # go to the next turn + for my $j (0 .. $#MUGWUMP) { + if ($MUGWUMP[$j]->[0] != -1) { + next TURN; + } + } + # You win! + printf("You got all of them in %d %s!\n\n", $turn, ($turn == 1 ? 'turn' : 'turns')); + # Pass execution down to the continue block + next PLAY; + + } # end of TURN loop + + print "\nSorry, that's 10 tries. Here's where they're hiding:\n"; + for my $i (0 .. $#MUGWUMP) { + printf("Mugwump %d is at (%d, %d)\n", $i+1, $MUGWUMP[$i]->[0], $MUGWUMP[$i]->[1]) + if $MUGWUMP[$i]->[0] != -1; + } +} +continue { + print "\nThat was fun! Let's play again.......\n"; + print "Four more Mugwumps are now in hiding.\n\n"; +} + From fd8c02371a272d3d64777c6c1e5de8fdd6af462d Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 19:49:30 -0300 Subject: [PATCH 122/337] Adjusting indexes. --- 55_Life/csharp/Program.cs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index a6fb0d98..d2cf8c1c 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -162,30 +162,30 @@ void ProcessSimulation() minY = nextMinY; maxY = nextMaxY; - if (minX < 2) // was 3 - { - minX = 2; // was 3 - isInvalid = true; - } - - const int limitX = 22; //maxHeight - 2; // was 22 - const int limitY = 68; //maxWidth - 2; // was 68 + const int limitX = 21; + const int limitY = 67; - if (maxX > limitX) // was 22 + if (minX < 2) { - maxX = limitX; // was 22 + minX = 2; + isInvalid = true; + } + + if (maxX > limitX) + { + maxX = limitX; isInvalid = true; } - if (minY < 2) // was 3 + if (minY < 2) { - minY = 2; // was 3 + minY = 2; isInvalid = true; } - if (maxY > limitY) // was 68 + if (maxY > limitY) { - maxY = limitY; // was 68 + maxY = limitY; isInvalid = true; } } From 5731a4df0823a6cc7d5337325d49f0b4ebf03ed0 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 19:50:32 -0300 Subject: [PATCH 123/337] Temporary compensation for error calculating (possibly related to rounding) that caused misplacement of the initial pattern by 2 in the y axis. --- 55_Life/csharp/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index d2cf8c1c..bb0463b4 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -66,7 +66,7 @@ Simulation InitializeSimulation(Pattern pattern, Matrix matrixToInitialize) { if (pattern.Content[x][y] == ' ') continue; - matrixToInitialize[minX + x, minY + y] = CellState.Stable; + matrixToInitialize[minX + x, minY + y + 2] = CellState.Stable; newSimulation.IncreasePopulation(); } } From 7a7d92ce2448517329eed7c62891415e9ffa4a35 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 20:07:52 -0300 Subject: [PATCH 124/337] Compensated for the displacement that was occurring in the y axis by adjusting the "middle" to a valid value when working with zero based indexes. --- 55_Life/csharp/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index bb0463b4..32514c75 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -6,8 +6,8 @@ const int maxHeight = 24; Console.WriteLine("ENTER YOUR PATTERN:"); var pattern = new Pattern(ReadPattern(limitHeight: maxHeight).ToArray()); -var minX = 10 - pattern.Height / 2; // was 11 -var minY = 32 - pattern.Width / 2; // was 33 +var minX = 10 - pattern.Height / 2; +var minY = 34 - pattern.Width / 2; var maxX = maxHeight - 1; var maxY = maxWidth - 1; @@ -66,7 +66,7 @@ Simulation InitializeSimulation(Pattern pattern, Matrix matrixToInitialize) { if (pattern.Content[x][y] == ' ') continue; - matrixToInitialize[minX + x, minY + y + 2] = CellState.Stable; + matrixToInitialize[minX + x, minY + y] = CellState.Stable; newSimulation.IncreasePopulation(); } } From f70b6d42ddac55660817f0357849bebcd016623d Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 20:08:53 -0300 Subject: [PATCH 125/337] Refactoring. --- 55_Life/csharp/Program.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 32514c75..8da15360 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -251,8 +251,12 @@ public class Pattern { Height = patternLines.Count; Width = patternLines.Max(x => x.Length); - - Content = patternLines + Content = NormalizeWidth(patternLines); + } + + private string[] NormalizeWidth(IReadOnlyCollection patternLines) + { + return patternLines .Select(x => x.PadRight(Width, ' ')) .ToArray(); } From d52981de7313a81ecca15e8d7176623bba266fdb Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 20:21:30 -0300 Subject: [PATCH 126/337] Refactoring. --- 55_Life/csharp/Program.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 8da15360..879b16be 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -76,15 +76,14 @@ Simulation InitializeSimulation(Pattern pattern, Matrix matrixToInitialize) { TimeSpan GetPauseBetweenIterations() { - if (args.Length == 2) + if (args.Length != 2) return TimeSpan.Zero; + + var parameter = args[0].ToLower(); + if (parameter.Contains("wait")) { - var parameter = args[0].ToLower(); - if (parameter.Contains("wait")) - { - var value = args[1]; - if (int.TryParse(value, out var sleepMilliseconds)) - return TimeSpan.FromMilliseconds(sleepMilliseconds); - } + var value = args[1]; + if (int.TryParse(value, out var sleepMilliseconds)) + return TimeSpan.FromMilliseconds(sleepMilliseconds); } return TimeSpan.Zero; From b93cc409e204f5f96d496364416a4c49fec9e04a Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 20:22:26 -0300 Subject: [PATCH 127/337] Adjusted message of "invalid" generations, matching the original. --- 55_Life/csharp/Program.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index 879b16be..bcfc22f4 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -96,9 +96,8 @@ void ProcessSimulation() while (true) { - Console.WriteLine($"GENERATION: {simulation.Generation}\tPOPULATION: {simulation.Population}"); - if (isInvalid) - Console.WriteLine("INVALID!"); + var invalidText = isInvalid ? "INVALID!" : ""; + Console.WriteLine($"GENERATION: {simulation.Generation}\tPOPULATION: {simulation.Population} {invalidText}"); simulation.StartNewGeneration(); From 2ac28191511259a6a9f3056a8766eb6b95c1ab61 Mon Sep 17 00:00:00 2001 From: Dyego Maas Date: Wed, 12 Jan 2022 20:23:17 -0300 Subject: [PATCH 128/337] Removed extra line printed after each generation, to better match the original's visuals. --- 55_Life/csharp/Program.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs index bcfc22f4..eeb00465 100644 --- a/55_Life/csharp/Program.cs +++ b/55_Life/csharp/Program.cs @@ -150,8 +150,7 @@ void ProcessSimulation() { matrixOutput.AppendLine(); } - Console.WriteLine(matrixOutput); - Console.WriteLine(); + Console.Write(matrixOutput); void UpdateSearchArea() { From 0c91432e5a096b421eebb39efc44b0d84b7b41c8 Mon Sep 17 00:00:00 2001 From: Jackson Brouwer Date: Wed, 12 Jan 2022 22:47:27 -0600 Subject: [PATCH 129/337] Added Basketball Java Version --- 07_Basketball/java/Basketball.java | 469 +++++++++++++++++++++++++++++ 1 file changed, 469 insertions(+) create mode 100644 07_Basketball/java/Basketball.java diff --git a/07_Basketball/java/Basketball.java b/07_Basketball/java/Basketball.java new file mode 100644 index 00000000..3ff9e7ab --- /dev/null +++ b/07_Basketball/java/Basketball.java @@ -0,0 +1,469 @@ +import java.lang.Math; +import java.util.*; +import java.util.Scanner; + +/* The basketball class is a computer game that allows you to play as + Dartmouth College's captain and playmaker + The game uses set probabilites to simulate outcomes of each posession + You are able to choose your shot types as well as defensive formations */ + +public class Basketball { + int time = 0; + int[] score = {0, 0}; + double defense = -1; + List defense_choices = Arrays.asList(6.0, 6.5, 7.0, 7.5); + int shot = -1; + List shot_choices = Arrays.asList(0, 1, 2, 3, 4); + double opponent_chance = 0; + String opponent = null; + + public Basketball() { + + // Explains the keyboard inputs + System.out.println("\t\t\t Basketball"); + System.out.println("\t Creative Computing Morristown, New Jersey\n\n\n"); + System.out.println("This is Dartmouth College basketball. "); + System.out.println("Υou will be Dartmouth captain and playmaker."); + System.out.println("Call shots as follows:"); + System.out.println("1. Long (30ft.) Jump Shot; 2. Short (15 ft.) Jump Shot; " + + "3. Lay up; 4. Set Shot"); + System.out.println("Both teams will use the same defense. Call Defense as follows:"); + System.out.println("6. Press; 6.5 Man-to-Man; 7. Zone; 7.5 None."); + System.out.println("To change defense, just type 0 as your next shot."); + System.out.print("Your starting defense will be? "); + + Scanner scanner = new Scanner(System.in); // creates a scanner + + // takes input for a defense + if (scanner.hasNextDouble()) { + defense = scanner.nextDouble(); + } + else { + scanner.next(); + } + + // makes sure that input is legal + while (!defense_choices.contains(defense)) { + System.out.print("Your new defensive allignment is? "); + if (scanner.hasNextDouble()) { + defense = scanner.nextDouble(); + } + else { + scanner.next(); + continue; + } + } + + // takes input for opponent's name + System.out.print("\nChoose your opponent? "); + + opponent = scanner.next(); + start_of_period(); + } + + // adds points to the score + // team can take 0 or 1, for opponent or Dartmouth, respectively + private void add_points(int team, int points) { + score[team] += points; + print_score(); + } + + + private void ball_passed_back() { + System.out.print("Ball passed back to you. "); + dartmouth_ball(); + } + + // change defense, called when the user enters 0 for their shot + private void change_defense() { + defense = -1; + Scanner scanner = new Scanner(System.in); // creates a scanner + + while (!defense_choices.contains(defense)) { + System.out.println("Your new defensive allignment is? "); + if (scanner.hasNextDouble()) { + defense = (double)(scanner.nextDouble()); + } + else { + continue; + } + } + + dartmouth_ball(); + } + + // simulates two foul shots for a player and adds the points + private void foul_shots(int team) { + System.out.println("Shooter fouled. Two shots."); + + if (Math.random() > .49) { + if (Math.random() > .75) { + System.out.println("Both shots missed."); + } + else { + System.out.println("Shooter makes one shot and misses one."); + score[team] += 1; + } + } + else { + System.out.println("Shooter makes both shots."); + score[team] += 2; + } + + print_score(); + } + + // called when time = 50, starts a new period + private void halftime() { + System.out.println("\n ***** End of first half *****\n"); + print_score(); + start_of_period(); + } + + // prints the current score + private void print_score() { + System.out.println("Score: " + score[1] + " to " + score[0] + "\n"); + } + + // simulates a center jump for posession at the beginning of a period + private void start_of_period() { + System.out.println("Center jump"); + if (Math.random() > .6) { + System.out.println("Dartmouth controls the tap.\n"); + dartmouth_ball(); + } + else { + System.out.println(opponent + " controls the tap.\n"); + opponent_ball(); + } + } + + // called when t = 92 + private void two_minute_warning() { + System.out.println(" *** Two minutes left in the game ***"); + } + + // called when the user enters 1 or 2 for their shot + private void dartmouth_jump_shot() { + time ++; + if (time == 50) { + halftime(); + } + else if (time == 92) { + two_minute_warning(); + } + + System.out.println("Jump Shot."); + // simulates chances of different possible outcomes + if (Math.random() > .341 * defense / 8) { + if (Math.random() > .682 * defense / 8) { + if (Math.random() > .782 * defense / 8) { + if (Math.random() > .843 * defense / 8) { + System.out.println("Charging foul. Dartmouth loses ball.\n"); + opponent_ball(); + } + else { + // player is fouled + foul_shots(1); + opponent_ball(); + } + } + else { + if (Math.random() > .5) { + System.out.println("Shot is blocked. Ball controlled by " + + opponent + ".\n"); + opponent_ball(); + } + else { + System.out.println("Shot is blocked. Ball controlled by Dartmouth."); + dartmouth_ball(); + } + } + } + else { + System.out.println("Shot is off target."); + if (defense / 6 * Math.random() > .45) { + System.out.println("Rebound to " + opponent + "\n"); + opponent_ball(); + } + else { + System.out.println("Dartmouth controls the rebound."); + if (Math.random() > .4) { + if (defense == 6 && Math.random() > .6) { + System.out.println("Pass stolen by " + opponent + + ", easy lay up"); + add_points(0, 2); + dartmouth_ball(); + } + else { + // ball is passed back to you + ball_passed_back(); + } + } + else { + System.out.println(""); + dartmouth_non_jump_shot(); + } + } + } + } + else { + System.out.println("Shot is good."); + add_points(1, 2); + opponent_ball(); + } + } + + // called when the user enters 0, 3, or 4 + // lay up, set shot, or defense change + private void dartmouth_non_jump_shot() { + time ++; + if (time == 50) { + halftime(); + } + else if (time == 92) { + two_minute_warning(); + } + + if (shot == 4) { + System.out.println("Set shot."); + } + else if (shot == 3) { + System.out.println("Lay up."); + } + else if (shot == 0) { + change_defense(); + } + + // simulates different outcomes after a lay up or set shot + if (7/defense*Math.random() > .4) { + if (7/defense*Math.random() > .7) { + if (7/defense*Math.random() > .875) { + if (7/defense*Math.random() > .925) { + System.out.println("Charging foul. Dartmouth loses the ball.\n"); + opponent_ball(); + } + else { + System.out.println("Shot blocked. " + opponent + "'s ball.\n"); + opponent_ball(); + } + } + else { + foul_shots(1); + opponent_ball(); + } + } + else { + System.out.println("Shot is off the rim."); + if (Math.random() > 2/3) { + System.out.println("Dartmouth controls the rebound."); + if (Math.random() > .4) { + System.out.println("Ball passed back to you.\n"); + dartmouth_ball(); + } + else { + dartmouth_non_jump_shot(); + } + } + else { + System.out.println(opponent + " controls the rebound.\n"); + opponent_ball(); + } + } + } + else { + System.out.println("Shot is good. Two points."); + add_points(1, 2); + opponent_ball(); + } + } + + + // plays out a Dartmouth posession, starting with your choice of shot + private void dartmouth_ball() { + Scanner scanner = new Scanner(System.in); // creates a scanner + System.out.print("Your shot? "); + shot = -1; + if (scanner.hasNextInt()) { + shot = scanner.nextInt(); + } + else { + System.out.println(""); + scanner.next(); + } + + while (!shot_choices.contains(shot)) { + System.out.print("Incorrect answer. Retype it. Your shot?"); + if (scanner.hasNextInt()) { + shot = scanner.nextInt(); + } + else { + System.out.println(""); + scanner.next(); + } + } + + if (time < 100 || Math.random() < .5) { + if (shot == 1 || shot == 2) { + dartmouth_jump_shot(); + } + else { + dartmouth_non_jump_shot(); + } + } + else { + if (score[0] != score[1]) { + System.out.println("\n ***** End Of Game *****"); + System.out.println("Final Score: Dartmouth: " + score[1] + " " + + opponent + ": " + score[0]); + System.exit(0); + } + else { + System.out.println("\n ***** End Of Second Half *****"); + System.out.println("Score at end of regulation time:"); + System.out.println(" Dartmouth: " + score[1] + " " + + opponent + ": " + score[0]); + System.out.println("Begin two minute overtime period"); + time = 93; + start_of_period(); + } + } + } + + // simulates the opponents jumpshot + private void opponent_jumpshot() { + System.out.println("Jump Shot."); + if (8/defense*Math.random() > .35) { + if (8/defense*Math.random() > .75) { + if (8/defense*Math.random() > .9) { + System.out.println("Offensive foul. Dartmouth's ball.\n"); + dartmouth_ball(); + } + else { + foul_shots(0); + dartmouth_ball(); + } + } + else { + System.out.println("Shot is off the rim."); + if (defense/6*Math.random() > .5) { + System.out.println(opponent + " controls the rebound."); + if (defense == 6) { + if (Math.random() > .75) { + System.out.println("Ball stolen. Easy lay up for Dartmouth."); + add_points(1, 2); + opponent_ball(); + } + else { + if (Math.random() > .5) { + System.out.println(""); + opponent_non_jumpshot(); + } + else { + System.out.println("Pass back to " + opponent + + " guard.\n"); + opponent_ball(); + } + } + } + else { + if (Math.random() > .5) { + opponent_non_jumpshot(); + } + else { + System.out.println("Pass back to " + opponent + + " guard.\n"); + opponent_ball(); + } + } + } + else { + System.out.println("Dartmouth controls the rebound.\n"); + dartmouth_ball(); + } + } + } + else { + System.out.println("Shot is good."); + add_points(0, 2); + dartmouth_ball(); + } + } + + // simulates opponents lay up or set shot + private void opponent_non_jumpshot() { + if (opponent_chance > 3) { + System.out.println("Set shot."); + } + else { + System.out.println("Lay up"); + } + if (7/defense*Math.random() > .413) { + System.out.println("Shot is missed."); + if (defense/6*Math.random() > .5) { + System.out.println(opponent + " controls the rebound."); + if (defense == 6) { + if (Math.random() > .75) { + System.out.println("Ball stolen. Easy lay up for Dartmouth."); + add_points(1, 2); + opponent_ball(); + } + else { + if (Math.random() > .5) { + System.out.println(""); + opponent_non_jumpshot(); + } + else { + System.out.println("Pass back to " + opponent + + " guard.\n"); + opponent_ball(); + } + } + } + else { + if (Math.random() > .5) { + System.out.println(""); + opponent_non_jumpshot(); + } + else { + System.out.println("Pass back to " + opponent + " guard\n"); + opponent_ball(); + } + } + } + else { + System.out.println("Dartmouth controls the rebound.\n"); + dartmouth_ball(); + } + } + else { + System.out.println("Shot is good."); + add_points(0, 2); + dartmouth_ball(); + } + } + + // simulates an opponents possesion + // #randomly picks jump shot or lay up / set shot. + private void opponent_ball() { + time ++; + if (time == 50) { + halftime(); + } + opponent_chance = 10/4*Math.random()+1; + if (opponent_chance > 2) { + opponent_non_jumpshot(); + } + else { + opponent_jumpshot(); + } + } + + public static void main(String[] args) { + Basketball new_game = new Basketball(); + } +} + + + + From 75cca25c386017eff5d9e5e2c926f703804f9d51 Mon Sep 17 00:00:00 2001 From: Jackson Brouwer Date: Wed, 12 Jan 2022 22:50:00 -0600 Subject: [PATCH 130/337] Bug fix on defense change --- 07_Basketball/python/basketball.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/07_Basketball/python/basketball.py b/07_Basketball/python/basketball.py index 5ba88188..20a6cd94 100644 --- a/07_Basketball/python/basketball.py +++ b/07_Basketball/python/basketball.py @@ -13,7 +13,7 @@ class Basketball(): self.defense = None self.defense_choices = [6, 6.5, 7, 7.5] self.shot = None - self.shot_choices = [1, 2, 3, 4] + self.shot_choices = [0, 1, 2, 3, 4] self.z1 = None # Explains the keyboard inputs From 08ea76d111770671a0935c44d930619150e394d5 Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Thu, 13 Jan 2022 16:28:08 +0800 Subject: [PATCH 131/337] Update display --- 73_Reverse/csharp/Reverse/Reverse/Program.cs | 24 ++++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/73_Reverse/csharp/Reverse/Reverse/Program.cs b/73_Reverse/csharp/Reverse/Reverse/Program.cs index 2f95cc55..82e78131 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Program.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Program.cs @@ -21,7 +21,8 @@ namespace Reverse { var reverser = new Reverser(arrayLength); - Console.WriteLine("HERE WE GO ... THE LIST IS:\n"); + Console.WriteLine("HERE WE GO ... THE LIST IS:"); + Console.WriteLine(); PrintList(reverser.GetArrayString()); var arrayIsNotInAscendingOrder = true; var numberOfMoves = 0; @@ -41,14 +42,17 @@ namespace Reverse { arrayIsNotInAscendingOrder = false; Console.WriteLine($"YOU WON IT IN {numberOfMoves} MOVES!!!"); + Console.WriteLine(); + Console.WriteLine(); } numberOfMoves++; } - Console.Write("TRY AGAIN (YES OR NO)"); + Console.Write("TRY AGAIN (YES OR NO) "); tryAgain = Console.ReadLine(); } + Console.WriteLine(); Console.WriteLine("OK HOPE YOU HAD FUN"); } @@ -90,31 +94,37 @@ namespace Reverse private static void PrintTitle() { - Console.WriteLine("REVERSE"); - Console.WriteLine("CREATIVE COMPUTING MORRISTON, NEW JERSEY"); + Console.WriteLine("\t\t REVERSE"); + Console.WriteLine(" CREATIVE COMPUTING MORRISTON, NEW JERSEY"); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("REVERSE -- A GAME OF SKILL"); + Console.WriteLine(); } private static void DisplayRules() { + Console.WriteLine(); Console.WriteLine("THIS IS THE GAME OF 'REVERSE'. TO WIN, ALL YOU HAVE"); Console.WriteLine("TO DO IS ARRANGE A LIST OF NUMBERS (1 THOUGH 9 )"); Console.WriteLine("IN NUMBERICAL ORDER FROM LEFT TO RIGHT. TO MOVE, YOU"); Console.WriteLine("TELL ME HOW MANY NUMBERS (COUNTING FROM THE LEFT) TO"); Console.WriteLine("REVERSE. FOR EXAMPLE, IF THE CURRENT LIST IS:"); Console.WriteLine(); - Console.WriteLine(" 2 3 4 5 1 6 7 8 9"); + Console.WriteLine("2 3 4 5 1 6 7 8 9"); Console.WriteLine(); Console.WriteLine("AND YOU REVERSE 4, THE RESULT WILL BE:"); Console.WriteLine(); - Console.WriteLine(" 5 4 3 2 1 6 7 8 9"); + Console.WriteLine("5 4 3 2 1 6 7 8 9"); Console.WriteLine(); Console.WriteLine("NOW IF YOU REVERSE 5, YOU WIN!"); Console.WriteLine(); - Console.WriteLine(" 1 2 3 4 5 6 7 8 9"); + Console.WriteLine("1 2 3 4 5 6 7 8 9"); Console.WriteLine(); Console.WriteLine("NO DOUBT YOU WILL LIKE THIS GAME, BUT "); Console.WriteLine("IF YOU WANT TO QUIT, REVERSE 0 (ZERO)"); Console.WriteLine(); + Console.WriteLine(); } } } From ed50c3e24b817e27a482ed0949d422c6a99b32c7 Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Thu, 13 Jan 2022 16:28:54 +0800 Subject: [PATCH 132/337] fix typo. --- 73_Reverse/csharp/Reverse/Reverse/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/73_Reverse/csharp/Reverse/Reverse/Program.cs b/73_Reverse/csharp/Reverse/Reverse/Program.cs index 82e78131..8454a58c 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Program.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Program.cs @@ -107,7 +107,7 @@ namespace Reverse Console.WriteLine(); Console.WriteLine("THIS IS THE GAME OF 'REVERSE'. TO WIN, ALL YOU HAVE"); Console.WriteLine("TO DO IS ARRANGE A LIST OF NUMBERS (1 THOUGH 9 )"); - Console.WriteLine("IN NUMBERICAL ORDER FROM LEFT TO RIGHT. TO MOVE, YOU"); + Console.WriteLine("IN NUMERICAL ORDER FROM LEFT TO RIGHT. TO MOVE, YOU"); Console.WriteLine("TELL ME HOW MANY NUMBERS (COUNTING FROM THE LEFT) TO"); Console.WriteLine("REVERSE. FOR EXAMPLE, IF THE CURRENT LIST IS:"); Console.WriteLine(); From 4f2bc6f98c97465e02da335d7bcb416d892ec194 Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Thu, 13 Jan 2022 16:32:55 +0800 Subject: [PATCH 133/337] Add test showing that reverse handles numbers less than zero. --- .../csharp/Reverse/Reverse.Tests/ReverserTests.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs index bd00436f..4e57a05a 100644 --- a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs @@ -87,6 +87,19 @@ namespace Reverse.Tests Assert.True(sut.GetArray().SequenceEqual(output)); } + [Fact] + public void Reverse_WithIndexLessThanZero_DoesNothing() + { + var input = new int[] { 1, 2 }; + var output = new int[] { 1, 2 }; + var sut = new TestReverser(1); + sut.SetArray(input); + + sut.Reverse(-1); + + Assert.True(sut.GetArray().SequenceEqual(output)); + } + [Theory] [InlineData(new int[] { 1 })] [InlineData(new int[] { 1, 2 })] From 7d14c37aaad85ac4c487ac247768a285fa8cc427 Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Thu, 13 Jan 2022 16:41:24 +0800 Subject: [PATCH 134/337] Handle array size inputs less than 1. --- 73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs | 9 +++++++++ 73_Reverse/csharp/Reverse/Reverse/Reverser.cs | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs index 4e57a05a..6fe3bb77 100644 --- a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs +++ b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs @@ -1,5 +1,6 @@ using FsCheck.Xunit; using Reverse.Tests.Generators; +using System; using System.Linq; using Xunit; @@ -7,6 +8,14 @@ namespace Reverse.Tests { public class ReverserTests { + [Fact] + public void Constructor_CannotAcceptNumberLessThanZero() + { + Action action = () => new Reverser(0); + + Assert.Throws(action); + } + [Property(Arbitrary = new[] { typeof(PositiveIntegerGenerator) })] public void Constructor_CreatesRandomArrayOfSpecifiedLength(int size) { diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs index 2d2ea700..fdab5e96 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs @@ -43,6 +43,11 @@ namespace Reverse private int[] CreateRandomArray(int size) { + if (size < 1) + { + throw new ArgumentOutOfRangeException(nameof(size), "Array size must be a positive integer"); + } + var array = new int[size]; for (int i = 1; i <= size; i++) { From ead374e8b5935ab49e4b7ad497de7d871aeee0b6 Mon Sep 17 00:00:00 2001 From: Kristian Stolen Date: Thu, 13 Jan 2022 16:53:09 +0800 Subject: [PATCH 135/337] refactor and reformat output. --- 73_Reverse/csharp/Reverse/Reverse/Program.cs | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/73_Reverse/csharp/Reverse/Reverse/Program.cs b/73_Reverse/csharp/Reverse/Reverse/Program.cs index 8454a58c..5f8c5967 100644 --- a/73_Reverse/csharp/Reverse/Reverse/Program.cs +++ b/73_Reverse/csharp/Reverse/Reverse/Program.cs @@ -22,11 +22,10 @@ namespace Reverse var reverser = new Reverser(arrayLength); Console.WriteLine("HERE WE GO ... THE LIST IS:"); - Console.WriteLine(); PrintList(reverser.GetArrayString()); - var arrayIsNotInAscendingOrder = true; + var arrayIsInAscendingOrder = false; var numberOfMoves = 0; - while (arrayIsNotInAscendingOrder) + while (arrayIsInAscendingOrder == false) { int index = ReadNextInput(); @@ -37,23 +36,24 @@ namespace Reverse reverser.Reverse(index); PrintList(reverser.GetArrayString()); - - if (reverser.IsArrayInAscendingOrder()) - { - arrayIsNotInAscendingOrder = false; - Console.WriteLine($"YOU WON IT IN {numberOfMoves} MOVES!!!"); - Console.WriteLine(); - Console.WriteLine(); - } + arrayIsInAscendingOrder = reverser.IsArrayInAscendingOrder(); numberOfMoves++; } + if (arrayIsInAscendingOrder) + { + Console.WriteLine($"YOU WON IT IN {numberOfMoves} MOVES!!!"); + + } + + Console.WriteLine(); + Console.WriteLine(); Console.Write("TRY AGAIN (YES OR NO) "); tryAgain = Console.ReadLine(); } Console.WriteLine(); - Console.WriteLine("OK HOPE YOU HAD FUN"); + Console.WriteLine("OK HOPE YOU HAD FUN!!"); } private static int ReadNextInput() From b887d2993052ee26b649496d7500021908d1e6e2 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 13 Jan 2022 08:36:27 -0500 Subject: [PATCH 136/337] Finished Move script (if it is correct) --- 48_High_IQ/python/High_IQ.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index b2e71b6c..548d984d 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -67,10 +67,15 @@ def move(board): if difference != 2 and difference != 18: return False center = (end + start) / 2 + if not board[center] == '!': + return False + board[start] = 'O' + board[center] = 'O' + board[end] = '!' + return True except: return False - return True def main(): # if input("Do you want instrunctions?\n").lower().startswith("y"): From 679481ea233b43ff55e19ff8d321cc00b31697bc Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 13 Jan 2022 08:41:13 -0500 Subject: [PATCH 137/337] Simplified / Shortened move script --- 48_High_IQ/python/High_IQ.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 548d984d..0f39b9d4 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -61,19 +61,14 @@ def move(board): return False end = int(input("TO WHERE? ")) - if not (board[end] == 'O'): - return False difference = abs(end - start) - if difference != 2 and difference != 18: - return False center = (end + start) / 2 - if not board[center] == '!': - return False - board[start] = 'O' - board[center] = 'O' - board[end] = '!' - return True + if (difference == 2 or difference == 18) and board[end] == 'O' and board[center] == '!': + board[start] = 'O' + board[center] = 'O' + board[end] == '!' + return True except: return False From 633c0137c7d3bdfb6b943f1535765e76b6d83fca Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 13 Jan 2022 08:45:48 -0500 Subject: [PATCH 138/337] Added Post-Game prints --- 48_High_IQ/python/High_IQ.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 0f39b9d4..57473922 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -53,6 +53,17 @@ def play_game(): print_board(board) while not move(board): print("ILLEGAL MOVE! TRY AGAIN") + + peg_count = 0 + for key in board.keys(): + if board[key] == '!': + peg_count += 1 + + print("YOU HAD " + str(peg_count) + " PEGS REMAINING") + + if peg_count == 1: + print("BRAVO! YOU MADE A PERFECT SCORE!") + print("SAVE THIS PAPER AS A RECORD OF YOUR ACCOMPLISHMENT!") def move(board): try: From 212cc1d8bd54f717e794ed5b006d51f67cf92a1a Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 13 Jan 2022 08:47:41 -0500 Subject: [PATCH 139/337] Removed Commented Line --- 48_High_IQ/python/High_IQ.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 57473922..1c69abda 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -84,7 +84,6 @@ def move(board): return False def main(): -# if input("Do you want instrunctions?\n").lower().startswith("y"): print(" " * 33 + "H-I-Q") print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") print_instructions() @@ -94,8 +93,8 @@ def is_game_finished(board): for pos in board.keys(): if board[pos] == "X": for space in [1,9]: - nextToPeg = ((pos + space) in board) and board[pos + space] == "X" - hasMovableSpace = (not ((pos - space) in board and board[pos - space] == "X")) or (not ((pos + space * 2) in board and board[pos + space * 2] == "X")) + nextToPeg = ((pos + space) in board) and board[pos + space] == "!" + hasMovableSpace = (not ((pos - space) in board and board[pos - space] == "!")) or (not ((pos + space * 2) in board and board[pos + space * 2] == "!")) if nextToPeg and hasMovableSpace: return False From 351530faed6ae8173b9b8e506970908a135b747d Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 13 Jan 2022 09:07:33 -0500 Subject: [PATCH 140/337] Removed extra quotation mark --- 48_High_IQ/python/High_IQ.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 1c69abda..e8cca71d 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -68,7 +68,7 @@ def play_game(): def move(board): try: start = int(input("MOVE WHICH PIECE? ")) - if not (board[start] == "'!'): + if not (board[start] == '!'): return False end = int(input("TO WHERE? ")) @@ -97,7 +97,6 @@ def is_game_finished(board): hasMovableSpace = (not ((pos - space) in board and board[pos - space] == "!")) or (not ((pos + space * 2) in board and board[pos + space * 2] == "!")) if nextToPeg and hasMovableSpace: return False - return True From d041d2f92a4031dd9805d5200ffc77ddad554cf1 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 13 Jan 2022 09:14:39 -0500 Subject: [PATCH 141/337] Replaced double quotes with single quotes --- 48_High_IQ/python/High_IQ.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index e8cca71d..69cc6210 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -2,8 +2,8 @@ def new_board(): board = {} for i in [13, 14, 15, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 38, 39, 40, 42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 58, 59, 60, 67, 68, 69]: - board[i] = "!" - board[41] = "O" + board[i] = '!' + board[41] = 'O' return board @@ -91,10 +91,10 @@ def main(): def is_game_finished(board): for pos in board.keys(): - if board[pos] == "X": + if board[pos] == 'X': for space in [1,9]: - nextToPeg = ((pos + space) in board) and board[pos + space] == "!" - hasMovableSpace = (not ((pos - space) in board and board[pos - space] == "!")) or (not ((pos + space * 2) in board and board[pos + space * 2] == "!")) + nextToPeg = ((pos + space) in board) and board[pos + space] == '!' + hasMovableSpace = (not ((pos - space) in board and board[pos - space] == '!')) or (not ((pos + space * 2) in board and board[pos + space * 2] == '!')) if nextToPeg and hasMovableSpace: return False return True From baf5d3750aeca07214747177522fcb84780ebce4 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Thu, 13 Jan 2022 16:24:46 +0200 Subject: [PATCH 142/337] Some utility scripts for C# and VB.NET ports --- 00_Utilities/DotnetUtils/.editorconfig | 168 ++++++++++++++++++ 00_Utilities/DotnetUtils/DotnetUtils.sln | 25 +++ .../DotnetUtils/DotnetUtils.csproj | 10 ++ .../DotnetUtils/DotnetUtils/Extensions.cs | 27 +++ .../DotnetUtils/DotnetUtils/Globals.cs | 8 + .../DotnetUtils/DotnetUtils/PortInfo.cs | 51 ++++++ .../DotnetUtils/DotnetUtils/PortInfos.cs | 22 +++ .../DotnetUtils/DotnetUtils/Program.cs | 163 +++++++++++++++++ 8 files changed, 474 insertions(+) create mode 100644 00_Utilities/DotnetUtils/.editorconfig create mode 100644 00_Utilities/DotnetUtils/DotnetUtils.sln create mode 100644 00_Utilities/DotnetUtils/DotnetUtils/DotnetUtils.csproj create mode 100644 00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs create mode 100644 00_Utilities/DotnetUtils/DotnetUtils/Globals.cs create mode 100644 00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs create mode 100644 00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs create mode 100644 00_Utilities/DotnetUtils/DotnetUtils/Program.cs diff --git a/00_Utilities/DotnetUtils/.editorconfig b/00_Utilities/DotnetUtils/.editorconfig new file mode 100644 index 00000000..9e7a90d5 --- /dev/null +++ b/00_Utilities/DotnetUtils/.editorconfig @@ -0,0 +1,168 @@ +root = true + + +[*.{cs,vb}] +indent_size = 4 +indent_style = space +end_of_line = crlf +insert_final_newline = true + +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = false + +dotnet_style_qualification_for_event = false:suggestion +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_property = false:suggestion + +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion + +dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:silent + +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent + +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_operator_placement_when_wrapping = end_of_line +dotnet_style_prefer_auto_properties = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_return = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion + + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_private_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_private_members_should_be_pascal_case.symbols = non_private_members +dotnet_naming_rule.non_private_members_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.private_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.private_members_should_be_pascal_case.symbols = private_members +dotnet_naming_rule.private_members_should_be_pascal_case.style = camel_case + + +# Symbols for use with naming rules + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum, delegate +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_private_members.applicable_kinds = property, method, field, event +dotnet_naming_symbols.non_private_members.applicable_accessibilities = public, internal, protected, protected_internal, private_protected + +dotnet_naming_symbols.private_members.applicable_kinds = property, method, field, event +dotnet_naming_symbols.private_members.applicable_accessibilities = private + + +# Naming styles + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.camel_case.required_prefix = +dotnet_naming_style.camel_case.required_suffix = +dotnet_naming_style.camel_case.word_separator = +dotnet_naming_style.camel_case.capitalization = camel_case + + +[*.cs] +csharp_new_line_before_catch = false +csharp_new_line_before_else = false +csharp_new_line_before_finally = false +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = none +csharp_new_line_between_query_expression_clauses = true + +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +csharp_prefer_braces = true:warning + +csharp_style_expression_bodied_constructors = true:suggestion +csharp_style_expression_bodied_methods = true:suggestion +csharp_style_expression_bodied_properties = true:suggestion + +csharp_prefer_simple_default_expression = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion + +csharp_style_var_elsewhere = true:suggestion +csharp_style_var_for_built_in_types = true:suggestion +csharp_style_var_when_type_is_apparent = true:suggestion + +csharp_preferred_modifier_order = internal,protected,public,private,static,readonly,abstract,override,sealed,virtual:suggestion + +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion + + +[*.vb] +visual_basic_preferred_modifier_order = partial,default,private,protected,public,friend,notoverridable,overridable,mustoverride,overloads,overrides,mustinherit,notinheritable,static,shared,shadows,readonly,writeonly,dim,const,withevents,widening,narrowing,custom,async,iterator:silent +visual_basic_style_unused_value_assignment_preference = unused_local_variable:suggestion +visual_basic_style_unused_value_expression_statement_preference = unused_local_variable:silent diff --git a/00_Utilities/DotnetUtils/DotnetUtils.sln b/00_Utilities/DotnetUtils/DotnetUtils.sln new file mode 100644 index 00000000..ecf9588c --- /dev/null +++ b/00_Utilities/DotnetUtils/DotnetUtils.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotnetUtils", "DotnetUtils\DotnetUtils.csproj", "{BFDF93C2-4FB7-4838-AFDF-E7B5F83C3F00}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BFDF93C2-4FB7-4838-AFDF-E7B5F83C3F00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BFDF93C2-4FB7-4838-AFDF-E7B5F83C3F00}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BFDF93C2-4FB7-4838-AFDF-E7B5F83C3F00}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BFDF93C2-4FB7-4838-AFDF-E7B5F83C3F00}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {30FCF56E-4E83-42F8-AB43-A52C86C7C9B4} + EndGlobalSection +EndGlobal diff --git a/00_Utilities/DotnetUtils/DotnetUtils/DotnetUtils.csproj b/00_Utilities/DotnetUtils/DotnetUtils/DotnetUtils.csproj new file mode 100644 index 00000000..74abf5c9 --- /dev/null +++ b/00_Utilities/DotnetUtils/DotnetUtils/DotnetUtils.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs b/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs new file mode 100644 index 00000000..82ff9532 --- /dev/null +++ b/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs @@ -0,0 +1,27 @@ +using System.Diagnostics.CodeAnalysis; + +namespace DotnetUtils; + +public static class Extensions { + public static IEnumerable SelectT(this IEnumerable<(T1, T2)> src, Func selector) => + src.Select(x => selector(x.Item1, x.Item2)); + public static IEnumerable SelectT(this IEnumerable<(T1, T2, T3)> src, Func selector) => + src.Select(x => selector(x.Item1, x.Item2, x.Item3)); + public static IEnumerable<(T1, T2, int)> WithIndex(this IEnumerable<(T1, T2)> src) => src.Select((x, index) => (x.Item1, x.Item2, index)); + + public static bool IsNullOrWhitespace([NotNullWhen(false)] this string? s) => string.IsNullOrWhiteSpace(s); + + [return: NotNullIfNotNull("path")] + public static string? RelativePath(this string? path, string? rootPath) { + if ( + path.IsNullOrWhitespace() || + rootPath.IsNullOrWhitespace() + ) { return path; } + + var path1 = path.TrimEnd('\\'); + rootPath = rootPath.TrimEnd('\\'); + if (!path1.StartsWith(rootPath, StringComparison.InvariantCultureIgnoreCase)) { return path; } + + return path1[(rootPath.Length + 1)..]; // ignore the initial / + } +} diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Globals.cs b/00_Utilities/DotnetUtils/DotnetUtils/Globals.cs new file mode 100644 index 00000000..1ff7c09d --- /dev/null +++ b/00_Utilities/DotnetUtils/DotnetUtils/Globals.cs @@ -0,0 +1,8 @@ +namespace DotnetUtils; + +public static class Globals { + public static readonly Dictionary LangData = new() { + { "csharp", ("cs", "csproj") }, + { "vbnet", ("vb", "vbproj") } + }; +} diff --git a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs new file mode 100644 index 00000000..894c8834 --- /dev/null +++ b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs @@ -0,0 +1,51 @@ +using System.Reflection; +using static System.IO.Directory; +using static System.IO.Path; +using static DotnetUtils.Globals; + +namespace DotnetUtils; + +public record PortInfo( + string FullPath, string FolderName, int Index, string GameName, + string LangPath, string Lang, string Ext, string ProjExt, + string[] CodeFiles, string[] Slns, string[] Projs +) { + + private static readonly EnumerationOptions enumerationOptions = new() { + RecurseSubdirectories = true, + MatchType = MatchType.Simple, + MatchCasing = MatchCasing.CaseInsensitive + }; + + public static PortInfo? Create(string fullPath, string langKeyword) { + var folderName = GetFileName(fullPath); + var parts = folderName.Split('_', 2); + + var index = + parts.Length > 0 && int.TryParse(parts[0], out var n) ? + n : + (int?)null; + + var gameName = + parts.Length > 1 ? + parts[1].Replace("_", "") : + null; + + if (index is 0 or null || gameName is null) { return null; } + + var (ext, projExt) = LangData[langKeyword]; + var langPath = Combine(fullPath, langKeyword); + var codeFiles = + GetFiles(langPath, $"*.{ext}", enumerationOptions) + .Where(x => !x.Contains("\\bin\\") && !x.Contains("\\obj\\")) + .ToArray(); + + return new PortInfo( + fullPath, folderName, index.Value, gameName, + langPath, langKeyword, ext, projExt, + codeFiles, + GetFiles(langPath, "*.sln", enumerationOptions), + GetFiles(langPath, $"*.{projExt}", enumerationOptions) + ); + } +} diff --git a/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs b/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs new file mode 100644 index 00000000..b8c1afd3 --- /dev/null +++ b/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using static System.IO.Directory; +using static DotnetUtils.Globals; + +namespace DotnetUtils; + +public static class PortInfos { + public static readonly string Root; + + static PortInfos() { + Root = GetParent(Assembly.GetEntryAssembly()!.Location)!.FullName; + Root = Root[..Root.IndexOf(@"\00_Utilities")]; + + Get = GetDirectories(Root) + .SelectMany(fullPath => LangData.Keys.Select(keyword => (fullPath, keyword))) + .SelectT((fullPath, keyword) => PortInfo.Create(fullPath, keyword)) + .Where(x => x is not null) + .ToArray()!; + } + + public static readonly PortInfo[] Get; +} diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs new file mode 100644 index 00000000..9bf36f4f --- /dev/null +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -0,0 +1,163 @@ +using DotnetUtils; +using static System.Console; +using static System.IO.Path; + +var infos = PortInfos.Get; + +var actions = new (Action action, string description)[] { + (printInfos, "Output information -- solution, project, and code files"), + (missingSln, "Output missing sln"), + (unexpectedSlnName, "Output misnamed sln"), + (multipleSlns, "Output multiple sln files"), + (missingProj, "Output missing project file"), + (unexpectedProjName, "Output misnamed project files"), + (multipleProjs, "Output multiple project files") +}; + +foreach (var (_, description, index) in actions.WithIndex()) { + WriteLine($"{index}: {description}"); +} + +WriteLine(); + +actions[getChoice(actions.Length - 1)].action(); + +int getChoice(int maxValue) { + int result; + do { + Write("? "); + } while (!int.TryParse(ReadLine(), out result) || result < 0 || result > maxValue); + WriteLine(); + return result; +} + +void printSlns(PortInfo pi) { + switch (pi.Slns.Length) { + case 0: + WriteLine("No sln"); + break; + case 1: + WriteLine($"Solution: {pi.Slns[0].RelativePath(pi.LangPath)}"); + break; + case > 1: + WriteLine("Solutions:"); + foreach (var sln in pi.Slns) { + Write(sln.RelativePath(pi.LangPath)); + WriteLine(); + } + break; + } +} + +void printProjs(PortInfo pi) { + switch (pi.Projs.Length) { + case 0: + WriteLine("No project"); + break; + case 1: + WriteLine($"Project: {pi.Projs[0].RelativePath(pi.LangPath)}"); + break; + case > 1: + WriteLine("Projects:"); + foreach (var proj in pi.Projs) { + Write(proj.RelativePath(pi.LangPath)); + WriteLine(); + } + break; + } + WriteLine(); +} + +void printInfos() { + foreach (var item in infos) { + WriteLine(item.LangPath); + WriteLine(); + + printSlns(item); + WriteLine(); + + printProjs(item); + WriteLine(); + + // get code files + foreach (var file in item.CodeFiles) { + WriteLine(file.RelativePath(item.LangPath)); + } + WriteLine(new string('-', 50)); + } +} + +void missingSln() { + var data = infos.Where(x => !x.Slns.Any()).ToArray(); + foreach (var item in data) { + WriteLine(item.LangPath); + } + WriteLine(); + WriteLine($"Count: {data.Length}"); +} + +void unexpectedSlnName() { + var counter = 0; + foreach (var item in infos) { + if (!item.Slns.Any()) { continue; } + + var expectedSlnName = $"{item.GameName}.sln"; + if (item.Slns.Contains(Combine(item.LangPath, expectedSlnName))) { continue; } + + counter += 1; + WriteLine(item.LangPath); + WriteLine($"Expected: {expectedSlnName}"); + + printSlns(item); + + WriteLine(); + } + WriteLine($"Count: {counter}"); +} + +void multipleSlns() { + var data = infos.Where(x => x.Slns.Length > 1).ToArray(); + foreach (var item in data) { + WriteLine(item.LangPath); + printSlns(item); + } + WriteLine(); + WriteLine($"Count: {data.Length}"); +} + +void missingProj() { + var data = infos.Where(x => !x.Projs.Any()).ToArray(); + foreach (var item in data) { + WriteLine(item.LangPath); + } + WriteLine(); + WriteLine($"Count: {data.Length}"); +} + +void unexpectedProjName() { + var counter = 0; + foreach (var item in infos) { + if (!item.Projs.Any()) { continue; } + + var expectedProjName = $"{item.GameName}.{item.ProjExt}"; + if (item.Projs.Contains(Combine(item.LangPath, expectedProjName))) { continue; } + + counter += 1; + WriteLine(item.LangPath); + WriteLine($"Expected: {expectedProjName}"); + + printProjs(item); + + WriteLine(); + } + WriteLine($"Count: {counter}"); +} + +void multipleProjs() { + var data = infos.Where(x => x.Projs.Length > 1).ToArray(); + foreach (var item in data) { + WriteLine(item.LangPath); + } + WriteLine(); + WriteLine($"Count: {data.Length}"); +} From db5face44a80f8f30c01e8e917aca8fc30b176ad Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Thu, 13 Jan 2022 16:32:13 +0200 Subject: [PATCH 143/337] Fix: print projects for multiproject script --- 00_Utilities/DotnetUtils/DotnetUtils/Program.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index 9bf36f4f..6d4594b7 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -157,6 +157,9 @@ void multipleProjs() { var data = infos.Where(x => x.Projs.Length > 1).ToArray(); foreach (var item in data) { WriteLine(item.LangPath); + WriteLine(); + printProjs(item); + } WriteLine(); WriteLine($"Count: {data.Length}"); From 6c1adde2056151fafe330ef9970403db5d372ce0 Mon Sep 17 00:00:00 2001 From: Stephen Childs Date: Thu, 13 Jan 2022 10:56:50 -0500 Subject: [PATCH 144/337] Move harvest calculation outside rat condition. This fixes an error where the harvest was only added to the total bushels if rats ate some. Note in the BASIC file, we check to see if rats eat the grain in line 522 and if not, go to line 530, which is where the `S=S-E+H` calculation is done. --- 43_Hammurabi/python/hamurabi.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/43_Hammurabi/python/hamurabi.py b/43_Hammurabi/python/hamurabi.py index 7c18f892..17c61982 100644 --- a/43_Hammurabi/python/hamurabi.py +++ b/43_Hammurabi/python/hamurabi.py @@ -154,7 +154,8 @@ while Z < 11: # line 270. main loop. while the year is less than 11 if int(C / 2) == C / 2: # even number. 50/50 chance # REM *** RATS ARE RUNNING WILD!! E = int(S / C) # calc losses due to rats, based on previous random number - S = S - E + H # deduct losses from stores + + S = S - E + H # deduct losses from stores C = gen_random() # REM *** LET'S HAVE SOME BABIES From 94a65239d5f6acd9b0817ad77bfb26622e82b676 Mon Sep 17 00:00:00 2001 From: Stephen Childs Date: Thu, 13 Jan 2022 11:04:43 -0500 Subject: [PATCH 145/337] Allow max fields to be worked in python Hamurabi. In the BASIC version the calculation is on line 455: `455 IF D<10*P THEN 510` Which skips over the not enough people message. In the Python version the logic is reversed, and we check to see if there is too few people and then run the message: `elif D >= 10 * P` (in the current code). However, this means that the case where you want to plant the maximum number of acres won't work. e.g. You have 100 people (P) and want to plant 1000 acres (D). `1000 >= 10 * 100` `1000 >= 1000` Which triggers the "not enough people code". Maybe this is a bug in the original program. --- 43_Hammurabi/python/hamurabi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/43_Hammurabi/python/hamurabi.py b/43_Hammurabi/python/hamurabi.py index 17c61982..e7310fc7 100644 --- a/43_Hammurabi/python/hamurabi.py +++ b/43_Hammurabi/python/hamurabi.py @@ -137,7 +137,7 @@ while Z < 11: # line 270. main loop. while the year is less than 11 # REM *** ENOUGH GRAIN FOR SEED? bad_input_710(S) D = -99 - elif D >= 10 * P: + elif D > 10 * P: # REM *** ENOUGH PEOPLE TO TEND THE CROPS? print("BUT YOU HAVE ONLY", P, "PEOPLE TO TEND THE FIELDS! NOW THEN,") D = -99 From 37791fe915067b256285a3e3d1ffcb9f0528e683 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 13 Jan 2022 11:29:05 -0500 Subject: [PATCH 146/337] Commented and fixed error --- 48_High_IQ/python/High_IQ.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 69cc6210..a91f3699 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -1,5 +1,6 @@ def new_board(): + # Using a dictionary in python to store the board, since we are not including all numbers within a given range. board = {} for i in [13, 14, 15, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 38, 39, 40, 42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 58, 59, 60, 67, 68, 69]: board[i] = '!' @@ -38,6 +39,7 @@ NUMBERS. OK, LET'S BEGIN. """) def print_board(board): + """Prints the boards using indexes in the passed parameter""" print(" " * 2 + board[13] + board[14] + board[15]) print(" " * 2 + board[22] + board[23] + board[24]) print(board[29] + board[30] + board[31] + board[32] + board[33] + board[34] + board[35]) @@ -47,13 +49,16 @@ def print_board(board): print(" " * 2 + board[67] + board[68] + board[69]) def play_game(): + # Create new board board = new_board() + # Main game loop while not is_game_finished(board): print_board(board) while not move(board): print("ILLEGAL MOVE! TRY AGAIN") + # Check peg count and print the user's score peg_count = 0 for key in board.keys(): if board[key] == '!': @@ -66,20 +71,29 @@ def play_game(): print("SAVE THIS PAPER AS A RECORD OF YOUR ACCOMPLISHMENT!") def move(board): + """Queries the user to move. Returns false if the user puts in an invalid input or move, returns true if the move was successful""" try: + # Ask for the "start" location start = int(input("MOVE WHICH PIECE? ")) + # Verify that the location has a peg if not (board[start] == '!'): return False + # Ask for the "end" location end = int(input("TO WHERE? ")) + + # difference and center difference = abs(end - start) center = (end + start) / 2 + # Execute the move if the difference is correct, there is a peg in the center and no peg at the end if (difference == 2 or difference == 18) and board[end] == 'O' and board[center] == '!': board[start] = 'O' board[center] = 'O' board[end] == '!' return True + else: + return False except: return False @@ -90,10 +104,13 @@ def main(): play_game() def is_game_finished(board): + # Checks all locations and whether or not a move is possible at that location. for pos in board.keys(): if board[pos] == 'X': for space in [1,9]: + # Checks if the next location has a peg nextToPeg = ((pos + space) in board) and board[pos + space] == '!' + # Checks both going forward (+ location) or backwards (-location) hasMovableSpace = (not ((pos - space) in board and board[pos - space] == '!')) or (not ((pos + space * 2) in board and board[pos + space * 2] == '!')) if nextToPeg and hasMovableSpace: return False From dc0ceba48ae791079c61f7bab540f67230b1836c Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 13 Jan 2022 12:27:53 -0500 Subject: [PATCH 147/337] Using tests instead of try catches --- 48_High_IQ/python/High_IQ.py | 70 +++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index a91f3699..2455049f 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -72,30 +72,60 @@ def play_game(): def move(board): """Queries the user to move. Returns false if the user puts in an invalid input or move, returns true if the move was successful""" - try: - # Ask for the "start" location - start = int(input("MOVE WHICH PIECE? ")) - # Verify that the location has a peg - if not (board[start] == '!'): - return False + # try: + # # Ask for the "start" location + # start = int(input("MOVE WHICH PIECE? ")) + # # Verify that the location has a peg + # if not (board[start] == '!'): + # return False - # Ask for the "end" location - end = int(input("TO WHERE? ")) + # # Ask for the "end" location + # end = int(input("TO WHERE? ")) - # difference and center - difference = abs(end - start) - center = (end + start) / 2 + # # difference and center + # difference = abs(end - start) + # center = (end + start) / 2 - # Execute the move if the difference is correct, there is a peg in the center and no peg at the end - if (difference == 2 or difference == 18) and board[end] == 'O' and board[center] == '!': - board[start] = 'O' - board[center] = 'O' - board[end] == '!' - return True - else: - return False - except: + # # Execute the move if the difference is correct, there is a peg in the center and no peg at the end + # if (difference == 2 or difference == 18) and board[end] == 'O' and board[center] == '!': + # board[start] = 'O' + # board[center] = 'O' + # board[end] == '!' + # return True + # else: + # return False + # except: + # return False + start_input = input("MOVE WHICH PIECE? ") + + if not start_input.isdigit(): return False + + start = int(start_input) + + if start not in board or board[start] != '!': + return False + + end_input = input("TO WHERE? ") + + if not end_input.isdigit(): + return False + + end = int(end_input) + + if end not in board or board[end] != '0': + return False + + difference = abs(start - end) + center = (end + start) / 2 + if (difference == 2 or difference == 18) and board[end] == 'O' and board[center] == '!': + board[start] = 'O' + board[center] = 'O' + board[end] == '!' + return True + else: + return False + def main(): print(" " * 33 + "H-I-Q") From e107e885095820ade482a836155747f5a8f4d8c2 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 13 Jan 2022 16:59:25 -0500 Subject: [PATCH 148/337] Fixed Bug --- 48_High_IQ/python/High_IQ.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index 2455049f..cd5a996d 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -136,7 +136,7 @@ def main(): def is_game_finished(board): # Checks all locations and whether or not a move is possible at that location. for pos in board.keys(): - if board[pos] == 'X': + if board[pos] == '!': for space in [1,9]: # Checks if the next location has a peg nextToPeg = ((pos + space) in board) and board[pos + space] == '!' From e7e16eb9498201c755a0d839917072b2106ac454 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 13 Jan 2022 17:01:43 -0500 Subject: [PATCH 149/337] Move code now properly works --- 48_High_IQ/python/High_IQ.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index cd5a996d..fe61e9ba 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -113,7 +113,7 @@ def move(board): end = int(end_input) - if end not in board or board[end] != '0': + if end not in board or board[end] != 'O': return False difference = abs(start - end) @@ -121,7 +121,7 @@ def move(board): if (difference == 2 or difference == 18) and board[end] == 'O' and board[center] == '!': board[start] = 'O' board[center] = 'O' - board[end] == '!' + board[end] = '!' return True else: return False From 33b5da4b1fb85b9073d83b38a56465358ce49b92 Mon Sep 17 00:00:00 2001 From: Thomas Kwashnak Date: Thu, 13 Jan 2022 17:16:45 -0500 Subject: [PATCH 150/337] Misc final steps Removed commented code Added to README.md --- 48_High_IQ/python/High_IQ.py | 24 ------------------------ 48_High_IQ/python/README.md | 2 ++ 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py index fe61e9ba..4e14ddc1 100644 --- a/48_High_IQ/python/High_IQ.py +++ b/48_High_IQ/python/High_IQ.py @@ -72,30 +72,6 @@ def play_game(): def move(board): """Queries the user to move. Returns false if the user puts in an invalid input or move, returns true if the move was successful""" - # try: - # # Ask for the "start" location - # start = int(input("MOVE WHICH PIECE? ")) - # # Verify that the location has a peg - # if not (board[start] == '!'): - # return False - - # # Ask for the "end" location - # end = int(input("TO WHERE? ")) - - # # difference and center - # difference = abs(end - start) - # center = (end + start) / 2 - - # # Execute the move if the difference is correct, there is a peg in the center and no peg at the end - # if (difference == 2 or difference == 18) and board[end] == 'O' and board[center] == '!': - # board[start] = 'O' - # board[center] = 'O' - # board[end] == '!' - # return True - # else: - # return False - # except: - # return False start_input = input("MOVE WHICH PIECE? ") if not start_input.isdigit(): diff --git a/48_High_IQ/python/README.md b/48_High_IQ/python/README.md index 781945ec..a0738c90 100644 --- a/48_High_IQ/python/README.md +++ b/48_High_IQ/python/README.md @@ -1,3 +1,5 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Python](https://www.python.org/about/) + +[Implementation](./High_IQ.py) by [Thomas Kwashnak](https://github.com/LittleTealeaf) \ No newline at end of file From cf55a5f63756691ce3145636cbaf43606fc61831 Mon Sep 17 00:00:00 2001 From: Bernard Cooke Date: Fri, 14 Jan 2022 01:28:30 +0000 Subject: [PATCH 151/337] 12. Port Bombs Away to Python --- 12_Bombs_Away/python/bombs_away.py | 177 +++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 12_Bombs_Away/python/bombs_away.py diff --git a/12_Bombs_Away/python/bombs_away.py b/12_Bombs_Away/python/bombs_away.py new file mode 100644 index 00000000..894f968c --- /dev/null +++ b/12_Bombs_Away/python/bombs_away.py @@ -0,0 +1,177 @@ +""" +Bombs away + +Ported from BASIC to Python3 by Bernard Cooke (bernardcooke53) +Tested with Python 3.8.10, formatted with Black and type checked with mypy. +""" +import random +from typing import Iterable + + +def _stdin_choice(*, prompt: str, choices: Iterable[str]) -> str: + ret = input(prompt) + while ret not in choices: + print("TRY AGAIN...") + ret = input(prompt) + return ret + + +def player_survived() -> None: + print("YOU MADE IT THROUGH TREMENDOUS FLAK!!") + + +def player_death() -> None: + print("* * * * BOOM * * * *") + print("YOU HAVE BEEN SHOT DOWN.....") + print("DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR") + print("LAST TRIBUTE...") + + +def mission_success() -> None: + print(f"DIRECT HIT!!!! {int(100 * random.random())} KILLED.") + print("MISSION SUCCESSFUL.") + + +def death_with_chance(p_death: float) -> bool: + """ + Takes a float between 0 and 1 and returns a boolean + if the player has survived (based on random chance) + + Returns True if death, False if survived + """ + return p_death > random.random() + + +def commence_non_kamikazi_attack() -> None: + nmissions = int(input("HOW MANY MISSIONS HAVE YOU FLOWN? ")) + + while nmissions >= 160: + print("MISSIONS, NOT MILES...") + print("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS") + nmissions = int(input("NOW THEN, HOW MANY MISSIONS HAVE YOU FLOWN? ")) + + if nmissions >= 100: + print("THAT'S PUSHING THE ODDS!") + + if nmissions < 25: + print("FRESH OUT OF TRAINING, EH?") + + print() + return ( + mission_success() if nmissions >= 160 * random.random() else mission_failure() + ) + + +def mission_failure() -> None: + weapons_choices = { + "1": "GUNS", + "2": "MISSILES", + "3": "BOTH", + } + print(f"MISSED TARGET BY {int(2 + 30 * random.random())} MILES!") + print("NOW YOU'RE REALLY IN FOR IT !!") + print() + enemy_weapons = _stdin_choice( + prompt="DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3)? ", + choices=weapons_choices.keys(), + ) + + # If there are no gunners (i.e. weapon choice 2) then + # we say that the gunners have 0 accuracy for the purposes + # of calculating probability of player death + + enemy_gunner_accuracy = 0.0 + if enemy_weapons != "2": + # If the enemy has guns, how accurate are the gunners? + enemy_gunner_accuracy = float( + input("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? ") + ) + + if enemy_gunner_accuracy < 10: + print("YOU LIE, BUT YOU'LL PAY...") + return player_death() + + missile_threat_weighting = 0 if enemy_weapons == "1" else 35 + + death = death_with_chance( + p_death=(enemy_gunner_accuracy + missile_threat_weighting) / 100 + ) + + return player_survived() if not death else player_death() + + +def play_italy() -> None: + targets_to_messages = { + # 1 - ALBANIA, 2 - GREECE, 3 - NORTH AFRICA + "1": "SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE.", + "2": "BE CAREFUL!!!", + "3": "YOU'RE GOING FOR THE OIL, EH?", + } + target = _stdin_choice( + prompt="YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3)", + choices=targets_to_messages.keys(), + ) + + print(targets_to_messages[target]) + return commence_non_kamikazi_attack() + + +def play_allies() -> None: + aircraft_to_message = { + "1": "YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI.", + "2": "YOU'RE DUMPING THE A-BOMB ON HIROSHIMA.", + "3": "YOU'RE CHASING THE BISMARK IN THE NORTH SEA.", + "4": "YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR.", + } + aircraft = _stdin_choice( + prompt="AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4): ", + choices=aircraft_to_message.keys(), + ) + + print(aircraft_to_message[aircraft]) + return commence_non_kamikazi_attack() + + +def play_japan() -> None: + print("YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.") + first_mission = input("YOUR FIRST KAMIKAZE MISSION? (Y OR N): ") + if first_mission.lower() == "n": + return player_death() + + if random.random() > 0.65: + return mission_success() + return player_death() + + +def play_germany() -> None: + targets_to_messages = { + # 1 - RUSSIA, 2 - ENGLAND, 3 - FRANCE + "1": "YOU'RE NEARING STALINGRAD.", + "2": "NEARING LONDON. BE CAREFUL, THEY'VE GOT RADAR.", + "3": "NEARING VERSAILLES. DUCK SOUP. THEY'RE NEARLY DEFENSELESS.", + } + target = _stdin_choice( + prompt="A NAZI, EH? OH WELL. ARE YOU GOING FOR RUSSIA(1),\nENGLAND(2), OR FRANCE(3)? ", + choices=targets_to_messages.keys(), + ) + + print(targets_to_messages[target]) + + return commence_non_kamikazi_attack() + + +def play_game() -> None: + print("YOU ARE A PILOT IN A WORLD WAR II BOMBER.") + sides = {"1": play_italy, "2": play_allies, "3": play_japan, "4": play_germany} + side = _stdin_choice( + prompt="WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4): ", + choices=sides.keys(), + ) + return sides[side]() + + +if __name__ == "__main__": + again = True + while again: + play_game() + again = True if input("ANOTHER MISSION (Y OR N)").upper() == "Y" else False From 11ffe9cf90d7b7f61c7fe576b1ad7b61f451daee Mon Sep 17 00:00:00 2001 From: Bernard Cooke Date: Fri, 14 Jan 2022 01:31:27 +0000 Subject: [PATCH 152/337] Tidy up 'Another mission?' message --- 12_Bombs_Away/python/bombs_away.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12_Bombs_Away/python/bombs_away.py b/12_Bombs_Away/python/bombs_away.py index 894f968c..a7c4ccd5 100644 --- a/12_Bombs_Away/python/bombs_away.py +++ b/12_Bombs_Away/python/bombs_away.py @@ -174,4 +174,4 @@ if __name__ == "__main__": again = True while again: play_game() - again = True if input("ANOTHER MISSION (Y OR N)").upper() == "Y" else False + again = True if input("ANOTHER MISSION? (Y OR N): ").upper() == "Y" else False From f29fa1792ce2dc0b7f161ae631a3cd63854cdf3f Mon Sep 17 00:00:00 2001 From: Bernard Cooke Date: Fri, 14 Jan 2022 01:53:41 +0000 Subject: [PATCH 153/337] Tidy logic with inline conditionals for clarity --- 12_Bombs_Away/python/bombs_away.py | 52 +++++++++++++++++++----------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/12_Bombs_Away/python/bombs_away.py b/12_Bombs_Away/python/bombs_away.py index a7c4ccd5..b3133ae3 100644 --- a/12_Bombs_Away/python/bombs_away.py +++ b/12_Bombs_Away/python/bombs_away.py @@ -8,7 +8,7 @@ import random from typing import Iterable -def _stdin_choice(*, prompt: str, choices: Iterable[str]) -> str: +def _stdin_choice(prompt: str, *, choices: Iterable[str]) -> str: ret = input(prompt) while ret not in choices: print("TRY AGAIN...") @@ -43,12 +43,22 @@ def death_with_chance(p_death: float) -> bool: def commence_non_kamikazi_attack() -> None: - nmissions = int(input("HOW MANY MISSIONS HAVE YOU FLOWN? ")) + while True: + try: + nmissions = int(input("HOW MANY MISSIONS HAVE YOU FLOWN? ")) - while nmissions >= 160: - print("MISSIONS, NOT MILES...") - print("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS") - nmissions = int(input("NOW THEN, HOW MANY MISSIONS HAVE YOU FLOWN? ")) + while nmissions >= 160: + print("MISSIONS, NOT MILES...") + print("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS") + nmissions = int(input("NOW THEN, HOW MANY MISSIONS HAVE YOU FLOWN? ")) + break + except ValueError: + # In the BASIC implementation this + # wasn't accounted for + print("TRY AGAIN...") + continue + else: + break if nmissions >= 100: print("THAT'S PUSHING THE ODDS!") @@ -73,7 +83,7 @@ def mission_failure() -> None: print() enemy_weapons = _stdin_choice( prompt="DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3)? ", - choices=weapons_choices.keys(), + choices=weapons_choices, ) # If there are no gunners (i.e. weapon choice 2) then @@ -83,9 +93,17 @@ def mission_failure() -> None: enemy_gunner_accuracy = 0.0 if enemy_weapons != "2": # If the enemy has guns, how accurate are the gunners? - enemy_gunner_accuracy = float( - input("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? ") - ) + while True: + try: + enemy_gunner_accuracy = float( + input("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? ") + ) + break + except ValueError: + # In the BASIC implementation this + # wasn't accounted for + print("TRY AGAIN...") + continue if enemy_gunner_accuracy < 10: print("YOU LIE, BUT YOU'LL PAY...") @@ -109,7 +127,7 @@ def play_italy() -> None: } target = _stdin_choice( prompt="YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3)", - choices=targets_to_messages.keys(), + choices=targets_to_messages, ) print(targets_to_messages[target]) @@ -125,7 +143,7 @@ def play_allies() -> None: } aircraft = _stdin_choice( prompt="AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4): ", - choices=aircraft_to_message.keys(), + choices=aircraft_to_message, ) print(aircraft_to_message[aircraft]) @@ -137,10 +155,7 @@ def play_japan() -> None: first_mission = input("YOUR FIRST KAMIKAZE MISSION? (Y OR N): ") if first_mission.lower() == "n": return player_death() - - if random.random() > 0.65: - return mission_success() - return player_death() + return mission_success() if random.random() > 0.65 else player_death() def play_germany() -> None: @@ -152,7 +167,7 @@ def play_germany() -> None: } target = _stdin_choice( prompt="A NAZI, EH? OH WELL. ARE YOU GOING FOR RUSSIA(1),\nENGLAND(2), OR FRANCE(3)? ", - choices=targets_to_messages.keys(), + choices=targets_to_messages, ) print(targets_to_messages[target]) @@ -164,8 +179,7 @@ def play_game() -> None: print("YOU ARE A PILOT IN A WORLD WAR II BOMBER.") sides = {"1": play_italy, "2": play_allies, "3": play_japan, "4": play_germany} side = _stdin_choice( - prompt="WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4): ", - choices=sides.keys(), + prompt="WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4): ", choices=sides ) return sides[side]() From 62af4c0ab2a4c64633ec39e4f7da6ec5971392a0 Mon Sep 17 00:00:00 2001 From: Bernard Cooke Date: Fri, 14 Jan 2022 08:47:21 +0000 Subject: [PATCH 154/337] Correct looping/breaking in number of missions dialogue --- 12_Bombs_Away/python/bombs_away.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/12_Bombs_Away/python/bombs_away.py b/12_Bombs_Away/python/bombs_away.py index b3133ae3..5c591f44 100644 --- a/12_Bombs_Away/python/bombs_away.py +++ b/12_Bombs_Away/python/bombs_away.py @@ -51,14 +51,12 @@ def commence_non_kamikazi_attack() -> None: print("MISSIONS, NOT MILES...") print("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS") nmissions = int(input("NOW THEN, HOW MANY MISSIONS HAVE YOU FLOWN? ")) - break + break except ValueError: # In the BASIC implementation this # wasn't accounted for print("TRY AGAIN...") continue - else: - break if nmissions >= 100: print("THAT'S PUSHING THE ODDS!") From 8245d7badba8fdf3fe5c0123759a9e9220315238 Mon Sep 17 00:00:00 2001 From: Joe Nellis Date: Fri, 14 Jan 2022 01:42:44 -0800 Subject: [PATCH 155/337] Breakdown of the original BASIC code for re-implementers of this game. Sample code in BASIC showing distribution of right and wrong dice rolls. --- 29_Craps/README.md | 208 +++++++++++++++++++++++++++++++++++++ 29_Craps/distributions.bas | 24 +++++ 2 files changed, 232 insertions(+) create mode 100644 29_Craps/distributions.bas diff --git a/29_Craps/README.md b/29_Craps/README.md index 7372b99f..3c45c62b 100644 --- a/29_Craps/README.md +++ b/29_Craps/README.md @@ -17,3 +17,211 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html + +### Comments on the BASIC code for re-implementers. + + 15 LET R=0 +`R` is a variable that tracks winnings and losings. Unlike other games that +start out with a lump sum of cash to spend this game assumes the user has as +much money as they want and we only track how much they lost or won. + + 21 LET T=1 + 22 PRINT "PICK A NUMBER AND INPUT TO ROLL DICE"; + 23 INPUT Z + 24 LET X=(RND(0)) + 25 LET T =T+1 + 26 IF T<=Z THEN 24 +This block of code does nothing other than try to scramble the random number +generator. Random number generation is not random, they are generated from the +previous generated number. Because of the slow speed of these systems back then, +gaming random number generators was a concern, mostly for gameplay quality. +If you could know the "seed value" to the generator then you could effectively +know how to get the exact same dice rolls to happen and change your bet to +maximize your winnings and minimize your losses. + +The first reason this is an example of bad coding practice is the user is asked +to input a number but no clue is given as to the use of this number. This number +has no bearing on the game and as we'll see only has bearing on the internal +implementation of somehow trying to get an un-game-able seed for the random number +generator (since all future random numbers generated are based off this seed value.) + +The `RND(1)` command generates a number from a seed value that is always +the same, everytime, from when the machine is booted up (old C64 behavior). In +order to avoid the same dice rolls being generated, a special call to `RND(-TI)` +would initialize the random generator with something else. But RND(-TI) is not +a valid command on all systems. So `RND(0)`, which generates a random number +from the system clock is used. But technically this could be gamed because the +system clock was driven by the bootup time, there wasn't a BIOS battery on these +systems that kept an internal real time clock going even when the system was +turned off, unlike your regular PC. Therefore, in order to ensure as true +randomness as possible, insert human reaction time by asking for human input. + +But a human could just be holding down the enter key on bootup and that would +just skip any kind of multi-millisecond variance assigned by a natural human +reaction time. So, paranoia being a great motivator, a number is asked of the +user to avoid just holding down the enter key which negates the timing variance +of a human reaction. + +What comes next is a bit of nonsense. The block of code loops a counter, recalling +the `RND(0)` function (and thus reseeding it with the system clock value) +and then comparing the counter to the user's number input +in order to bail out of the loop. Because the `RND(0)` function is based off the +system clock and the loop of code has no branching other than the bailout +condition, the loop also takes a fixed amount of time to execute, thus making +repeated calls to `RND(0)` predictive and this scheming to get a better random +number is pointless. Furthermore, the loop is based on the number the user inputs +so a huge number like ten million causes a very noticable delay and leaves the +user wondering if the program has errored. The author could have simply called +`RND(0)` once and used a prompt that made more sense like asking for the users +name and then using that name in the game's replies. + +It is advised that you use whatever your languages' random number generator +provides and simply skip trying to recreate this bit of nonsense including +the user input. + + 27 PRINT"INPUT THE AMOUNT OF YOUR WAGER."; + 28 INPUT F + 30 PRINT "I WILL NOW THROW THE DICE" + 40 LET E=INT(7*RND(1)) + 41 LET S=INT(7*RND(1)) + 42 LET X=E+S + .... a bit later .... + 60 IF X=1 THEN 40 + 65 IF X=0 THEN 40 + + +`F` is a variable that represents the users wager for this betting round. +`E` and `S` represent the two individual and random dice being rolled. +This code is actually wrong because it returns a value between 0 and 6. +`X` is the sum of these dice rolls. As you'll see though further down in the +code, if `X` is zero or one it re-rolls the dice to maintain a potential +outcome of the sum of two dice between 2 and 12. This skews the normal distribution +of dice values to favor lower numbers because it does not consider that `E` +could be zero and `S` could be 2 or higher. To show this skewing of values +you can run the `distribution.bas` program which creates a histogram of the +distribution of the bad dice throw code and proper dice throw code. + +Here are the results: + + DISTRIBUTION OF DICE ROLLS WITH INT(7*RND(1)) VS INT(6*RND(1)+1) + THE INT(7*RND(1)) DISTRIBUTION: + 2 3 4 5 6 7 8 9 10 11 12 + 6483 8662 10772 13232 15254 13007 10746 8878 6486 4357 2123 + THE INT(6*RND(1)+1) DISTRIBUTION + 2 3 4 5 6 7 8 9 10 11 12 + 2788 5466 8363 11072 13947 16656 13884 11149 8324 5561 2790 +If the dice rolls are fair then we should see the largest occurrence be a 7 and +the smallest should be 2 and 12. Furthermore the occurrences should be +symetrical meaning there should be roughly the same amount of 2's as 12's, the +same amount of 3's as 11's, 4's as 10's and so on until you reach the middle, 7. +But notice in the skewed dice roll, 6 is the most rolled number not 7, and the +rest of the numbers are not symetrical, there are many more 2's than 12's. +So the lesson is test your code. + +The proper way to model a dice throw, in almost every language is + `INT(6*RND(1)+1)` or `INT(6*RND(1))+1` + +SideNote: `X` was used already in the +previous code block discussed but its value was never used. This is another +poor coding practice: **Don't reuse variable names for different purposes.** + + 50 IF X=7 THEN 180 + 55 IF X=11 THEN 180 + 60 IF X=1 THEN 40 + 62 IF X=2 THEN 195 + 65 IF X=0 THEN 40 + 70 IF X=2 THEN 200 + 80 IF X=3 THEN 200 + 90 IF X=12 THEN 200 + 125 IF X=5 THEN 220 + 130 IF X =6 THEN 220 + 140 IF X=8 THEN 220 + 150 IF X=9 THEN 220 + 160 IF X =10 THEN 220 + 170 IF X=4 THEN 220 + +This bit of code determines the routing of where to go for payout, or loss. +Of course, line 60 and 65 are pointless as we've just shown and should be removed +as long as the correct dice algorithm is also changed. + + 62 IF X=2 THEN 195 + .... + 70 IF X=2 THEN 200 +The check for a 2 has already been made and the jump is done. Line 70 is +therefore redundant and can be left out. The purpose of line 62 is only to +print a special output, "SNAKE EYES!" which we'll see in the next block creates +duplicate code. + +Lines 125-170 are also pointlessly checked because we know previous values have +been ruled out, only these last values must remain, and they are all going to +the same place, line 220. Line 125-170 could have simply been replaced with +`GOTO 220` + + + + 180 PRINT X "- NATURAL....A WINNER!!!!" + 185 PRINT X"PAYS EVEN MONEY, YOU WIN"F"DOLLARS" + 190 GOTO 210 + 195 PRINT X"- SNAKE EYES....YOU LOSE." + 196 PRINT "YOU LOSE"F "DOLLARS." + 197 LET F=0-F + 198 GOTO 210 + 200 PRINT X " - CRAPS...YOU LOSE." + 205 PRINT "YOU LOSE"F"DOLLARS." + 206 LET F=0-F + 210 LET R= R+F + 211 GOTO 320 + +This bit of code manages instant wins or losses due to 7,11 or 2,3,12. As +mentioned previously, lines 196 and 197 are essentially the same as lines +205 and 206. A simpler code would be just to jump after printing the special +message of "SNAKE EYES!" to line 205. + +Lines 197 and 206 just negate the wager by subtracting it from zero. Just saying +`F = -F` would have sufficed. Line 210 updates your running total of winnings +or losses with this bet. + + 220 PRINT X "IS THE POINT. I WILL ROLL AGAIN" + 230 LET H=INT(7*RND(1)) + 231 LET Q=INT(7*RND(1)) + 232 LET O=H+Q + 240 IF O=1 THEN 230 + 250 IF O=7 THEN 290 + 255 IF O=0 THEN 230 + +This code sets the point, the number you must re-roll to win without rolling +a 7, the most probable number to roll. Except in this case again, it has the +same incorrect dice rolling code and therefore 6 is the most probable number +to roll. The concept of DRY (don't repeat yourself) is a coding practice which +encourages non-duplication of code because if there is an error in the code, it +can be fixed in one place and not multiple places like in this code. The scenario +might be that a programmer sees some wrong code, fixes it, but neglects to +consider that there might be duplicates of the same wrong code elsewhere. If +you practice DRY then you never worry much about behaviors in your code diverging +due to duplicate code snippets. + + 260 IF O=X THEN 310 + 270 PRINT O " - NO POINT. I WILL ROLL AGAIN" + 280 GOTO 230 + 290 PRINT O "- CRAPS. YOU LOSE." + 291 PRINT "YOU LOSE $"F + 292 F=0-F + 293 GOTO 210 + 300 GOTO 320 + 310 PRINT X"- A WINNER.........CONGRATS!!!!!!!!" + 311 PRINT X "AT 2 TO 1 ODDS PAYS YOU...LET ME SEE..."2*F"DOLLARS" + 312 LET F=2*F + 313 GOTO 210 + +This is the code to keep rolling until the point is made or a seven is rolled. +Again we see the negated `F` wager and lose message duplicated. This code could +have been reorganized using a subroutine, or in BASIC, the GOSUB command, but +in your language its most likely just known as a function or method. You can +do a `grep -r 'GOSUB'` from the root directory to see other BASIC programs in +this set that use GOSUB. + +The rest of the code if fairly straight forward, replay the game or end with +a report of your winnings or losings. + + + diff --git a/29_Craps/distributions.bas b/29_Craps/distributions.bas new file mode 100644 index 00000000..a963b228 --- /dev/null +++ b/29_Craps/distributions.bas @@ -0,0 +1,24 @@ +10 PRINT "DISTRIBUTION OF DICE ROLLS WITH INT(7*RND(1)) VS INT(6*RND(1)+1)" +20 DIM A(12) +30 DIM B(12) +100 FOR X = 1 TO 100000 : REM CHOOSE A LARGE NUMBER TO GET A FINER GRAINED HISTOGRAM +140 REM GET A NUMBER FROM 0 TO 6 INCLUSIVE WITH THE INTENT TO THROW AWAY ZEROES. +150 LET D1 = INT(7*RND(1)) +155 LET D2 = INT(7*RND(1)) +160 LET S1 = D1+D2 +165 REM IF THIS SUM IS LESS THAN TWO THEN TRY AGAIN. +170 IF S1<2 THEN 150 +199 REM GET A NUMBER FROM 0 TO 5 THEN ADD 1 TO IT TO MAKE IT 1 TO 6 +200 LET D3 = INT(6*RND(1))+1 +210 LET D4 = INT(6*RND(1))+1 +220 LET S2 = D3+D4 +245 REM USE OUR ARRAY AS A HISTOGRAM, COUNTING EACH OCCURRENCE OF DICE ROLL +250 A(S1) = A(S1) + 1 +260 B(S2) = B(S2) + 1 +290 NEXT X +300 PRINT "THE INT(7*RND(1)) DISTRIBUTION:" +310 FOR I = 2 TO 12 :PRINT I,:NEXT:PRINT +320 FOR I = 2 TO 12 :PRINT A(I),:NEXT:PRINT +325 PRINT "THE INT(6*RND(1)+1) DISTRIBUTION" +330 FOR I = 2 TO 12 :PRINT I,:NEXT:PRINT +340 FOR I = 2 TO 12 :PRINT B(I),:NEXT:PRINT From b4c8bfc9c8ae609713bdfa0c6024bcf6908e9ce8 Mon Sep 17 00:00:00 2001 From: Joe Nellis Date: Fri, 14 Jan 2022 01:43:24 -0800 Subject: [PATCH 156/337] Java port of BASIC Craps --- 29_Craps/java/src/Craps.java | 125 +++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 29_Craps/java/src/Craps.java diff --git a/29_Craps/java/src/Craps.java b/29_Craps/java/src/Craps.java new file mode 100644 index 00000000..483c16a9 --- /dev/null +++ b/29_Craps/java/src/Craps.java @@ -0,0 +1,125 @@ +import java.util.Random; +import java.util.Scanner; + +/** + * Port of Craps from BASIC to Java 17. + */ +public class Craps { + public static final Random random = new Random(); + + public static void main(String[] args) { + System.out.println(""" + CRAPS + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + + 2,3,12 ARE LOSERS; 4,5,6,8,9,10 ARE POINTS; 7,11 ARE NATURAL WINNERS. + """); + double winnings = 0.0; + do { + winnings = playCraps(winnings); + } while (stillInterested(winnings)); + winningsReport(winnings); + } + + public static double playCraps(double winnings) { + double wager = getWager(); + System.out.println("I WILL NOW THROW THE DICE"); + int roll = rollDice(); + double payout = switch (roll) { + case 7, 11 -> naturalWin(roll, wager); + case 2, 3, 12 -> lose(roll, wager); + default -> setPoint(roll, wager); + }; + return winnings + payout; + } + + public static int rollDice() { + return random.nextInt(1, 7) + random.nextInt(1, 7); + } + + private static double setPoint(int point, double wager) { + System.out.printf("%1$ d IS THE POINT. I WILL ROLL AGAIN%n",point); + return makePoint(point, wager); + } + + private static double makePoint(int point, double wager) { + int roll = rollDice(); + if (roll == 7) + return lose(roll, wager); + if (roll == point) + return win(roll, wager); + System.out.printf("%1$ d - NO POINT. I WILL ROLL AGAIN%n", roll); + return makePoint(point, wager); // recursive + } + + private static double win(int roll, double wager) { + double payout = 2 * wager; + System.out.printf("%1$ d - A WINNER.........CONGRATS!!!!!!!!%n", roll); + System.out.printf("%1$ d AT 2 TO 1 ODDS PAYS YOU...LET ME SEE...$%2$3.2f%n", + roll, payout); + return payout; + } + + private static double lose(int roll, double wager) { + String msg = roll == 2 ? "SNAKE EYES.":"CRAPS"; + System.out.printf("%1$ d - %2$s...YOU LOSE.%n", roll, msg); + System.out.printf("YOU LOSE $%3.2f%n", wager); + return -wager; + } + + public static double naturalWin(int roll, double wager) { + System.out.printf("%1$ d - NATURAL....A WINNER!!!!%n", roll); + System.out.printf("%1$ d PAYS EVEN MONEY, YOU WIN $%2$3.2f%n", roll, wager); + return wager; + } + + public static void winningsUpdate(double winnings) { + System.out.println(switch ((int) Math.signum(winnings)) { + case 1 -> "YOU ARE NOW AHEAD $%3.2f".formatted(winnings); + case 0 -> "YOU ARE NOW EVEN AT 0"; + default -> "YOU ARE NOW UNDER $%3.2f".formatted(-winnings); + }); + } + + public static void winningsReport(double winnings) { + System.out.println( + switch ((int) Math.signum(winnings)) { + case 1 -> "CONGRATULATIONS---YOU CAME OUT A WINNER. COME AGAIN!"; + case 0 -> "CONGRATULATIONS---YOU CAME OUT EVEN, NOT BAD FOR AN AMATEUR"; + default -> "TOO BAD, YOU ARE IN THE HOLE. COME AGAIN."; + } + ); + } + + public static boolean stillInterested(double winnings) { + System.out.print(" IF YOU WANT TO PLAY AGAIN PRINT 5 IF NOT PRINT 2 "); + int fiveOrTwo = (int)getInput(); + winningsUpdate(winnings); + return fiveOrTwo == 5; + } + + public static double getWager() { + System.out.print("INPUT THE AMOUNT OF YOUR WAGER. "); + return getInput(); + } + + public static double getInput() { + Scanner scanner = new Scanner(System.in); + System.out.print("> "); + while (true) { + try { + return scanner.nextDouble(); + } catch (Exception ex) { + try { + scanner.nextLine(); // flush whatever this non number stuff is. + } catch (Exception ns_ex) { // received EOF (ctrl-d or ctrl-z if windows) + System.out.println("END OF INPUT, STOPPING PROGRAM."); + System.exit(1); + } + } + System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE"); + System.out.print("> "); + } + } +} From 3b082b4db98b178f5db65c4e97dc66b35f451779 Mon Sep 17 00:00:00 2001 From: Alessandro Tegner Date: Fri, 14 Jan 2022 09:32:16 -0300 Subject: [PATCH 157/337] Chief in Ruby --- 25_Chief/ruby/chief.rb | 98 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 25_Chief/ruby/chief.rb diff --git a/25_Chief/ruby/chief.rb b/25_Chief/ruby/chief.rb new file mode 100644 index 00000000..c60b2519 --- /dev/null +++ b/25_Chief/ruby/chief.rb @@ -0,0 +1,98 @@ +def tab(size) + str = '' + size.times do + str += ' ' + end + + str +end + +def input + gets.chomp +end + +def bye + print "BYE!!!\n" +end + +def main + print tab(30), "CHIEF\n" + print tab(15), "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n" + print "\n" + print "\n" + print "\n" + print "I AM CHIEF NUMBERS FREEK, THE GREAT INDIAN MATH GOD.\n" + print "ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR\n" + + a = input + if a != 'YES' + print "SHUT UP, PALE FACE WITH WISE TONGUE.\n" + end + + print " TAKE A NUMBER AND ADD 3. DIVIDE THIS NUMBER BY 5 AND\n" + print "MULTIPLY BY 8. DIVIDE BY 5 AND ADD THE SAME. SUBTRACT 1.\n" + print " WHAT DO YOU HAVE\n" + + b = input.to_f + c = ((b + 1 - 5) * 5 / 8 * 5 -3).to_f + print "I BET YOUR NUMBER WAS #{c}. AM I RIGHT\n" + + d = input + if d == 'YES' + return bye + end + + print "WHAT WAS YOUR ORIGINAL NUMBER\n" + + k = input.to_f + f = k + 3 + g = f / 5 + h = g * 8 + i = h / 5 + 5 + j = i - 1 + + print "SO YOU THINK YOU'RE SO SMART, EH?\n" + print "NOW WATCH.\n" + print k, " PLUS 3 EQUALS ", f, ". THIS DIVIDED BY 5 EQUALS ", g, ";\n" + print "THIS TIMES 8 EQUALS ", h, ". IF WE DIVIDE BY 5 AND ADD 5,\n" + print "WE GET ", i, ", WHICH, MINUS 1, EQUALS ", j, ".\n" + print "NOW DO YOU BELIEVE ME\n" + + z = input + if z == 'YES' + return bye + end + + print "YOU HAVE MADE ME MAD!!!\n" + print "THERE MUST BE A GREAT LIGHTNING BOLT!\n" + print "\n" + print "\n" + + x = 30 + while x >= 22 + print tab(x), "X X\n" + x -= 1 + end + + print tab(21), "X XXX\n" + print tab(20), "X X\n" + print tab(19), "XX X\n" + + y = 20 + while y >= 13 + print tab(y), "X X\n" + y -= 1 + end + + print tab(12), "XX\n" + print tab(11), "X\n" + print tab(10), "*\n" + + print "\n" + print "#########################\n" + print "\n" + print "I HOPE YOU BELIEVE ME NOW, FOR YOUR SAKE!!\n" + return bye +end + +main From f9a9a791e2e82f576cea7ef7dedb9845bfd902c5 Mon Sep 17 00:00:00 2001 From: markbernard Date: Fri, 14 Jan 2022 09:54:49 -0500 Subject: [PATCH 158/337] Add Notepad++ syntax colouring for Vintage BASIC. --- 00_Utilities/VintageBASIC.xml | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 00_Utilities/VintageBASIC.xml diff --git a/00_Utilities/VintageBASIC.xml b/00_Utilities/VintageBASIC.xml new file mode 100644 index 00000000..4b49b888 --- /dev/null +++ b/00_Utilities/VintageBASIC.xml @@ -0,0 +1,64 @@ + + + + + + + + 00REM 01 02 03 04 + + + + + + + + - + ^ * / = <> < > <= >= + + + + + + + + + + + DATA DEF FN DIM END FOR GOSUB GOTO IF THEN INPUT LET NEXT ON PRINT RANDOMIZE REM RESTORE RETURN STOP TO + ABS ASC ATN CHR$ COS EXP INT LEFT$ LEN LOG MID$ RIGHT$ RND SGN SIN SPC SQR STR TAB TAN VAL + NOT AND OR + + + + + + 00" 01 02" 03( 04 05) 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f6c6065bdd51f4ebbbc8222b9b02f083aa15be64 Mon Sep 17 00:00:00 2001 From: Nezumi Ronin Date: Fri, 14 Jan 2022 11:31:02 -0600 Subject: [PATCH 159/337] Create gomoko.pl Original "intelligent move" it's awful. Seems it only move below user. --- 40_Gomoko/perl/gomoko.pl | 121 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 40_Gomoko/perl/gomoko.pl diff --git a/40_Gomoko/perl/gomoko.pl b/40_Gomoko/perl/gomoko.pl new file mode 100644 index 00000000..9bd2f3db --- /dev/null +++ b/40_Gomoko/perl/gomoko.pl @@ -0,0 +1,121 @@ +#!/usr/bin/perl +use strict; + + +print ' 'x 33 . "GOMOKO\n"; +print ' 'x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; +print "\n"; print "\n"; print "\n"; +#my @A; +print "WELCOME TO THE ORIENTAL GAME OF GOMOKO.\n"; +print "\n"; print "THE GAME IS PLAYED ON AN N BY N GRID OF A SIZE\n"; +print "THAT YOU SPECIFY. DURING YOUR PLAY, YOU MAY COVER ONE GRID\n"; +print "INTERSECTION WITH A MARKER. THE OBJECT OF THE GAME IS TO GET\n"; +print "5 ADJACENT MARKERS IN A ROW -- HORIZONTALLY, VERTICALLY, OR\n"; +print "DIAGONALLY. ON THE BOARD DIAGRAM, YOUR MOVES ARE MARKED\n"; +print "WITH A '1' AND THE COMPUTER MOVES WITH A '2'.\n"; +print "\n"; print "THE COMPUTER DOES NOT KEEP TRACK OF WHO HAS WON.\n"; +print "TO END THE GAME, TYPE -1,-1 FOR YOUR MOVE.\n"; print "\n"; + + +my $Ret; +my $I; +my $J; + +my @Board; +my $Size= 0; + + +while (1) { + + do { + $Size= 0; + print "WHAT IS YOUR BOARD SIZE (MIN 7/ MAX 19)"; print "? "; chomp($Size = uc()); + if ($Size<7 || $Size>19) { + $Size=0; + print "I SAID, THE MINIMUM IS 7, THE MAXIMUM IS 19.\n"; + } + } until ($Size); + + #==> Reset Board to zeroes... + for (my $I=1; $I<=$Size; $I++) { + for (my $J=1; $J<=$Size; $J++) { + $Board[$I][$J]= 0; + } + } + + print "\n"; print "WE ALTERNATE MOVES. YOU GO FIRST...\n"; print "\n"; + + while (1) { + do { + print "YOUR PLAY (I,J)"; print "? "; chomp(my $Inp = uc()); + ($I, $J)= split(",", $Inp); + print "\n"; + if ($I==-1) { last; } + $Ret= &ValidMove($I, $J, 1); + } until ($Ret==1); + if ($I==-1) { last; } + $Board[$I][$J]= 1; + + my $X; + my $Y; + my $Found=0; + # REM *** COMPUTER TRIES AN INTELLIGENT MOVE *** + #==> Too complex, original basic code seems only move below user. + $Ret= &ValidMove($I+1, $J); + if ($Ret==1) { + $Found=1; + $X= $I+1; + $Y= $J; + } + + while($Found==0) { + # REM *** COMPUTER TRIES A RANDOM MOVE *** + $X= int($Size*rand(1)+1); + $Y= int($Size*rand(1)+1); + $Ret= &ValidMove($X, $Y, 2); + if ($Ret==1) { $Found= 1; } + }; + $Board[$X][$Y]=2; + + &ShowBoard(); + } + + print "\n"; print "THANKS FOR THE GAME!!\n"; + print "PLAY AGAIN (1 FOR YES, 0 FOR NO)"; print "? "; chomp(my $Q = uc()); + if ($Q==0) { last; } + } + + + +exit; + + +sub ShowBoard { + for (my $I=1; $I<=$Size; $I++) { + print " "; + for (my $J=1; $J<=$Size; $J++) { + print "$Board[$I][$J] "; + } + print "\n"; + } + print "\n"; + return; + } + + +sub ValidMove { + my ($X, $Y, $Val)= @_; + if ($X<1 || $X>$Size || $Y<1 || $Y>$Size) { + if ($Val==1) { print "ILLEGAL MOVE. TRY AGAIN...\n"; } + return 0; + } + if ($Board[$X][$Y]!=0) { + if ($Val==1) { print "SQUARE OCCUPIED. TRY AGAIN...\n"; } + return 0; + } + + #$Board[$X][$Y]= $Val; + return 1; + } + + From 697697228d38520bec7bb71993d8272a4793283b Mon Sep 17 00:00:00 2001 From: imiro Date: Fri, 14 Jan 2022 12:41:42 -0600 Subject: [PATCH 160/337] 67-One Check on Python --- 67_One_Check/python/onecheck.py | 115 ++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 67_One_Check/python/onecheck.py diff --git a/67_One_Check/python/onecheck.py b/67_One_Check/python/onecheck.py new file mode 100644 index 00000000..b3d828b1 --- /dev/null +++ b/67_One_Check/python/onecheck.py @@ -0,0 +1,115 @@ +# ONE CHECK + +# Port to python by imiro + +def tab(x): + return ' '*x + +def main(): + + # Initial instructions + print(tab(30) + "ONE CHECK"); + print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + print(); + print(); + print(); + print("SOLITAIRE CHECKER PUZZLE BY DAVID AHL"); + print(); + print("48 CHECKERS ARE PLACED ON THE 2 OUTSIDE SPACES OF A"); + print("STANDARD 64-SQUARE CHECKERBOARD. THE OBJECT IS TO"); + print("REMOVE AS MANY CHECKERS AS POSSIBLE BY DIAGONAL JUMPS"); + print("(AS IN STANDARD CHECKERS). USE THE NUMBERED BOARD TO"); + print("INDICATE THE SQUARE YOU WISH TO JUMP FROM AND TO. ON"); + print("THE BOARD PRINTED OUT ON EACH TURN '1' INDICATES A"); + print("CHECKER AND '0' AN EMPTY SQUARE. WHEN YOU HAVE NO"); + print("POSSIBLE JUMPS REMAINING, INPUT A '0' IN RESPONSE TO"); + print("QUESTION 'JUMP FROM ?'"); + print(); + print("HERE IS THE NUMERICAL BOARD:"); + print(); + + while(True): + for j in range(1,64,8): + for i in range(j,j+7): + print(i, end=(' '*(3 if i < 10 else 2))) + print(j+7) + print() + print("AND HERE IS THE OPENING POSITION OF THE CHECKERS.") + print() + + (jumps, left) = play_game() + + print() + print("YOU MADE " + jumps + " JUMPS AND HAD " + left + " PIECES") + print("REMAINING ON THE BOARD.") + print() + + if not(try_again()): + break + + print() + print("O.K. HOPE YOU HAD FUN!!") + +def play_game(): + # Initialize board + # Give more than 64 elements to accomodate 1-based indexing + board = [1]*70 + for j in range(19,44,8): + for i in range(j,j+4): + board[i] = 0 + jumps = 0 + while True: + # print board + for j in range(1,64,8): + for i in range(j,j+7): + print(board[i], end=' ') + print(board[j+7]) + print() + + while True: + print("JUMP FROM", end=' ') + f = input() + f = int(f) + if f == 0: + break + print("TO", end=' ') + t = input() + t = int(t) + print() + + # Check legality of move + f1 = ((f-1) // 8) + f2 = f - 8 * f1 + t1 = ((t-1) // 8) + t2 = t - 8 * t1 + if (f1 > 7 or t1 > 7 or f2 > 8 or t2 > 8 or abs(f1 - t1) != 2 or + abs(f2 - t2) != 2 or board[(t + f) // 2] == 0 or + board[f] == 0 or board[t] == 1): + print("ILLEGAL MOVE. TRY AGAIN...") + continue + break + + if(f == 0): + break + board[t] = 1 + board[f] = 0 + board[(t+f) // 2] = 0 + jumps = jumps + 1 + + left = 0 + for i in range(1,64+1): + left = left + board[i] + return (str(jumps), str(left)) + +def try_again(): + print("TRY AGAIN", end=' ') + answer = input() + if (answer.upper() == "YES"): + return True + elif (answer.upper() == "NO"): + return False + print("PLEASE ANSWER 'YES' OR 'NO'.") + try_again() + +if __name__ == '__main__': + main() From cb2aeed07cef61000fc5d15234666241bcd40e1c Mon Sep 17 00:00:00 2001 From: Joe Nellis Date: Fri, 14 Jan 2022 12:36:11 -0800 Subject: [PATCH 161/337] Fix dice roll computation. Remove obscure input prompt for random number generation scrambling. --- 29_Craps/javascript/craps.js | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/29_Craps/javascript/craps.js b/29_Craps/javascript/craps.js index 93351011..108f6067 100644 --- a/29_Craps/javascript/craps.js +++ b/29_Craps/javascript/craps.js @@ -42,6 +42,11 @@ function tab(space) return str; } +function roll() +{ + return Math.floor(6 * Math.random())+1 + Math.floor(6 * Math.random())+1; +} + // Main program async function main() { @@ -52,22 +57,11 @@ async function main() print("\n"); r = 0; print("2,3,12 ARE LOSERS: 4,5,6,8,9,10 ARE POINTS: 7,11 ARE NATURAL WINNERS.\n"); - t = 1; - print("PICK A NUMBER AND INPUT TO ROLL DICE"); - z = parseInt(await input()); - do { - x = Math.random(); - t++; - } while (t <= z) ; while (1) { print("INPUT THE AMOUNT OF YOUR WAGER."); f = parseInt(await input()); print("I WILL NOW THROW THE DICE\n"); - do { - e = Math.floor(7 * Math.random()); - s = Math.floor(7 * Math.random()); - x = e + s; - } while (x == 0 || x == 1) ; + x = roll(); if (x == 7 || x == 11) { print(x + " - NATURAL....A WINNER!!!!\n"); print(x + " PAYS EVEN MONEY, YOU WIN " + f + " DOLLARS\n"); @@ -83,11 +77,7 @@ async function main() } else { print(x + " IS THE POINT. I WILL ROLL AGAIN\n"); while (1) { - do { - h = Math.floor(7 * Math.random()); - q = Math.floor(7 * Math.random()); - o = h + q; - } while (o == 0 || o == 1) ; + o = roll(); if (o == 7) { print(o + " - CRAPS, YOU LOSE.\n"); print("YOU LOSE $" + f + "\n"); From db0b1ffe4e976a5b18bcf9e6d7862756b8d0835d Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 16 Jan 2022 01:48:34 +1100 Subject: [PATCH 162/337] Add bug descriptions discovered by Jack Boyce in Super Star Trek to the main game description. --- 84_Super_Star_Trek/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/84_Super_Star_Trek/README.md b/84_Super_Star_Trek/README.md index 77fae3d8..28bd3c03 100644 --- a/84_Super_Star_Trek/README.md +++ b/84_Super_Star_Trek/README.md @@ -88,6 +88,17 @@ The relation between the Historical and Standard nomenclatures is shown in the s 15. This version of Star Trek was created for a Data General Nova 800 system with 32K or core. So that it would fit, the instructions are separated from the main program via a CHAIN. For conversion to DEC BASIC-PLUS, Statement 160 (Randomize) should be moved after the return from the chained instructions, say to Statement 245. For Altair BASIC, Randomize and the chain instructions should be eliminated. +--- +#### Bugs + +Many of the programs in this book and this collection have bugs in the original code. + +Jack Boyce has discovered and fixed a number of bugs in his [python implementation](python/superstartrek.py), which should be noted by other implementers: + +- line `4410` : `D(7)` should be `D(6)` +- lines `8310`,`8330`,`8430`,`8450` : Division by zero is possible +- line `440` : `B9` should be initialised to 0, not 2 + --- As published in Basic Computer Games (1978): From 1085d282fff2f6d369ed302b278b4e15c4113eba Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sat, 15 Jan 2022 16:32:12 +0000 Subject: [PATCH 163/337] Clean up YES/NO input and validation --- 27_Civil_War/java/src/CivilWar.java | 70 ++++++++++++++++++----------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java index fa6cd27a..bdf1bff6 100644 --- a/27_Civil_War/java/src/CivilWar.java +++ b/27_Civil_War/java/src/CivilWar.java @@ -1,6 +1,7 @@ import java.io.PrintStream; import java.util.List; import java.util.Scanner; +import java.util.function.Predicate; import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; @@ -46,6 +47,9 @@ public class CivilWar { private double R; private boolean wantBattleDescriptions; + private final static String YES_NO_REMINDER = "(ANSWER YES OR NO)"; + private final static Predicate YES_NO_CHECKER = i -> isYes(i) || isNo(i); + /** * ORIGINAL GAME DESIGN: CRAM, GOODIE, HIBBARD LEXINGTON H.S. * MODIFICATIONS: G. PAUL, R. HESS (TIES), 1973 @@ -58,16 +62,11 @@ public class CivilWar { System.out.print("DO YOU WANT INSTRUCTIONS? "); - var terminalInput = new Scanner(System.in); - String s = terminalInput.nextLine(); - switch (s) { - case "Y" -> { - x.showHelp(); - x.gameLoop(); - } - case "N" -> x.gameLoop(); - default -> System.out.println("YES OR NO -- "); + if (isYes(inputString(YES_NO_CHECKER, YES_NO_REMINDER))) { + x.showHelp(); } + + x.gameLoop(); } private void gameLoop() { @@ -76,19 +75,13 @@ public class CivilWar { out.println(); out.print("ARE THERE TWO GENERALS PRESENT (ANSWER YES OR NO)? "); - var terminalInput = new Scanner(System.in); - String twoGeneralsAnswer = terminalInput.nextLine(); - switch (twoGeneralsAnswer) { - case "YES" -> this.numGenerals = 2; - case "NO" -> { - this.numGenerals = 1; - out.println(); - out.println("YOU ARE THE CONFEDERACY. GOOD LUCK!"); - out.println(); - } - default -> { - // FIXME Retry! - } + if (isYes(inputString(YES_NO_CHECKER, YES_NO_REMINDER))) { + this.numGenerals = 2; + } else { + this.numGenerals = 1; + out.println(); + out.println("YOU ARE THE CONFEDERACY. GOOD LUCK!"); + out.println(); } out.println("SELECT A BATTLE BY TYPING A NUMBER FROM 1 TO 14 ON"); @@ -101,9 +94,8 @@ public class CivilWar { out.println(); out.print("AFTER REQUESTING A BATTLE, DO YOU WISH BATTLE DESCRIPTIONS (ANSWER YES OR NO)? "); - String descriptionsAnswer = terminalInput.nextLine(); - this.wantBattleDescriptions = descriptionsAnswer.equals("YES"); - // FIXME Retry if not "YES" or "NO" + + this.wantBattleDescriptions = isYes(inputString(YES_NO_CHECKER, YES_NO_REMINDER)); while (true) { var battle = startBattle(); @@ -584,6 +576,34 @@ public class CivilWar { return rightAlignInt((int) Math.floor(number)); } + private static String inputString(Predicate validator, String reminder) { + var terminalInput = new Scanner(System.in); + + while (true) { + var input = terminalInput.nextLine(); + if (validator.test(input)) { + return input; + } + System.out.println(reminder); + } + } + + private static boolean isYes(String s) { + if (s == null) { + return false; + } + var uppercase = s.toUpperCase(); + return uppercase.equals("Y") || uppercase.equals("YES"); + } + + private static boolean isNo(String s) { + if (s == null) { + return false; + } + var uppercase = s.toUpperCase(); + return uppercase.equals("N") || uppercase.equals("NO"); + } + private static class BattleState { private final HistoricalDatum data; private double F1; From e18ff85b2e26340a1ad3dfd4d4c969905c265524 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Sat, 15 Jan 2022 22:17:29 +0200 Subject: [PATCH 164/337] Add all .vs folders in hierarchy to gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3412076c..078ff6f9 100644 --- a/.gitignore +++ b/.gitignore @@ -31,5 +31,4 @@ out/ Pipfile .DS_Store -/.vs/basic-computer-games/v16 -/.vs +.vs/ From df95ff0eff9d90310fe376f6bf6e01502199c32f Mon Sep 17 00:00:00 2001 From: Mark Wieder Date: Sat, 15 Jan 2022 13:16:28 -0800 Subject: [PATCH 165/337] Cube in ruby --- 30_Cube/ruby/cube.rb | 261 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 30_Cube/ruby/cube.rb diff --git a/30_Cube/ruby/cube.rb b/30_Cube/ruby/cube.rb new file mode 100644 index 00000000..a881986e --- /dev/null +++ b/30_Cube/ruby/cube.rb @@ -0,0 +1,261 @@ +$landmines = Array.new + +$currentLocation = "111" + +$standings = 500 # starting amount + +def getYesOrNoResponseTo prompt + print prompt + # strip leading and trailing whitespace from entry + yesno = gets.strip.upcase[0] + yesno == "Y" +end + +def greeting + puts "CUBE".center(80) + puts "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY".center(80) + puts "\n\n\n" + response = getYesOrNoResponseTo "Do you want to see the INSTRUCTIONS?" + if response + puts "This is a game in which you will be playing against the" + puts "random decision of the computer. The field of play is a" + puts "cube of size 3. Any of your 27 locations can be designated" + puts "by inputting three numbers such as 231." + puts "At the start you are automatically at location 1,1,1.\n" + puts "The object of the game is to get to location 3,3,3.\n" + + puts "\nONE MINOR DETAIL:" + puts "The computer will pick five random locations at which it will" + puts "plant land mines. if you hit one of these locations you lose.\n" + + puts "\nONE OTHER DETAIL:" + puts "You may move only one space in one direction each move." + puts "For example: from 1,1,2 you may move to 2,1,2 or 1,1,3." + puts "You may not change more than one number on the same move." + puts "If you make an illegal move, you lose and the computer takes" + puts "the money you may have bet on that round." + puts "" + puts "When stating the amount of a wager, enter only the number" + puts "of dollars (example: 250) You are automatically started with" + puts "500 dollars in your account." + puts + puts "Good luck!" + end +end + +def landMindStringFrom x, y, z + landMine = x.to_s + y.to_s + z.to_s + return landMine +end + +def assignLandMines + $landmines.clear + + # put five unique entries into the landmines array + while $landmines.size < 5 do + a = rand(3)+1 + b = rand(3)+1 + c = rand(3)+1 + landmine = landMindStringFrom(a, b, c) + if !$landmines.include?(landmine) && landmine != "333" +# puts landmine # debugging + $landmines.push landmine + end + end + $currentLocation = "111" +end + +def initializePot + $standings = 500 # starting amount +end + +def startGame + assignLandMines + displayStandings + response = getYesOrNoResponseTo "WANT TO MAKE A WAGER? " + if response + print "HOW MUCH? " + while true do + wager = gets.strip.tr('^0-9', '').to_i + if $standings < wager + puts "TRIED TO FOOL ME; BET AGAIN "; + else + break + end + end + else + wager = 0 + end + + # start at location 1,1,1 + $currentLocation = "111" + return wager +end + +def goodbye + puts "TOUGH LUCK!" + puts "" + puts "GOODBYE." + exit +end + +def bust + puts "YOU BUST." + goodbye +end + +def tryAgain + again = getYesOrNoResponseTo "WANT TO TRY AGAIN? " + if not again + exit + end +end + +def isLegalMove? newLocation + # test for illegal moves + # can only change one variable per move + # newLocation is the proposed new position + # can only move one space from the current position + + moveX = newLocation[0].to_i + moveY = newLocation[1].to_i + moveZ = newLocation[2].to_i + + # currentX, currentY, currentZ contains the current position + currentX = $currentLocation[0].to_i + currentY = $currentLocation[1].to_i + currentZ = $currentLocation[2].to_i + + isLegalMove = true + errorString = "" + # ensure we're not moving off the cube + if not (moveX.between?(1,3) && moveY.between?(1,3) && moveZ.between?(1,3)) + errorString = "You moved off the cube!" + return errorString + end + + # test for only one move from current position + if not moveX.between?(currentX-1,currentX+1) + isLegalMove = false + end + if not moveY.between?(currentY-1,currentY+1) + isLegalMove = false + end + if not moveZ.between?(currentZ-1,currentZ+1) + isLegalMove = false + end + if not isLegalMove + errorString = "You've gone too far" + end + + # only allow change to one variable at a time + if isLegalMove + if moveX != currentX + if moveY != currentY or moveZ != currentZ + isLegalMove = false + end + end + if moveY != currentY + if moveX != currentX or moveZ != currentZ + isLegalMove = false + end + end + if moveZ != currentZ + if moveY != currentY or moveX != currentX + isLegalMove = false + end + end + if not isLegalMove + errorString = "You made too many changes" + end + end + + return errorString +end + +def displayStandings + print "You now have " + $standings.to_s + if $standings > 1 + puts " dollars" + else + puts " dollar" + end +end + +def didWin? location + location == "333" +end + +def youWin amount + $standings += amount + puts "*** You win " + amount.to_s + " dollars! ***\n\n" + displayStandings + tryAgain + assignLandMines + puts "*** new cube ***" + puts "different landmine locations" + puts "starting over at location 111" +end + +def youLose amount + # subtract the bet amount from the standings + if amount > 0 + puts "You lose " + amount.to_s + " dollars!\n\n" + $standings -= amount + end + if $standings <= 0 + # no money left, so end the game + bust + else + displayStandings + end + tryAgain + $currentLocation = "111" + puts "starting over at location 111" +end + +def landMine betAmount + puts "******BANG******" + puts "You hit a land mine at " + $currentLocation + "!" + youLose betAmount +end + +def gameLoop betAmount + while true do + puts "" + print "IT'S YOUR MOVE: " + # allow only integers: strip anything else from input + moveToLocation = gets.strip.tr('^0-9', '') + + # test for illegal moves + # can only change one variable per move + # moveToLocation is the proposed new position + + error = isLegalMove?(moveToLocation) + if error == "" + # assign the new position + $currentLocation = moveToLocation + + # test for win + if didWin?(moveToLocation) + youWin betAmount + end + + # haven't won yet, test the land mines + if $landmines.include? moveToLocation + landMine betAmount + end + + else + puts "Illegal move: " + error + youLose betAmount + end + + end +end + + +greeting +initializePot +gameLoop startGame + From 2e82f08efddbda677b161d2d0cf7ee250f561525 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sat, 15 Jan 2022 22:11:45 +0000 Subject: [PATCH 166/337] Improve encapsulation --- 27_Civil_War/java/src/CivilWar.java | 117 +++++++++++++++------------- 1 file changed, 65 insertions(+), 52 deletions(-) diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java index bdf1bff6..ea667890 100644 --- a/27_Civil_War/java/src/CivilWar.java +++ b/27_Civil_War/java/src/CivilWar.java @@ -13,15 +13,9 @@ public class CivilWar { private final List data; private BattleState currentBattle; - private int R1; - private int R2; private final int[] strategies; private int numGenerals; - private final int[] B; - private final int[] F; - private final int[] H; - private final int[] D; - private final double[] O; + private final ArmyPair resources; private int battleNumber; private int Y; private int Y2; @@ -31,10 +25,9 @@ public class CivilWar { private int excessiveUnionLosses; private int L; private int W; - private int M3; - private int M4; - private int Q1; - private int Q2; + private final ArmyPair revenue; + private final ArmyPair totalExpenditure; + private final ArmyPair totalTroops; private double C6; private double E2; private int W0; @@ -42,8 +35,7 @@ public class CivilWar { private int unionTroops; // M6 private boolean confedSurrender; private boolean unionSurrender; - private int I1; - private int I2; + private final ArmyPair inflation; private double R; private boolean wantBattleDescriptions; @@ -152,21 +144,21 @@ public class CivilWar { // INFLATION CALC // REM - ONLY IN PRINTOUT IS CONFED INFLATION = I1+15% - I1 = 10 + (L - W) * 2; - I2 = 10 + (W - L) * 2; + inflation.confederate = 10 + (L - W) * 2; + inflation.union = 10 + (W - L) * 2; // MONEY AVAILABLE - this.D[0] = 100 * (int) Math.floor((battle.troops.confederate * (100.0 - I1) / 2000) * (1 + (R1 - Q1) / (R1 + 1.0)) + .5); + resources.confederate.budget = 100 * (int) Math.floor((battle.troops.confederate * (100.0 - inflation.confederate) / 2000) * (1 + (revenue.confederate - totalExpenditure.confederate) / (revenue.confederate + 1.0)) + .5); // MEN AVAILABLE - this.confedTroops = (int) Math.floor(battle.troops.confederate * (1 + (totalExpectedCasualties.confederate - totalCasualties.confederate) / (M3 + 1.0))); - this.unionTroops = (int) Math.floor(battle.troops.union * (1 + (totalExpectedCasualties.union - totalCasualties.union) / (M4 + 1.0))); + this.confedTroops = (int) Math.floor(battle.troops.confederate * (1 + (totalExpectedCasualties.confederate - totalCasualties.confederate) / (totalTroops.confederate + 1.0))); + this.unionTroops = (int) Math.floor(battle.troops.union * (1 + (totalExpectedCasualties.union - totalCasualties.union) / (totalTroops.union + 1.0))); battleState.F1 = 5 * battle.troops.confederate / 6.0; if (this.numGenerals == 2) { - this.D[1] = 100 * (int) Math.floor((battle.troops.union * (100.0 - I2) / 2000) * (1 + (R2 - Q2) / (R2 + 1.0)) + .5); + resources.union.budget = 100 * (int) Math.floor((battle.troops.union * (100.0 - inflation.union) / 2000) * (1 + (revenue.union - totalExpenditure.union) / (revenue.union + 1.0)) + .5); } else { - this.D[1] = 100 * (int) Math.floor(battle.troops.union * (100.0 - I2) / 2000 + .5); + resources.union.budget = 100 * (int) Math.floor(battle.troops.union * (100.0 - inflation.union) / 2000 + .5); } out.println(); @@ -185,8 +177,8 @@ public class CivilWar { out.println(); out.println(" CONFEDERACY UNION"); out.println("MEN " + confedTroops + " " + unionTroops); - out.println("MONEY $ " + this.D[0] + " $ " + this.D[1]); - out.println("INFLATION " + (I1 + 15) + "% " + I2 + "%"); + out.println("MONEY $ " + resources.confederate.budget + " $ " + resources.union.budget); + out.println("INFLATION " + (inflation.confederate + 15) + "% " + inflation.union + "%"); // ONLY IN PRINTOUT IS CONFED INFLATION = I1+15% // IF TWO GENERALS, INPUT CONFED. FIRST @@ -194,32 +186,36 @@ public class CivilWar { for (int i = 0; i < numGenerals; i++) { out.println(); + ArmyResources currentResources; + if (this.numGenerals == 1 || i == 0) { out.print("CONFEDERATE GENERAL --- "); + currentResources = resources.confederate; } else { out.print("UNION GENERAL --- "); + currentResources = resources.union; } out.println("HOW MUCH DO YOU WISH TO SPEND FOR"); out.print("- FOOD...... ? "); var F = terminalInput.nextInt(); if (F == 0) { - if (this.R1 != 0) { + if (this.revenue.confederate != 0) { out.println("ASSUME YOU WANT TO KEEP SAME ALLOCATIONS"); out.println(); } } - this.F[i] = F; + currentResources.food = F; out.print("- SALARIES.. ? "); - this.H[i] = terminalInput.nextInt(); + currentResources.salaries = terminalInput.nextInt(); out.print("- AMMUNITION ? "); - this.B[i] = terminalInput.nextInt(); // FIXME Retry if -ve + currentResources.ammunition = terminalInput.nextInt(); // FIXME Retry if -ve - if (this.F[i] + this.H[i] + this.B[i] > this.D[i]) { - out.println("THINK AGAIN! YOU HAVE ONLY $" + this.D[i]); + if (currentResources.getTotal() > currentResources.budget) { + out.println("THINK AGAIN! YOU HAVE ONLY $" + currentResources.budget); // FIXME Redo inputs from Food } } @@ -237,17 +233,21 @@ public class CivilWar { private String moraleForArmy(BattleState battleState, int armyIdx) { var builder = new StringBuilder(); + ArmyResources currentResources; + if (this.numGenerals == 1 || armyIdx == 0) { builder.append("CONFEDERATE "); + currentResources = resources.confederate; } else { builder.append("UNION "); + currentResources = resources.union; } // FIND MORALE - this.O[armyIdx] = (2 * Math.pow(F[armyIdx], 2) + Math.pow(H[armyIdx], 2)) / Math.pow(battleState.F1, 2) + 1; - if (this.O[armyIdx] >= 10) { + currentResources.morale = (2 * Math.pow(currentResources.food, 2) + Math.pow(currentResources.salaries, 2)) / Math.pow(battleState.F1, 2) + 1; + if (currentResources.morale >= 10) { builder.append("MORALE IS HIGH"); - } else if (this.O[armyIdx] >= 5) { + } else if (currentResources.morale >= 5) { builder.append("MORALE IS FAIR"); } else { builder.append("MORALE IS POOR"); @@ -295,10 +295,10 @@ public class CivilWar { // 2070 REM : SIMULATED LOSSES-NORTH private void simulatedLosses(HistoricalDatum battle) { C6 = (2.0 * battle.expectedCasualties.union / 5) * (1 + 1.0 / (2 * (Math.abs(Y2 - Y) + 1))); - C6 = C6 * (1.28 + (5.0 * battle.troops.union / 6) / (B[1] + 1)); - C6 = Math.floor(C6 * (1 + 1 / O[1]) + 0.5); + C6 = C6 * (1.28 + (5.0 * battle.troops.union / 6) / (resources.union.ammunition + 1)); + C6 = Math.floor(C6 * (1 + 1 / resources.union.morale) + 0.5); // IF LOSS > MEN PRESENT, RESCALE LOSSES - E2 = 100 / O[1]; + E2 = 100 / resources.union.morale; if (Math.floor(C6 + E2) >= unionTroops) { C6 = Math.floor(13.0 * unionTroops / 20); E2 = 7 * C6 / 13; @@ -313,11 +313,11 @@ public class CivilWar { out.println(" CONFEDERACY UNION"); var C5 = (2 * battle.data.expectedCasualties.confederate / 5) * (1 + 1.0 / (2 * (Math.abs(Y2 - Y) + 1))); - C5 = (int) Math.floor(C5 * (1 + 1.0 / this.O[0]) * (1.28 + battle.F1 / (this.B[0] + 1.0)) + .5); - var E = 100 / O[0]; + C5 = (int) Math.floor(C5 * (1 + 1.0 / resources.confederate.morale) * (1.28 + battle.F1 / (resources.confederate.ammunition + 1.0)) + .5); + var E = 100 / resources.confederate.morale; - if (C5 + 100 / O[0] >= battle.data.troops.confederate * (1 + (totalExpectedCasualties.confederate - totalCasualties.confederate) / (M3 + 1.0))) { - C5 = (int) Math.floor(13.0 * battle.data.troops.confederate / 20 * (1 + (totalExpectedCasualties.union - totalCasualties.confederate) / (M3 + 1.0))); + if (C5 + 100 / resources.confederate.morale >= battle.data.troops.confederate * (1 + (totalExpectedCasualties.confederate - totalCasualties.confederate) / (totalTroops.confederate + 1.0))) { + C5 = (int) Math.floor(13.0 * battle.data.troops.confederate / 20 * (1 + (totalExpectedCasualties.union - totalCasualties.confederate) / (totalTroops.confederate + 1.0))); E = 7 * C5 / 13.0; excessiveConfederateLosses = 1; } @@ -326,7 +326,7 @@ public class CivilWar { if (this.numGenerals == 1) { C6 = (int) Math.floor(17.0 * battle.data.expectedCasualties.union * battle.data.expectedCasualties.confederate / (C5 * 20)); - E2 = 5 * O[0]; + E2 = 5 * resources.confederate.morale; } out.println("CASUALTIES: " + rightAlignInt(C5) + " " + rightAlignInt(C6)); @@ -379,12 +379,12 @@ public class CivilWar { totalCasualties.union += (int) (C6 + E2); totalExpectedCasualties.confederate += battle.data.expectedCasualties.confederate; totalExpectedCasualties.union += battle.data.expectedCasualties.union; - Q1 += F[0] + H[0] + B[0]; - Q2 += F[1] + H[1] + B[1]; - R1 += battle.data.troops.confederate * (100 - I1) / 20; - R2 += battle.data.troops.union * (100 - I2) / 20; - M3 += battle.data.troops.confederate; - M4 += battle.data.troops.union; + totalExpenditure.confederate += resources.confederate.getTotal(); + totalExpenditure.union += resources.union.getTotal(); + revenue.confederate += battle.data.troops.confederate * (100 - inflation.confederate) / 20; + revenue.union += battle.data.troops.union * (100 - inflation.union) / 20; + totalTroops.confederate += battle.data.troops.confederate; + totalTroops.union += battle.data.troops.union; updateStrategies(this.Y); } @@ -420,7 +420,6 @@ public class CivilWar { // FIXME 2960 IF R1=0 THEN 3100 out.println("FOR THE " + (W + L + W0) + " BATTLES FOUGHT (EXCLUDING RERUNS)"); -// out.println(" ", " ", " "); out.println(" CONFEDERACY UNION"); out.println("HISTORICAL LOSSES " + (int) Math.floor(totalExpectedCasualties.confederate + .5) + " " + (int) Math.floor(totalExpectedCasualties.union + .5)); out.println("SIMULATED LOSSES " + (int) Math.floor(totalCasualties.confederate + .5) + " " + (int) Math.floor(totalCasualties.union + .5)); @@ -494,16 +493,17 @@ public class CivilWar { this.totalCasualties = new ArmyPair<>(0, 0); this.totalExpectedCasualties = new ArmyPair<>(0, 0); + this.totalExpenditure = new ArmyPair<>(0, 0); + this.totalTroops = new ArmyPair<>(0, 0); + + this.revenue = new ArmyPair<>(0, 0); + this.inflation = new ArmyPair<>(0, 0); + + this.resources = new ArmyPair<>(new ArmyResources(), new ArmyResources()); // UNION INFO ON LIKELY CONFEDERATE STRATEGY this.strategies = new int[]{25, 25, 25, 25}; - this.F = new int[]{0, 0}; - this.H = new int[]{0, 0}; - this.B = new int[]{0, 0}; - this.D = new int[]{0, 0}; - this.O = new double[]{0, 0}; - // READ HISTORICAL DATA. // HISTORICAL DATA...CAN ADD MORE (STRAT.,ETC) BY INSERTING DATA STATEMENTS AFTER APPRO. INFO, AND ADJUSTING READ this.data = List.of(new HistoricalDatum("BULL RUN", new ArmyPair<>(18000, 18500), new ArmyPair<>(1967, 2708), OffensiveStatus.DEFENSIVE, new String[]{"JULY 21, 1861. GEN. BEAUREGARD, COMMANDING THE SOUTH, MET", "UNION FORCES WITH GEN. MCDOWELL IN A PREMATURE BATTLE AT", "BULL RUN. GEN. JACKSON HELPED PUSH BACK THE UNION ATTACK."}), new HistoricalDatum("SHILOH", new ArmyPair<>(40000, 44894), new ArmyPair<>(10699, 13047), OffensiveStatus.OFFENSIVE, new String[]{"APRIL 6-7, 1862. THE CONFEDERATE SURPRISE ATTACK AT", "SHILOH FAILED DUE TO POOR ORGANIZATION."}), new HistoricalDatum("SEVEN DAYS", new ArmyPair<>(95000, 115000), new ArmyPair<>(20614, 15849), OffensiveStatus.OFFENSIVE, new String[]{"JUNE 25-JULY 1, 1862. GENERAL LEE (CSA) UPHELD THE", "OFFENSIVE THROUGHOUT THE BATTLE AND FORCED GEN. MCCLELLAN", "AND THE UNION FORCES AWAY FROM RICHMOND."}), new HistoricalDatum("SECOND BULL RUN", new ArmyPair<>(54000, 63000), new ArmyPair<>(10000, 14000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"AUG 29-30, 1862. THE COMBINED CONFEDERATE FORCES UNDER", " LEE", "AND JACKSON DROVE THE UNION FORCES BACK INTO WASHINGTON."}), new HistoricalDatum("ANTIETAM", new ArmyPair<>(40000, 50000), new ArmyPair<>(10000, 12000), OffensiveStatus.OFFENSIVE, new String[]{"SEPT 17, 1862. THE SOUTH FAILED TO INCORPORATE MARYLAND", "INTO THE CONFEDERACY."}), new HistoricalDatum("FREDERICKSBURG", new ArmyPair<>(75000, 120000), new ArmyPair<>(5377, 12653), OffensiveStatus.DEFENSIVE, new String[]{"DEC 13, 1862. THE CONFEDERACY UNDER LEE SUCCESSFULLY", "REPULSED AN ATTACK BY THE UNION UNDER GEN. BURNSIDE."}), new HistoricalDatum("MURFREESBORO", new ArmyPair<>(38000, 45000), new ArmyPair<>(11000, 12000), OffensiveStatus.DEFENSIVE, new String[]{"DEC 31, 1862. THE SOUTH UNDER GEN. BRAGG WON A CLOSE BATTLE."}), new HistoricalDatum("CHANCELLORSVILLE", new ArmyPair<>(32000, 90000), new ArmyPair<>(13000, 17197), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"MAY 1-6, 1863. THE SOUTH HAD A COSTLY VICTORY AND LOST", "ONE OF THEIR OUTSTANDING GENERALS, 'STONEWALL' JACKSON."}), new HistoricalDatum("VICKSBURG", new ArmyPair<>(50000, 70000), new ArmyPair<>(12000, 19000), OffensiveStatus.DEFENSIVE, new String[]{"JULY 4, 1863. VICKSBURG WAS A COSTLY DEFEAT FOR THE SOUTH", "BECAUSE IT GAVE THE UNION ACCESS TO THE MISSISSIPPI."}), new HistoricalDatum("GETTYSBURG", new ArmyPair<>(72500, 85000), new ArmyPair<>(20000, 23000), OffensiveStatus.OFFENSIVE, new String[]{"JULY 1-3, 1863. A SOUTHERN MISTAKE BY GEN. LEE AT GETTYSBURG", "COST THEM ONE OF THE MOST CRUCIAL BATTLES OF THE WAR."}), new HistoricalDatum("CHICKAMAUGA", new ArmyPair<>(66000, 60000), new ArmyPair<>(18000, 16000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"SEPT. 15, 1863. CONFUSION IN A FOREST NEAR CHICKAMAUGA LED", "TO A COSTLY SOUTHERN VICTORY."}), new HistoricalDatum("CHATTANOOGA", new ArmyPair<>(37000, 60000), new ArmyPair<>(36700, 5800), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"NOV. 25, 1863. AFTER THE SOUTH HAD SIEGED GEN. ROSENCRANS'", "ARMY FOR THREE MONTHS, GEN. GRANT BROKE THE SIEGE."}), new HistoricalDatum("SPOTSYLVANIA", new ArmyPair<>(62000, 110000), new ArmyPair<>(17723, 18000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"MAY 5, 1864. GRANT'S PLAN TO KEEP LEE ISOLATED BEGAN TO", "FAIL HERE, AND CONTINUED AT COLD HARBOR AND PETERSBURG."}), new HistoricalDatum("ATLANTA", new ArmyPair<>(65000, 100000), new ArmyPair<>(8500, 3700), OffensiveStatus.DEFENSIVE, new String[]{"AUGUST, 1864. SHERMAN AND THREE VETERAN ARMIES CONVERGED", "ON ATLANTA AND DEALT THE DEATH BLOW TO THE CONFEDERACY."})); @@ -623,6 +623,19 @@ public class CivilWar { } } + private static class ArmyResources { + private int food; + private int salaries; + private int ammunition; + private int budget; + + private double morale; // TODO really here? + + public int getTotal() { + return this.food + this.salaries + this.ammunition; + } + } + private record HistoricalDatum(String name, ArmyPair troops, ArmyPair expectedCasualties, OffensiveStatus offensiveStatus, String[] blurb) { From 32efeeb4fe6a5bc75938ba725486abc1f2c7596a Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sat, 15 Jan 2022 22:40:17 +0000 Subject: [PATCH 167/337] Refactor --- 27_Civil_War/java/src/CivilWar.java | 103 ++++++++++++++++------------ 1 file changed, 59 insertions(+), 44 deletions(-) diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java index ea667890..8e13b760 100644 --- a/27_Civil_War/java/src/CivilWar.java +++ b/27_Civil_War/java/src/CivilWar.java @@ -21,21 +21,16 @@ public class CivilWar { private int Y2; private final ArmyPair totalExpectedCasualties; private final ArmyPair totalCasualties; - private int excessiveConfederateLosses; - private int excessiveUnionLosses; - private int L; - private int W; + private boolean excessiveConfederateLosses; + private boolean excessiveUnionLosses; + private final BattleResults results; private final ArmyPair revenue; + private final ArmyPair inflation; private final ArmyPair totalExpenditure; private final ArmyPair totalTroops; - private double C6; - private double E2; - private int W0; - private int confedTroops; // M5 private int unionTroops; // M6 private boolean confedSurrender; private boolean unionSurrender; - private final ArmyPair inflation; private double R; private boolean wantBattleDescriptions; @@ -101,7 +96,6 @@ public class CivilWar { unionStrategy(); - simulatedLosses(battle.data); calcLosses(battle); reset(); @@ -140,18 +134,18 @@ public class CivilWar { var battleState = new BattleState(battle); - excessiveConfederateLosses = 0; + excessiveConfederateLosses = false; // INFLATION CALC // REM - ONLY IN PRINTOUT IS CONFED INFLATION = I1+15% - inflation.confederate = 10 + (L - W) * 2; - inflation.union = 10 + (W - L) * 2; + inflation.confederate = 10 + (results.union - results.confederate) * 2; + inflation.union = 10 + (results.confederate - results.union) * 2; // MONEY AVAILABLE resources.confederate.budget = 100 * (int) Math.floor((battle.troops.confederate * (100.0 - inflation.confederate) / 2000) * (1 + (revenue.confederate - totalExpenditure.confederate) / (revenue.confederate + 1.0)) + .5); // MEN AVAILABLE - this.confedTroops = (int) Math.floor(battle.troops.confederate * (1 + (totalExpectedCasualties.confederate - totalCasualties.confederate) / (totalTroops.confederate + 1.0))); + var confedTroops = (int) Math.floor(battle.troops.confederate * (1 + (totalExpectedCasualties.confederate - totalCasualties.confederate) / (totalTroops.confederate + 1.0))); this.unionTroops = (int) Math.floor(battle.troops.union * (1 + (totalExpectedCasualties.union - totalCasualties.union) / (totalTroops.union + 1.0))); battleState.F1 = 5 * battle.troops.confederate / 6.0; @@ -293,17 +287,20 @@ public class CivilWar { } // 2070 REM : SIMULATED LOSSES-NORTH - private void simulatedLosses(HistoricalDatum battle) { - C6 = (2.0 * battle.expectedCasualties.union / 5) * (1 + 1.0 / (2 * (Math.abs(Y2 - Y) + 1))); - C6 = C6 * (1.28 + (5.0 * battle.troops.union / 6) / (resources.union.ammunition + 1)); - C6 = Math.floor(C6 * (1 + 1 / resources.union.morale) + 0.5); + private UnionLosses simulateUnionLosses(HistoricalDatum battle) { + var losses = (2.0 * battle.expectedCasualties.union / 5) * (1 + 1.0 / (2 * (Math.abs(Y2 - Y) + 1))); + losses = losses * (1.28 + (5.0 * battle.troops.union / 6) / (resources.union.ammunition + 1)); + losses = Math.floor(losses * (1 + 1 / resources.union.morale) + 0.5); // IF LOSS > MEN PRESENT, RESCALE LOSSES - E2 = 100 / resources.union.morale; - if (Math.floor(C6 + E2) >= unionTroops) { - C6 = Math.floor(13.0 * unionTroops / 20); - E2 = 7 * C6 / 13; - excessiveUnionLosses = 1; + var moraleFactor = 100 / resources.union.morale; + + if (Math.floor(losses + moraleFactor) >= unionTroops) { + losses = Math.floor(13.0 * unionTroops / 20); + moraleFactor = 7 * losses / 13; + excessiveUnionLosses = true; } + + return new UnionLosses((int) losses, (int) Math.floor(moraleFactor)); } // 2170: CALCULATE SIMULATED LOSSES @@ -319,41 +316,44 @@ public class CivilWar { if (C5 + 100 / resources.confederate.morale >= battle.data.troops.confederate * (1 + (totalExpectedCasualties.confederate - totalCasualties.confederate) / (totalTroops.confederate + 1.0))) { C5 = (int) Math.floor(13.0 * battle.data.troops.confederate / 20 * (1 + (totalExpectedCasualties.union - totalCasualties.confederate) / (totalTroops.confederate + 1.0))); E = 7 * C5 / 13.0; - excessiveConfederateLosses = 1; + excessiveConfederateLosses = true; } ///// 2270 + final UnionLosses unionLosses; + if (this.numGenerals == 1) { - C6 = (int) Math.floor(17.0 * battle.data.expectedCasualties.union * battle.data.expectedCasualties.confederate / (C5 * 20)); - E2 = 5 * resources.confederate.morale; + unionLosses = new UnionLosses((int) Math.floor(17.0 * battle.data.expectedCasualties.union * battle.data.expectedCasualties.confederate / (C5 * 20)), (int) Math.floor(5 * resources.confederate.morale)); + } else { + unionLosses = simulateUnionLosses(battle.data); } - out.println("CASUALTIES: " + rightAlignInt(C5) + " " + rightAlignInt(C6)); - out.println("DESERTIONS: " + rightAlignInt(E) + " " + rightAlignInt(E2)); + out.println("CASUALTIES: " + rightAlignInt(C5) + " " + rightAlignInt(unionLosses.losses)); + out.println("DESERTIONS: " + rightAlignInt(E) + " " + rightAlignInt(unionLosses.desertions)); out.println(); if (numGenerals == 2) { out.println("COMPARED TO THE ACTUAL CASUALTIES AT " + battle.data.name); out.println("CONFEDERATE: " + (int) Math.floor(100 * (C5 / (double) battle.data.expectedCasualties.confederate) + 0.5) + " % OF THE ORIGINAL"); - out.println("UNION: " + (int) Math.floor(100 * (C6 / (double) battle.data.expectedCasualties.union) + 0.5) + " % OF THE ORIGINAL"); + out.println("UNION: " + (int) Math.floor(100 * (unionLosses.losses / (double) battle.data.expectedCasualties.union) + 0.5) + " % OF THE ORIGINAL"); out.println(); // REM - 1 WHO WON - var winner = findWinner(C5 + E, C6 + E2); + var winner = findWinner(C5 + E, unionLosses.losses + unionLosses.desertions); switch (winner) { case UNION -> { out.println("THE UNION WINS " + battle.data.name); - L++; + results.union++; } case CONFED -> { out.println("THE CONFEDERACY WINS " + battle.data.name); - W++; + results.confederate++; } case INDECISIVE -> { out.println("BATTLE OUTCOME UNRESOLVED"); - this.W0++; + results.indeterminate++; } } } else { @@ -361,22 +361,22 @@ public class CivilWar { // FIND WHO WON - if (excessiveConfederateLosses == 1) { + if (excessiveConfederateLosses) { out.println("YOU LOSE " + battle.data.name); if (this.battleNumber != 0) { - L++; + results.union++; } } else { out.println("YOU WIN " + battle.data.name); // CUMULATIVE BATTLE FACTORS WHICH ALTER HISTORICAL RESOURCES AVAILABLE.IF A REPLAY DON'T UPDATE. - W++; + results.confederate++; } } if (this.battleNumber != 0) { totalCasualties.confederate += (int) (C5 + E); - totalCasualties.union += (int) (C6 + E2); + totalCasualties.union += unionLosses.losses + unionLosses.desertions; totalExpectedCasualties.confederate += battle.data.expectedCasualties.confederate; totalExpectedCasualties.union += battle.data.expectedCasualties.union; totalExpenditure.confederate += resources.confederate.getTotal(); @@ -392,7 +392,7 @@ public class CivilWar { // 2790 private void reset() { - excessiveConfederateLosses = excessiveUnionLosses = 0; + excessiveConfederateLosses = excessiveUnionLosses = false; out.println("---------------"); } @@ -405,13 +405,13 @@ public class CivilWar { out.println(); out.println(); out.println(); - out.println("THE CONFEDERACY HAS WON " + this.W + " BATTLES AND LOST " + this.L); + out.println("THE CONFEDERACY HAS WON " + results.confederate + " BATTLES AND LOST " + results.union); if (this.Y2 == 5) { out.println("THE CONFEDERACY HAS WON THE WAR"); } - if (this.Y == 5 || this.W <= this.L) { + if (this.Y == 5 || results.confederate <= results.union) { out.println("THE UNION HAS WON THE WAR"); } @@ -419,7 +419,7 @@ public class CivilWar { // FIXME 2960 IF R1=0 THEN 3100 - out.println("FOR THE " + (W + L + W0) + " BATTLES FOUGHT (EXCLUDING RERUNS)"); + out.println("FOR THE " + results.getTotal() + " BATTLES FOUGHT (EXCLUDING RERUNS)"); out.println(" CONFEDERACY UNION"); out.println("HISTORICAL LOSSES " + (int) Math.floor(totalExpectedCasualties.confederate + .5) + " " + (int) Math.floor(totalExpectedCasualties.union + .5)); out.println("SIMULATED LOSSES " + (int) Math.floor(totalCasualties.confederate + .5) + " " + (int) Math.floor(totalCasualties.union + .5)); @@ -435,15 +435,15 @@ public class CivilWar { } private Winner findWinner(double confLosses, double unionLosses) { - if (this.excessiveConfederateLosses == 1 && this.excessiveUnionLosses == 1) { + if (this.excessiveConfederateLosses && this.excessiveUnionLosses) { return Winner.INDECISIVE; } - if (this.excessiveConfederateLosses == 1) { + if (this.excessiveConfederateLosses) { return Winner.UNION; } - if (this.excessiveUnionLosses == 1 || confLosses < unionLosses) { + if (this.excessiveUnionLosses || confLosses < unionLosses) { return Winner.CONFED; } @@ -491,6 +491,8 @@ public class CivilWar { public CivilWar(PrintStream out) { this.out = out; + this.results = new BattleResults(); + this.totalCasualties = new ArmyPair<>(0, 0); this.totalExpectedCasualties = new ArmyPair<>(0, 0); this.totalExpenditure = new ArmyPair<>(0, 0); @@ -623,6 +625,16 @@ public class CivilWar { } } + private static class BattleResults { + private int confederate; + private int union; + private int indeterminate; + + public int getTotal() { + return confederate + union + indeterminate; + } + } + private static class ArmyResources { private int food; private int salaries; @@ -640,4 +652,7 @@ public class CivilWar { ArmyPair expectedCasualties, OffensiveStatus offensiveStatus, String[] blurb) { } + + private record UnionLosses(int losses, int desertions) { + } } \ No newline at end of file From 48edb2c5d7b0b2a2c724dff3c1184deded10b909 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sat, 15 Jan 2022 22:43:28 +0000 Subject: [PATCH 168/337] Make more readable --- 27_Civil_War/java/src/CivilWar.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java index 8e13b760..ad909f2c 100644 --- a/27_Civil_War/java/src/CivilWar.java +++ b/27_Civil_War/java/src/CivilWar.java @@ -508,7 +508,22 @@ public class CivilWar { // READ HISTORICAL DATA. // HISTORICAL DATA...CAN ADD MORE (STRAT.,ETC) BY INSERTING DATA STATEMENTS AFTER APPRO. INFO, AND ADJUSTING READ - this.data = List.of(new HistoricalDatum("BULL RUN", new ArmyPair<>(18000, 18500), new ArmyPair<>(1967, 2708), OffensiveStatus.DEFENSIVE, new String[]{"JULY 21, 1861. GEN. BEAUREGARD, COMMANDING THE SOUTH, MET", "UNION FORCES WITH GEN. MCDOWELL IN A PREMATURE BATTLE AT", "BULL RUN. GEN. JACKSON HELPED PUSH BACK THE UNION ATTACK."}), new HistoricalDatum("SHILOH", new ArmyPair<>(40000, 44894), new ArmyPair<>(10699, 13047), OffensiveStatus.OFFENSIVE, new String[]{"APRIL 6-7, 1862. THE CONFEDERATE SURPRISE ATTACK AT", "SHILOH FAILED DUE TO POOR ORGANIZATION."}), new HistoricalDatum("SEVEN DAYS", new ArmyPair<>(95000, 115000), new ArmyPair<>(20614, 15849), OffensiveStatus.OFFENSIVE, new String[]{"JUNE 25-JULY 1, 1862. GENERAL LEE (CSA) UPHELD THE", "OFFENSIVE THROUGHOUT THE BATTLE AND FORCED GEN. MCCLELLAN", "AND THE UNION FORCES AWAY FROM RICHMOND."}), new HistoricalDatum("SECOND BULL RUN", new ArmyPair<>(54000, 63000), new ArmyPair<>(10000, 14000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"AUG 29-30, 1862. THE COMBINED CONFEDERATE FORCES UNDER", " LEE", "AND JACKSON DROVE THE UNION FORCES BACK INTO WASHINGTON."}), new HistoricalDatum("ANTIETAM", new ArmyPair<>(40000, 50000), new ArmyPair<>(10000, 12000), OffensiveStatus.OFFENSIVE, new String[]{"SEPT 17, 1862. THE SOUTH FAILED TO INCORPORATE MARYLAND", "INTO THE CONFEDERACY."}), new HistoricalDatum("FREDERICKSBURG", new ArmyPair<>(75000, 120000), new ArmyPair<>(5377, 12653), OffensiveStatus.DEFENSIVE, new String[]{"DEC 13, 1862. THE CONFEDERACY UNDER LEE SUCCESSFULLY", "REPULSED AN ATTACK BY THE UNION UNDER GEN. BURNSIDE."}), new HistoricalDatum("MURFREESBORO", new ArmyPair<>(38000, 45000), new ArmyPair<>(11000, 12000), OffensiveStatus.DEFENSIVE, new String[]{"DEC 31, 1862. THE SOUTH UNDER GEN. BRAGG WON A CLOSE BATTLE."}), new HistoricalDatum("CHANCELLORSVILLE", new ArmyPair<>(32000, 90000), new ArmyPair<>(13000, 17197), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"MAY 1-6, 1863. THE SOUTH HAD A COSTLY VICTORY AND LOST", "ONE OF THEIR OUTSTANDING GENERALS, 'STONEWALL' JACKSON."}), new HistoricalDatum("VICKSBURG", new ArmyPair<>(50000, 70000), new ArmyPair<>(12000, 19000), OffensiveStatus.DEFENSIVE, new String[]{"JULY 4, 1863. VICKSBURG WAS A COSTLY DEFEAT FOR THE SOUTH", "BECAUSE IT GAVE THE UNION ACCESS TO THE MISSISSIPPI."}), new HistoricalDatum("GETTYSBURG", new ArmyPair<>(72500, 85000), new ArmyPair<>(20000, 23000), OffensiveStatus.OFFENSIVE, new String[]{"JULY 1-3, 1863. A SOUTHERN MISTAKE BY GEN. LEE AT GETTYSBURG", "COST THEM ONE OF THE MOST CRUCIAL BATTLES OF THE WAR."}), new HistoricalDatum("CHICKAMAUGA", new ArmyPair<>(66000, 60000), new ArmyPair<>(18000, 16000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"SEPT. 15, 1863. CONFUSION IN A FOREST NEAR CHICKAMAUGA LED", "TO A COSTLY SOUTHERN VICTORY."}), new HistoricalDatum("CHATTANOOGA", new ArmyPair<>(37000, 60000), new ArmyPair<>(36700, 5800), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"NOV. 25, 1863. AFTER THE SOUTH HAD SIEGED GEN. ROSENCRANS'", "ARMY FOR THREE MONTHS, GEN. GRANT BROKE THE SIEGE."}), new HistoricalDatum("SPOTSYLVANIA", new ArmyPair<>(62000, 110000), new ArmyPair<>(17723, 18000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"MAY 5, 1864. GRANT'S PLAN TO KEEP LEE ISOLATED BEGAN TO", "FAIL HERE, AND CONTINUED AT COLD HARBOR AND PETERSBURG."}), new HistoricalDatum("ATLANTA", new ArmyPair<>(65000, 100000), new ArmyPair<>(8500, 3700), OffensiveStatus.DEFENSIVE, new String[]{"AUGUST, 1864. SHERMAN AND THREE VETERAN ARMIES CONVERGED", "ON ATLANTA AND DEALT THE DEATH BLOW TO THE CONFEDERACY."})); + this.data = List.of( + new HistoricalDatum("BULL RUN", new ArmyPair<>(18000, 18500), new ArmyPair<>(1967, 2708), OffensiveStatus.DEFENSIVE, new String[]{"JULY 21, 1861. GEN. BEAUREGARD, COMMANDING THE SOUTH, MET", "UNION FORCES WITH GEN. MCDOWELL IN A PREMATURE BATTLE AT", "BULL RUN. GEN. JACKSON HELPED PUSH BACK THE UNION ATTACK."}), + new HistoricalDatum("SHILOH", new ArmyPair<>(40000, 44894), new ArmyPair<>(10699, 13047), OffensiveStatus.OFFENSIVE, new String[]{"APRIL 6-7, 1862. THE CONFEDERATE SURPRISE ATTACK AT", "SHILOH FAILED DUE TO POOR ORGANIZATION."}), + new HistoricalDatum("SEVEN DAYS", new ArmyPair<>(95000, 115000), new ArmyPair<>(20614, 15849), OffensiveStatus.OFFENSIVE, new String[]{"JUNE 25-JULY 1, 1862. GENERAL LEE (CSA) UPHELD THE", "OFFENSIVE THROUGHOUT THE BATTLE AND FORCED GEN. MCCLELLAN", "AND THE UNION FORCES AWAY FROM RICHMOND."}), + new HistoricalDatum("SECOND BULL RUN", new ArmyPair<>(54000, 63000), new ArmyPair<>(10000, 14000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"AUG 29-30, 1862. THE COMBINED CONFEDERATE FORCES UNDER", " LEE", "AND JACKSON DROVE THE UNION FORCES BACK INTO WASHINGTON."}), + new HistoricalDatum("ANTIETAM", new ArmyPair<>(40000, 50000), new ArmyPair<>(10000, 12000), OffensiveStatus.OFFENSIVE, new String[]{"SEPT 17, 1862. THE SOUTH FAILED TO INCORPORATE MARYLAND", "INTO THE CONFEDERACY."}), + new HistoricalDatum("FREDERICKSBURG", new ArmyPair<>(75000, 120000), new ArmyPair<>(5377, 12653), OffensiveStatus.DEFENSIVE, new String[]{"DEC 13, 1862. THE CONFEDERACY UNDER LEE SUCCESSFULLY", "REPULSED AN ATTACK BY THE UNION UNDER GEN. BURNSIDE."}), + new HistoricalDatum("MURFREESBORO", new ArmyPair<>(38000, 45000), new ArmyPair<>(11000, 12000), OffensiveStatus.DEFENSIVE, new String[]{"DEC 31, 1862. THE SOUTH UNDER GEN. BRAGG WON A CLOSE BATTLE."}), + new HistoricalDatum("CHANCELLORSVILLE", new ArmyPair<>(32000, 90000), new ArmyPair<>(13000, 17197), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"MAY 1-6, 1863. THE SOUTH HAD A COSTLY VICTORY AND LOST", "ONE OF THEIR OUTSTANDING GENERALS, 'STONEWALL' JACKSON."}), + new HistoricalDatum("VICKSBURG", new ArmyPair<>(50000, 70000), new ArmyPair<>(12000, 19000), OffensiveStatus.DEFENSIVE, new String[]{"JULY 4, 1863. VICKSBURG WAS A COSTLY DEFEAT FOR THE SOUTH", "BECAUSE IT GAVE THE UNION ACCESS TO THE MISSISSIPPI."}), + new HistoricalDatum("GETTYSBURG", new ArmyPair<>(72500, 85000), new ArmyPair<>(20000, 23000), OffensiveStatus.OFFENSIVE, new String[]{"JULY 1-3, 1863. A SOUTHERN MISTAKE BY GEN. LEE AT GETTYSBURG", "COST THEM ONE OF THE MOST CRUCIAL BATTLES OF THE WAR."}), + new HistoricalDatum("CHICKAMAUGA", new ArmyPair<>(66000, 60000), new ArmyPair<>(18000, 16000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"SEPT. 15, 1863. CONFUSION IN A FOREST NEAR CHICKAMAUGA LED", "TO A COSTLY SOUTHERN VICTORY."}), + new HistoricalDatum("CHATTANOOGA", new ArmyPair<>(37000, 60000), new ArmyPair<>(36700, 5800), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"NOV. 25, 1863. AFTER THE SOUTH HAD SIEGED GEN. ROSENCRANS'", "ARMY FOR THREE MONTHS, GEN. GRANT BROKE THE SIEGE."}), + new HistoricalDatum("SPOTSYLVANIA", new ArmyPair<>(62000, 110000), new ArmyPair<>(17723, 18000), OffensiveStatus.BOTH_OFFENSIVE, new String[]{"MAY 5, 1864. GRANT'S PLAN TO KEEP LEE ISOLATED BEGAN TO", "FAIL HERE, AND CONTINUED AT COLD HARBOR AND PETERSBURG."}), + new HistoricalDatum("ATLANTA", new ArmyPair<>(65000, 100000), new ArmyPair<>(8500, 3700), OffensiveStatus.DEFENSIVE, new String[]{"AUGUST, 1864. SHERMAN AND THREE VETERAN ARMIES CONVERGED", "ON ATLANTA AND DEALT THE DEATH BLOW TO THE CONFEDERACY."}) + ); } private void showCredits() { From c256a7b0fb085c77eb520e991451cf33a1d3c497 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sat, 15 Jan 2022 22:54:13 +0000 Subject: [PATCH 169/337] Fix budget validation; restore "keep same allocations" --- 27_Civil_War/java/src/CivilWar.java | 38 ++++++++++++++++------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java index ad909f2c..7b8d8b4c 100644 --- a/27_Civil_War/java/src/CivilWar.java +++ b/27_Civil_War/java/src/CivilWar.java @@ -190,27 +190,31 @@ public class CivilWar { currentResources = resources.union; } - out.println("HOW MUCH DO YOU WISH TO SPEND FOR"); - out.print("- FOOD...... ? "); - var F = terminalInput.nextInt(); - if (F == 0) { - if (this.revenue.confederate != 0) { - out.println("ASSUME YOU WANT TO KEEP SAME ALLOCATIONS"); - out.println(); + var validInputs = false; + while (!validInputs) { + out.println("HOW MUCH DO YOU WISH TO SPEND FOR"); + out.print("- FOOD...... ? "); + var food = terminalInput.nextInt(); + if (food == 0) { + if (this.revenue.confederate != 0) { + out.println("ASSUME YOU WANT TO KEEP SAME ALLOCATIONS"); + out.println(); + } + } else { + currentResources.food = food; } - } - currentResources.food = F; + out.print("- SALARIES.. ? "); + currentResources.salaries = terminalInput.nextInt(); - out.print("- SALARIES.. ? "); - currentResources.salaries = terminalInput.nextInt(); + out.print("- AMMUNITION ? "); + currentResources.ammunition = terminalInput.nextInt(); // FIXME Retry if -ve - out.print("- AMMUNITION ? "); - currentResources.ammunition = terminalInput.nextInt(); // FIXME Retry if -ve - - if (currentResources.getTotal() > currentResources.budget) { - out.println("THINK AGAIN! YOU HAVE ONLY $" + currentResources.budget); - // FIXME Redo inputs from Food + if (currentResources.getTotal() > currentResources.budget) { + out.println("THINK AGAIN! YOU HAVE ONLY $" + currentResources.budget); + } else { + validInputs = true; + } } } From b53005727860f312e22fd71db01a77a9e94c84b2 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sat, 15 Jan 2022 23:34:11 +0000 Subject: [PATCH 170/337] More robust validation --- 27_Civil_War/civilwar.bas | 44 +++++++++++++++++++++++------ 27_Civil_War/java/src/CivilWar.java | 26 +++++++++++++---- 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/27_Civil_War/civilwar.bas b/27_Civil_War/civilwar.bas index f8fe9701..f9cb256b 100644 --- a/27_Civil_War/civilwar.bas +++ b/27_Civil_War/civilwar.bas @@ -172,23 +172,47 @@ 1840 PRINT 1850 REM - CHOOSE STRATEGIES 1860 IF B$ <> "YES" THEN 1910 -1870 FOR I=1 TO 2 -1880 ON I GOTO 1890,1920 + + +== 2 +1890 PRINT "CONFEDERATE STRATEGY "; +1920 INPUT Y +1930 IF ABS(Y-3)<3 THEN 1960 +1940 PRINT "STRATEGY";Y;"NOT ALLOWED." +1950 GOTO 1910 +2010 LET Y1=Y + +2020 PRINT "UNION STRATEGY "; +1920 INPUT Y +1930 IF ABS(Y-3)<3 THEN 1960 +1940 PRINT "STRATEGY";Y;"NOT ALLOWED." +1950 GOTO 1910 + + +== 1 1890 PRINT "CONFEDERATE STRATEGY "; -1900 GOTO 1920 -1910 PRINT "YOUR STRATEGY "; 1920 INPUT Y 1930 IF ABS(Y-3)<3 THEN 1960 1940 PRINT "STRATEGY";Y;"NOT ALLOWED." 1950 GOTO 1910 -1960 IF B$="YES" THEN 2000 1970 IF Y=5 THEN 2830 1980 GOSUB 3110 1990 GOTO 2170 -2000 IF I=2 THEN 2040 2010 LET Y1=Y -2020 PRINT "UNION STRATEGY "; -2030 NEXT I + +# 2020 PRINT "UNION STRATEGY "; +# 1920 INPUT Y +# 1930 IF ABS(Y-3)<3 THEN 1960 +# 1940 PRINT "STRATEGY";Y;"NOT ALLOWED." +# 1950 GOTO 1910 +# 1970 IF Y=5 THEN 2830 +# 1980 GOSUB 3110 +# 1990 GOTO 2170 + + + + + 2040 LET Y2=Y 2050 LET Y=Y1 2060 IF Y2=5 THEN 2020 @@ -298,6 +322,7 @@ 3080 PRINT S(1);S(2);S(3);S(4) 3090 REM--------------------------------- 3100 STOP + 3110 REM - UNION STRATEGY IS COMPUTER CHOSEN 3120 PRINT "UNION STRATEGY IS "; 3130 IF A <> 0 THEN 3180 @@ -318,6 +343,9 @@ 3270 LET Y2=I 3280 PRINT Y2 3290 RETURN + + + 3300 REM LEARN PRESENT STRATEGY, START FORGETTING OLD ONES 3310 REM - PRESENT STRATEGY OF SOUTH GAINS 3*S, OTHERS LOSE S 3320 REM PROBABILITY POINTS, UNLESS A STRATEGY FALLS BELOW 5%. diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java index 7b8d8b4c..099a9183 100644 --- a/27_Civil_War/java/src/CivilWar.java +++ b/27_Civil_War/java/src/CivilWar.java @@ -598,17 +598,33 @@ public class CivilWar { } private static String inputString(Predicate validator, String reminder) { - var terminalInput = new Scanner(System.in); - while (true) { - var input = terminalInput.nextLine(); - if (validator.test(input)) { - return input; + try { + var input = new Scanner(System.in).nextLine(); + if (validator.test(input)) { + return input; + } + } catch (InputMismatchException e) { + // Ignore } System.out.println(reminder); } } + private static int inputInt(Predicate validator, Function reminder) { + while (true) { + try { + var input = new Scanner(System.in).nextInt(); + if (validator.test(input)) { + return input; + } + System.out.println(reminder.apply(input)); + } catch (InputMismatchException e) { + System.out.println(reminder.apply(0)); + } + } + } + private static boolean isYes(String s) { if (s == null) { return false; From 416033b8e0e68e2c067746f3b76f19f2898d7cfe Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sat, 15 Jan 2022 23:46:21 +0000 Subject: [PATCH 171/337] Improve battle number validation --- 27_Civil_War/java/src/CivilWar.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java index 099a9183..7733fb7f 100644 --- a/27_Civil_War/java/src/CivilWar.java +++ b/27_Civil_War/java/src/CivilWar.java @@ -1,6 +1,8 @@ import java.io.PrintStream; +import java.util.InputMismatchException; import java.util.List; import java.util.Scanner; +import java.util.function.Function; import java.util.function.Predicate; import static java.util.stream.Collectors.joining; @@ -116,15 +118,14 @@ public class CivilWar { out.println(); out.print("WHICH BATTLE DO YOU WISH TO SIMULATE ? "); - var terminalInput = new Scanner(System.in); - var battleNumber = terminalInput.nextInt(); + var battleNumber = inputInt(i -> i >= 1 || (i == 0 && this.currentBattle != null), i -> "BATTLE " + i + " NOT ALLOWED."); - if (battleNumber == 0 && this.currentBattle != null) { + if (battleNumber == 0) { out.println(this.currentBattle.data.name + " INSTANT REPLAY"); return this.currentBattle; } - if (battleNumber <= 0 || battleNumber > this.data.size()) { + if (battleNumber > this.data.size()) { // TYPE ANY OTHER NUMBER TO END THE SIMULATION return null; } @@ -177,6 +178,8 @@ public class CivilWar { // ONLY IN PRINTOUT IS CONFED INFLATION = I1+15% // IF TWO GENERALS, INPUT CONFED. FIRST + var terminalInput = new Scanner(System.in); + for (int i = 0; i < numGenerals; i++) { out.println(); From 7fc9a1d8dc9024901c51895b965946ed981c379f Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sat, 15 Jan 2022 23:52:09 +0000 Subject: [PATCH 172/337] Changed in error --- 27_Civil_War/civilwar.bas | 44 +++++++-------------------------------- 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/27_Civil_War/civilwar.bas b/27_Civil_War/civilwar.bas index f9cb256b..f8fe9701 100644 --- a/27_Civil_War/civilwar.bas +++ b/27_Civil_War/civilwar.bas @@ -172,47 +172,23 @@ 1840 PRINT 1850 REM - CHOOSE STRATEGIES 1860 IF B$ <> "YES" THEN 1910 - - -== 2 -1890 PRINT "CONFEDERATE STRATEGY "; -1920 INPUT Y -1930 IF ABS(Y-3)<3 THEN 1960 -1940 PRINT "STRATEGY";Y;"NOT ALLOWED." -1950 GOTO 1910 -2010 LET Y1=Y - -2020 PRINT "UNION STRATEGY "; -1920 INPUT Y -1930 IF ABS(Y-3)<3 THEN 1960 -1940 PRINT "STRATEGY";Y;"NOT ALLOWED." -1950 GOTO 1910 - - -== 1 +1870 FOR I=1 TO 2 +1880 ON I GOTO 1890,1920 1890 PRINT "CONFEDERATE STRATEGY "; +1900 GOTO 1920 +1910 PRINT "YOUR STRATEGY "; 1920 INPUT Y 1930 IF ABS(Y-3)<3 THEN 1960 1940 PRINT "STRATEGY";Y;"NOT ALLOWED." 1950 GOTO 1910 +1960 IF B$="YES" THEN 2000 1970 IF Y=5 THEN 2830 1980 GOSUB 3110 1990 GOTO 2170 +2000 IF I=2 THEN 2040 2010 LET Y1=Y - -# 2020 PRINT "UNION STRATEGY "; -# 1920 INPUT Y -# 1930 IF ABS(Y-3)<3 THEN 1960 -# 1940 PRINT "STRATEGY";Y;"NOT ALLOWED." -# 1950 GOTO 1910 -# 1970 IF Y=5 THEN 2830 -# 1980 GOSUB 3110 -# 1990 GOTO 2170 - - - - - +2020 PRINT "UNION STRATEGY "; +2030 NEXT I 2040 LET Y2=Y 2050 LET Y=Y1 2060 IF Y2=5 THEN 2020 @@ -322,7 +298,6 @@ 3080 PRINT S(1);S(2);S(3);S(4) 3090 REM--------------------------------- 3100 STOP - 3110 REM - UNION STRATEGY IS COMPUTER CHOSEN 3120 PRINT "UNION STRATEGY IS "; 3130 IF A <> 0 THEN 3180 @@ -343,9 +318,6 @@ 3270 LET Y2=I 3280 PRINT Y2 3290 RETURN - - - 3300 REM LEARN PRESENT STRATEGY, START FORGETTING OLD ONES 3310 REM - PRESENT STRATEGY OF SOUTH GAINS 3*S, OTHERS LOSE S 3320 REM PROBABILITY POINTS, UNLESS A STRATEGY FALLS BELOW 5%. From 373905adb2a84c524b7aa2e4097a52d83a38b208 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sat, 15 Jan 2022 23:59:42 +0000 Subject: [PATCH 173/337] Refactor / rework Union strategy for simulation --- 27_Civil_War/java/src/CivilWar.java | 51 +++++++++++++++-------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java index 7733fb7f..d65601de 100644 --- a/27_Civil_War/java/src/CivilWar.java +++ b/27_Civil_War/java/src/CivilWar.java @@ -19,8 +19,8 @@ public class CivilWar { private int numGenerals; private final ArmyPair resources; private int battleNumber; - private int Y; - private int Y2; + private int confedStrategy; + private int unionStrategy; private final ArmyPair totalExpectedCasualties; private final ArmyPair totalCasualties; private boolean excessiveConfederateLosses; @@ -96,8 +96,6 @@ public class CivilWar { offensiveLogic(battle.data); - unionStrategy(); - calcLosses(battle); reset(); @@ -280,22 +278,26 @@ public class CivilWar { out.print("YOUR STRATEGY ? "); } - var terminalInput = new Scanner(System.in); - Y = terminalInput.nextInt(); - if (Math.abs(Y - 3) >= 3) { - out.println("STRATEGY " + Y + " NOT ALLOWED."); - // FIXME Proper numeric check!! Not abs - // FIXME Retry Y input + confedStrategy = inputInt(i -> i >= 1 && i <= 5, i -> "STRATEGY " + i + " NOT ALLOWED."); + if (confedStrategy == 5) { // 1970 + confedSurrender = true; } - if (Y == 5) { // 1970 - confedSurrender = true; + if (numGenerals == 2) { + out.print("UNION STRATEGY ? "); + + unionStrategy = inputInt(i -> i >= 1 && i <= 5, i -> "STRATEGY " + i + " NOT ALLOWED."); + if (unionStrategy == 5) { // 1970 + unionSurrender = true; + } + } else { + unionStrategy(); } } // 2070 REM : SIMULATED LOSSES-NORTH private UnionLosses simulateUnionLosses(HistoricalDatum battle) { - var losses = (2.0 * battle.expectedCasualties.union / 5) * (1 + 1.0 / (2 * (Math.abs(Y2 - Y) + 1))); + var losses = (2.0 * battle.expectedCasualties.union / 5) * (1 + 1.0 / (2 * (Math.abs(unionStrategy - confedStrategy) + 1))); losses = losses * (1.28 + (5.0 * battle.troops.union / 6) / (resources.union.ammunition + 1)); losses = Math.floor(losses * (1 + 1 / resources.union.morale) + 0.5); // IF LOSS > MEN PRESENT, RESCALE LOSSES @@ -316,7 +318,7 @@ public class CivilWar { out.println(); out.println(" CONFEDERACY UNION"); - var C5 = (2 * battle.data.expectedCasualties.confederate / 5) * (1 + 1.0 / (2 * (Math.abs(Y2 - Y) + 1))); + var C5 = (2 * battle.data.expectedCasualties.confederate / 5) * (1 + 1.0 / (2 * (Math.abs(unionStrategy - confedStrategy) + 1))); C5 = (int) Math.floor(C5 * (1 + 1.0 / resources.confederate.morale) * (1.28 + battle.F1 / (resources.confederate.ammunition + 1.0)) + .5); var E = 100 / resources.confederate.morale; @@ -393,7 +395,7 @@ public class CivilWar { totalTroops.confederate += battle.data.troops.confederate; totalTroops.union += battle.data.troops.union; - updateStrategies(this.Y); + updateStrategies(this.confedStrategy); } } @@ -414,11 +416,11 @@ public class CivilWar { out.println(); out.println("THE CONFEDERACY HAS WON " + results.confederate + " BATTLES AND LOST " + results.union); - if (this.Y2 == 5) { + if (this.unionStrategy == 5) { out.println("THE CONFEDERACY HAS WON THE WAR"); } - if (this.Y == 5 || results.confederate <= results.union) { + if (this.confedStrategy == 5 || results.confederate <= results.union) { out.println("THE UNION HAS WON THE WAR"); } @@ -466,16 +468,17 @@ public class CivilWar { } private void unionStrategy() { - if (this.battleNumber != 0) { + // 3130 ... so you can only input / override Union strategy on re-run?? + if (this.battleNumber == 0) { out.print("UNION STRATEGY ? "); var terminalInput = new Scanner(System.in); - Y2 = terminalInput.nextInt(); - if (Y2 < 0) { + unionStrategy = terminalInput.nextInt(); + if (unionStrategy < 0) { out.println("ENTER 1, 2, 3, OR 4 (USUALLY PREVIOUS UNION STRATEGY)"); // FIXME Retry Y2 input !!! } - if (Y2 < 5) { // 3155 + if (unionStrategy < 5) { // 3155 return; } } @@ -484,15 +487,15 @@ public class CivilWar { this.R = 100 * Math.random(); - for (Y2 = 0; Y2 < 4; Y2++) { - S0 += this.strategies[Y2]; + for (unionStrategy = 1; unionStrategy <= 4; unionStrategy++) { + S0 += this.strategies[unionStrategy - 1]; // IF ACTUAL STRATEGY INFO IS IN PROGRAM DATA STATEMENTS THEN R-100 IS EXTRA WEIGHT GIVEN TO THAT STATEGY. if (R < S0) { break; } } // IF ACTUAL STRAT. IN,THEN HERE IS Y2= HIST. STRAT. - out.println("UNION STRATEGY IS " + Y2); + out.println("UNION STRATEGY IS " + unionStrategy); } public CivilWar(PrintStream out) { From 32f506a9c78c90760d68dbf47ffa34cca755a0ff Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sun, 16 Jan 2022 00:01:21 +0000 Subject: [PATCH 174/337] R => local --- 27_Civil_War/java/src/CivilWar.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java index d65601de..a3992492 100644 --- a/27_Civil_War/java/src/CivilWar.java +++ b/27_Civil_War/java/src/CivilWar.java @@ -33,7 +33,6 @@ public class CivilWar { private int unionTroops; // M6 private boolean confedSurrender; private boolean unionSurrender; - private double R; private boolean wantBattleDescriptions; private final static String YES_NO_REMINDER = "(ANSWER YES OR NO)"; @@ -484,13 +483,12 @@ public class CivilWar { } var S0 = 0; - - this.R = 100 * Math.random(); + var r = 100 * Math.random(); for (unionStrategy = 1; unionStrategy <= 4; unionStrategy++) { S0 += this.strategies[unionStrategy - 1]; // IF ACTUAL STRATEGY INFO IS IN PROGRAM DATA STATEMENTS THEN R-100 IS EXTRA WEIGHT GIVEN TO THAT STATEGY. - if (R < S0) { + if (r < S0) { break; } } From e43300a23ec8ef8ea1d14559479480574f173266 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sun, 16 Jan 2022 00:10:40 +0000 Subject: [PATCH 175/337] Refactor --- 27_Civil_War/java/src/CivilWar.java | 34 +++++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java index a3992492..042126f6 100644 --- a/27_Civil_War/java/src/CivilWar.java +++ b/27_Civil_War/java/src/CivilWar.java @@ -14,26 +14,30 @@ public class CivilWar { private final PrintStream out; private final List data; + private final BattleResults results; + private BattleState currentBattle; - private final int[] strategies; private int numGenerals; - private final ArmyPair resources; private int battleNumber; + private boolean wantBattleDescriptions; + private final int[] strategies; + private int confedStrategy; private int unionStrategy; + + private final ArmyPair resources; private final ArmyPair totalExpectedCasualties; private final ArmyPair totalCasualties; - private boolean excessiveConfederateLosses; - private boolean excessiveUnionLosses; - private final BattleResults results; private final ArmyPair revenue; private final ArmyPair inflation; private final ArmyPair totalExpenditure; private final ArmyPair totalTroops; - private int unionTroops; // M6 + + private boolean excessiveConfederateLosses; + private boolean excessiveUnionLosses; + private boolean confedSurrender; private boolean unionSurrender; - private boolean wantBattleDescriptions; private final static String YES_NO_REMINDER = "(ANSWER YES OR NO)"; private final static Predicate YES_NO_CHECKER = i -> isYes(i) || isNo(i); @@ -143,8 +147,6 @@ public class CivilWar { resources.confederate.budget = 100 * (int) Math.floor((battle.troops.confederate * (100.0 - inflation.confederate) / 2000) * (1 + (revenue.confederate - totalExpenditure.confederate) / (revenue.confederate + 1.0)) + .5); // MEN AVAILABLE - var confedTroops = (int) Math.floor(battle.troops.confederate * (1 + (totalExpectedCasualties.confederate - totalCasualties.confederate) / (totalTroops.confederate + 1.0))); - this.unionTroops = (int) Math.floor(battle.troops.union * (1 + (totalExpectedCasualties.union - totalCasualties.union) / (totalTroops.union + 1.0))); battleState.F1 = 5 * battle.troops.confederate / 6.0; if (this.numGenerals == 2) { @@ -168,7 +170,7 @@ public class CivilWar { out.println(); out.println(" CONFEDERACY UNION"); - out.println("MEN " + confedTroops + " " + unionTroops); + out.println("MEN " + getConfedTroops(battle) + " " + getUnionTroops(battle)); out.println("MONEY $ " + resources.confederate.budget + " $ " + resources.union.budget); out.println("INFLATION " + (inflation.confederate + 15) + "% " + inflation.union + "%"); @@ -228,6 +230,14 @@ public class CivilWar { return battleState; } + private int getUnionTroops(HistoricalDatum battle) { + return (int) Math.floor(battle.troops.union * (1 + (totalExpectedCasualties.union - totalCasualties.union) / (totalTroops.union + 1.0))); + } + + private int getConfedTroops(HistoricalDatum battle) { + return (int) Math.floor(battle.troops.confederate * (1 + (totalExpectedCasualties.confederate - totalCasualties.confederate) / (totalTroops.confederate + 1.0))); + } + private String moraleForArmy(BattleState battleState, int armyIdx) { var builder = new StringBuilder(); @@ -302,8 +312,8 @@ public class CivilWar { // IF LOSS > MEN PRESENT, RESCALE LOSSES var moraleFactor = 100 / resources.union.morale; - if (Math.floor(losses + moraleFactor) >= unionTroops) { - losses = Math.floor(13.0 * unionTroops / 20); + if (Math.floor(losses + moraleFactor) >= getUnionTroops(battle)) { + losses = Math.floor(13.0 * getUnionTroops(battle) / 20); moraleFactor = 7 * losses / 13; excessiveUnionLosses = true; } From cd0c4420e1cfd99a1f5920e6340a8c8610959b30 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Sun, 16 Jan 2022 03:27:32 +0200 Subject: [PATCH 176/337] Utils: generate solution and project files --- .../DotnetUtils/DotnetUtils/Extensions.cs | 8 +-- .../DotnetUtils/DotnetUtils/Methods.cs | 56 +++++++++++++++++++ .../DotnetUtils/DotnetUtils/PortInfo.cs | 19 +++++-- .../DotnetUtils/DotnetUtils/Program.cs | 55 +++++++++++++++++- 4 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 00_Utilities/DotnetUtils/DotnetUtils/Methods.cs diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs b/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs index 82ff9532..a0f52bee 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using static System.IO.Path; namespace DotnetUtils; @@ -18,10 +19,7 @@ public static class Extensions { rootPath.IsNullOrWhitespace() ) { return path; } - var path1 = path.TrimEnd('\\'); - rootPath = rootPath.TrimEnd('\\'); - if (!path1.StartsWith(rootPath, StringComparison.InvariantCultureIgnoreCase)) { return path; } - - return path1[(rootPath.Length + 1)..]; // ignore the initial / + path = path.TrimEnd('\\'); // remove trailing backslash, if present + return GetRelativePath(rootPath, path.TrimEnd('\\')); } } diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs b/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs new file mode 100644 index 00000000..de69131f --- /dev/null +++ b/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs @@ -0,0 +1,56 @@ +using System.Diagnostics; + +namespace DotnetUtils; + +public static class Methods { + public static ProcessResult RunProcess(string filename, string arguments) { + var process = new Process() { + StartInfo = { + FileName = filename, + Arguments = arguments, + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardOutput = true, + RedirectStandardError = true, + }, + EnableRaisingEvents = true + }; + return RunProcess(process); + } + + public static ProcessResult RunProcess(Process process, string input = "") { + var (output, error) = ("", ""); + var (redirectOut, redirectErr) = ( + process.StartInfo.RedirectStandardOutput, + process.StartInfo.RedirectStandardError + ); + if (redirectOut) { + process.OutputDataReceived += (s, ea) => output += ea.Data + "\n"; + } + if (redirectErr) { + process.ErrorDataReceived += (s, ea) => error += ea.Data + "\n"; + } + + if (!process.Start()) { + throw new InvalidOperationException(); + }; + + if (redirectOut) { process.BeginOutputReadLine(); } + if (redirectErr) { process.BeginErrorReadLine(); } + if (!string.IsNullOrEmpty(input)) { + process.StandardInput.WriteLine(input); + process.StandardInput.Close(); + } + process.WaitForExit(); + return new ProcessResult(process.ExitCode, output, error); + } +} + +public sealed record ProcessResult(int ExitCode, string StdOut, string StdErr) { + public override string? ToString() => + StdOut + + (StdOut is not (null or "") && ExitCode > 0 ? "\n" : "") + + (ExitCode > 0 ? + $"{ExitCode}\n{StdErr}" : + ""); +} diff --git a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs index 894c8834..547e2878 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using static System.IO.Directory; +using static System.IO.Directory; using static System.IO.Path; using static DotnetUtils.Globals; @@ -17,6 +16,14 @@ public record PortInfo( MatchCasing = MatchCasing.CaseInsensitive }; + // .NET namespaces cannot have a digit as the first character + // For games whose name starts with a digit, we map the name to a specific string + private static readonly Dictionary specialGameNames = new() { + { "3-D_Plot", "ThreeDPlot" }, + { "3-D_Tic-Tac-Toe", "ThreeDTicTacToe" }, + { "23_Matches", "TwentyThreeMatches"} + }; + public static PortInfo? Create(string fullPath, string langKeyword) { var folderName = GetFileName(fullPath); var parts = folderName.Split('_', 2); @@ -27,9 +34,11 @@ public record PortInfo( (int?)null; var gameName = - parts.Length > 1 ? - parts[1].Replace("_", "") : - null; + parts.Length == 0 ? + null : + specialGameNames.TryGetValue(parts[1], out var specialName) ? + specialName : + parts[1].Replace("_", "").Replace("-", ""); if (index is 0 or null || gameName is null) { return null; } diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index 6d4594b7..f082060c 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -1,6 +1,8 @@ -using DotnetUtils; +using System.Diagnostics; +using DotnetUtils; using static System.Console; using static System.IO.Path; +using static DotnetUtils.Methods; var infos = PortInfos.Get; @@ -11,7 +13,10 @@ var actions = new (Action action, string description)[] { (multipleSlns, "Output multiple sln files"), (missingProj, "Output missing project file"), (unexpectedProjName, "Output misnamed project files"), - (multipleProjs, "Output multiple project files") + (multipleProjs, "Output multiple project files"), + + (generateMissingSlns, "Generate solution files when missing"), + (generateMissingProjs, "Generate project files when missing") }; foreach (var (_, description, index) in actions.WithIndex()) { @@ -159,8 +164,52 @@ void multipleProjs() { WriteLine(item.LangPath); WriteLine(); printProjs(item); - } WriteLine(); WriteLine($"Count: {data.Length}"); } + +void generateMissingSlns() { + foreach (var item in infos.Where(x => !x.Slns.Any())) { + var result = RunProcess("dotnet", $"new sln -n {item.GameName} -o {item.LangPath}"); + WriteLine(result); + + var slnFullPath = Combine(item.LangPath, $"{item.GameName}.sln"); + foreach (var proj in item.Projs) { + result = RunProcess("dotnet", $"sln {slnFullPath} add {proj}"); + WriteLine(result); + } + } +} + +void generateMissingProjs() { + foreach (var item in infos.Where(x => !x.Projs.Any())) { + var (langArg, langVersion) = item.Lang switch { + "csharp" => ("\"C#\"", 10), + "vbnet" => ("\"VB\"", 16.9), + _ => throw new InvalidOperationException() + }; + + var result = RunProcess("dotnet", $"new console --language {langArg} --name {item.GameName}.{item.ProjExt} -o {item.LangPath} -f net6.0 --langversion {langVersion}"); + WriteLine(result); + + var projFullPath = Combine(item.LangPath, $"{item.GameName}.{item.ProjExt}"); + if (item.Slns.Length == 1) { + result = RunProcess("dotnet", $"sln {item.Slns[0]} add {projFullPath}"); + WriteLine(result); + } + } +} + +void checkProjects() { + // warn if project files do not: + // target .NET 6 + // implicit using + // nullable enable + // warn if none og the projects have: + // output type exe +} + +void tryBuild() { + // if has code files, try to build +} From 5b1aaadac1c6e929c40892394832e0f8bf44ee92 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 16 Jan 2022 12:30:34 +1100 Subject: [PATCH 177/337] Update with link to give credit where it is due, @jkboyce --- 84_Super_Star_Trek/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/84_Super_Star_Trek/README.md b/84_Super_Star_Trek/README.md index 28bd3c03..e47c90b7 100644 --- a/84_Super_Star_Trek/README.md +++ b/84_Super_Star_Trek/README.md @@ -93,7 +93,7 @@ The relation between the Historical and Standard nomenclatures is shown in the s Many of the programs in this book and this collection have bugs in the original code. -Jack Boyce has discovered and fixed a number of bugs in his [python implementation](python/superstartrek.py), which should be noted by other implementers: +@jkboyce has done a great job of discovering and fixing a number of bugs in the [original code](superstartrek.bas), as part of his [python implementation](python/superstartrek.py), which should be noted by other implementers: - line `4410` : `D(7)` should be `D(6)` - lines `8310`,`8330`,`8430`,`8450` : Division by zero is possible From c4f9b15db0f033373aa533969ea9274cd6ad26e0 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 16 Jan 2022 13:09:47 +1100 Subject: [PATCH 178/337] Name should have an uppercase class name, and the correct file suffix. --- 63_Name/java/{main.class => Name.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename 63_Name/java/{main.class => Name.java} (98%) diff --git a/63_Name/java/main.class b/63_Name/java/Name.java similarity index 98% rename from 63_Name/java/main.class rename to 63_Name/java/Name.java index db01b014..7b67f489 100644 --- a/63_Name/java/main.class +++ b/63_Name/java/Name.java @@ -1,7 +1,7 @@ import java.util.Arrays; import java.util.Scanner; -public class main { +public class Name { public static void printempty() { System.out.println(" "); } From 18574bd155f20af30aa2789520d86526230a7ad1 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 16 Jan 2022 13:24:12 +1100 Subject: [PATCH 179/337] Stop ignoring buildJvm and build.gradle files in gitignore! Add build files for some of the new games Basketball java Battle java Craps java Cube java High IQ java Name java --- .gitignore | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 3412076c..64e591f9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,8 @@ .vscode/ .gradle/ node_modules/ -buildJvm/ - -build.gradle +buildJvm/bin +buildJvm/*/build/ .classpath .project From 1f018419a74aa836e94437ae48fdf52044fc1ff7 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 16 Jan 2022 13:31:53 +1100 Subject: [PATCH 180/337] Second version of number has the wrong file name, and class names clashed. Added buildscript for Number1 --- 66_Number/java/{main.class => Number1.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename 66_Number/java/{main.class => Number1.java} (99%) diff --git a/66_Number/java/main.class b/66_Number/java/Number1.java similarity index 99% rename from 66_Number/java/main.class rename to 66_Number/java/Number1.java index c3df4ebf..c1d71bda 100644 --- a/66_Number/java/main.class +++ b/66_Number/java/Number1.java @@ -4,7 +4,7 @@ import java.util.Arrays; import java.util.Random; import java.util.Scanner; -public class Number { +public class Number1 { public static int points = 0; From 7278f607750bec360ede755cfda88f3b4fba8a9d Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 16 Jan 2022 13:45:52 +1100 Subject: [PATCH 181/337] Change buildscript for two versions of Number --- 66_Number/java/{Number1.java => 1/Number.java} | 2 +- 66_Number/java/{ => 2}/Number.java | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename 66_Number/java/{Number1.java => 1/Number.java} (99%) rename 66_Number/java/{ => 2}/Number.java (100%) diff --git a/66_Number/java/Number1.java b/66_Number/java/1/Number.java similarity index 99% rename from 66_Number/java/Number1.java rename to 66_Number/java/1/Number.java index c1d71bda..c3df4ebf 100644 --- a/66_Number/java/Number1.java +++ b/66_Number/java/1/Number.java @@ -4,7 +4,7 @@ import java.util.Arrays; import java.util.Random; import java.util.Scanner; -public class Number1 { +public class Number { public static int points = 0; diff --git a/66_Number/java/Number.java b/66_Number/java/2/Number.java similarity index 100% rename from 66_Number/java/Number.java rename to 66_Number/java/2/Number.java From e51103148bc9b9183dcdd4ca2174be28bd191dca Mon Sep 17 00:00:00 2001 From: RibTips <36372030+ribtips@users.noreply.github.com> Date: Sun, 16 Jan 2022 00:34:02 -0500 Subject: [PATCH 182/337] The game of craps in perl 29_Craps --- 29_Craps/perl/craps.pl | 113 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 29_Craps/perl/craps.pl diff --git a/29_Craps/perl/craps.pl b/29_Craps/perl/craps.pl new file mode 100644 index 00000000..7dd39856 --- /dev/null +++ b/29_Craps/perl/craps.pl @@ -0,0 +1,113 @@ +#!/usr/bin/perl +# + +my $bank = 0; + +&main; + +sub main { + &print_intro; + my $continue=5; + until ($continue != 5) { + $continue=&game_play; + &print_bank; + } + &final_bank; +} + +sub game_play { + my $point = 0; + my $continue = 1; + print "INPUT THE AMOUNT OF YOUR WAGER.\n"; + chomp(my $wager=); + print "I WILL NOW THROW THE DICE\n"; + until ($continue == 0) { + my $roll = &roll_dice; + $continue = &check_value($roll,$wager); + } + print "IF YOU WANT TO PLAY AGAIN PRINT 5 IF NOT PRINT 2\n"; + chomp(my $ans=); + return $ans; +} + +sub print_bank { + if ($bank < 0) { + print "YOU ARE NOW UNDER \$$bank\n"; + } + elsif ($bank > 0) { + print "YOU ARE NOW AHEAD \$$bank\n"; + } + else { + print "YOU ARE EVEN AT 0\n"; + } +} + +sub final_bank { + if ($bank < 0) { + print "TOO BAD, YOU ARE IN THE HOLE. COME AGAIN\n"; + } + elsif ($bank > 0) { + print "CONGRATULATIONS---YOU CAME OUT A WINNER. COME AGAIN!\n"; + } + else { + print "CONGRATULATIONS---YOU CAME OUT EVEN. NOT BAD FOR AN AMATEUR!\n"; + } +} + +sub check_value { + my $roll = shift; + my $wager = shift; + if ($roll == 7 || $roll == 11) { + print "$roll - NATURAL....A WINNER!!!!\n"; + print "$roll PAYS EVEN MONEY, YOU WIN $wager DOLLARS\n"; + $bank += $wager; + return 0; + } + elsif ($roll == 2 || $roll == 3 || $roll == 12) { + if ($roll == 2) { + print "$roll - SNAKE EYES....YOU LOSE.\n"; + print "YOU LOSE $wager DOLLARS.\n"; + } + else { + print "$roll - CRAPS...YOU LOSE.\n"; + print "YOU LOSE $wager DOLLARS.\n"; + } + $bank -= $wager; + return 0; + } + else { + my $point = $roll; + print "$point IS THE POINT. I WILL ROLL AGAIN\n"; + until (1==2) { + $roll = &roll_dice; + if ($roll == 7) { + print "$roll YOU LOSE $wager\n"; + $bank -= $wager; + return 0; + } + elsif ($roll == $point) { + print "$roll - A WINNER..........CONGRATS!!!!!!!!\n"; + my $payout = $wager * 2; + print "$roll AT 2 TO 1 ODDS PAYS YOU...LET ME SEE...$payout DOLLARS\n"; + $bank += $payout; + return 0; + } + else { + print "$roll - NO POINT. I WILL ROLL AGAIN\n"; + sleep(1); + } + } + } +} + +sub roll_dice { + my $die1 = 1+int rand(6); + my $die2 = 1+int rand(6); + return ($die1 + $die2); +} + +sub print_intro { + print ' ' x 33 . "CRAPS\n"; + print ' ' x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n"; + print "2,3,12 ARE LOSERS; 4,5,6,8,9,10 ARE POINTS; 7,11 ARE NATURAL WINNERS.\n"; +} From 7fabf7fa261596de52121db02ccc21407cdbfc86 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Sun, 16 Jan 2022 08:09:58 +0200 Subject: [PATCH 183/337] Project generation by hand instead of using dotnet new --- .../DotnetUtils/DotnetUtils/Methods.cs | 2 +- .../DotnetUtils/DotnetUtils/PortInfo.cs | 2 +- .../DotnetUtils/DotnetUtils/Program.cs | 35 ++++++++++++++----- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs b/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs index de69131f..2aafa800 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs @@ -50,7 +50,7 @@ public sealed record ProcessResult(int ExitCode, string StdOut, string StdErr) { public override string? ToString() => StdOut + (StdOut is not (null or "") && ExitCode > 0 ? "\n" : "") + - (ExitCode > 0 ? + (ExitCode != 0 ? $"{ExitCode}\n{StdErr}" : ""); } diff --git a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs index 547e2878..a1caaf15 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs @@ -34,7 +34,7 @@ public record PortInfo( (int?)null; var gameName = - parts.Length == 0 ? + parts.Length <= 1 ? null : specialGameNames.TryGetValue(parts[1], out var specialName) ? specialName : diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index f082060c..f9995994 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -184,18 +184,37 @@ void generateMissingSlns() { void generateMissingProjs() { foreach (var item in infos.Where(x => !x.Projs.Any())) { - var (langArg, langVersion) = item.Lang switch { - "csharp" => ("\"C#\"", 10), - "vbnet" => ("\"VB\"", 16.9), + // We can't use the dotnet command to create a new project using the built-in console template, because part of that template + // is a Program.cs / Program.vb file. If there already are code files, there's no need to add a new empty one; and + // if there's already such a file, it might try to overwrite it. + + var projText = item.Lang switch { + "csharp" => @" + + Exe + net6.0 + 10 + enable + enable + + +", + "vbnet" => @$" + + Exe + {item.GameName} + net6.0 + 16.9 + + +", _ => throw new InvalidOperationException() }; - - var result = RunProcess("dotnet", $"new console --language {langArg} --name {item.GameName}.{item.ProjExt} -o {item.LangPath} -f net6.0 --langversion {langVersion}"); - WriteLine(result); - var projFullPath = Combine(item.LangPath, $"{item.GameName}.{item.ProjExt}"); + File.WriteAllText(projFullPath, projText); + if (item.Slns.Length == 1) { - result = RunProcess("dotnet", $"sln {item.Slns[0]} add {projFullPath}"); + var result = RunProcess("dotnet", $"sln {item.Slns[0]} add {projFullPath}"); WriteLine(result); } } From 75def2707dae65fed551218afbad633100323d37 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Sun, 16 Jan 2022 08:17:31 +0200 Subject: [PATCH 184/337] Add sln and csroj/vbproj files where missing --- .../DotnetUtils/DotnetUtils/Program.cs | 3 +-- 02_Amazing/vbnet/Amazing.sln | 22 +++++++++++++++ 02_Amazing/vbnet/Amazing.vbproj | 8 ++++++ 03_Animal/vbnet/Animal.sln | 22 +++++++++++++++ 03_Animal/vbnet/Animal.vbproj | 8 ++++++ 04_Awari/csharp/Awari.sln | 22 +++++++++++++++ 04_Awari/vbnet/Awari.sln | 22 +++++++++++++++ 04_Awari/vbnet/Awari.vbproj | 8 ++++++ 05_Bagels/csharp/Bagels.sln | 22 +++++++++++++++ 05_Bagels/vbnet/Bagels.sln | 22 +++++++++++++++ 05_Bagels/vbnet/Bagels.vbproj | 8 ++++++ 07_Basketball/csharp/Basketball.csproj | 9 +++++++ 07_Basketball/csharp/Basketball.sln | 22 +++++++++++++++ 07_Basketball/vbnet/Basketball.sln | 22 +++++++++++++++ 07_Basketball/vbnet/Basketball.vbproj | 8 ++++++ 09_Battle/vbnet/Battle.sln | 22 +++++++++++++++ 09_Battle/vbnet/Battle.vbproj | 8 ++++++ 10_Blackjack/csharp/Blackjack.sln | 22 +++++++++++++++ 10_Blackjack/vbnet/Blackjack.sln | 22 +++++++++++++++ 10_Blackjack/vbnet/Blackjack.vbproj | 8 ++++++ 11_Bombardment/csharp/Bombardment.sln | 22 +++++++++++++++ 11_Bombardment/vbnet/Bombardment.sln | 22 +++++++++++++++ 11_Bombardment/vbnet/Bombardment.vbproj | 8 ++++++ 12_Bombs_Away/vbnet/BombsAway.sln | 22 +++++++++++++++ 12_Bombs_Away/vbnet/BombsAway.vbproj | 8 ++++++ 13_Bounce/csharp/Bounce.csproj | 9 +++++++ 13_Bounce/csharp/Bounce.sln | 22 +++++++++++++++ 13_Bounce/vbnet/Bounce.sln | 22 +++++++++++++++ 13_Bounce/vbnet/Bounce.vbproj | 8 ++++++ 14_Bowling/csharp/Bowling.csproj | 9 +++++++ 14_Bowling/csharp/Bowling.sln | 22 +++++++++++++++ 14_Bowling/vbnet/Bowling.sln | 22 +++++++++++++++ 14_Bowling/vbnet/Bowling.vbproj | 8 ++++++ 15_Boxing/vbnet/Boxing.sln | 22 +++++++++++++++ 15_Boxing/vbnet/Boxing.vbproj | 8 ++++++ 16_Bug/csharp/Bug.csproj | 9 +++++++ 16_Bug/csharp/Bug.sln | 22 +++++++++++++++ 16_Bug/vbnet/Bug.sln | 22 +++++++++++++++ 16_Bug/vbnet/Bug.vbproj | 8 ++++++ 17_Bullfight/vbnet/Bullfight.sln | 22 +++++++++++++++ 17_Bullfight/vbnet/Bullfight.vbproj | 8 ++++++ 18_Bullseye/vbnet/Bullseye.sln | 22 +++++++++++++++ 18_Bullseye/vbnet/Bullseye.vbproj | 8 ++++++ 19_Bunny/csharp/Bunny.csproj | 9 +++++++ 19_Bunny/csharp/Bunny.sln | 22 +++++++++++++++ 19_Bunny/vbnet/Bunny.sln | 22 +++++++++++++++ 19_Bunny/vbnet/Bunny.vbproj | 8 ++++++ 20_Buzzword/vbnet/Buzzword.sln | 22 +++++++++++++++ 20_Buzzword/vbnet/Buzzword.vbproj | 8 ++++++ 21_Calendar/vbnet/Calendar.sln | 22 +++++++++++++++ 21_Calendar/vbnet/Calendar.vbproj | 8 ++++++ 22_Change/vbnet/Change.sln | 22 +++++++++++++++ 22_Change/vbnet/Change.vbproj | 8 ++++++ 23_Checkers/csharp/Checkers.csproj | 9 +++++++ 23_Checkers/csharp/Checkers.sln | 22 +++++++++++++++ 23_Checkers/vbnet/Checkers.sln | 22 +++++++++++++++ 23_Checkers/vbnet/Checkers.vbproj | 8 ++++++ 24_Chemist/vbnet/Chemist.sln | 22 +++++++++++++++ 24_Chemist/vbnet/Chemist.vbproj | 8 ++++++ 25_Chief/csharp/Chief.csproj | 9 +++++++ 25_Chief/csharp/Chief.sln | 22 +++++++++++++++ 25_Chief/vbnet/Chief.sln | 22 +++++++++++++++ 25_Chief/vbnet/Chief.vbproj | 8 ++++++ 26_Chomp/csharp/Chomp.csproj | 9 +++++++ 26_Chomp/csharp/Chomp.sln | 22 +++++++++++++++ 26_Chomp/vbnet/Chomp.sln | 22 +++++++++++++++ 26_Chomp/vbnet/Chomp.vbproj | 8 ++++++ 27_Civil_War/vbnet/CivilWar.sln | 22 +++++++++++++++ 27_Civil_War/vbnet/CivilWar.vbproj | 8 ++++++ 28_Combat/vbnet/Combat.sln | 22 +++++++++++++++ 28_Combat/vbnet/Combat.vbproj | 8 ++++++ 29_Craps/vbnet/Craps.sln | 22 +++++++++++++++ 29_Craps/vbnet/Craps.vbproj | 8 ++++++ 30_Cube/csharp/Cube.csproj | 9 +++++++ 30_Cube/csharp/Cube.sln | 22 +++++++++++++++ 30_Cube/vbnet/Cube.sln | 22 +++++++++++++++ 30_Cube/vbnet/Cube.vbproj | 8 ++++++ 31_Depth_Charge/vbnet/DepthCharge.sln | 22 +++++++++++++++ 31_Depth_Charge/vbnet/DepthCharge.vbproj | 8 ++++++ 32_Diamond/csharp/Diamond.csproj | 9 +++++++ 32_Diamond/csharp/Diamond.sln | 22 +++++++++++++++ 32_Diamond/vbnet/Diamond.sln | 22 +++++++++++++++ 32_Diamond/vbnet/Diamond.vbproj | 8 ++++++ 33_Dice/csharp/Dice.sln | 22 +++++++++++++++ 33_Dice/vbnet/Dice.sln | 22 +++++++++++++++ 33_Dice/vbnet/Dice.vbproj | 8 ++++++ 34_Digits/csharp/Digits.csproj | 9 +++++++ 34_Digits/csharp/Digits.sln | 22 +++++++++++++++ 34_Digits/vbnet/Digits.sln | 22 +++++++++++++++ 34_Digits/vbnet/Digits.vbproj | 8 ++++++ 35_Even_Wins/csharp/EvenWins.csproj | 9 +++++++ 35_Even_Wins/csharp/EvenWins.sln | 22 +++++++++++++++ 35_Even_Wins/vbnet/EvenWins.sln | 22 +++++++++++++++ 35_Even_Wins/vbnet/EvenWins.vbproj | 8 ++++++ 36_Flip_Flop/vbnet/FlipFlop.sln | 22 +++++++++++++++ 36_Flip_Flop/vbnet/FlipFlop.vbproj | 8 ++++++ 37_Football/csharp/Football.csproj | 9 +++++++ 37_Football/csharp/Football.sln | 22 +++++++++++++++ 37_Football/vbnet/Football.sln | 22 +++++++++++++++ 37_Football/vbnet/Football.vbproj | 8 ++++++ 38_Fur_Trader/vbnet/FurTrader.sln | 22 +++++++++++++++ 38_Fur_Trader/vbnet/FurTrader.vbproj | 8 ++++++ 39_Golf/csharp/Golf.csproj | 9 +++++++ 39_Golf/csharp/Golf.sln | 22 +++++++++++++++ 39_Golf/vbnet/Golf.sln | 22 +++++++++++++++ 39_Golf/vbnet/Golf.vbproj | 8 ++++++ 40_Gomoko/csharp/Gomoko.csproj | 9 +++++++ 40_Gomoko/csharp/Gomoko.sln | 22 +++++++++++++++ 40_Gomoko/vbnet/Gomoko.sln | 22 +++++++++++++++ 40_Gomoko/vbnet/Gomoko.vbproj | 8 ++++++ 41_Guess/csharp/Guess.csproj | 9 +++++++ 41_Guess/csharp/Guess.sln | 22 +++++++++++++++ 41_Guess/vbnet/Guess.sln | 22 +++++++++++++++ 41_Guess/vbnet/Guess.vbproj | 8 ++++++ 42_Gunner/csharp/Gunner.sln | 22 +++++++++++++++ 42_Gunner/vbnet/Gunner.sln | 22 +++++++++++++++ 42_Gunner/vbnet/Gunner.vbproj | 8 ++++++ 43_Hammurabi/vbnet/Hammurabi.sln | 22 +++++++++++++++ 43_Hammurabi/vbnet/Hammurabi.vbproj | 8 ++++++ 44_Hangman/vbnet/Hangman.sln | 22 +++++++++++++++ 44_Hangman/vbnet/Hangman.vbproj | 8 ++++++ 45_Hello/csharp/Hello.csproj | 9 +++++++ 45_Hello/csharp/Hello.sln | 22 +++++++++++++++ 45_Hello/vbnet/Hello.sln | 22 +++++++++++++++ 45_Hello/vbnet/Hello.vbproj | 8 ++++++ 46_Hexapawn/vbnet/Hexapawn.sln | 22 +++++++++++++++ 46_Hexapawn/vbnet/Hexapawn.vbproj | 8 ++++++ 47_Hi-Lo/csharp/HiLo.sln | 22 +++++++++++++++ 47_Hi-Lo/vbnet/HiLo.sln | 22 +++++++++++++++ 47_Hi-Lo/vbnet/HiLo.vbproj | 8 ++++++ 48_High_IQ/csharp/HighIQ.csproj | 9 +++++++ 48_High_IQ/csharp/HighIQ.sln | 22 +++++++++++++++ 48_High_IQ/vbnet/HighIQ.sln | 22 +++++++++++++++ 48_High_IQ/vbnet/HighIQ.vbproj | 8 ++++++ 49_Hockey/csharp/Hockey.csproj | 9 +++++++ 49_Hockey/csharp/Hockey.sln | 22 +++++++++++++++ 49_Hockey/vbnet/Hockey.sln | 22 +++++++++++++++ 49_Hockey/vbnet/Hockey.vbproj | 8 ++++++ 50_Horserace/csharp/Horserace.csproj | 9 +++++++ 50_Horserace/csharp/Horserace.sln | 22 +++++++++++++++ 50_Horserace/vbnet/Horserace.sln | 22 +++++++++++++++ 50_Horserace/vbnet/Horserace.vbproj | 8 ++++++ 51_Hurkle/csharp/Hurkle.sln | 27 +++++++++++++++++++ 51_Hurkle/vbnet/Hurkle.sln | 22 +++++++++++++++ 51_Hurkle/vbnet/Hurkle.vbproj | 8 ++++++ 52_Kinema/csharp/Kinema.csproj | 9 +++++++ 52_Kinema/csharp/Kinema.sln | 22 +++++++++++++++ 52_Kinema/vbnet/Kinema.sln | 22 +++++++++++++++ 52_Kinema/vbnet/Kinema.vbproj | 8 ++++++ 53_King/csharp/King.csproj | 9 +++++++ 53_King/csharp/King.sln | 22 +++++++++++++++ 53_King/vbnet/King.sln | 22 +++++++++++++++ 53_King/vbnet/King.vbproj | 8 ++++++ 54_Letter/csharp/Letter.csproj | 9 +++++++ 54_Letter/csharp/Letter.sln | 22 +++++++++++++++ 54_Letter/vbnet/Letter.sln | 22 +++++++++++++++ 54_Letter/vbnet/Letter.vbproj | 8 ++++++ 55_Life/vbnet/Life.sln | 22 +++++++++++++++ 55_Life/vbnet/Life.vbproj | 8 ++++++ 56_Life_for_Two/csharp/LifeforTwo.csproj | 9 +++++++ 56_Life_for_Two/csharp/LifeforTwo.sln | 22 +++++++++++++++ 56_Life_for_Two/vbnet/LifeforTwo.sln | 22 +++++++++++++++ 56_Life_for_Two/vbnet/LifeforTwo.vbproj | 8 ++++++ .../csharp/LiteratureQuiz.csproj | 9 +++++++ 57_Literature_Quiz/csharp/LiteratureQuiz.sln | 22 +++++++++++++++ 57_Literature_Quiz/vbnet/LiteratureQuiz.sln | 22 +++++++++++++++ .../vbnet/LiteratureQuiz.vbproj | 8 ++++++ 58_Love/vbnet/Love.sln | 22 +++++++++++++++ 58_Love/vbnet/Love.vbproj | 8 ++++++ .../csharp/LunarLEMRocket.csproj | 9 +++++++ 59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.sln | 22 +++++++++++++++ 59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.sln | 22 +++++++++++++++ .../vbnet/LunarLEMRocket.vbproj | 8 ++++++ 60_Mastermind/vbnet/Mastermind.sln | 22 +++++++++++++++ 60_Mastermind/vbnet/Mastermind.vbproj | 8 ++++++ 61_Math_Dice/vbnet/MathDice.sln | 22 +++++++++++++++ 61_Math_Dice/vbnet/MathDice.vbproj | 8 ++++++ 62_Mugwump/vbnet/Mugwump.sln | 22 +++++++++++++++ 62_Mugwump/vbnet/Mugwump.vbproj | 8 ++++++ 63_Name/vbnet/Name.sln | 22 +++++++++++++++ 63_Name/vbnet/Name.vbproj | 8 ++++++ 64_Nicomachus/csharp/Nicomachus.csproj | 9 +++++++ 64_Nicomachus/csharp/Nicomachus.sln | 22 +++++++++++++++ 64_Nicomachus/vbnet/Nicomachus.sln | 22 +++++++++++++++ 64_Nicomachus/vbnet/Nicomachus.vbproj | 8 ++++++ 65_Nim/csharp/Nim.csproj | 9 +++++++ 65_Nim/csharp/Nim.sln | 22 +++++++++++++++ 65_Nim/vbnet/Nim.sln | 22 +++++++++++++++ 65_Nim/vbnet/Nim.vbproj | 8 ++++++ 66_Number/csharp/Number.csproj | 9 +++++++ 66_Number/csharp/Number.sln | 22 +++++++++++++++ 66_Number/vbnet/Number.sln | 22 +++++++++++++++ 66_Number/vbnet/Number.vbproj | 8 ++++++ 67_One_Check/csharp/OneCheck.csproj | 9 +++++++ 67_One_Check/csharp/OneCheck.sln | 22 +++++++++++++++ 67_One_Check/vbnet/OneCheck.sln | 22 +++++++++++++++ 67_One_Check/vbnet/OneCheck.vbproj | 8 ++++++ 68_Orbit/csharp/Orbit.csproj | 9 +++++++ 68_Orbit/csharp/Orbit.sln | 22 +++++++++++++++ 68_Orbit/vbnet/Orbit.sln | 22 +++++++++++++++ 68_Orbit/vbnet/Orbit.vbproj | 8 ++++++ 69_Pizza/vbnet/Pizza.sln | 22 +++++++++++++++ 69_Pizza/vbnet/Pizza.vbproj | 8 ++++++ 70_Poetry/csharp/Poetry.csproj | 9 +++++++ 70_Poetry/csharp/Poetry.sln | 22 +++++++++++++++ 70_Poetry/vbnet/Poetry.sln | 22 +++++++++++++++ 70_Poetry/vbnet/Poetry.vbproj | 8 ++++++ 71_Poker/csharp/Poker.csproj | 9 +++++++ 71_Poker/csharp/Poker.sln | 22 +++++++++++++++ 71_Poker/vbnet/Poker.sln | 22 +++++++++++++++ 71_Poker/vbnet/Poker.vbproj | 8 ++++++ 72_Queen/csharp/Queen.csproj | 9 +++++++ 72_Queen/csharp/Queen.sln | 22 +++++++++++++++ 72_Queen/vbnet/Queen.sln | 22 +++++++++++++++ 72_Queen/vbnet/Queen.vbproj | 8 ++++++ 73_Reverse/vbnet/Reverse.sln | 22 +++++++++++++++ 73_Reverse/vbnet/Reverse.vbproj | 8 ++++++ .../csharp/RockScissorsPaper.sln | 22 +++++++++++++++ .../vbnet/RockScissorsPaper.sln | 22 +++++++++++++++ .../vbnet/RockScissorsPaper.vbproj | 8 ++++++ 75_Roulette/csharp/Roulette.csproj | 9 +++++++ 75_Roulette/csharp/Roulette.sln | 22 +++++++++++++++ 75_Roulette/vbnet/Roulette.sln | 22 +++++++++++++++ 75_Roulette/vbnet/Roulette.vbproj | 8 ++++++ 76_Russian_Roulette/vbnet/RussianRoulette.sln | 22 +++++++++++++++ .../vbnet/RussianRoulette.vbproj | 8 ++++++ 77_Salvo/csharp/Salvo.csproj | 9 +++++++ 77_Salvo/csharp/Salvo.sln | 22 +++++++++++++++ 77_Salvo/vbnet/Salvo.sln | 22 +++++++++++++++ 77_Salvo/vbnet/Salvo.vbproj | 8 ++++++ 78_Sine_Wave/vbnet/SineWave.sln | 22 +++++++++++++++ 78_Sine_Wave/vbnet/SineWave.vbproj | 8 ++++++ 79_Slalom/csharp/Slalom.csproj | 9 +++++++ 79_Slalom/csharp/Slalom.sln | 22 +++++++++++++++ 79_Slalom/vbnet/Slalom.sln | 22 +++++++++++++++ 79_Slalom/vbnet/Slalom.vbproj | 8 ++++++ 80_Slots/csharp/Slots.csproj | 9 +++++++ 80_Slots/csharp/Slots.sln | 22 +++++++++++++++ 80_Slots/vbnet/Slots.sln | 22 +++++++++++++++ 80_Slots/vbnet/Slots.vbproj | 8 ++++++ 81_Splat/csharp/Splat.csproj | 9 +++++++ 81_Splat/csharp/Splat.sln | 22 +++++++++++++++ 81_Splat/vbnet/Splat.sln | 22 +++++++++++++++ 81_Splat/vbnet/Splat.vbproj | 8 ++++++ 82_Stars/vbnet/Stars.sln | 22 +++++++++++++++ 82_Stars/vbnet/Stars.vbproj | 8 ++++++ 83_Stock_Market/vbnet/StockMarket.sln | 22 +++++++++++++++ 83_Stock_Market/vbnet/StockMarket.vbproj | 8 ++++++ 84_Super_Star_Trek/vbnet/SuperStarTrek.sln | 22 +++++++++++++++ 84_Super_Star_Trek/vbnet/SuperStarTrek.vbproj | 8 ++++++ 85_Synonym/csharp/Synonym.csproj | 9 +++++++ 85_Synonym/csharp/Synonym.sln | 22 +++++++++++++++ 85_Synonym/vbnet/Synonym.sln | 22 +++++++++++++++ 85_Synonym/vbnet/Synonym.vbproj | 8 ++++++ 86_Target/vbnet/Target.sln | 22 +++++++++++++++ 86_Target/vbnet/Target.vbproj | 8 ++++++ 87_3-D_Plot/vbnet/ThreeDPlot.sln | 22 +++++++++++++++ 87_3-D_Plot/vbnet/ThreeDPlot.vbproj | 8 ++++++ .../csharp/ThreeDTicTacToe.csproj | 9 +++++++ 88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.sln | 22 +++++++++++++++ 88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.sln | 22 +++++++++++++++ .../vbnet/ThreeDTicTacToe.vbproj | 8 ++++++ 89_Tic-Tac-Toe/csharp/TicTacToe.sln | 22 +++++++++++++++ 89_Tic-Tac-Toe/vbnet/TicTacToe.sln | 22 +++++++++++++++ 89_Tic-Tac-Toe/vbnet/TicTacToe.vbproj | 8 ++++++ 90_Tower/vbnet/Tower.sln | 22 +++++++++++++++ 90_Tower/vbnet/Tower.vbproj | 8 ++++++ 91_Train/vbnet/Train.sln | 22 +++++++++++++++ 91_Train/vbnet/Train.vbproj | 8 ++++++ 92_Trap/csharp/Trap.csproj | 9 +++++++ 92_Trap/csharp/Trap.sln | 22 +++++++++++++++ 92_Trap/vbnet/Trap.sln | 22 +++++++++++++++ 92_Trap/vbnet/Trap.vbproj | 8 ++++++ 93_23_Matches/vbnet/TwentyThreeMatches.sln | 22 +++++++++++++++ 93_23_Matches/vbnet/TwentyThreeMatches.vbproj | 8 ++++++ 94_War/vbnet/War.sln | 22 +++++++++++++++ 94_War/vbnet/War.vbproj | 8 ++++++ 95_Weekday/csharp/Weekday.csproj | 9 +++++++ 95_Weekday/csharp/Weekday.sln | 22 +++++++++++++++ 95_Weekday/vbnet/Weekday.sln | 22 +++++++++++++++ 95_Weekday/vbnet/Weekday.vbproj | 8 ++++++ 281 files changed, 4319 insertions(+), 2 deletions(-) create mode 100644 02_Amazing/vbnet/Amazing.sln create mode 100644 02_Amazing/vbnet/Amazing.vbproj create mode 100644 03_Animal/vbnet/Animal.sln create mode 100644 03_Animal/vbnet/Animal.vbproj create mode 100644 04_Awari/csharp/Awari.sln create mode 100644 04_Awari/vbnet/Awari.sln create mode 100644 04_Awari/vbnet/Awari.vbproj create mode 100644 05_Bagels/csharp/Bagels.sln create mode 100644 05_Bagels/vbnet/Bagels.sln create mode 100644 05_Bagels/vbnet/Bagels.vbproj create mode 100644 07_Basketball/csharp/Basketball.csproj create mode 100644 07_Basketball/csharp/Basketball.sln create mode 100644 07_Basketball/vbnet/Basketball.sln create mode 100644 07_Basketball/vbnet/Basketball.vbproj create mode 100644 09_Battle/vbnet/Battle.sln create mode 100644 09_Battle/vbnet/Battle.vbproj create mode 100644 10_Blackjack/csharp/Blackjack.sln create mode 100644 10_Blackjack/vbnet/Blackjack.sln create mode 100644 10_Blackjack/vbnet/Blackjack.vbproj create mode 100644 11_Bombardment/csharp/Bombardment.sln create mode 100644 11_Bombardment/vbnet/Bombardment.sln create mode 100644 11_Bombardment/vbnet/Bombardment.vbproj create mode 100644 12_Bombs_Away/vbnet/BombsAway.sln create mode 100644 12_Bombs_Away/vbnet/BombsAway.vbproj create mode 100644 13_Bounce/csharp/Bounce.csproj create mode 100644 13_Bounce/csharp/Bounce.sln create mode 100644 13_Bounce/vbnet/Bounce.sln create mode 100644 13_Bounce/vbnet/Bounce.vbproj create mode 100644 14_Bowling/csharp/Bowling.csproj create mode 100644 14_Bowling/csharp/Bowling.sln create mode 100644 14_Bowling/vbnet/Bowling.sln create mode 100644 14_Bowling/vbnet/Bowling.vbproj create mode 100644 15_Boxing/vbnet/Boxing.sln create mode 100644 15_Boxing/vbnet/Boxing.vbproj create mode 100644 16_Bug/csharp/Bug.csproj create mode 100644 16_Bug/csharp/Bug.sln create mode 100644 16_Bug/vbnet/Bug.sln create mode 100644 16_Bug/vbnet/Bug.vbproj create mode 100644 17_Bullfight/vbnet/Bullfight.sln create mode 100644 17_Bullfight/vbnet/Bullfight.vbproj create mode 100644 18_Bullseye/vbnet/Bullseye.sln create mode 100644 18_Bullseye/vbnet/Bullseye.vbproj create mode 100644 19_Bunny/csharp/Bunny.csproj create mode 100644 19_Bunny/csharp/Bunny.sln create mode 100644 19_Bunny/vbnet/Bunny.sln create mode 100644 19_Bunny/vbnet/Bunny.vbproj create mode 100644 20_Buzzword/vbnet/Buzzword.sln create mode 100644 20_Buzzword/vbnet/Buzzword.vbproj create mode 100644 21_Calendar/vbnet/Calendar.sln create mode 100644 21_Calendar/vbnet/Calendar.vbproj create mode 100644 22_Change/vbnet/Change.sln create mode 100644 22_Change/vbnet/Change.vbproj create mode 100644 23_Checkers/csharp/Checkers.csproj create mode 100644 23_Checkers/csharp/Checkers.sln create mode 100644 23_Checkers/vbnet/Checkers.sln create mode 100644 23_Checkers/vbnet/Checkers.vbproj create mode 100644 24_Chemist/vbnet/Chemist.sln create mode 100644 24_Chemist/vbnet/Chemist.vbproj create mode 100644 25_Chief/csharp/Chief.csproj create mode 100644 25_Chief/csharp/Chief.sln create mode 100644 25_Chief/vbnet/Chief.sln create mode 100644 25_Chief/vbnet/Chief.vbproj create mode 100644 26_Chomp/csharp/Chomp.csproj create mode 100644 26_Chomp/csharp/Chomp.sln create mode 100644 26_Chomp/vbnet/Chomp.sln create mode 100644 26_Chomp/vbnet/Chomp.vbproj create mode 100644 27_Civil_War/vbnet/CivilWar.sln create mode 100644 27_Civil_War/vbnet/CivilWar.vbproj create mode 100644 28_Combat/vbnet/Combat.sln create mode 100644 28_Combat/vbnet/Combat.vbproj create mode 100644 29_Craps/vbnet/Craps.sln create mode 100644 29_Craps/vbnet/Craps.vbproj create mode 100644 30_Cube/csharp/Cube.csproj create mode 100644 30_Cube/csharp/Cube.sln create mode 100644 30_Cube/vbnet/Cube.sln create mode 100644 30_Cube/vbnet/Cube.vbproj create mode 100644 31_Depth_Charge/vbnet/DepthCharge.sln create mode 100644 31_Depth_Charge/vbnet/DepthCharge.vbproj create mode 100644 32_Diamond/csharp/Diamond.csproj create mode 100644 32_Diamond/csharp/Diamond.sln create mode 100644 32_Diamond/vbnet/Diamond.sln create mode 100644 32_Diamond/vbnet/Diamond.vbproj create mode 100644 33_Dice/csharp/Dice.sln create mode 100644 33_Dice/vbnet/Dice.sln create mode 100644 33_Dice/vbnet/Dice.vbproj create mode 100644 34_Digits/csharp/Digits.csproj create mode 100644 34_Digits/csharp/Digits.sln create mode 100644 34_Digits/vbnet/Digits.sln create mode 100644 34_Digits/vbnet/Digits.vbproj create mode 100644 35_Even_Wins/csharp/EvenWins.csproj create mode 100644 35_Even_Wins/csharp/EvenWins.sln create mode 100644 35_Even_Wins/vbnet/EvenWins.sln create mode 100644 35_Even_Wins/vbnet/EvenWins.vbproj create mode 100644 36_Flip_Flop/vbnet/FlipFlop.sln create mode 100644 36_Flip_Flop/vbnet/FlipFlop.vbproj create mode 100644 37_Football/csharp/Football.csproj create mode 100644 37_Football/csharp/Football.sln create mode 100644 37_Football/vbnet/Football.sln create mode 100644 37_Football/vbnet/Football.vbproj create mode 100644 38_Fur_Trader/vbnet/FurTrader.sln create mode 100644 38_Fur_Trader/vbnet/FurTrader.vbproj create mode 100644 39_Golf/csharp/Golf.csproj create mode 100644 39_Golf/csharp/Golf.sln create mode 100644 39_Golf/vbnet/Golf.sln create mode 100644 39_Golf/vbnet/Golf.vbproj create mode 100644 40_Gomoko/csharp/Gomoko.csproj create mode 100644 40_Gomoko/csharp/Gomoko.sln create mode 100644 40_Gomoko/vbnet/Gomoko.sln create mode 100644 40_Gomoko/vbnet/Gomoko.vbproj create mode 100644 41_Guess/csharp/Guess.csproj create mode 100644 41_Guess/csharp/Guess.sln create mode 100644 41_Guess/vbnet/Guess.sln create mode 100644 41_Guess/vbnet/Guess.vbproj create mode 100644 42_Gunner/csharp/Gunner.sln create mode 100644 42_Gunner/vbnet/Gunner.sln create mode 100644 42_Gunner/vbnet/Gunner.vbproj create mode 100644 43_Hammurabi/vbnet/Hammurabi.sln create mode 100644 43_Hammurabi/vbnet/Hammurabi.vbproj create mode 100644 44_Hangman/vbnet/Hangman.sln create mode 100644 44_Hangman/vbnet/Hangman.vbproj create mode 100644 45_Hello/csharp/Hello.csproj create mode 100644 45_Hello/csharp/Hello.sln create mode 100644 45_Hello/vbnet/Hello.sln create mode 100644 45_Hello/vbnet/Hello.vbproj create mode 100644 46_Hexapawn/vbnet/Hexapawn.sln create mode 100644 46_Hexapawn/vbnet/Hexapawn.vbproj create mode 100644 47_Hi-Lo/csharp/HiLo.sln create mode 100644 47_Hi-Lo/vbnet/HiLo.sln create mode 100644 47_Hi-Lo/vbnet/HiLo.vbproj create mode 100644 48_High_IQ/csharp/HighIQ.csproj create mode 100644 48_High_IQ/csharp/HighIQ.sln create mode 100644 48_High_IQ/vbnet/HighIQ.sln create mode 100644 48_High_IQ/vbnet/HighIQ.vbproj create mode 100644 49_Hockey/csharp/Hockey.csproj create mode 100644 49_Hockey/csharp/Hockey.sln create mode 100644 49_Hockey/vbnet/Hockey.sln create mode 100644 49_Hockey/vbnet/Hockey.vbproj create mode 100644 50_Horserace/csharp/Horserace.csproj create mode 100644 50_Horserace/csharp/Horserace.sln create mode 100644 50_Horserace/vbnet/Horserace.sln create mode 100644 50_Horserace/vbnet/Horserace.vbproj create mode 100644 51_Hurkle/csharp/Hurkle.sln create mode 100644 51_Hurkle/vbnet/Hurkle.sln create mode 100644 51_Hurkle/vbnet/Hurkle.vbproj create mode 100644 52_Kinema/csharp/Kinema.csproj create mode 100644 52_Kinema/csharp/Kinema.sln create mode 100644 52_Kinema/vbnet/Kinema.sln create mode 100644 52_Kinema/vbnet/Kinema.vbproj create mode 100644 53_King/csharp/King.csproj create mode 100644 53_King/csharp/King.sln create mode 100644 53_King/vbnet/King.sln create mode 100644 53_King/vbnet/King.vbproj create mode 100644 54_Letter/csharp/Letter.csproj create mode 100644 54_Letter/csharp/Letter.sln create mode 100644 54_Letter/vbnet/Letter.sln create mode 100644 54_Letter/vbnet/Letter.vbproj create mode 100644 55_Life/vbnet/Life.sln create mode 100644 55_Life/vbnet/Life.vbproj create mode 100644 56_Life_for_Two/csharp/LifeforTwo.csproj create mode 100644 56_Life_for_Two/csharp/LifeforTwo.sln create mode 100644 56_Life_for_Two/vbnet/LifeforTwo.sln create mode 100644 56_Life_for_Two/vbnet/LifeforTwo.vbproj create mode 100644 57_Literature_Quiz/csharp/LiteratureQuiz.csproj create mode 100644 57_Literature_Quiz/csharp/LiteratureQuiz.sln create mode 100644 57_Literature_Quiz/vbnet/LiteratureQuiz.sln create mode 100644 57_Literature_Quiz/vbnet/LiteratureQuiz.vbproj create mode 100644 58_Love/vbnet/Love.sln create mode 100644 58_Love/vbnet/Love.vbproj create mode 100644 59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.csproj create mode 100644 59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.sln create mode 100644 59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.sln create mode 100644 59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.vbproj create mode 100644 60_Mastermind/vbnet/Mastermind.sln create mode 100644 60_Mastermind/vbnet/Mastermind.vbproj create mode 100644 61_Math_Dice/vbnet/MathDice.sln create mode 100644 61_Math_Dice/vbnet/MathDice.vbproj create mode 100644 62_Mugwump/vbnet/Mugwump.sln create mode 100644 62_Mugwump/vbnet/Mugwump.vbproj create mode 100644 63_Name/vbnet/Name.sln create mode 100644 63_Name/vbnet/Name.vbproj create mode 100644 64_Nicomachus/csharp/Nicomachus.csproj create mode 100644 64_Nicomachus/csharp/Nicomachus.sln create mode 100644 64_Nicomachus/vbnet/Nicomachus.sln create mode 100644 64_Nicomachus/vbnet/Nicomachus.vbproj create mode 100644 65_Nim/csharp/Nim.csproj create mode 100644 65_Nim/csharp/Nim.sln create mode 100644 65_Nim/vbnet/Nim.sln create mode 100644 65_Nim/vbnet/Nim.vbproj create mode 100644 66_Number/csharp/Number.csproj create mode 100644 66_Number/csharp/Number.sln create mode 100644 66_Number/vbnet/Number.sln create mode 100644 66_Number/vbnet/Number.vbproj create mode 100644 67_One_Check/csharp/OneCheck.csproj create mode 100644 67_One_Check/csharp/OneCheck.sln create mode 100644 67_One_Check/vbnet/OneCheck.sln create mode 100644 67_One_Check/vbnet/OneCheck.vbproj create mode 100644 68_Orbit/csharp/Orbit.csproj create mode 100644 68_Orbit/csharp/Orbit.sln create mode 100644 68_Orbit/vbnet/Orbit.sln create mode 100644 68_Orbit/vbnet/Orbit.vbproj create mode 100644 69_Pizza/vbnet/Pizza.sln create mode 100644 69_Pizza/vbnet/Pizza.vbproj create mode 100644 70_Poetry/csharp/Poetry.csproj create mode 100644 70_Poetry/csharp/Poetry.sln create mode 100644 70_Poetry/vbnet/Poetry.sln create mode 100644 70_Poetry/vbnet/Poetry.vbproj create mode 100644 71_Poker/csharp/Poker.csproj create mode 100644 71_Poker/csharp/Poker.sln create mode 100644 71_Poker/vbnet/Poker.sln create mode 100644 71_Poker/vbnet/Poker.vbproj create mode 100644 72_Queen/csharp/Queen.csproj create mode 100644 72_Queen/csharp/Queen.sln create mode 100644 72_Queen/vbnet/Queen.sln create mode 100644 72_Queen/vbnet/Queen.vbproj create mode 100644 73_Reverse/vbnet/Reverse.sln create mode 100644 73_Reverse/vbnet/Reverse.vbproj create mode 100644 74_Rock_Scissors_Paper/csharp/RockScissorsPaper.sln create mode 100644 74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.sln create mode 100644 74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.vbproj create mode 100644 75_Roulette/csharp/Roulette.csproj create mode 100644 75_Roulette/csharp/Roulette.sln create mode 100644 75_Roulette/vbnet/Roulette.sln create mode 100644 75_Roulette/vbnet/Roulette.vbproj create mode 100644 76_Russian_Roulette/vbnet/RussianRoulette.sln create mode 100644 76_Russian_Roulette/vbnet/RussianRoulette.vbproj create mode 100644 77_Salvo/csharp/Salvo.csproj create mode 100644 77_Salvo/csharp/Salvo.sln create mode 100644 77_Salvo/vbnet/Salvo.sln create mode 100644 77_Salvo/vbnet/Salvo.vbproj create mode 100644 78_Sine_Wave/vbnet/SineWave.sln create mode 100644 78_Sine_Wave/vbnet/SineWave.vbproj create mode 100644 79_Slalom/csharp/Slalom.csproj create mode 100644 79_Slalom/csharp/Slalom.sln create mode 100644 79_Slalom/vbnet/Slalom.sln create mode 100644 79_Slalom/vbnet/Slalom.vbproj create mode 100644 80_Slots/csharp/Slots.csproj create mode 100644 80_Slots/csharp/Slots.sln create mode 100644 80_Slots/vbnet/Slots.sln create mode 100644 80_Slots/vbnet/Slots.vbproj create mode 100644 81_Splat/csharp/Splat.csproj create mode 100644 81_Splat/csharp/Splat.sln create mode 100644 81_Splat/vbnet/Splat.sln create mode 100644 81_Splat/vbnet/Splat.vbproj create mode 100644 82_Stars/vbnet/Stars.sln create mode 100644 82_Stars/vbnet/Stars.vbproj create mode 100644 83_Stock_Market/vbnet/StockMarket.sln create mode 100644 83_Stock_Market/vbnet/StockMarket.vbproj create mode 100644 84_Super_Star_Trek/vbnet/SuperStarTrek.sln create mode 100644 84_Super_Star_Trek/vbnet/SuperStarTrek.vbproj create mode 100644 85_Synonym/csharp/Synonym.csproj create mode 100644 85_Synonym/csharp/Synonym.sln create mode 100644 85_Synonym/vbnet/Synonym.sln create mode 100644 85_Synonym/vbnet/Synonym.vbproj create mode 100644 86_Target/vbnet/Target.sln create mode 100644 86_Target/vbnet/Target.vbproj create mode 100644 87_3-D_Plot/vbnet/ThreeDPlot.sln create mode 100644 87_3-D_Plot/vbnet/ThreeDPlot.vbproj create mode 100644 88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.csproj create mode 100644 88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.sln create mode 100644 88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.sln create mode 100644 88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.vbproj create mode 100644 89_Tic-Tac-Toe/csharp/TicTacToe.sln create mode 100644 89_Tic-Tac-Toe/vbnet/TicTacToe.sln create mode 100644 89_Tic-Tac-Toe/vbnet/TicTacToe.vbproj create mode 100644 90_Tower/vbnet/Tower.sln create mode 100644 90_Tower/vbnet/Tower.vbproj create mode 100644 91_Train/vbnet/Train.sln create mode 100644 91_Train/vbnet/Train.vbproj create mode 100644 92_Trap/csharp/Trap.csproj create mode 100644 92_Trap/csharp/Trap.sln create mode 100644 92_Trap/vbnet/Trap.sln create mode 100644 92_Trap/vbnet/Trap.vbproj create mode 100644 93_23_Matches/vbnet/TwentyThreeMatches.sln create mode 100644 93_23_Matches/vbnet/TwentyThreeMatches.vbproj create mode 100644 94_War/vbnet/War.sln create mode 100644 94_War/vbnet/War.vbproj create mode 100644 95_Weekday/csharp/Weekday.csproj create mode 100644 95_Weekday/csharp/Weekday.sln create mode 100644 95_Weekday/vbnet/Weekday.sln create mode 100644 95_Weekday/vbnet/Weekday.vbproj diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index f9995994..e8ea235e 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -1,5 +1,4 @@ -using System.Diagnostics; -using DotnetUtils; +using DotnetUtils; using static System.Console; using static System.IO.Path; using static DotnetUtils.Methods; diff --git a/02_Amazing/vbnet/Amazing.sln b/02_Amazing/vbnet/Amazing.sln new file mode 100644 index 00000000..81309fe0 --- /dev/null +++ b/02_Amazing/vbnet/Amazing.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Amazing", "Amazing.vbproj", "{FB9DF301-CB34-4C9A-8823-F034303F5DA3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FB9DF301-CB34-4C9A-8823-F034303F5DA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB9DF301-CB34-4C9A-8823-F034303F5DA3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB9DF301-CB34-4C9A-8823-F034303F5DA3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB9DF301-CB34-4C9A-8823-F034303F5DA3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/02_Amazing/vbnet/Amazing.vbproj b/02_Amazing/vbnet/Amazing.vbproj new file mode 100644 index 00000000..c619d3fa --- /dev/null +++ b/02_Amazing/vbnet/Amazing.vbproj @@ -0,0 +1,8 @@ + + + Exe + Amazing + net6.0 + 16.9 + + diff --git a/03_Animal/vbnet/Animal.sln b/03_Animal/vbnet/Animal.sln new file mode 100644 index 00000000..eaaf1b67 --- /dev/null +++ b/03_Animal/vbnet/Animal.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Animal", "Animal.vbproj", "{147D66D5-D817-4024-9447-9F5B9A6D2B7D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {147D66D5-D817-4024-9447-9F5B9A6D2B7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {147D66D5-D817-4024-9447-9F5B9A6D2B7D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {147D66D5-D817-4024-9447-9F5B9A6D2B7D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {147D66D5-D817-4024-9447-9F5B9A6D2B7D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/03_Animal/vbnet/Animal.vbproj b/03_Animal/vbnet/Animal.vbproj new file mode 100644 index 00000000..f54e4e3d --- /dev/null +++ b/03_Animal/vbnet/Animal.vbproj @@ -0,0 +1,8 @@ + + + Exe + Animal + net6.0 + 16.9 + + diff --git a/04_Awari/csharp/Awari.sln b/04_Awari/csharp/Awari.sln new file mode 100644 index 00000000..816cfcc9 --- /dev/null +++ b/04_Awari/csharp/Awari.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp", "csharp.csproj", "{4E2057CB-0BFE-41A4-910C-798DFABF7FE9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4E2057CB-0BFE-41A4-910C-798DFABF7FE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E2057CB-0BFE-41A4-910C-798DFABF7FE9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E2057CB-0BFE-41A4-910C-798DFABF7FE9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E2057CB-0BFE-41A4-910C-798DFABF7FE9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/04_Awari/vbnet/Awari.sln b/04_Awari/vbnet/Awari.sln new file mode 100644 index 00000000..ef0fd0cf --- /dev/null +++ b/04_Awari/vbnet/Awari.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Awari", "Awari.vbproj", "{718AECEB-CC24-49C8-B620-B2F93E021C51}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {718AECEB-CC24-49C8-B620-B2F93E021C51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {718AECEB-CC24-49C8-B620-B2F93E021C51}.Debug|Any CPU.Build.0 = Debug|Any CPU + {718AECEB-CC24-49C8-B620-B2F93E021C51}.Release|Any CPU.ActiveCfg = Release|Any CPU + {718AECEB-CC24-49C8-B620-B2F93E021C51}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/04_Awari/vbnet/Awari.vbproj b/04_Awari/vbnet/Awari.vbproj new file mode 100644 index 00000000..368d6f02 --- /dev/null +++ b/04_Awari/vbnet/Awari.vbproj @@ -0,0 +1,8 @@ + + + Exe + Awari + net6.0 + 16.9 + + diff --git a/05_Bagels/csharp/Bagels.sln b/05_Bagels/csharp/Bagels.sln new file mode 100644 index 00000000..3aaa718b --- /dev/null +++ b/05_Bagels/csharp/Bagels.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bagels", "Bagels.csproj", "{2FC5F33F-2C4B-4707-94E5-3C9B2B633EFE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2FC5F33F-2C4B-4707-94E5-3C9B2B633EFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2FC5F33F-2C4B-4707-94E5-3C9B2B633EFE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2FC5F33F-2C4B-4707-94E5-3C9B2B633EFE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2FC5F33F-2C4B-4707-94E5-3C9B2B633EFE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/05_Bagels/vbnet/Bagels.sln b/05_Bagels/vbnet/Bagels.sln new file mode 100644 index 00000000..ab6fa275 --- /dev/null +++ b/05_Bagels/vbnet/Bagels.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Bagels", "Bagels.vbproj", "{913FE7A8-B481-4EB3-8938-566BEAD5B0F2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {913FE7A8-B481-4EB3-8938-566BEAD5B0F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {913FE7A8-B481-4EB3-8938-566BEAD5B0F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {913FE7A8-B481-4EB3-8938-566BEAD5B0F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {913FE7A8-B481-4EB3-8938-566BEAD5B0F2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/05_Bagels/vbnet/Bagels.vbproj b/05_Bagels/vbnet/Bagels.vbproj new file mode 100644 index 00000000..c0d9d2d0 --- /dev/null +++ b/05_Bagels/vbnet/Bagels.vbproj @@ -0,0 +1,8 @@ + + + Exe + Bagels + net6.0 + 16.9 + + diff --git a/07_Basketball/csharp/Basketball.csproj b/07_Basketball/csharp/Basketball.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/07_Basketball/csharp/Basketball.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/07_Basketball/csharp/Basketball.sln b/07_Basketball/csharp/Basketball.sln new file mode 100644 index 00000000..92f2de05 --- /dev/null +++ b/07_Basketball/csharp/Basketball.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Basketball", "Basketball.csproj", "{00D03FB3-B485-480F-B14D-746371BDE08B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {00D03FB3-B485-480F-B14D-746371BDE08B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00D03FB3-B485-480F-B14D-746371BDE08B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00D03FB3-B485-480F-B14D-746371BDE08B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00D03FB3-B485-480F-B14D-746371BDE08B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/07_Basketball/vbnet/Basketball.sln b/07_Basketball/vbnet/Basketball.sln new file mode 100644 index 00000000..b32c954f --- /dev/null +++ b/07_Basketball/vbnet/Basketball.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Basketball", "Basketball.vbproj", "{09C533F2-4874-4BA4-9F80-BBE9E8E17456}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {09C533F2-4874-4BA4-9F80-BBE9E8E17456}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {09C533F2-4874-4BA4-9F80-BBE9E8E17456}.Debug|Any CPU.Build.0 = Debug|Any CPU + {09C533F2-4874-4BA4-9F80-BBE9E8E17456}.Release|Any CPU.ActiveCfg = Release|Any CPU + {09C533F2-4874-4BA4-9F80-BBE9E8E17456}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/07_Basketball/vbnet/Basketball.vbproj b/07_Basketball/vbnet/Basketball.vbproj new file mode 100644 index 00000000..6d9f101f --- /dev/null +++ b/07_Basketball/vbnet/Basketball.vbproj @@ -0,0 +1,8 @@ + + + Exe + Basketball + net6.0 + 16.9 + + diff --git a/09_Battle/vbnet/Battle.sln b/09_Battle/vbnet/Battle.sln new file mode 100644 index 00000000..bf92bf39 --- /dev/null +++ b/09_Battle/vbnet/Battle.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Battle", "Battle.vbproj", "{D8475464-CB9B-448F-89A7-5BA15193C495}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D8475464-CB9B-448F-89A7-5BA15193C495}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D8475464-CB9B-448F-89A7-5BA15193C495}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D8475464-CB9B-448F-89A7-5BA15193C495}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D8475464-CB9B-448F-89A7-5BA15193C495}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/09_Battle/vbnet/Battle.vbproj b/09_Battle/vbnet/Battle.vbproj new file mode 100644 index 00000000..dc5c5908 --- /dev/null +++ b/09_Battle/vbnet/Battle.vbproj @@ -0,0 +1,8 @@ + + + Exe + Battle + net6.0 + 16.9 + + diff --git a/10_Blackjack/csharp/Blackjack.sln b/10_Blackjack/csharp/Blackjack.sln new file mode 100644 index 00000000..1a01fb8b --- /dev/null +++ b/10_Blackjack/csharp/Blackjack.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blackjack", "Blackjack.csproj", "{83253F48-9CCD-475C-A990-8703F1A2E31C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {83253F48-9CCD-475C-A990-8703F1A2E31C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {83253F48-9CCD-475C-A990-8703F1A2E31C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83253F48-9CCD-475C-A990-8703F1A2E31C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {83253F48-9CCD-475C-A990-8703F1A2E31C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/10_Blackjack/vbnet/Blackjack.sln b/10_Blackjack/vbnet/Blackjack.sln new file mode 100644 index 00000000..2610b4a7 --- /dev/null +++ b/10_Blackjack/vbnet/Blackjack.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Blackjack", "Blackjack.vbproj", "{B112CA5F-142B-46E9-92CB-5E3A84816AAE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B112CA5F-142B-46E9-92CB-5E3A84816AAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B112CA5F-142B-46E9-92CB-5E3A84816AAE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B112CA5F-142B-46E9-92CB-5E3A84816AAE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B112CA5F-142B-46E9-92CB-5E3A84816AAE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/10_Blackjack/vbnet/Blackjack.vbproj b/10_Blackjack/vbnet/Blackjack.vbproj new file mode 100644 index 00000000..bc1d8eed --- /dev/null +++ b/10_Blackjack/vbnet/Blackjack.vbproj @@ -0,0 +1,8 @@ + + + Exe + Blackjack + net6.0 + 16.9 + + diff --git a/11_Bombardment/csharp/Bombardment.sln b/11_Bombardment/csharp/Bombardment.sln new file mode 100644 index 00000000..a401c67e --- /dev/null +++ b/11_Bombardment/csharp/Bombardment.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bombardment", "Bombardment.csproj", "{1DCFD283-9300-405B-A2B4-231F30265730}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1DCFD283-9300-405B-A2B4-231F30265730}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1DCFD283-9300-405B-A2B4-231F30265730}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1DCFD283-9300-405B-A2B4-231F30265730}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1DCFD283-9300-405B-A2B4-231F30265730}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/11_Bombardment/vbnet/Bombardment.sln b/11_Bombardment/vbnet/Bombardment.sln new file mode 100644 index 00000000..326fb000 --- /dev/null +++ b/11_Bombardment/vbnet/Bombardment.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Bombardment", "Bombardment.vbproj", "{7C967BC0-101C-413F-92A8-3A8A7D9846FE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7C967BC0-101C-413F-92A8-3A8A7D9846FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7C967BC0-101C-413F-92A8-3A8A7D9846FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7C967BC0-101C-413F-92A8-3A8A7D9846FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7C967BC0-101C-413F-92A8-3A8A7D9846FE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/11_Bombardment/vbnet/Bombardment.vbproj b/11_Bombardment/vbnet/Bombardment.vbproj new file mode 100644 index 00000000..746887ce --- /dev/null +++ b/11_Bombardment/vbnet/Bombardment.vbproj @@ -0,0 +1,8 @@ + + + Exe + Bombardment + net6.0 + 16.9 + + diff --git a/12_Bombs_Away/vbnet/BombsAway.sln b/12_Bombs_Away/vbnet/BombsAway.sln new file mode 100644 index 00000000..124d3943 --- /dev/null +++ b/12_Bombs_Away/vbnet/BombsAway.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "BombsAway", "BombsAway.vbproj", "{7FB28848-EC1C-4594-B823-BA6DB06B34A8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7FB28848-EC1C-4594-B823-BA6DB06B34A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7FB28848-EC1C-4594-B823-BA6DB06B34A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7FB28848-EC1C-4594-B823-BA6DB06B34A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7FB28848-EC1C-4594-B823-BA6DB06B34A8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/12_Bombs_Away/vbnet/BombsAway.vbproj b/12_Bombs_Away/vbnet/BombsAway.vbproj new file mode 100644 index 00000000..da557be9 --- /dev/null +++ b/12_Bombs_Away/vbnet/BombsAway.vbproj @@ -0,0 +1,8 @@ + + + Exe + BombsAway + net6.0 + 16.9 + + diff --git a/13_Bounce/csharp/Bounce.csproj b/13_Bounce/csharp/Bounce.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/13_Bounce/csharp/Bounce.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/13_Bounce/csharp/Bounce.sln b/13_Bounce/csharp/Bounce.sln new file mode 100644 index 00000000..f844a126 --- /dev/null +++ b/13_Bounce/csharp/Bounce.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bounce", "Bounce.csproj", "{4A967985-8CB0-49D2-B322-B2668491CA6E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4A967985-8CB0-49D2-B322-B2668491CA6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A967985-8CB0-49D2-B322-B2668491CA6E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A967985-8CB0-49D2-B322-B2668491CA6E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A967985-8CB0-49D2-B322-B2668491CA6E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/13_Bounce/vbnet/Bounce.sln b/13_Bounce/vbnet/Bounce.sln new file mode 100644 index 00000000..327f27dc --- /dev/null +++ b/13_Bounce/vbnet/Bounce.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Bounce", "Bounce.vbproj", "{95D84C53-AE4E-4A5A-869A-A49D6FC89618}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {95D84C53-AE4E-4A5A-869A-A49D6FC89618}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95D84C53-AE4E-4A5A-869A-A49D6FC89618}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95D84C53-AE4E-4A5A-869A-A49D6FC89618}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95D84C53-AE4E-4A5A-869A-A49D6FC89618}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/13_Bounce/vbnet/Bounce.vbproj b/13_Bounce/vbnet/Bounce.vbproj new file mode 100644 index 00000000..33443331 --- /dev/null +++ b/13_Bounce/vbnet/Bounce.vbproj @@ -0,0 +1,8 @@ + + + Exe + Bounce + net6.0 + 16.9 + + diff --git a/14_Bowling/csharp/Bowling.csproj b/14_Bowling/csharp/Bowling.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/14_Bowling/csharp/Bowling.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/14_Bowling/csharp/Bowling.sln b/14_Bowling/csharp/Bowling.sln new file mode 100644 index 00000000..aa48103b --- /dev/null +++ b/14_Bowling/csharp/Bowling.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bowling", "Bowling.csproj", "{9951637A-8D70-42A4-8CB7-315FA414F960}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9951637A-8D70-42A4-8CB7-315FA414F960}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9951637A-8D70-42A4-8CB7-315FA414F960}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9951637A-8D70-42A4-8CB7-315FA414F960}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9951637A-8D70-42A4-8CB7-315FA414F960}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/14_Bowling/vbnet/Bowling.sln b/14_Bowling/vbnet/Bowling.sln new file mode 100644 index 00000000..98b8a996 --- /dev/null +++ b/14_Bowling/vbnet/Bowling.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Bowling", "Bowling.vbproj", "{DBEB424A-1538-4F14-BA57-BA4E326EF4D8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DBEB424A-1538-4F14-BA57-BA4E326EF4D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DBEB424A-1538-4F14-BA57-BA4E326EF4D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBEB424A-1538-4F14-BA57-BA4E326EF4D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DBEB424A-1538-4F14-BA57-BA4E326EF4D8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/14_Bowling/vbnet/Bowling.vbproj b/14_Bowling/vbnet/Bowling.vbproj new file mode 100644 index 00000000..36ec929f --- /dev/null +++ b/14_Bowling/vbnet/Bowling.vbproj @@ -0,0 +1,8 @@ + + + Exe + Bowling + net6.0 + 16.9 + + diff --git a/15_Boxing/vbnet/Boxing.sln b/15_Boxing/vbnet/Boxing.sln new file mode 100644 index 00000000..4cca8bb5 --- /dev/null +++ b/15_Boxing/vbnet/Boxing.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Boxing", "Boxing.vbproj", "{8BCEDE01-59A7-4AA3-AE09-8B7FD69A5867}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8BCEDE01-59A7-4AA3-AE09-8B7FD69A5867}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8BCEDE01-59A7-4AA3-AE09-8B7FD69A5867}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8BCEDE01-59A7-4AA3-AE09-8B7FD69A5867}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8BCEDE01-59A7-4AA3-AE09-8B7FD69A5867}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/15_Boxing/vbnet/Boxing.vbproj b/15_Boxing/vbnet/Boxing.vbproj new file mode 100644 index 00000000..f6774e72 --- /dev/null +++ b/15_Boxing/vbnet/Boxing.vbproj @@ -0,0 +1,8 @@ + + + Exe + Boxing + net6.0 + 16.9 + + diff --git a/16_Bug/csharp/Bug.csproj b/16_Bug/csharp/Bug.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/16_Bug/csharp/Bug.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/16_Bug/csharp/Bug.sln b/16_Bug/csharp/Bug.sln new file mode 100644 index 00000000..9024df5b --- /dev/null +++ b/16_Bug/csharp/Bug.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bug", "Bug.csproj", "{C1929CC1-C366-43E4-9476-AE107231A302}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C1929CC1-C366-43E4-9476-AE107231A302}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C1929CC1-C366-43E4-9476-AE107231A302}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C1929CC1-C366-43E4-9476-AE107231A302}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C1929CC1-C366-43E4-9476-AE107231A302}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/16_Bug/vbnet/Bug.sln b/16_Bug/vbnet/Bug.sln new file mode 100644 index 00000000..f0ef35a4 --- /dev/null +++ b/16_Bug/vbnet/Bug.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Bug", "Bug.vbproj", "{4F4EA8E5-55A8-4191-BE57-B28638C33609}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4F4EA8E5-55A8-4191-BE57-B28638C33609}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F4EA8E5-55A8-4191-BE57-B28638C33609}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F4EA8E5-55A8-4191-BE57-B28638C33609}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F4EA8E5-55A8-4191-BE57-B28638C33609}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/16_Bug/vbnet/Bug.vbproj b/16_Bug/vbnet/Bug.vbproj new file mode 100644 index 00000000..dd4f74e4 --- /dev/null +++ b/16_Bug/vbnet/Bug.vbproj @@ -0,0 +1,8 @@ + + + Exe + Bug + net6.0 + 16.9 + + diff --git a/17_Bullfight/vbnet/Bullfight.sln b/17_Bullfight/vbnet/Bullfight.sln new file mode 100644 index 00000000..9fec219d --- /dev/null +++ b/17_Bullfight/vbnet/Bullfight.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Bullfight", "Bullfight.vbproj", "{38805A6B-C251-4C45-9832-B8E2F3F6436F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {38805A6B-C251-4C45-9832-B8E2F3F6436F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {38805A6B-C251-4C45-9832-B8E2F3F6436F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {38805A6B-C251-4C45-9832-B8E2F3F6436F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {38805A6B-C251-4C45-9832-B8E2F3F6436F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/17_Bullfight/vbnet/Bullfight.vbproj b/17_Bullfight/vbnet/Bullfight.vbproj new file mode 100644 index 00000000..016406fa --- /dev/null +++ b/17_Bullfight/vbnet/Bullfight.vbproj @@ -0,0 +1,8 @@ + + + Exe + Bullfight + net6.0 + 16.9 + + diff --git a/18_Bullseye/vbnet/Bullseye.sln b/18_Bullseye/vbnet/Bullseye.sln new file mode 100644 index 00000000..03e2390c --- /dev/null +++ b/18_Bullseye/vbnet/Bullseye.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Bullseye", "Bullseye.vbproj", "{0CFD308F-EB9C-4A05-B742-5EE7C912A5E4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0CFD308F-EB9C-4A05-B742-5EE7C912A5E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0CFD308F-EB9C-4A05-B742-5EE7C912A5E4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0CFD308F-EB9C-4A05-B742-5EE7C912A5E4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0CFD308F-EB9C-4A05-B742-5EE7C912A5E4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/18_Bullseye/vbnet/Bullseye.vbproj b/18_Bullseye/vbnet/Bullseye.vbproj new file mode 100644 index 00000000..3f13676f --- /dev/null +++ b/18_Bullseye/vbnet/Bullseye.vbproj @@ -0,0 +1,8 @@ + + + Exe + Bullseye + net6.0 + 16.9 + + diff --git a/19_Bunny/csharp/Bunny.csproj b/19_Bunny/csharp/Bunny.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/19_Bunny/csharp/Bunny.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/19_Bunny/csharp/Bunny.sln b/19_Bunny/csharp/Bunny.sln new file mode 100644 index 00000000..c7f9f008 --- /dev/null +++ b/19_Bunny/csharp/Bunny.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bunny", "Bunny.csproj", "{6685F5CF-20F2-4682-B187-50105BD44906}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6685F5CF-20F2-4682-B187-50105BD44906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6685F5CF-20F2-4682-B187-50105BD44906}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6685F5CF-20F2-4682-B187-50105BD44906}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6685F5CF-20F2-4682-B187-50105BD44906}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/19_Bunny/vbnet/Bunny.sln b/19_Bunny/vbnet/Bunny.sln new file mode 100644 index 00000000..b5d177ca --- /dev/null +++ b/19_Bunny/vbnet/Bunny.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Bunny", "Bunny.vbproj", "{E9098ADF-4B31-4082-9102-2A5BB8B40C6C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E9098ADF-4B31-4082-9102-2A5BB8B40C6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9098ADF-4B31-4082-9102-2A5BB8B40C6C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9098ADF-4B31-4082-9102-2A5BB8B40C6C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9098ADF-4B31-4082-9102-2A5BB8B40C6C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/19_Bunny/vbnet/Bunny.vbproj b/19_Bunny/vbnet/Bunny.vbproj new file mode 100644 index 00000000..49bd3df2 --- /dev/null +++ b/19_Bunny/vbnet/Bunny.vbproj @@ -0,0 +1,8 @@ + + + Exe + Bunny + net6.0 + 16.9 + + diff --git a/20_Buzzword/vbnet/Buzzword.sln b/20_Buzzword/vbnet/Buzzword.sln new file mode 100644 index 00000000..2f8a8ef3 --- /dev/null +++ b/20_Buzzword/vbnet/Buzzword.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Buzzword", "Buzzword.vbproj", "{B2BD53F2-82C3-4729-BA82-DB96E18F8666}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B2BD53F2-82C3-4729-BA82-DB96E18F8666}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2BD53F2-82C3-4729-BA82-DB96E18F8666}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2BD53F2-82C3-4729-BA82-DB96E18F8666}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2BD53F2-82C3-4729-BA82-DB96E18F8666}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/20_Buzzword/vbnet/Buzzword.vbproj b/20_Buzzword/vbnet/Buzzword.vbproj new file mode 100644 index 00000000..945c5a63 --- /dev/null +++ b/20_Buzzword/vbnet/Buzzword.vbproj @@ -0,0 +1,8 @@ + + + Exe + Buzzword + net6.0 + 16.9 + + diff --git a/21_Calendar/vbnet/Calendar.sln b/21_Calendar/vbnet/Calendar.sln new file mode 100644 index 00000000..c8e5c017 --- /dev/null +++ b/21_Calendar/vbnet/Calendar.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Calendar", "Calendar.vbproj", "{00B21257-3E25-4150-AA6D-266350688663}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {00B21257-3E25-4150-AA6D-266350688663}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00B21257-3E25-4150-AA6D-266350688663}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00B21257-3E25-4150-AA6D-266350688663}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00B21257-3E25-4150-AA6D-266350688663}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/21_Calendar/vbnet/Calendar.vbproj b/21_Calendar/vbnet/Calendar.vbproj new file mode 100644 index 00000000..ed6bd15a --- /dev/null +++ b/21_Calendar/vbnet/Calendar.vbproj @@ -0,0 +1,8 @@ + + + Exe + Calendar + net6.0 + 16.9 + + diff --git a/22_Change/vbnet/Change.sln b/22_Change/vbnet/Change.sln new file mode 100644 index 00000000..4af8571a --- /dev/null +++ b/22_Change/vbnet/Change.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Change", "Change.vbproj", "{77FC724B-EA88-4419-824B-32366FFE9608}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {77FC724B-EA88-4419-824B-32366FFE9608}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {77FC724B-EA88-4419-824B-32366FFE9608}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77FC724B-EA88-4419-824B-32366FFE9608}.Release|Any CPU.ActiveCfg = Release|Any CPU + {77FC724B-EA88-4419-824B-32366FFE9608}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/22_Change/vbnet/Change.vbproj b/22_Change/vbnet/Change.vbproj new file mode 100644 index 00000000..b6a5e3c1 --- /dev/null +++ b/22_Change/vbnet/Change.vbproj @@ -0,0 +1,8 @@ + + + Exe + Change + net6.0 + 16.9 + + diff --git a/23_Checkers/csharp/Checkers.csproj b/23_Checkers/csharp/Checkers.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/23_Checkers/csharp/Checkers.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/23_Checkers/csharp/Checkers.sln b/23_Checkers/csharp/Checkers.sln new file mode 100644 index 00000000..f7cce0b6 --- /dev/null +++ b/23_Checkers/csharp/Checkers.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Checkers", "Checkers.csproj", "{52D0DDFC-1A0D-4E57-A4FC-428EC717313C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {52D0DDFC-1A0D-4E57-A4FC-428EC717313C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52D0DDFC-1A0D-4E57-A4FC-428EC717313C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52D0DDFC-1A0D-4E57-A4FC-428EC717313C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52D0DDFC-1A0D-4E57-A4FC-428EC717313C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/23_Checkers/vbnet/Checkers.sln b/23_Checkers/vbnet/Checkers.sln new file mode 100644 index 00000000..f5409425 --- /dev/null +++ b/23_Checkers/vbnet/Checkers.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Checkers", "Checkers.vbproj", "{92B871EF-4871-40C0-ADDE-406301B937B9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {92B871EF-4871-40C0-ADDE-406301B937B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92B871EF-4871-40C0-ADDE-406301B937B9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92B871EF-4871-40C0-ADDE-406301B937B9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92B871EF-4871-40C0-ADDE-406301B937B9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/23_Checkers/vbnet/Checkers.vbproj b/23_Checkers/vbnet/Checkers.vbproj new file mode 100644 index 00000000..fb77091f --- /dev/null +++ b/23_Checkers/vbnet/Checkers.vbproj @@ -0,0 +1,8 @@ + + + Exe + Checkers + net6.0 + 16.9 + + diff --git a/24_Chemist/vbnet/Chemist.sln b/24_Chemist/vbnet/Chemist.sln new file mode 100644 index 00000000..1200eeff --- /dev/null +++ b/24_Chemist/vbnet/Chemist.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Chemist", "Chemist.vbproj", "{25BEFBB8-58A1-4691-9CE6-D8C770F5189D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {25BEFBB8-58A1-4691-9CE6-D8C770F5189D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25BEFBB8-58A1-4691-9CE6-D8C770F5189D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25BEFBB8-58A1-4691-9CE6-D8C770F5189D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25BEFBB8-58A1-4691-9CE6-D8C770F5189D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/24_Chemist/vbnet/Chemist.vbproj b/24_Chemist/vbnet/Chemist.vbproj new file mode 100644 index 00000000..7990a9b7 --- /dev/null +++ b/24_Chemist/vbnet/Chemist.vbproj @@ -0,0 +1,8 @@ + + + Exe + Chemist + net6.0 + 16.9 + + diff --git a/25_Chief/csharp/Chief.csproj b/25_Chief/csharp/Chief.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/25_Chief/csharp/Chief.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/25_Chief/csharp/Chief.sln b/25_Chief/csharp/Chief.sln new file mode 100644 index 00000000..036992c3 --- /dev/null +++ b/25_Chief/csharp/Chief.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chief", "Chief.csproj", "{AE650092-EEF2-4747-91F4-C8311AD16A4B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AE650092-EEF2-4747-91F4-C8311AD16A4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE650092-EEF2-4747-91F4-C8311AD16A4B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE650092-EEF2-4747-91F4-C8311AD16A4B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE650092-EEF2-4747-91F4-C8311AD16A4B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/25_Chief/vbnet/Chief.sln b/25_Chief/vbnet/Chief.sln new file mode 100644 index 00000000..579b0124 --- /dev/null +++ b/25_Chief/vbnet/Chief.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Chief", "Chief.vbproj", "{9BAA28D9-1DCF-42DA-934A-CD3EC5E26E7C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9BAA28D9-1DCF-42DA-934A-CD3EC5E26E7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9BAA28D9-1DCF-42DA-934A-CD3EC5E26E7C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9BAA28D9-1DCF-42DA-934A-CD3EC5E26E7C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9BAA28D9-1DCF-42DA-934A-CD3EC5E26E7C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/25_Chief/vbnet/Chief.vbproj b/25_Chief/vbnet/Chief.vbproj new file mode 100644 index 00000000..09c22917 --- /dev/null +++ b/25_Chief/vbnet/Chief.vbproj @@ -0,0 +1,8 @@ + + + Exe + Chief + net6.0 + 16.9 + + diff --git a/26_Chomp/csharp/Chomp.csproj b/26_Chomp/csharp/Chomp.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/26_Chomp/csharp/Chomp.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/26_Chomp/csharp/Chomp.sln b/26_Chomp/csharp/Chomp.sln new file mode 100644 index 00000000..1567eb9d --- /dev/null +++ b/26_Chomp/csharp/Chomp.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chomp", "Chomp.csproj", "{35863FB3-002D-4618-B993-51A51A586BCC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {35863FB3-002D-4618-B993-51A51A586BCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35863FB3-002D-4618-B993-51A51A586BCC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35863FB3-002D-4618-B993-51A51A586BCC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35863FB3-002D-4618-B993-51A51A586BCC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/26_Chomp/vbnet/Chomp.sln b/26_Chomp/vbnet/Chomp.sln new file mode 100644 index 00000000..3b772010 --- /dev/null +++ b/26_Chomp/vbnet/Chomp.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Chomp", "Chomp.vbproj", "{F7F8E933-9679-4393-94F0-46F47D81B025}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F7F8E933-9679-4393-94F0-46F47D81B025}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F7F8E933-9679-4393-94F0-46F47D81B025}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F7F8E933-9679-4393-94F0-46F47D81B025}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F7F8E933-9679-4393-94F0-46F47D81B025}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/26_Chomp/vbnet/Chomp.vbproj b/26_Chomp/vbnet/Chomp.vbproj new file mode 100644 index 00000000..a3308b2a --- /dev/null +++ b/26_Chomp/vbnet/Chomp.vbproj @@ -0,0 +1,8 @@ + + + Exe + Chomp + net6.0 + 16.9 + + diff --git a/27_Civil_War/vbnet/CivilWar.sln b/27_Civil_War/vbnet/CivilWar.sln new file mode 100644 index 00000000..3f696f6f --- /dev/null +++ b/27_Civil_War/vbnet/CivilWar.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CivilWar", "CivilWar.vbproj", "{D726A817-AF69-43B9-9092-876453960C19}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D726A817-AF69-43B9-9092-876453960C19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D726A817-AF69-43B9-9092-876453960C19}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D726A817-AF69-43B9-9092-876453960C19}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D726A817-AF69-43B9-9092-876453960C19}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/27_Civil_War/vbnet/CivilWar.vbproj b/27_Civil_War/vbnet/CivilWar.vbproj new file mode 100644 index 00000000..d132bbbc --- /dev/null +++ b/27_Civil_War/vbnet/CivilWar.vbproj @@ -0,0 +1,8 @@ + + + Exe + CivilWar + net6.0 + 16.9 + + diff --git a/28_Combat/vbnet/Combat.sln b/28_Combat/vbnet/Combat.sln new file mode 100644 index 00000000..f06a8366 --- /dev/null +++ b/28_Combat/vbnet/Combat.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Combat", "Combat.vbproj", "{B7C67E0E-1493-4957-9FD9-A384D038F024}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B7C67E0E-1493-4957-9FD9-A384D038F024}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7C67E0E-1493-4957-9FD9-A384D038F024}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7C67E0E-1493-4957-9FD9-A384D038F024}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7C67E0E-1493-4957-9FD9-A384D038F024}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/28_Combat/vbnet/Combat.vbproj b/28_Combat/vbnet/Combat.vbproj new file mode 100644 index 00000000..19ba1b19 --- /dev/null +++ b/28_Combat/vbnet/Combat.vbproj @@ -0,0 +1,8 @@ + + + Exe + Combat + net6.0 + 16.9 + + diff --git a/29_Craps/vbnet/Craps.sln b/29_Craps/vbnet/Craps.sln new file mode 100644 index 00000000..7d564508 --- /dev/null +++ b/29_Craps/vbnet/Craps.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Craps", "Craps.vbproj", "{297AA824-815F-4E2B-948C-BDAD2266C5AF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {297AA824-815F-4E2B-948C-BDAD2266C5AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {297AA824-815F-4E2B-948C-BDAD2266C5AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {297AA824-815F-4E2B-948C-BDAD2266C5AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {297AA824-815F-4E2B-948C-BDAD2266C5AF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/29_Craps/vbnet/Craps.vbproj b/29_Craps/vbnet/Craps.vbproj new file mode 100644 index 00000000..a1c6ee27 --- /dev/null +++ b/29_Craps/vbnet/Craps.vbproj @@ -0,0 +1,8 @@ + + + Exe + Craps + net6.0 + 16.9 + + diff --git a/30_Cube/csharp/Cube.csproj b/30_Cube/csharp/Cube.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/30_Cube/csharp/Cube.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/30_Cube/csharp/Cube.sln b/30_Cube/csharp/Cube.sln new file mode 100644 index 00000000..be69dc76 --- /dev/null +++ b/30_Cube/csharp/Cube.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cube", "Cube.csproj", "{CC2F0DBE-EBA0-4275-ACA4-7140E3202889}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CC2F0DBE-EBA0-4275-ACA4-7140E3202889}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CC2F0DBE-EBA0-4275-ACA4-7140E3202889}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CC2F0DBE-EBA0-4275-ACA4-7140E3202889}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CC2F0DBE-EBA0-4275-ACA4-7140E3202889}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/30_Cube/vbnet/Cube.sln b/30_Cube/vbnet/Cube.sln new file mode 100644 index 00000000..36f7fc75 --- /dev/null +++ b/30_Cube/vbnet/Cube.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Cube", "Cube.vbproj", "{C4AA207B-37EC-4746-B634-FBFC9522F3F8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C4AA207B-37EC-4746-B634-FBFC9522F3F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C4AA207B-37EC-4746-B634-FBFC9522F3F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C4AA207B-37EC-4746-B634-FBFC9522F3F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C4AA207B-37EC-4746-B634-FBFC9522F3F8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/30_Cube/vbnet/Cube.vbproj b/30_Cube/vbnet/Cube.vbproj new file mode 100644 index 00000000..1cbe484d --- /dev/null +++ b/30_Cube/vbnet/Cube.vbproj @@ -0,0 +1,8 @@ + + + Exe + Cube + net6.0 + 16.9 + + diff --git a/31_Depth_Charge/vbnet/DepthCharge.sln b/31_Depth_Charge/vbnet/DepthCharge.sln new file mode 100644 index 00000000..b042eee0 --- /dev/null +++ b/31_Depth_Charge/vbnet/DepthCharge.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "DepthCharge", "DepthCharge.vbproj", "{7F8404FE-7CF2-46AC-B4D4-2CAB5EF3FB2F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7F8404FE-7CF2-46AC-B4D4-2CAB5EF3FB2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F8404FE-7CF2-46AC-B4D4-2CAB5EF3FB2F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F8404FE-7CF2-46AC-B4D4-2CAB5EF3FB2F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F8404FE-7CF2-46AC-B4D4-2CAB5EF3FB2F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/31_Depth_Charge/vbnet/DepthCharge.vbproj b/31_Depth_Charge/vbnet/DepthCharge.vbproj new file mode 100644 index 00000000..ee43c035 --- /dev/null +++ b/31_Depth_Charge/vbnet/DepthCharge.vbproj @@ -0,0 +1,8 @@ + + + Exe + DepthCharge + net6.0 + 16.9 + + diff --git a/32_Diamond/csharp/Diamond.csproj b/32_Diamond/csharp/Diamond.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/32_Diamond/csharp/Diamond.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/32_Diamond/csharp/Diamond.sln b/32_Diamond/csharp/Diamond.sln new file mode 100644 index 00000000..2af37dbd --- /dev/null +++ b/32_Diamond/csharp/Diamond.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Diamond", "Diamond.csproj", "{44B406C8-70F0-4183-B19A-5B045A1AEBA4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {44B406C8-70F0-4183-B19A-5B045A1AEBA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {44B406C8-70F0-4183-B19A-5B045A1AEBA4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {44B406C8-70F0-4183-B19A-5B045A1AEBA4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {44B406C8-70F0-4183-B19A-5B045A1AEBA4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/32_Diamond/vbnet/Diamond.sln b/32_Diamond/vbnet/Diamond.sln new file mode 100644 index 00000000..3f05715d --- /dev/null +++ b/32_Diamond/vbnet/Diamond.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Diamond", "Diamond.vbproj", "{87084ED3-F01C-4D7E-8BE7-10C2F3FA148F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {87084ED3-F01C-4D7E-8BE7-10C2F3FA148F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87084ED3-F01C-4D7E-8BE7-10C2F3FA148F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87084ED3-F01C-4D7E-8BE7-10C2F3FA148F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87084ED3-F01C-4D7E-8BE7-10C2F3FA148F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/32_Diamond/vbnet/Diamond.vbproj b/32_Diamond/vbnet/Diamond.vbproj new file mode 100644 index 00000000..069fe872 --- /dev/null +++ b/32_Diamond/vbnet/Diamond.vbproj @@ -0,0 +1,8 @@ + + + Exe + Diamond + net6.0 + 16.9 + + diff --git a/33_Dice/csharp/Dice.sln b/33_Dice/csharp/Dice.sln new file mode 100644 index 00000000..738a8c1c --- /dev/null +++ b/33_Dice/csharp/Dice.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dice", "Dice.csproj", "{D136AC51-DDC0-471A-8EAC-D3C772FA7D51}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D136AC51-DDC0-471A-8EAC-D3C772FA7D51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D136AC51-DDC0-471A-8EAC-D3C772FA7D51}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D136AC51-DDC0-471A-8EAC-D3C772FA7D51}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D136AC51-DDC0-471A-8EAC-D3C772FA7D51}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/33_Dice/vbnet/Dice.sln b/33_Dice/vbnet/Dice.sln new file mode 100644 index 00000000..afb7b912 --- /dev/null +++ b/33_Dice/vbnet/Dice.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Dice", "Dice.vbproj", "{6410CCD0-0D78-49C9-9B15-70F901A1EB19}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6410CCD0-0D78-49C9-9B15-70F901A1EB19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6410CCD0-0D78-49C9-9B15-70F901A1EB19}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6410CCD0-0D78-49C9-9B15-70F901A1EB19}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6410CCD0-0D78-49C9-9B15-70F901A1EB19}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/33_Dice/vbnet/Dice.vbproj b/33_Dice/vbnet/Dice.vbproj new file mode 100644 index 00000000..16929f96 --- /dev/null +++ b/33_Dice/vbnet/Dice.vbproj @@ -0,0 +1,8 @@ + + + Exe + Dice + net6.0 + 16.9 + + diff --git a/34_Digits/csharp/Digits.csproj b/34_Digits/csharp/Digits.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/34_Digits/csharp/Digits.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/34_Digits/csharp/Digits.sln b/34_Digits/csharp/Digits.sln new file mode 100644 index 00000000..04b94496 --- /dev/null +++ b/34_Digits/csharp/Digits.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Digits", "Digits.csproj", "{BB89211D-85FB-4FC0-AF62-715459227D7E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BB89211D-85FB-4FC0-AF62-715459227D7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB89211D-85FB-4FC0-AF62-715459227D7E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB89211D-85FB-4FC0-AF62-715459227D7E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB89211D-85FB-4FC0-AF62-715459227D7E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/34_Digits/vbnet/Digits.sln b/34_Digits/vbnet/Digits.sln new file mode 100644 index 00000000..2d5733a9 --- /dev/null +++ b/34_Digits/vbnet/Digits.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Digits", "Digits.vbproj", "{837EB2E4-3EE6-447A-8AF7-91CA08841B93}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {837EB2E4-3EE6-447A-8AF7-91CA08841B93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {837EB2E4-3EE6-447A-8AF7-91CA08841B93}.Debug|Any CPU.Build.0 = Debug|Any CPU + {837EB2E4-3EE6-447A-8AF7-91CA08841B93}.Release|Any CPU.ActiveCfg = Release|Any CPU + {837EB2E4-3EE6-447A-8AF7-91CA08841B93}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/34_Digits/vbnet/Digits.vbproj b/34_Digits/vbnet/Digits.vbproj new file mode 100644 index 00000000..d8f673e1 --- /dev/null +++ b/34_Digits/vbnet/Digits.vbproj @@ -0,0 +1,8 @@ + + + Exe + Digits + net6.0 + 16.9 + + diff --git a/35_Even_Wins/csharp/EvenWins.csproj b/35_Even_Wins/csharp/EvenWins.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/35_Even_Wins/csharp/EvenWins.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/35_Even_Wins/csharp/EvenWins.sln b/35_Even_Wins/csharp/EvenWins.sln new file mode 100644 index 00000000..b384c20c --- /dev/null +++ b/35_Even_Wins/csharp/EvenWins.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EvenWins", "EvenWins.csproj", "{84209510-4089-4147-B220-E41E534A228B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {84209510-4089-4147-B220-E41E534A228B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {84209510-4089-4147-B220-E41E534A228B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {84209510-4089-4147-B220-E41E534A228B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {84209510-4089-4147-B220-E41E534A228B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/35_Even_Wins/vbnet/EvenWins.sln b/35_Even_Wins/vbnet/EvenWins.sln new file mode 100644 index 00000000..0714f204 --- /dev/null +++ b/35_Even_Wins/vbnet/EvenWins.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "EvenWins", "EvenWins.vbproj", "{16D44A7A-9C05-4845-8289-3A65A4D978D0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {16D44A7A-9C05-4845-8289-3A65A4D978D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16D44A7A-9C05-4845-8289-3A65A4D978D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16D44A7A-9C05-4845-8289-3A65A4D978D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16D44A7A-9C05-4845-8289-3A65A4D978D0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/35_Even_Wins/vbnet/EvenWins.vbproj b/35_Even_Wins/vbnet/EvenWins.vbproj new file mode 100644 index 00000000..7ca1146f --- /dev/null +++ b/35_Even_Wins/vbnet/EvenWins.vbproj @@ -0,0 +1,8 @@ + + + Exe + EvenWins + net6.0 + 16.9 + + diff --git a/36_Flip_Flop/vbnet/FlipFlop.sln b/36_Flip_Flop/vbnet/FlipFlop.sln new file mode 100644 index 00000000..8301941b --- /dev/null +++ b/36_Flip_Flop/vbnet/FlipFlop.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "FlipFlop", "FlipFlop.vbproj", "{4A5887DD-FA0C-47EE-B3A2-E334DCE3544C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4A5887DD-FA0C-47EE-B3A2-E334DCE3544C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A5887DD-FA0C-47EE-B3A2-E334DCE3544C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A5887DD-FA0C-47EE-B3A2-E334DCE3544C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A5887DD-FA0C-47EE-B3A2-E334DCE3544C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/36_Flip_Flop/vbnet/FlipFlop.vbproj b/36_Flip_Flop/vbnet/FlipFlop.vbproj new file mode 100644 index 00000000..388b75c1 --- /dev/null +++ b/36_Flip_Flop/vbnet/FlipFlop.vbproj @@ -0,0 +1,8 @@ + + + Exe + FlipFlop + net6.0 + 16.9 + + diff --git a/37_Football/csharp/Football.csproj b/37_Football/csharp/Football.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/37_Football/csharp/Football.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/37_Football/csharp/Football.sln b/37_Football/csharp/Football.sln new file mode 100644 index 00000000..b0d85b41 --- /dev/null +++ b/37_Football/csharp/Football.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Football", "Football.csproj", "{092442FA-EA04-4A80-AB12-138E18CD480A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {092442FA-EA04-4A80-AB12-138E18CD480A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {092442FA-EA04-4A80-AB12-138E18CD480A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {092442FA-EA04-4A80-AB12-138E18CD480A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {092442FA-EA04-4A80-AB12-138E18CD480A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/37_Football/vbnet/Football.sln b/37_Football/vbnet/Football.sln new file mode 100644 index 00000000..2e177718 --- /dev/null +++ b/37_Football/vbnet/Football.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Football", "Football.vbproj", "{5491221D-33D3-4ADF-9E0A-FB58D5C12EE2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5491221D-33D3-4ADF-9E0A-FB58D5C12EE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5491221D-33D3-4ADF-9E0A-FB58D5C12EE2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5491221D-33D3-4ADF-9E0A-FB58D5C12EE2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5491221D-33D3-4ADF-9E0A-FB58D5C12EE2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/37_Football/vbnet/Football.vbproj b/37_Football/vbnet/Football.vbproj new file mode 100644 index 00000000..ce404640 --- /dev/null +++ b/37_Football/vbnet/Football.vbproj @@ -0,0 +1,8 @@ + + + Exe + Football + net6.0 + 16.9 + + diff --git a/38_Fur_Trader/vbnet/FurTrader.sln b/38_Fur_Trader/vbnet/FurTrader.sln new file mode 100644 index 00000000..cb129718 --- /dev/null +++ b/38_Fur_Trader/vbnet/FurTrader.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "FurTrader", "FurTrader.vbproj", "{D8310FB8-132A-4D43-A654-17E5A267DDBD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D8310FB8-132A-4D43-A654-17E5A267DDBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D8310FB8-132A-4D43-A654-17E5A267DDBD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D8310FB8-132A-4D43-A654-17E5A267DDBD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D8310FB8-132A-4D43-A654-17E5A267DDBD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/38_Fur_Trader/vbnet/FurTrader.vbproj b/38_Fur_Trader/vbnet/FurTrader.vbproj new file mode 100644 index 00000000..61ab6d99 --- /dev/null +++ b/38_Fur_Trader/vbnet/FurTrader.vbproj @@ -0,0 +1,8 @@ + + + Exe + FurTrader + net6.0 + 16.9 + + diff --git a/39_Golf/csharp/Golf.csproj b/39_Golf/csharp/Golf.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/39_Golf/csharp/Golf.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/39_Golf/csharp/Golf.sln b/39_Golf/csharp/Golf.sln new file mode 100644 index 00000000..07c90dde --- /dev/null +++ b/39_Golf/csharp/Golf.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Golf", "Golf.csproj", "{0D91BC87-BADF-445F-876F-38F3A66A3B83}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0D91BC87-BADF-445F-876F-38F3A66A3B83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0D91BC87-BADF-445F-876F-38F3A66A3B83}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0D91BC87-BADF-445F-876F-38F3A66A3B83}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0D91BC87-BADF-445F-876F-38F3A66A3B83}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/39_Golf/vbnet/Golf.sln b/39_Golf/vbnet/Golf.sln new file mode 100644 index 00000000..6698c79f --- /dev/null +++ b/39_Golf/vbnet/Golf.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Golf", "Golf.vbproj", "{65A2E065-6541-4E6E-B6F0-9881080B5FFF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {65A2E065-6541-4E6E-B6F0-9881080B5FFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65A2E065-6541-4E6E-B6F0-9881080B5FFF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65A2E065-6541-4E6E-B6F0-9881080B5FFF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65A2E065-6541-4E6E-B6F0-9881080B5FFF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/39_Golf/vbnet/Golf.vbproj b/39_Golf/vbnet/Golf.vbproj new file mode 100644 index 00000000..1a20f831 --- /dev/null +++ b/39_Golf/vbnet/Golf.vbproj @@ -0,0 +1,8 @@ + + + Exe + Golf + net6.0 + 16.9 + + diff --git a/40_Gomoko/csharp/Gomoko.csproj b/40_Gomoko/csharp/Gomoko.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/40_Gomoko/csharp/Gomoko.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/40_Gomoko/csharp/Gomoko.sln b/40_Gomoko/csharp/Gomoko.sln new file mode 100644 index 00000000..84182037 --- /dev/null +++ b/40_Gomoko/csharp/Gomoko.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gomoko", "Gomoko.csproj", "{558B84AB-2010-436E-B191-00980C6CBA61}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {558B84AB-2010-436E-B191-00980C6CBA61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {558B84AB-2010-436E-B191-00980C6CBA61}.Debug|Any CPU.Build.0 = Debug|Any CPU + {558B84AB-2010-436E-B191-00980C6CBA61}.Release|Any CPU.ActiveCfg = Release|Any CPU + {558B84AB-2010-436E-B191-00980C6CBA61}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/40_Gomoko/vbnet/Gomoko.sln b/40_Gomoko/vbnet/Gomoko.sln new file mode 100644 index 00000000..fb1c4673 --- /dev/null +++ b/40_Gomoko/vbnet/Gomoko.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Gomoko", "Gomoko.vbproj", "{AEA608B9-083C-4EE7-9DE7-A0AB4FE313A8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AEA608B9-083C-4EE7-9DE7-A0AB4FE313A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AEA608B9-083C-4EE7-9DE7-A0AB4FE313A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AEA608B9-083C-4EE7-9DE7-A0AB4FE313A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AEA608B9-083C-4EE7-9DE7-A0AB4FE313A8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/40_Gomoko/vbnet/Gomoko.vbproj b/40_Gomoko/vbnet/Gomoko.vbproj new file mode 100644 index 00000000..5350e761 --- /dev/null +++ b/40_Gomoko/vbnet/Gomoko.vbproj @@ -0,0 +1,8 @@ + + + Exe + Gomoko + net6.0 + 16.9 + + diff --git a/41_Guess/csharp/Guess.csproj b/41_Guess/csharp/Guess.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/41_Guess/csharp/Guess.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/41_Guess/csharp/Guess.sln b/41_Guess/csharp/Guess.sln new file mode 100644 index 00000000..c6649256 --- /dev/null +++ b/41_Guess/csharp/Guess.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Guess", "Guess.csproj", "{0D116201-33C0-4C86-A8D5-FF7C9CCC638F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0D116201-33C0-4C86-A8D5-FF7C9CCC638F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0D116201-33C0-4C86-A8D5-FF7C9CCC638F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0D116201-33C0-4C86-A8D5-FF7C9CCC638F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0D116201-33C0-4C86-A8D5-FF7C9CCC638F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/41_Guess/vbnet/Guess.sln b/41_Guess/vbnet/Guess.sln new file mode 100644 index 00000000..2238b0be --- /dev/null +++ b/41_Guess/vbnet/Guess.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Guess", "Guess.vbproj", "{33AB1024-1609-4163-BEAF-BA02A5D42F8A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {33AB1024-1609-4163-BEAF-BA02A5D42F8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {33AB1024-1609-4163-BEAF-BA02A5D42F8A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {33AB1024-1609-4163-BEAF-BA02A5D42F8A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {33AB1024-1609-4163-BEAF-BA02A5D42F8A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/41_Guess/vbnet/Guess.vbproj b/41_Guess/vbnet/Guess.vbproj new file mode 100644 index 00000000..8a5fe396 --- /dev/null +++ b/41_Guess/vbnet/Guess.vbproj @@ -0,0 +1,8 @@ + + + Exe + Guess + net6.0 + 16.9 + + diff --git a/42_Gunner/csharp/Gunner.sln b/42_Gunner/csharp/Gunner.sln new file mode 100644 index 00000000..bbc80af3 --- /dev/null +++ b/42_Gunner/csharp/Gunner.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp", "csharp.csproj", "{83323E98-D981-4AC2-A74B-36804C9C2497}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {83323E98-D981-4AC2-A74B-36804C9C2497}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {83323E98-D981-4AC2-A74B-36804C9C2497}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83323E98-D981-4AC2-A74B-36804C9C2497}.Release|Any CPU.ActiveCfg = Release|Any CPU + {83323E98-D981-4AC2-A74B-36804C9C2497}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/42_Gunner/vbnet/Gunner.sln b/42_Gunner/vbnet/Gunner.sln new file mode 100644 index 00000000..33d68126 --- /dev/null +++ b/42_Gunner/vbnet/Gunner.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Gunner", "Gunner.vbproj", "{CC347B04-B99C-4F77-BFCF-2DDFBB4A135D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CC347B04-B99C-4F77-BFCF-2DDFBB4A135D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CC347B04-B99C-4F77-BFCF-2DDFBB4A135D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CC347B04-B99C-4F77-BFCF-2DDFBB4A135D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CC347B04-B99C-4F77-BFCF-2DDFBB4A135D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/42_Gunner/vbnet/Gunner.vbproj b/42_Gunner/vbnet/Gunner.vbproj new file mode 100644 index 00000000..19918a80 --- /dev/null +++ b/42_Gunner/vbnet/Gunner.vbproj @@ -0,0 +1,8 @@ + + + Exe + Gunner + net6.0 + 16.9 + + diff --git a/43_Hammurabi/vbnet/Hammurabi.sln b/43_Hammurabi/vbnet/Hammurabi.sln new file mode 100644 index 00000000..41a13843 --- /dev/null +++ b/43_Hammurabi/vbnet/Hammurabi.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Hammurabi", "Hammurabi.vbproj", "{52BC86C8-4AE8-4F0C-9566-5E0D97BB17BF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {52BC86C8-4AE8-4F0C-9566-5E0D97BB17BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52BC86C8-4AE8-4F0C-9566-5E0D97BB17BF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52BC86C8-4AE8-4F0C-9566-5E0D97BB17BF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52BC86C8-4AE8-4F0C-9566-5E0D97BB17BF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/43_Hammurabi/vbnet/Hammurabi.vbproj b/43_Hammurabi/vbnet/Hammurabi.vbproj new file mode 100644 index 00000000..8f89306c --- /dev/null +++ b/43_Hammurabi/vbnet/Hammurabi.vbproj @@ -0,0 +1,8 @@ + + + Exe + Hammurabi + net6.0 + 16.9 + + diff --git a/44_Hangman/vbnet/Hangman.sln b/44_Hangman/vbnet/Hangman.sln new file mode 100644 index 00000000..355c5093 --- /dev/null +++ b/44_Hangman/vbnet/Hangman.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Hangman", "Hangman.vbproj", "{048C4117-70FC-4457-9B1D-BBD1FEDFEB76}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {048C4117-70FC-4457-9B1D-BBD1FEDFEB76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {048C4117-70FC-4457-9B1D-BBD1FEDFEB76}.Debug|Any CPU.Build.0 = Debug|Any CPU + {048C4117-70FC-4457-9B1D-BBD1FEDFEB76}.Release|Any CPU.ActiveCfg = Release|Any CPU + {048C4117-70FC-4457-9B1D-BBD1FEDFEB76}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/44_Hangman/vbnet/Hangman.vbproj b/44_Hangman/vbnet/Hangman.vbproj new file mode 100644 index 00000000..6ad7969c --- /dev/null +++ b/44_Hangman/vbnet/Hangman.vbproj @@ -0,0 +1,8 @@ + + + Exe + Hangman + net6.0 + 16.9 + + diff --git a/45_Hello/csharp/Hello.csproj b/45_Hello/csharp/Hello.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/45_Hello/csharp/Hello.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/45_Hello/csharp/Hello.sln b/45_Hello/csharp/Hello.sln new file mode 100644 index 00000000..216c70b6 --- /dev/null +++ b/45_Hello/csharp/Hello.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hello", "Hello.csproj", "{8ECD89E1-D9E1-4FA5-97B6-B1E68FE1CA16}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8ECD89E1-D9E1-4FA5-97B6-B1E68FE1CA16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8ECD89E1-D9E1-4FA5-97B6-B1E68FE1CA16}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8ECD89E1-D9E1-4FA5-97B6-B1E68FE1CA16}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8ECD89E1-D9E1-4FA5-97B6-B1E68FE1CA16}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/45_Hello/vbnet/Hello.sln b/45_Hello/vbnet/Hello.sln new file mode 100644 index 00000000..72ecdc64 --- /dev/null +++ b/45_Hello/vbnet/Hello.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Hello", "Hello.vbproj", "{7E2BDA03-A9F7-4DE5-AB8F-222DD87C833D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7E2BDA03-A9F7-4DE5-AB8F-222DD87C833D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7E2BDA03-A9F7-4DE5-AB8F-222DD87C833D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7E2BDA03-A9F7-4DE5-AB8F-222DD87C833D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7E2BDA03-A9F7-4DE5-AB8F-222DD87C833D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/45_Hello/vbnet/Hello.vbproj b/45_Hello/vbnet/Hello.vbproj new file mode 100644 index 00000000..9b55d805 --- /dev/null +++ b/45_Hello/vbnet/Hello.vbproj @@ -0,0 +1,8 @@ + + + Exe + Hello + net6.0 + 16.9 + + diff --git a/46_Hexapawn/vbnet/Hexapawn.sln b/46_Hexapawn/vbnet/Hexapawn.sln new file mode 100644 index 00000000..5aff142b --- /dev/null +++ b/46_Hexapawn/vbnet/Hexapawn.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Hexapawn", "Hexapawn.vbproj", "{83C2A51C-6014-4CC7-A4AF-81004B5F721F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {83C2A51C-6014-4CC7-A4AF-81004B5F721F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {83C2A51C-6014-4CC7-A4AF-81004B5F721F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83C2A51C-6014-4CC7-A4AF-81004B5F721F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {83C2A51C-6014-4CC7-A4AF-81004B5F721F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/46_Hexapawn/vbnet/Hexapawn.vbproj b/46_Hexapawn/vbnet/Hexapawn.vbproj new file mode 100644 index 00000000..4ed34b92 --- /dev/null +++ b/46_Hexapawn/vbnet/Hexapawn.vbproj @@ -0,0 +1,8 @@ + + + Exe + Hexapawn + net6.0 + 16.9 + + diff --git a/47_Hi-Lo/csharp/HiLo.sln b/47_Hi-Lo/csharp/HiLo.sln new file mode 100644 index 00000000..b735d83d --- /dev/null +++ b/47_Hi-Lo/csharp/HiLo.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "hi-lo", "hi-lo.csproj", "{59721819-A474-4348-8E3D-5F2FCA5D95FA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {59721819-A474-4348-8E3D-5F2FCA5D95FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {59721819-A474-4348-8E3D-5F2FCA5D95FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {59721819-A474-4348-8E3D-5F2FCA5D95FA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {59721819-A474-4348-8E3D-5F2FCA5D95FA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/47_Hi-Lo/vbnet/HiLo.sln b/47_Hi-Lo/vbnet/HiLo.sln new file mode 100644 index 00000000..fbd97f94 --- /dev/null +++ b/47_Hi-Lo/vbnet/HiLo.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "HiLo", "HiLo.vbproj", "{B93E0994-AEC4-4FC9-93C2-FC708368B32F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B93E0994-AEC4-4FC9-93C2-FC708368B32F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B93E0994-AEC4-4FC9-93C2-FC708368B32F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B93E0994-AEC4-4FC9-93C2-FC708368B32F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B93E0994-AEC4-4FC9-93C2-FC708368B32F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/47_Hi-Lo/vbnet/HiLo.vbproj b/47_Hi-Lo/vbnet/HiLo.vbproj new file mode 100644 index 00000000..634099d3 --- /dev/null +++ b/47_Hi-Lo/vbnet/HiLo.vbproj @@ -0,0 +1,8 @@ + + + Exe + HiLo + net6.0 + 16.9 + + diff --git a/48_High_IQ/csharp/HighIQ.csproj b/48_High_IQ/csharp/HighIQ.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/48_High_IQ/csharp/HighIQ.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/48_High_IQ/csharp/HighIQ.sln b/48_High_IQ/csharp/HighIQ.sln new file mode 100644 index 00000000..2cdbddc4 --- /dev/null +++ b/48_High_IQ/csharp/HighIQ.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighIQ", "HighIQ.csproj", "{B334E0AD-4A84-4F93-85FB-E6370BC8B71A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B334E0AD-4A84-4F93-85FB-E6370BC8B71A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B334E0AD-4A84-4F93-85FB-E6370BC8B71A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B334E0AD-4A84-4F93-85FB-E6370BC8B71A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B334E0AD-4A84-4F93-85FB-E6370BC8B71A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/48_High_IQ/vbnet/HighIQ.sln b/48_High_IQ/vbnet/HighIQ.sln new file mode 100644 index 00000000..ca1f79c5 --- /dev/null +++ b/48_High_IQ/vbnet/HighIQ.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "HighIQ", "HighIQ.vbproj", "{18AA4FCA-2733-4BBC-B65F-68C37B8CFDAF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {18AA4FCA-2733-4BBC-B65F-68C37B8CFDAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {18AA4FCA-2733-4BBC-B65F-68C37B8CFDAF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {18AA4FCA-2733-4BBC-B65F-68C37B8CFDAF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {18AA4FCA-2733-4BBC-B65F-68C37B8CFDAF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/48_High_IQ/vbnet/HighIQ.vbproj b/48_High_IQ/vbnet/HighIQ.vbproj new file mode 100644 index 00000000..c37eb8db --- /dev/null +++ b/48_High_IQ/vbnet/HighIQ.vbproj @@ -0,0 +1,8 @@ + + + Exe + HighIQ + net6.0 + 16.9 + + diff --git a/49_Hockey/csharp/Hockey.csproj b/49_Hockey/csharp/Hockey.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/49_Hockey/csharp/Hockey.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/49_Hockey/csharp/Hockey.sln b/49_Hockey/csharp/Hockey.sln new file mode 100644 index 00000000..d2ca8d36 --- /dev/null +++ b/49_Hockey/csharp/Hockey.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hockey", "Hockey.csproj", "{98E2914A-41D4-4931-B17F-4EAD3C98CFE1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {98E2914A-41D4-4931-B17F-4EAD3C98CFE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {98E2914A-41D4-4931-B17F-4EAD3C98CFE1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {98E2914A-41D4-4931-B17F-4EAD3C98CFE1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {98E2914A-41D4-4931-B17F-4EAD3C98CFE1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/49_Hockey/vbnet/Hockey.sln b/49_Hockey/vbnet/Hockey.sln new file mode 100644 index 00000000..396cfe92 --- /dev/null +++ b/49_Hockey/vbnet/Hockey.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Hockey", "Hockey.vbproj", "{9ED23BC7-7C12-4B48-8E85-F21E310813D5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9ED23BC7-7C12-4B48-8E85-F21E310813D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9ED23BC7-7C12-4B48-8E85-F21E310813D5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9ED23BC7-7C12-4B48-8E85-F21E310813D5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9ED23BC7-7C12-4B48-8E85-F21E310813D5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/49_Hockey/vbnet/Hockey.vbproj b/49_Hockey/vbnet/Hockey.vbproj new file mode 100644 index 00000000..59df31bf --- /dev/null +++ b/49_Hockey/vbnet/Hockey.vbproj @@ -0,0 +1,8 @@ + + + Exe + Hockey + net6.0 + 16.9 + + diff --git a/50_Horserace/csharp/Horserace.csproj b/50_Horserace/csharp/Horserace.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/50_Horserace/csharp/Horserace.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/50_Horserace/csharp/Horserace.sln b/50_Horserace/csharp/Horserace.sln new file mode 100644 index 00000000..17d7fae3 --- /dev/null +++ b/50_Horserace/csharp/Horserace.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Horserace", "Horserace.csproj", "{B1CD8505-43BA-4C2C-A458-54E14539DB35}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B1CD8505-43BA-4C2C-A458-54E14539DB35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B1CD8505-43BA-4C2C-A458-54E14539DB35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B1CD8505-43BA-4C2C-A458-54E14539DB35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B1CD8505-43BA-4C2C-A458-54E14539DB35}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/50_Horserace/vbnet/Horserace.sln b/50_Horserace/vbnet/Horserace.sln new file mode 100644 index 00000000..63adf310 --- /dev/null +++ b/50_Horserace/vbnet/Horserace.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Horserace", "Horserace.vbproj", "{B44BF36F-DF93-4374-A3A0-C6D447B4D0A7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B44BF36F-DF93-4374-A3A0-C6D447B4D0A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B44BF36F-DF93-4374-A3A0-C6D447B4D0A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B44BF36F-DF93-4374-A3A0-C6D447B4D0A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B44BF36F-DF93-4374-A3A0-C6D447B4D0A7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/50_Horserace/vbnet/Horserace.vbproj b/50_Horserace/vbnet/Horserace.vbproj new file mode 100644 index 00000000..245d9098 --- /dev/null +++ b/50_Horserace/vbnet/Horserace.vbproj @@ -0,0 +1,8 @@ + + + Exe + Horserace + net6.0 + 16.9 + + diff --git a/51_Hurkle/csharp/Hurkle.sln b/51_Hurkle/csharp/Hurkle.sln new file mode 100644 index 00000000..e1792677 --- /dev/null +++ b/51_Hurkle/csharp/Hurkle.sln @@ -0,0 +1,27 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EBE7BC2B-8F2E-41D5-AF36-7AAC7CE0E1BF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "hurkle", "src\hurkle\hurkle.csproj", "{47578EC1-A012-4BF7-8709-64F675E72DB0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {47578EC1-A012-4BF7-8709-64F675E72DB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47578EC1-A012-4BF7-8709-64F675E72DB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47578EC1-A012-4BF7-8709-64F675E72DB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47578EC1-A012-4BF7-8709-64F675E72DB0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {47578EC1-A012-4BF7-8709-64F675E72DB0} = {EBE7BC2B-8F2E-41D5-AF36-7AAC7CE0E1BF} + EndGlobalSection +EndGlobal diff --git a/51_Hurkle/vbnet/Hurkle.sln b/51_Hurkle/vbnet/Hurkle.sln new file mode 100644 index 00000000..dda01502 --- /dev/null +++ b/51_Hurkle/vbnet/Hurkle.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Hurkle", "Hurkle.vbproj", "{63674AC0-0FE6-467F-B2D0-016105155ADE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {63674AC0-0FE6-467F-B2D0-016105155ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63674AC0-0FE6-467F-B2D0-016105155ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63674AC0-0FE6-467F-B2D0-016105155ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63674AC0-0FE6-467F-B2D0-016105155ADE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/51_Hurkle/vbnet/Hurkle.vbproj b/51_Hurkle/vbnet/Hurkle.vbproj new file mode 100644 index 00000000..9d93e823 --- /dev/null +++ b/51_Hurkle/vbnet/Hurkle.vbproj @@ -0,0 +1,8 @@ + + + Exe + Hurkle + net6.0 + 16.9 + + diff --git a/52_Kinema/csharp/Kinema.csproj b/52_Kinema/csharp/Kinema.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/52_Kinema/csharp/Kinema.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/52_Kinema/csharp/Kinema.sln b/52_Kinema/csharp/Kinema.sln new file mode 100644 index 00000000..ddd98662 --- /dev/null +++ b/52_Kinema/csharp/Kinema.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kinema", "Kinema.csproj", "{FD7FF20E-F7A8-4372-BF7C-6898BDEF53D7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FD7FF20E-F7A8-4372-BF7C-6898BDEF53D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FD7FF20E-F7A8-4372-BF7C-6898BDEF53D7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FD7FF20E-F7A8-4372-BF7C-6898BDEF53D7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FD7FF20E-F7A8-4372-BF7C-6898BDEF53D7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/52_Kinema/vbnet/Kinema.sln b/52_Kinema/vbnet/Kinema.sln new file mode 100644 index 00000000..a669536c --- /dev/null +++ b/52_Kinema/vbnet/Kinema.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Kinema", "Kinema.vbproj", "{C929831F-0B1C-4EE4-9BAA-001BE5CCC2E2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C929831F-0B1C-4EE4-9BAA-001BE5CCC2E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C929831F-0B1C-4EE4-9BAA-001BE5CCC2E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C929831F-0B1C-4EE4-9BAA-001BE5CCC2E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C929831F-0B1C-4EE4-9BAA-001BE5CCC2E2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/52_Kinema/vbnet/Kinema.vbproj b/52_Kinema/vbnet/Kinema.vbproj new file mode 100644 index 00000000..b779698b --- /dev/null +++ b/52_Kinema/vbnet/Kinema.vbproj @@ -0,0 +1,8 @@ + + + Exe + Kinema + net6.0 + 16.9 + + diff --git a/53_King/csharp/King.csproj b/53_King/csharp/King.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/53_King/csharp/King.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/53_King/csharp/King.sln b/53_King/csharp/King.sln new file mode 100644 index 00000000..94eb4d7d --- /dev/null +++ b/53_King/csharp/King.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "King", "King.csproj", "{6CB6A32F-FFC7-4839-AAE2-4091D349BD34}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6CB6A32F-FFC7-4839-AAE2-4091D349BD34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CB6A32F-FFC7-4839-AAE2-4091D349BD34}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CB6A32F-FFC7-4839-AAE2-4091D349BD34}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CB6A32F-FFC7-4839-AAE2-4091D349BD34}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/53_King/vbnet/King.sln b/53_King/vbnet/King.sln new file mode 100644 index 00000000..c5bdb50c --- /dev/null +++ b/53_King/vbnet/King.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "King", "King.vbproj", "{043D7CC7-1FFC-438E-BB00-31CB467BEB73}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {043D7CC7-1FFC-438E-BB00-31CB467BEB73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {043D7CC7-1FFC-438E-BB00-31CB467BEB73}.Debug|Any CPU.Build.0 = Debug|Any CPU + {043D7CC7-1FFC-438E-BB00-31CB467BEB73}.Release|Any CPU.ActiveCfg = Release|Any CPU + {043D7CC7-1FFC-438E-BB00-31CB467BEB73}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/53_King/vbnet/King.vbproj b/53_King/vbnet/King.vbproj new file mode 100644 index 00000000..62bef191 --- /dev/null +++ b/53_King/vbnet/King.vbproj @@ -0,0 +1,8 @@ + + + Exe + King + net6.0 + 16.9 + + diff --git a/54_Letter/csharp/Letter.csproj b/54_Letter/csharp/Letter.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/54_Letter/csharp/Letter.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/54_Letter/csharp/Letter.sln b/54_Letter/csharp/Letter.sln new file mode 100644 index 00000000..3f567521 --- /dev/null +++ b/54_Letter/csharp/Letter.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Letter", "Letter.csproj", "{8BE20DCF-A729-46ED-92EA-55866844EB93}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8BE20DCF-A729-46ED-92EA-55866844EB93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8BE20DCF-A729-46ED-92EA-55866844EB93}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8BE20DCF-A729-46ED-92EA-55866844EB93}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8BE20DCF-A729-46ED-92EA-55866844EB93}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/54_Letter/vbnet/Letter.sln b/54_Letter/vbnet/Letter.sln new file mode 100644 index 00000000..e2896128 --- /dev/null +++ b/54_Letter/vbnet/Letter.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Letter", "Letter.vbproj", "{15392FFC-0EBB-4CA3-970F-8AC32DE84724}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {15392FFC-0EBB-4CA3-970F-8AC32DE84724}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15392FFC-0EBB-4CA3-970F-8AC32DE84724}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15392FFC-0EBB-4CA3-970F-8AC32DE84724}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15392FFC-0EBB-4CA3-970F-8AC32DE84724}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/54_Letter/vbnet/Letter.vbproj b/54_Letter/vbnet/Letter.vbproj new file mode 100644 index 00000000..0c55e2e6 --- /dev/null +++ b/54_Letter/vbnet/Letter.vbproj @@ -0,0 +1,8 @@ + + + Exe + Letter + net6.0 + 16.9 + + diff --git a/55_Life/vbnet/Life.sln b/55_Life/vbnet/Life.sln new file mode 100644 index 00000000..8feae175 --- /dev/null +++ b/55_Life/vbnet/Life.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Life", "Life.vbproj", "{05455AEE-3BE0-4DDD-A59E-89F862EF68AE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {05455AEE-3BE0-4DDD-A59E-89F862EF68AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05455AEE-3BE0-4DDD-A59E-89F862EF68AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05455AEE-3BE0-4DDD-A59E-89F862EF68AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05455AEE-3BE0-4DDD-A59E-89F862EF68AE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/55_Life/vbnet/Life.vbproj b/55_Life/vbnet/Life.vbproj new file mode 100644 index 00000000..5d62487f --- /dev/null +++ b/55_Life/vbnet/Life.vbproj @@ -0,0 +1,8 @@ + + + Exe + Life + net6.0 + 16.9 + + diff --git a/56_Life_for_Two/csharp/LifeforTwo.csproj b/56_Life_for_Two/csharp/LifeforTwo.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/56_Life_for_Two/csharp/LifeforTwo.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/56_Life_for_Two/csharp/LifeforTwo.sln b/56_Life_for_Two/csharp/LifeforTwo.sln new file mode 100644 index 00000000..7a5585cb --- /dev/null +++ b/56_Life_for_Two/csharp/LifeforTwo.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LifeforTwo", "LifeforTwo.csproj", "{B2BFE429-A4BC-4CEA-881E-32382182EA32}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B2BFE429-A4BC-4CEA-881E-32382182EA32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2BFE429-A4BC-4CEA-881E-32382182EA32}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2BFE429-A4BC-4CEA-881E-32382182EA32}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2BFE429-A4BC-4CEA-881E-32382182EA32}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/56_Life_for_Two/vbnet/LifeforTwo.sln b/56_Life_for_Two/vbnet/LifeforTwo.sln new file mode 100644 index 00000000..2d5167d3 --- /dev/null +++ b/56_Life_for_Two/vbnet/LifeforTwo.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LifeforTwo", "LifeforTwo.vbproj", "{571A55BD-86BA-4DD2-9769-B258E7654586}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {571A55BD-86BA-4DD2-9769-B258E7654586}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {571A55BD-86BA-4DD2-9769-B258E7654586}.Debug|Any CPU.Build.0 = Debug|Any CPU + {571A55BD-86BA-4DD2-9769-B258E7654586}.Release|Any CPU.ActiveCfg = Release|Any CPU + {571A55BD-86BA-4DD2-9769-B258E7654586}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/56_Life_for_Two/vbnet/LifeforTwo.vbproj b/56_Life_for_Two/vbnet/LifeforTwo.vbproj new file mode 100644 index 00000000..31087af1 --- /dev/null +++ b/56_Life_for_Two/vbnet/LifeforTwo.vbproj @@ -0,0 +1,8 @@ + + + Exe + LifeforTwo + net6.0 + 16.9 + + diff --git a/57_Literature_Quiz/csharp/LiteratureQuiz.csproj b/57_Literature_Quiz/csharp/LiteratureQuiz.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/57_Literature_Quiz/csharp/LiteratureQuiz.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/57_Literature_Quiz/csharp/LiteratureQuiz.sln b/57_Literature_Quiz/csharp/LiteratureQuiz.sln new file mode 100644 index 00000000..8ba67c92 --- /dev/null +++ b/57_Literature_Quiz/csharp/LiteratureQuiz.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LiteratureQuiz", "LiteratureQuiz.csproj", "{1B77EECB-5ECC-41E5-BD12-519CA4C745AE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1B77EECB-5ECC-41E5-BD12-519CA4C745AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1B77EECB-5ECC-41E5-BD12-519CA4C745AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1B77EECB-5ECC-41E5-BD12-519CA4C745AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1B77EECB-5ECC-41E5-BD12-519CA4C745AE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/57_Literature_Quiz/vbnet/LiteratureQuiz.sln b/57_Literature_Quiz/vbnet/LiteratureQuiz.sln new file mode 100644 index 00000000..67ca803d --- /dev/null +++ b/57_Literature_Quiz/vbnet/LiteratureQuiz.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LiteratureQuiz", "LiteratureQuiz.vbproj", "{7897F5C5-055B-449D-9BD5-1F631DA87D06}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7897F5C5-055B-449D-9BD5-1F631DA87D06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7897F5C5-055B-449D-9BD5-1F631DA87D06}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7897F5C5-055B-449D-9BD5-1F631DA87D06}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7897F5C5-055B-449D-9BD5-1F631DA87D06}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/57_Literature_Quiz/vbnet/LiteratureQuiz.vbproj b/57_Literature_Quiz/vbnet/LiteratureQuiz.vbproj new file mode 100644 index 00000000..32c35664 --- /dev/null +++ b/57_Literature_Quiz/vbnet/LiteratureQuiz.vbproj @@ -0,0 +1,8 @@ + + + Exe + LiteratureQuiz + net6.0 + 16.9 + + diff --git a/58_Love/vbnet/Love.sln b/58_Love/vbnet/Love.sln new file mode 100644 index 00000000..44ae6e7f --- /dev/null +++ b/58_Love/vbnet/Love.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Love", "Love.vbproj", "{440AD3C3-D842-4717-BB4D-C54463F59ECA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {440AD3C3-D842-4717-BB4D-C54463F59ECA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {440AD3C3-D842-4717-BB4D-C54463F59ECA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {440AD3C3-D842-4717-BB4D-C54463F59ECA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {440AD3C3-D842-4717-BB4D-C54463F59ECA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/58_Love/vbnet/Love.vbproj b/58_Love/vbnet/Love.vbproj new file mode 100644 index 00000000..444df2a3 --- /dev/null +++ b/58_Love/vbnet/Love.vbproj @@ -0,0 +1,8 @@ + + + Exe + Love + net6.0 + 16.9 + + diff --git a/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.csproj b/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.sln b/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.sln new file mode 100644 index 00000000..4f74244d --- /dev/null +++ b/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LunarLEMRocket", "LunarLEMRocket.csproj", "{12D3D8F6-5468-49BD-BDD6-E9B4D5954496}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {12D3D8F6-5468-49BD-BDD6-E9B4D5954496}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12D3D8F6-5468-49BD-BDD6-E9B4D5954496}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12D3D8F6-5468-49BD-BDD6-E9B4D5954496}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12D3D8F6-5468-49BD-BDD6-E9B4D5954496}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.sln b/59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.sln new file mode 100644 index 00000000..a77348e6 --- /dev/null +++ b/59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LunarLEMRocket", "LunarLEMRocket.vbproj", "{6145C5DF-CFFB-42B8-9025-913D9D4A8B10}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6145C5DF-CFFB-42B8-9025-913D9D4A8B10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6145C5DF-CFFB-42B8-9025-913D9D4A8B10}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6145C5DF-CFFB-42B8-9025-913D9D4A8B10}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6145C5DF-CFFB-42B8-9025-913D9D4A8B10}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.vbproj b/59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.vbproj new file mode 100644 index 00000000..553bdcd5 --- /dev/null +++ b/59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.vbproj @@ -0,0 +1,8 @@ + + + Exe + LunarLEMRocket + net6.0 + 16.9 + + diff --git a/60_Mastermind/vbnet/Mastermind.sln b/60_Mastermind/vbnet/Mastermind.sln new file mode 100644 index 00000000..5ea0a369 --- /dev/null +++ b/60_Mastermind/vbnet/Mastermind.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Mastermind", "Mastermind.vbproj", "{B32A8054-8790-4810-93A8-CD0C740CEBD5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B32A8054-8790-4810-93A8-CD0C740CEBD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B32A8054-8790-4810-93A8-CD0C740CEBD5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B32A8054-8790-4810-93A8-CD0C740CEBD5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B32A8054-8790-4810-93A8-CD0C740CEBD5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/60_Mastermind/vbnet/Mastermind.vbproj b/60_Mastermind/vbnet/Mastermind.vbproj new file mode 100644 index 00000000..dc0b7890 --- /dev/null +++ b/60_Mastermind/vbnet/Mastermind.vbproj @@ -0,0 +1,8 @@ + + + Exe + Mastermind + net6.0 + 16.9 + + diff --git a/61_Math_Dice/vbnet/MathDice.sln b/61_Math_Dice/vbnet/MathDice.sln new file mode 100644 index 00000000..4fe58a59 --- /dev/null +++ b/61_Math_Dice/vbnet/MathDice.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "MathDice", "MathDice.vbproj", "{1341C416-E919-4262-B378-113A6B6317DD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1341C416-E919-4262-B378-113A6B6317DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1341C416-E919-4262-B378-113A6B6317DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1341C416-E919-4262-B378-113A6B6317DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1341C416-E919-4262-B378-113A6B6317DD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/61_Math_Dice/vbnet/MathDice.vbproj b/61_Math_Dice/vbnet/MathDice.vbproj new file mode 100644 index 00000000..dd19501b --- /dev/null +++ b/61_Math_Dice/vbnet/MathDice.vbproj @@ -0,0 +1,8 @@ + + + Exe + MathDice + net6.0 + 16.9 + + diff --git a/62_Mugwump/vbnet/Mugwump.sln b/62_Mugwump/vbnet/Mugwump.sln new file mode 100644 index 00000000..49f0dd09 --- /dev/null +++ b/62_Mugwump/vbnet/Mugwump.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Mugwump", "Mugwump.vbproj", "{5A0B0AE7-4148-42CB-8010-5A0683E3CF3A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5A0B0AE7-4148-42CB-8010-5A0683E3CF3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A0B0AE7-4148-42CB-8010-5A0683E3CF3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A0B0AE7-4148-42CB-8010-5A0683E3CF3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A0B0AE7-4148-42CB-8010-5A0683E3CF3A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/62_Mugwump/vbnet/Mugwump.vbproj b/62_Mugwump/vbnet/Mugwump.vbproj new file mode 100644 index 00000000..50f8a0a1 --- /dev/null +++ b/62_Mugwump/vbnet/Mugwump.vbproj @@ -0,0 +1,8 @@ + + + Exe + Mugwump + net6.0 + 16.9 + + diff --git a/63_Name/vbnet/Name.sln b/63_Name/vbnet/Name.sln new file mode 100644 index 00000000..29b92356 --- /dev/null +++ b/63_Name/vbnet/Name.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Name", "Name.vbproj", "{178E4E2F-5264-47A1-9BC6-2B724E7DCC79}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {178E4E2F-5264-47A1-9BC6-2B724E7DCC79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {178E4E2F-5264-47A1-9BC6-2B724E7DCC79}.Debug|Any CPU.Build.0 = Debug|Any CPU + {178E4E2F-5264-47A1-9BC6-2B724E7DCC79}.Release|Any CPU.ActiveCfg = Release|Any CPU + {178E4E2F-5264-47A1-9BC6-2B724E7DCC79}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/63_Name/vbnet/Name.vbproj b/63_Name/vbnet/Name.vbproj new file mode 100644 index 00000000..a06d78f3 --- /dev/null +++ b/63_Name/vbnet/Name.vbproj @@ -0,0 +1,8 @@ + + + Exe + Name + net6.0 + 16.9 + + diff --git a/64_Nicomachus/csharp/Nicomachus.csproj b/64_Nicomachus/csharp/Nicomachus.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/64_Nicomachus/csharp/Nicomachus.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/64_Nicomachus/csharp/Nicomachus.sln b/64_Nicomachus/csharp/Nicomachus.sln new file mode 100644 index 00000000..5287cabf --- /dev/null +++ b/64_Nicomachus/csharp/Nicomachus.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nicomachus", "Nicomachus.csproj", "{AC3B6DDA-13CE-40FC-B9E0-4246390DFC20}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AC3B6DDA-13CE-40FC-B9E0-4246390DFC20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC3B6DDA-13CE-40FC-B9E0-4246390DFC20}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC3B6DDA-13CE-40FC-B9E0-4246390DFC20}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC3B6DDA-13CE-40FC-B9E0-4246390DFC20}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/64_Nicomachus/vbnet/Nicomachus.sln b/64_Nicomachus/vbnet/Nicomachus.sln new file mode 100644 index 00000000..bea341c4 --- /dev/null +++ b/64_Nicomachus/vbnet/Nicomachus.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Nicomachus", "Nicomachus.vbproj", "{B4987617-A235-4CBA-A158-A668B6C36FE1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B4987617-A235-4CBA-A158-A668B6C36FE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B4987617-A235-4CBA-A158-A668B6C36FE1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4987617-A235-4CBA-A158-A668B6C36FE1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B4987617-A235-4CBA-A158-A668B6C36FE1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/64_Nicomachus/vbnet/Nicomachus.vbproj b/64_Nicomachus/vbnet/Nicomachus.vbproj new file mode 100644 index 00000000..404fd9d9 --- /dev/null +++ b/64_Nicomachus/vbnet/Nicomachus.vbproj @@ -0,0 +1,8 @@ + + + Exe + Nicomachus + net6.0 + 16.9 + + diff --git a/65_Nim/csharp/Nim.csproj b/65_Nim/csharp/Nim.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/65_Nim/csharp/Nim.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/65_Nim/csharp/Nim.sln b/65_Nim/csharp/Nim.sln new file mode 100644 index 00000000..dd324894 --- /dev/null +++ b/65_Nim/csharp/Nim.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nim", "Nim.csproj", "{00B15B50-9CB1-46B1-8066-5877F972EE88}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {00B15B50-9CB1-46B1-8066-5877F972EE88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00B15B50-9CB1-46B1-8066-5877F972EE88}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00B15B50-9CB1-46B1-8066-5877F972EE88}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00B15B50-9CB1-46B1-8066-5877F972EE88}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/65_Nim/vbnet/Nim.sln b/65_Nim/vbnet/Nim.sln new file mode 100644 index 00000000..17c6bf86 --- /dev/null +++ b/65_Nim/vbnet/Nim.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Nim", "Nim.vbproj", "{224F08AA-BE60-4B49-877F-36F239C56F6F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {224F08AA-BE60-4B49-877F-36F239C56F6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {224F08AA-BE60-4B49-877F-36F239C56F6F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {224F08AA-BE60-4B49-877F-36F239C56F6F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {224F08AA-BE60-4B49-877F-36F239C56F6F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/65_Nim/vbnet/Nim.vbproj b/65_Nim/vbnet/Nim.vbproj new file mode 100644 index 00000000..f551edd0 --- /dev/null +++ b/65_Nim/vbnet/Nim.vbproj @@ -0,0 +1,8 @@ + + + Exe + Nim + net6.0 + 16.9 + + diff --git a/66_Number/csharp/Number.csproj b/66_Number/csharp/Number.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/66_Number/csharp/Number.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/66_Number/csharp/Number.sln b/66_Number/csharp/Number.sln new file mode 100644 index 00000000..f42e7e2a --- /dev/null +++ b/66_Number/csharp/Number.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Number", "Number.csproj", "{F39E3DE8-3564-424C-AD89-D47478FD6E47}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F39E3DE8-3564-424C-AD89-D47478FD6E47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F39E3DE8-3564-424C-AD89-D47478FD6E47}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F39E3DE8-3564-424C-AD89-D47478FD6E47}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F39E3DE8-3564-424C-AD89-D47478FD6E47}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/66_Number/vbnet/Number.sln b/66_Number/vbnet/Number.sln new file mode 100644 index 00000000..d0838e1a --- /dev/null +++ b/66_Number/vbnet/Number.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Number", "Number.vbproj", "{FEF524F1-E940-43AF-A7EF-4D0DEB1E3F1E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FEF524F1-E940-43AF-A7EF-4D0DEB1E3F1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FEF524F1-E940-43AF-A7EF-4D0DEB1E3F1E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FEF524F1-E940-43AF-A7EF-4D0DEB1E3F1E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FEF524F1-E940-43AF-A7EF-4D0DEB1E3F1E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/66_Number/vbnet/Number.vbproj b/66_Number/vbnet/Number.vbproj new file mode 100644 index 00000000..ad922daf --- /dev/null +++ b/66_Number/vbnet/Number.vbproj @@ -0,0 +1,8 @@ + + + Exe + Number + net6.0 + 16.9 + + diff --git a/67_One_Check/csharp/OneCheck.csproj b/67_One_Check/csharp/OneCheck.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/67_One_Check/csharp/OneCheck.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/67_One_Check/csharp/OneCheck.sln b/67_One_Check/csharp/OneCheck.sln new file mode 100644 index 00000000..f6a550c7 --- /dev/null +++ b/67_One_Check/csharp/OneCheck.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneCheck", "OneCheck.csproj", "{3964167F-17D8-44FB-A9F7-EA2DB1C5DA3F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3964167F-17D8-44FB-A9F7-EA2DB1C5DA3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3964167F-17D8-44FB-A9F7-EA2DB1C5DA3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3964167F-17D8-44FB-A9F7-EA2DB1C5DA3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3964167F-17D8-44FB-A9F7-EA2DB1C5DA3F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/67_One_Check/vbnet/OneCheck.sln b/67_One_Check/vbnet/OneCheck.sln new file mode 100644 index 00000000..d641e964 --- /dev/null +++ b/67_One_Check/vbnet/OneCheck.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "OneCheck", "OneCheck.vbproj", "{E19E8AE0-06FE-4EB5-9F24-7FF74D65F55A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E19E8AE0-06FE-4EB5-9F24-7FF74D65F55A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E19E8AE0-06FE-4EB5-9F24-7FF74D65F55A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E19E8AE0-06FE-4EB5-9F24-7FF74D65F55A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E19E8AE0-06FE-4EB5-9F24-7FF74D65F55A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/67_One_Check/vbnet/OneCheck.vbproj b/67_One_Check/vbnet/OneCheck.vbproj new file mode 100644 index 00000000..2b36f16f --- /dev/null +++ b/67_One_Check/vbnet/OneCheck.vbproj @@ -0,0 +1,8 @@ + + + Exe + OneCheck + net6.0 + 16.9 + + diff --git a/68_Orbit/csharp/Orbit.csproj b/68_Orbit/csharp/Orbit.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/68_Orbit/csharp/Orbit.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/68_Orbit/csharp/Orbit.sln b/68_Orbit/csharp/Orbit.sln new file mode 100644 index 00000000..0ca7e270 --- /dev/null +++ b/68_Orbit/csharp/Orbit.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orbit", "Orbit.csproj", "{2912E79E-D9A2-488F-B77E-7C348E3347E7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2912E79E-D9A2-488F-B77E-7C348E3347E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2912E79E-D9A2-488F-B77E-7C348E3347E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2912E79E-D9A2-488F-B77E-7C348E3347E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2912E79E-D9A2-488F-B77E-7C348E3347E7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/68_Orbit/vbnet/Orbit.sln b/68_Orbit/vbnet/Orbit.sln new file mode 100644 index 00000000..b2b021d1 --- /dev/null +++ b/68_Orbit/vbnet/Orbit.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Orbit", "Orbit.vbproj", "{4EC039CE-66F1-46ED-97B1-9DB2A2B8A648}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4EC039CE-66F1-46ED-97B1-9DB2A2B8A648}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EC039CE-66F1-46ED-97B1-9DB2A2B8A648}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EC039CE-66F1-46ED-97B1-9DB2A2B8A648}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EC039CE-66F1-46ED-97B1-9DB2A2B8A648}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/68_Orbit/vbnet/Orbit.vbproj b/68_Orbit/vbnet/Orbit.vbproj new file mode 100644 index 00000000..29be1358 --- /dev/null +++ b/68_Orbit/vbnet/Orbit.vbproj @@ -0,0 +1,8 @@ + + + Exe + Orbit + net6.0 + 16.9 + + diff --git a/69_Pizza/vbnet/Pizza.sln b/69_Pizza/vbnet/Pizza.sln new file mode 100644 index 00000000..8fc145ee --- /dev/null +++ b/69_Pizza/vbnet/Pizza.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Pizza", "Pizza.vbproj", "{395C3162-11F0-459B-9027-45A8ED6E4E8E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {395C3162-11F0-459B-9027-45A8ED6E4E8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {395C3162-11F0-459B-9027-45A8ED6E4E8E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {395C3162-11F0-459B-9027-45A8ED6E4E8E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {395C3162-11F0-459B-9027-45A8ED6E4E8E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/69_Pizza/vbnet/Pizza.vbproj b/69_Pizza/vbnet/Pizza.vbproj new file mode 100644 index 00000000..db16f023 --- /dev/null +++ b/69_Pizza/vbnet/Pizza.vbproj @@ -0,0 +1,8 @@ + + + Exe + Pizza + net6.0 + 16.9 + + diff --git a/70_Poetry/csharp/Poetry.csproj b/70_Poetry/csharp/Poetry.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/70_Poetry/csharp/Poetry.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/70_Poetry/csharp/Poetry.sln b/70_Poetry/csharp/Poetry.sln new file mode 100644 index 00000000..f62c6d2b --- /dev/null +++ b/70_Poetry/csharp/Poetry.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Poetry", "Poetry.csproj", "{965EE29C-4FEC-4A31-92C9-55FBA8FDB0CB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {965EE29C-4FEC-4A31-92C9-55FBA8FDB0CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {965EE29C-4FEC-4A31-92C9-55FBA8FDB0CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {965EE29C-4FEC-4A31-92C9-55FBA8FDB0CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {965EE29C-4FEC-4A31-92C9-55FBA8FDB0CB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/70_Poetry/vbnet/Poetry.sln b/70_Poetry/vbnet/Poetry.sln new file mode 100644 index 00000000..8e235514 --- /dev/null +++ b/70_Poetry/vbnet/Poetry.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Poetry", "Poetry.vbproj", "{422855D5-5841-40E0-AF1E-993FB25DE7B3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {422855D5-5841-40E0-AF1E-993FB25DE7B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {422855D5-5841-40E0-AF1E-993FB25DE7B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {422855D5-5841-40E0-AF1E-993FB25DE7B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {422855D5-5841-40E0-AF1E-993FB25DE7B3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/70_Poetry/vbnet/Poetry.vbproj b/70_Poetry/vbnet/Poetry.vbproj new file mode 100644 index 00000000..fc71a15e --- /dev/null +++ b/70_Poetry/vbnet/Poetry.vbproj @@ -0,0 +1,8 @@ + + + Exe + Poetry + net6.0 + 16.9 + + diff --git a/71_Poker/csharp/Poker.csproj b/71_Poker/csharp/Poker.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/71_Poker/csharp/Poker.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/71_Poker/csharp/Poker.sln b/71_Poker/csharp/Poker.sln new file mode 100644 index 00000000..5dd63fff --- /dev/null +++ b/71_Poker/csharp/Poker.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Poker", "Poker.csproj", "{CAEDA88F-1585-41AA-8213-40012B044FA9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CAEDA88F-1585-41AA-8213-40012B044FA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CAEDA88F-1585-41AA-8213-40012B044FA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CAEDA88F-1585-41AA-8213-40012B044FA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CAEDA88F-1585-41AA-8213-40012B044FA9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/71_Poker/vbnet/Poker.sln b/71_Poker/vbnet/Poker.sln new file mode 100644 index 00000000..f1514e74 --- /dev/null +++ b/71_Poker/vbnet/Poker.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Poker", "Poker.vbproj", "{107C29F8-C499-4E4A-B162-324CA17AA57F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {107C29F8-C499-4E4A-B162-324CA17AA57F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {107C29F8-C499-4E4A-B162-324CA17AA57F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {107C29F8-C499-4E4A-B162-324CA17AA57F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {107C29F8-C499-4E4A-B162-324CA17AA57F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/71_Poker/vbnet/Poker.vbproj b/71_Poker/vbnet/Poker.vbproj new file mode 100644 index 00000000..5e1a61a3 --- /dev/null +++ b/71_Poker/vbnet/Poker.vbproj @@ -0,0 +1,8 @@ + + + Exe + Poker + net6.0 + 16.9 + + diff --git a/72_Queen/csharp/Queen.csproj b/72_Queen/csharp/Queen.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/72_Queen/csharp/Queen.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/72_Queen/csharp/Queen.sln b/72_Queen/csharp/Queen.sln new file mode 100644 index 00000000..b4d865ab --- /dev/null +++ b/72_Queen/csharp/Queen.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Queen", "Queen.csproj", "{34BFC22A-4459-416E-B271-1E276689AC29}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {34BFC22A-4459-416E-B271-1E276689AC29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {34BFC22A-4459-416E-B271-1E276689AC29}.Debug|Any CPU.Build.0 = Debug|Any CPU + {34BFC22A-4459-416E-B271-1E276689AC29}.Release|Any CPU.ActiveCfg = Release|Any CPU + {34BFC22A-4459-416E-B271-1E276689AC29}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/72_Queen/vbnet/Queen.sln b/72_Queen/vbnet/Queen.sln new file mode 100644 index 00000000..33f87b9a --- /dev/null +++ b/72_Queen/vbnet/Queen.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Queen", "Queen.vbproj", "{9FCBF8AB-8E16-4E1A-AA05-D64B475D36FC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9FCBF8AB-8E16-4E1A-AA05-D64B475D36FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9FCBF8AB-8E16-4E1A-AA05-D64B475D36FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9FCBF8AB-8E16-4E1A-AA05-D64B475D36FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9FCBF8AB-8E16-4E1A-AA05-D64B475D36FC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/72_Queen/vbnet/Queen.vbproj b/72_Queen/vbnet/Queen.vbproj new file mode 100644 index 00000000..19b46d90 --- /dev/null +++ b/72_Queen/vbnet/Queen.vbproj @@ -0,0 +1,8 @@ + + + Exe + Queen + net6.0 + 16.9 + + diff --git a/73_Reverse/vbnet/Reverse.sln b/73_Reverse/vbnet/Reverse.sln new file mode 100644 index 00000000..8e8fa1ee --- /dev/null +++ b/73_Reverse/vbnet/Reverse.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Reverse", "Reverse.vbproj", "{8C9839D4-D0FD-47C2-B54D-429C55F1C6D0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8C9839D4-D0FD-47C2-B54D-429C55F1C6D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C9839D4-D0FD-47C2-B54D-429C55F1C6D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C9839D4-D0FD-47C2-B54D-429C55F1C6D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C9839D4-D0FD-47C2-B54D-429C55F1C6D0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/73_Reverse/vbnet/Reverse.vbproj b/73_Reverse/vbnet/Reverse.vbproj new file mode 100644 index 00000000..978b4e56 --- /dev/null +++ b/73_Reverse/vbnet/Reverse.vbproj @@ -0,0 +1,8 @@ + + + Exe + Reverse + net6.0 + 16.9 + + diff --git a/74_Rock_Scissors_Paper/csharp/RockScissorsPaper.sln b/74_Rock_Scissors_Paper/csharp/RockScissorsPaper.sln new file mode 100644 index 00000000..5c563dd8 --- /dev/null +++ b/74_Rock_Scissors_Paper/csharp/RockScissorsPaper.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RockScissorsPaper", "RockScissorsPaper.csproj", "{162F12A7-72D0-44C8-9854-EA50C707690F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {162F12A7-72D0-44C8-9854-EA50C707690F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {162F12A7-72D0-44C8-9854-EA50C707690F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {162F12A7-72D0-44C8-9854-EA50C707690F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {162F12A7-72D0-44C8-9854-EA50C707690F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.sln b/74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.sln new file mode 100644 index 00000000..481f3105 --- /dev/null +++ b/74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "RockScissorsPaper", "RockScissorsPaper.vbproj", "{05C592E9-1A74-4812-88CF-3B078A315378}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {05C592E9-1A74-4812-88CF-3B078A315378}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05C592E9-1A74-4812-88CF-3B078A315378}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05C592E9-1A74-4812-88CF-3B078A315378}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05C592E9-1A74-4812-88CF-3B078A315378}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.vbproj b/74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.vbproj new file mode 100644 index 00000000..e6cf95c5 --- /dev/null +++ b/74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.vbproj @@ -0,0 +1,8 @@ + + + Exe + RockScissorsPaper + net6.0 + 16.9 + + diff --git a/75_Roulette/csharp/Roulette.csproj b/75_Roulette/csharp/Roulette.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/75_Roulette/csharp/Roulette.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/75_Roulette/csharp/Roulette.sln b/75_Roulette/csharp/Roulette.sln new file mode 100644 index 00000000..de44173b --- /dev/null +++ b/75_Roulette/csharp/Roulette.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Roulette", "Roulette.csproj", "{9FC3EC1F-2052-4D08-901C-5184E17740FC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9FC3EC1F-2052-4D08-901C-5184E17740FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9FC3EC1F-2052-4D08-901C-5184E17740FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9FC3EC1F-2052-4D08-901C-5184E17740FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9FC3EC1F-2052-4D08-901C-5184E17740FC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/75_Roulette/vbnet/Roulette.sln b/75_Roulette/vbnet/Roulette.sln new file mode 100644 index 00000000..a9db1b6e --- /dev/null +++ b/75_Roulette/vbnet/Roulette.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Roulette", "Roulette.vbproj", "{B2D2B22C-D332-4153-8ACF-E8136283FBC7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B2D2B22C-D332-4153-8ACF-E8136283FBC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2D2B22C-D332-4153-8ACF-E8136283FBC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2D2B22C-D332-4153-8ACF-E8136283FBC7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2D2B22C-D332-4153-8ACF-E8136283FBC7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/75_Roulette/vbnet/Roulette.vbproj b/75_Roulette/vbnet/Roulette.vbproj new file mode 100644 index 00000000..d5c17f88 --- /dev/null +++ b/75_Roulette/vbnet/Roulette.vbproj @@ -0,0 +1,8 @@ + + + Exe + Roulette + net6.0 + 16.9 + + diff --git a/76_Russian_Roulette/vbnet/RussianRoulette.sln b/76_Russian_Roulette/vbnet/RussianRoulette.sln new file mode 100644 index 00000000..8a87ebbb --- /dev/null +++ b/76_Russian_Roulette/vbnet/RussianRoulette.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "RussianRoulette", "RussianRoulette.vbproj", "{19A2F0DB-9F77-4E3A-9346-4FDDAF0A457F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {19A2F0DB-9F77-4E3A-9346-4FDDAF0A457F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19A2F0DB-9F77-4E3A-9346-4FDDAF0A457F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19A2F0DB-9F77-4E3A-9346-4FDDAF0A457F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19A2F0DB-9F77-4E3A-9346-4FDDAF0A457F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/76_Russian_Roulette/vbnet/RussianRoulette.vbproj b/76_Russian_Roulette/vbnet/RussianRoulette.vbproj new file mode 100644 index 00000000..dbfebdae --- /dev/null +++ b/76_Russian_Roulette/vbnet/RussianRoulette.vbproj @@ -0,0 +1,8 @@ + + + Exe + RussianRoulette + net6.0 + 16.9 + + diff --git a/77_Salvo/csharp/Salvo.csproj b/77_Salvo/csharp/Salvo.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/77_Salvo/csharp/Salvo.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/77_Salvo/csharp/Salvo.sln b/77_Salvo/csharp/Salvo.sln new file mode 100644 index 00000000..290237a3 --- /dev/null +++ b/77_Salvo/csharp/Salvo.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Salvo", "Salvo.csproj", "{F3AFBC83-22A7-4837-9DA3-F3EE854DD8CA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F3AFBC83-22A7-4837-9DA3-F3EE854DD8CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3AFBC83-22A7-4837-9DA3-F3EE854DD8CA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3AFBC83-22A7-4837-9DA3-F3EE854DD8CA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3AFBC83-22A7-4837-9DA3-F3EE854DD8CA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/77_Salvo/vbnet/Salvo.sln b/77_Salvo/vbnet/Salvo.sln new file mode 100644 index 00000000..3acb9449 --- /dev/null +++ b/77_Salvo/vbnet/Salvo.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Salvo", "Salvo.vbproj", "{849885BF-24BD-4FEB-A224-A9502742D4B0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {849885BF-24BD-4FEB-A224-A9502742D4B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {849885BF-24BD-4FEB-A224-A9502742D4B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {849885BF-24BD-4FEB-A224-A9502742D4B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {849885BF-24BD-4FEB-A224-A9502742D4B0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/77_Salvo/vbnet/Salvo.vbproj b/77_Salvo/vbnet/Salvo.vbproj new file mode 100644 index 00000000..90ec0e38 --- /dev/null +++ b/77_Salvo/vbnet/Salvo.vbproj @@ -0,0 +1,8 @@ + + + Exe + Salvo + net6.0 + 16.9 + + diff --git a/78_Sine_Wave/vbnet/SineWave.sln b/78_Sine_Wave/vbnet/SineWave.sln new file mode 100644 index 00000000..37f4bf7e --- /dev/null +++ b/78_Sine_Wave/vbnet/SineWave.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SineWave", "SineWave.vbproj", "{204DD0CD-1DA5-4B4B-992F-1C3ED089A147}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {204DD0CD-1DA5-4B4B-992F-1C3ED089A147}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {204DD0CD-1DA5-4B4B-992F-1C3ED089A147}.Debug|Any CPU.Build.0 = Debug|Any CPU + {204DD0CD-1DA5-4B4B-992F-1C3ED089A147}.Release|Any CPU.ActiveCfg = Release|Any CPU + {204DD0CD-1DA5-4B4B-992F-1C3ED089A147}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/78_Sine_Wave/vbnet/SineWave.vbproj b/78_Sine_Wave/vbnet/SineWave.vbproj new file mode 100644 index 00000000..610c360f --- /dev/null +++ b/78_Sine_Wave/vbnet/SineWave.vbproj @@ -0,0 +1,8 @@ + + + Exe + SineWave + net6.0 + 16.9 + + diff --git a/79_Slalom/csharp/Slalom.csproj b/79_Slalom/csharp/Slalom.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/79_Slalom/csharp/Slalom.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/79_Slalom/csharp/Slalom.sln b/79_Slalom/csharp/Slalom.sln new file mode 100644 index 00000000..c1621f2e --- /dev/null +++ b/79_Slalom/csharp/Slalom.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Slalom", "Slalom.csproj", "{6D0607CF-B01C-4E17-A4DE-D15514AE5F84}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6D0607CF-B01C-4E17-A4DE-D15514AE5F84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6D0607CF-B01C-4E17-A4DE-D15514AE5F84}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6D0607CF-B01C-4E17-A4DE-D15514AE5F84}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6D0607CF-B01C-4E17-A4DE-D15514AE5F84}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/79_Slalom/vbnet/Slalom.sln b/79_Slalom/vbnet/Slalom.sln new file mode 100644 index 00000000..daa61623 --- /dev/null +++ b/79_Slalom/vbnet/Slalom.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Slalom", "Slalom.vbproj", "{9A7FDEAB-071F-404C-BBA4-91D77E797DF1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9A7FDEAB-071F-404C-BBA4-91D77E797DF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A7FDEAB-071F-404C-BBA4-91D77E797DF1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A7FDEAB-071F-404C-BBA4-91D77E797DF1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A7FDEAB-071F-404C-BBA4-91D77E797DF1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/79_Slalom/vbnet/Slalom.vbproj b/79_Slalom/vbnet/Slalom.vbproj new file mode 100644 index 00000000..0622bcd9 --- /dev/null +++ b/79_Slalom/vbnet/Slalom.vbproj @@ -0,0 +1,8 @@ + + + Exe + Slalom + net6.0 + 16.9 + + diff --git a/80_Slots/csharp/Slots.csproj b/80_Slots/csharp/Slots.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/80_Slots/csharp/Slots.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/80_Slots/csharp/Slots.sln b/80_Slots/csharp/Slots.sln new file mode 100644 index 00000000..60f90046 --- /dev/null +++ b/80_Slots/csharp/Slots.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Slots", "Slots.csproj", "{D855ECF3-DF8C-46DD-8BEF-2ADFF3AE7817}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D855ECF3-DF8C-46DD-8BEF-2ADFF3AE7817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D855ECF3-DF8C-46DD-8BEF-2ADFF3AE7817}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D855ECF3-DF8C-46DD-8BEF-2ADFF3AE7817}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D855ECF3-DF8C-46DD-8BEF-2ADFF3AE7817}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/80_Slots/vbnet/Slots.sln b/80_Slots/vbnet/Slots.sln new file mode 100644 index 00000000..1f493198 --- /dev/null +++ b/80_Slots/vbnet/Slots.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Slots", "Slots.vbproj", "{F64CB361-215F-4984-B154-304FF663A60C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F64CB361-215F-4984-B154-304FF663A60C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F64CB361-215F-4984-B154-304FF663A60C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F64CB361-215F-4984-B154-304FF663A60C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F64CB361-215F-4984-B154-304FF663A60C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/80_Slots/vbnet/Slots.vbproj b/80_Slots/vbnet/Slots.vbproj new file mode 100644 index 00000000..04f381a3 --- /dev/null +++ b/80_Slots/vbnet/Slots.vbproj @@ -0,0 +1,8 @@ + + + Exe + Slots + net6.0 + 16.9 + + diff --git a/81_Splat/csharp/Splat.csproj b/81_Splat/csharp/Splat.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/81_Splat/csharp/Splat.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/81_Splat/csharp/Splat.sln b/81_Splat/csharp/Splat.sln new file mode 100644 index 00000000..d7184859 --- /dev/null +++ b/81_Splat/csharp/Splat.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Splat", "Splat.csproj", "{95640CEE-A1A6-4824-A2C7-CF72CADA40FB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {95640CEE-A1A6-4824-A2C7-CF72CADA40FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95640CEE-A1A6-4824-A2C7-CF72CADA40FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95640CEE-A1A6-4824-A2C7-CF72CADA40FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95640CEE-A1A6-4824-A2C7-CF72CADA40FB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/81_Splat/vbnet/Splat.sln b/81_Splat/vbnet/Splat.sln new file mode 100644 index 00000000..b132583d --- /dev/null +++ b/81_Splat/vbnet/Splat.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Splat", "Splat.vbproj", "{62FD7167-97B2-4EA7-8BC8-CBC5765DF721}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {62FD7167-97B2-4EA7-8BC8-CBC5765DF721}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62FD7167-97B2-4EA7-8BC8-CBC5765DF721}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62FD7167-97B2-4EA7-8BC8-CBC5765DF721}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62FD7167-97B2-4EA7-8BC8-CBC5765DF721}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/81_Splat/vbnet/Splat.vbproj b/81_Splat/vbnet/Splat.vbproj new file mode 100644 index 00000000..daf6de3c --- /dev/null +++ b/81_Splat/vbnet/Splat.vbproj @@ -0,0 +1,8 @@ + + + Exe + Splat + net6.0 + 16.9 + + diff --git a/82_Stars/vbnet/Stars.sln b/82_Stars/vbnet/Stars.sln new file mode 100644 index 00000000..edb5e587 --- /dev/null +++ b/82_Stars/vbnet/Stars.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Stars", "Stars.vbproj", "{181B70F5-C2CB-4A73-9982-30C16DE89240}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {181B70F5-C2CB-4A73-9982-30C16DE89240}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {181B70F5-C2CB-4A73-9982-30C16DE89240}.Debug|Any CPU.Build.0 = Debug|Any CPU + {181B70F5-C2CB-4A73-9982-30C16DE89240}.Release|Any CPU.ActiveCfg = Release|Any CPU + {181B70F5-C2CB-4A73-9982-30C16DE89240}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/82_Stars/vbnet/Stars.vbproj b/82_Stars/vbnet/Stars.vbproj new file mode 100644 index 00000000..caad7d6e --- /dev/null +++ b/82_Stars/vbnet/Stars.vbproj @@ -0,0 +1,8 @@ + + + Exe + Stars + net6.0 + 16.9 + + diff --git a/83_Stock_Market/vbnet/StockMarket.sln b/83_Stock_Market/vbnet/StockMarket.sln new file mode 100644 index 00000000..00c39242 --- /dev/null +++ b/83_Stock_Market/vbnet/StockMarket.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "StockMarket", "StockMarket.vbproj", "{BF9F62B1-4F0E-40F0-AE76-D1055F0A2F31}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BF9F62B1-4F0E-40F0-AE76-D1055F0A2F31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BF9F62B1-4F0E-40F0-AE76-D1055F0A2F31}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BF9F62B1-4F0E-40F0-AE76-D1055F0A2F31}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BF9F62B1-4F0E-40F0-AE76-D1055F0A2F31}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/83_Stock_Market/vbnet/StockMarket.vbproj b/83_Stock_Market/vbnet/StockMarket.vbproj new file mode 100644 index 00000000..1404eb48 --- /dev/null +++ b/83_Stock_Market/vbnet/StockMarket.vbproj @@ -0,0 +1,8 @@ + + + Exe + StockMarket + net6.0 + 16.9 + + diff --git a/84_Super_Star_Trek/vbnet/SuperStarTrek.sln b/84_Super_Star_Trek/vbnet/SuperStarTrek.sln new file mode 100644 index 00000000..82633753 --- /dev/null +++ b/84_Super_Star_Trek/vbnet/SuperStarTrek.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SuperStarTrek", "SuperStarTrek.vbproj", "{92825C31-5966-4E6A-9CB0-5AEEE3D6A2A4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {92825C31-5966-4E6A-9CB0-5AEEE3D6A2A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92825C31-5966-4E6A-9CB0-5AEEE3D6A2A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92825C31-5966-4E6A-9CB0-5AEEE3D6A2A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92825C31-5966-4E6A-9CB0-5AEEE3D6A2A4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/84_Super_Star_Trek/vbnet/SuperStarTrek.vbproj b/84_Super_Star_Trek/vbnet/SuperStarTrek.vbproj new file mode 100644 index 00000000..1a4afed5 --- /dev/null +++ b/84_Super_Star_Trek/vbnet/SuperStarTrek.vbproj @@ -0,0 +1,8 @@ + + + Exe + SuperStarTrek + net6.0 + 16.9 + + diff --git a/85_Synonym/csharp/Synonym.csproj b/85_Synonym/csharp/Synonym.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/85_Synonym/csharp/Synonym.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/85_Synonym/csharp/Synonym.sln b/85_Synonym/csharp/Synonym.sln new file mode 100644 index 00000000..69614aff --- /dev/null +++ b/85_Synonym/csharp/Synonym.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Synonym", "Synonym.csproj", "{9CCC22AC-EDF3-4137-8EF7-EBB2F8677CE4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9CCC22AC-EDF3-4137-8EF7-EBB2F8677CE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9CCC22AC-EDF3-4137-8EF7-EBB2F8677CE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9CCC22AC-EDF3-4137-8EF7-EBB2F8677CE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9CCC22AC-EDF3-4137-8EF7-EBB2F8677CE4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/85_Synonym/vbnet/Synonym.sln b/85_Synonym/vbnet/Synonym.sln new file mode 100644 index 00000000..8b55f812 --- /dev/null +++ b/85_Synonym/vbnet/Synonym.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Synonym", "Synonym.vbproj", "{E6BEB53F-F6A3-4AA9-8EB9-68D8238DFAA6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E6BEB53F-F6A3-4AA9-8EB9-68D8238DFAA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6BEB53F-F6A3-4AA9-8EB9-68D8238DFAA6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6BEB53F-F6A3-4AA9-8EB9-68D8238DFAA6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6BEB53F-F6A3-4AA9-8EB9-68D8238DFAA6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/85_Synonym/vbnet/Synonym.vbproj b/85_Synonym/vbnet/Synonym.vbproj new file mode 100644 index 00000000..8c920a56 --- /dev/null +++ b/85_Synonym/vbnet/Synonym.vbproj @@ -0,0 +1,8 @@ + + + Exe + Synonym + net6.0 + 16.9 + + diff --git a/86_Target/vbnet/Target.sln b/86_Target/vbnet/Target.sln new file mode 100644 index 00000000..3b1edd8c --- /dev/null +++ b/86_Target/vbnet/Target.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Target", "Target.vbproj", "{48A62242-16CC-4BFC-B7DB-C2DAE3C13B5A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {48A62242-16CC-4BFC-B7DB-C2DAE3C13B5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {48A62242-16CC-4BFC-B7DB-C2DAE3C13B5A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {48A62242-16CC-4BFC-B7DB-C2DAE3C13B5A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {48A62242-16CC-4BFC-B7DB-C2DAE3C13B5A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/86_Target/vbnet/Target.vbproj b/86_Target/vbnet/Target.vbproj new file mode 100644 index 00000000..21a19379 --- /dev/null +++ b/86_Target/vbnet/Target.vbproj @@ -0,0 +1,8 @@ + + + Exe + Target + net6.0 + 16.9 + + diff --git a/87_3-D_Plot/vbnet/ThreeDPlot.sln b/87_3-D_Plot/vbnet/ThreeDPlot.sln new file mode 100644 index 00000000..b2ea1dbe --- /dev/null +++ b/87_3-D_Plot/vbnet/ThreeDPlot.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ThreeDPlot", "ThreeDPlot.vbproj", "{FF54B85E-8AD1-4AD5-BB54-2E3DABAA0998}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FF54B85E-8AD1-4AD5-BB54-2E3DABAA0998}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FF54B85E-8AD1-4AD5-BB54-2E3DABAA0998}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FF54B85E-8AD1-4AD5-BB54-2E3DABAA0998}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FF54B85E-8AD1-4AD5-BB54-2E3DABAA0998}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/87_3-D_Plot/vbnet/ThreeDPlot.vbproj b/87_3-D_Plot/vbnet/ThreeDPlot.vbproj new file mode 100644 index 00000000..903ea6aa --- /dev/null +++ b/87_3-D_Plot/vbnet/ThreeDPlot.vbproj @@ -0,0 +1,8 @@ + + + Exe + ThreeDPlot + net6.0 + 16.9 + + diff --git a/88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.csproj b/88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.sln b/88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.sln new file mode 100644 index 00000000..0dcb9034 --- /dev/null +++ b/88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThreeDTicTacToe", "ThreeDTicTacToe.csproj", "{6001B6FB-DF8A-4D59-8E22-BA126C8DA274}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6001B6FB-DF8A-4D59-8E22-BA126C8DA274}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6001B6FB-DF8A-4D59-8E22-BA126C8DA274}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6001B6FB-DF8A-4D59-8E22-BA126C8DA274}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6001B6FB-DF8A-4D59-8E22-BA126C8DA274}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.sln b/88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.sln new file mode 100644 index 00000000..6479b013 --- /dev/null +++ b/88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ThreeDTicTacToe", "ThreeDTicTacToe.vbproj", "{AD17E9E0-4795-4533-A215-09DD99F7D696}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AD17E9E0-4795-4533-A215-09DD99F7D696}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD17E9E0-4795-4533-A215-09DD99F7D696}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD17E9E0-4795-4533-A215-09DD99F7D696}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD17E9E0-4795-4533-A215-09DD99F7D696}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.vbproj b/88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.vbproj new file mode 100644 index 00000000..d1cd4c2b --- /dev/null +++ b/88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.vbproj @@ -0,0 +1,8 @@ + + + Exe + ThreeDTicTacToe + net6.0 + 16.9 + + diff --git a/89_Tic-Tac-Toe/csharp/TicTacToe.sln b/89_Tic-Tac-Toe/csharp/TicTacToe.sln new file mode 100644 index 00000000..c26bd1b4 --- /dev/null +++ b/89_Tic-Tac-Toe/csharp/TicTacToe.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tictactoe1", "tictactoe1\tictactoe1.csproj", "{FE9379CF-AF73-43DA-8FEC-2BCA7FA13A5E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FE9379CF-AF73-43DA-8FEC-2BCA7FA13A5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE9379CF-AF73-43DA-8FEC-2BCA7FA13A5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE9379CF-AF73-43DA-8FEC-2BCA7FA13A5E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE9379CF-AF73-43DA-8FEC-2BCA7FA13A5E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/89_Tic-Tac-Toe/vbnet/TicTacToe.sln b/89_Tic-Tac-Toe/vbnet/TicTacToe.sln new file mode 100644 index 00000000..47935624 --- /dev/null +++ b/89_Tic-Tac-Toe/vbnet/TicTacToe.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "TicTacToe", "TicTacToe.vbproj", "{5B43817F-EEF6-4298-BADF-69203BE7D088}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5B43817F-EEF6-4298-BADF-69203BE7D088}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5B43817F-EEF6-4298-BADF-69203BE7D088}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5B43817F-EEF6-4298-BADF-69203BE7D088}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5B43817F-EEF6-4298-BADF-69203BE7D088}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/89_Tic-Tac-Toe/vbnet/TicTacToe.vbproj b/89_Tic-Tac-Toe/vbnet/TicTacToe.vbproj new file mode 100644 index 00000000..5bac9e9e --- /dev/null +++ b/89_Tic-Tac-Toe/vbnet/TicTacToe.vbproj @@ -0,0 +1,8 @@ + + + Exe + TicTacToe + net6.0 + 16.9 + + diff --git a/90_Tower/vbnet/Tower.sln b/90_Tower/vbnet/Tower.sln new file mode 100644 index 00000000..059a8d70 --- /dev/null +++ b/90_Tower/vbnet/Tower.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Tower", "Tower.vbproj", "{9B62545A-F076-4390-864B-ABE6FC20CC62}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9B62545A-F076-4390-864B-ABE6FC20CC62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B62545A-F076-4390-864B-ABE6FC20CC62}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B62545A-F076-4390-864B-ABE6FC20CC62}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B62545A-F076-4390-864B-ABE6FC20CC62}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/90_Tower/vbnet/Tower.vbproj b/90_Tower/vbnet/Tower.vbproj new file mode 100644 index 00000000..d5d8396b --- /dev/null +++ b/90_Tower/vbnet/Tower.vbproj @@ -0,0 +1,8 @@ + + + Exe + Tower + net6.0 + 16.9 + + diff --git a/91_Train/vbnet/Train.sln b/91_Train/vbnet/Train.sln new file mode 100644 index 00000000..ea959481 --- /dev/null +++ b/91_Train/vbnet/Train.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Train", "Train.vbproj", "{05F1229A-9138-4B1D-9781-CE8C4F7A6151}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {05F1229A-9138-4B1D-9781-CE8C4F7A6151}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05F1229A-9138-4B1D-9781-CE8C4F7A6151}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05F1229A-9138-4B1D-9781-CE8C4F7A6151}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05F1229A-9138-4B1D-9781-CE8C4F7A6151}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/91_Train/vbnet/Train.vbproj b/91_Train/vbnet/Train.vbproj new file mode 100644 index 00000000..84f03013 --- /dev/null +++ b/91_Train/vbnet/Train.vbproj @@ -0,0 +1,8 @@ + + + Exe + Train + net6.0 + 16.9 + + diff --git a/92_Trap/csharp/Trap.csproj b/92_Trap/csharp/Trap.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/92_Trap/csharp/Trap.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/92_Trap/csharp/Trap.sln b/92_Trap/csharp/Trap.sln new file mode 100644 index 00000000..6226bef3 --- /dev/null +++ b/92_Trap/csharp/Trap.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Trap", "Trap.csproj", "{4386B4A0-16A9-48E7-8FBA-E35D4C9FEDAA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4386B4A0-16A9-48E7-8FBA-E35D4C9FEDAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4386B4A0-16A9-48E7-8FBA-E35D4C9FEDAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4386B4A0-16A9-48E7-8FBA-E35D4C9FEDAA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4386B4A0-16A9-48E7-8FBA-E35D4C9FEDAA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/92_Trap/vbnet/Trap.sln b/92_Trap/vbnet/Trap.sln new file mode 100644 index 00000000..65f0a10d --- /dev/null +++ b/92_Trap/vbnet/Trap.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Trap", "Trap.vbproj", "{BAA7B27D-D52D-4C34-972B-2F357F60B8AB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BAA7B27D-D52D-4C34-972B-2F357F60B8AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BAA7B27D-D52D-4C34-972B-2F357F60B8AB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BAA7B27D-D52D-4C34-972B-2F357F60B8AB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BAA7B27D-D52D-4C34-972B-2F357F60B8AB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/92_Trap/vbnet/Trap.vbproj b/92_Trap/vbnet/Trap.vbproj new file mode 100644 index 00000000..f9d5a790 --- /dev/null +++ b/92_Trap/vbnet/Trap.vbproj @@ -0,0 +1,8 @@ + + + Exe + Trap + net6.0 + 16.9 + + diff --git a/93_23_Matches/vbnet/TwentyThreeMatches.sln b/93_23_Matches/vbnet/TwentyThreeMatches.sln new file mode 100644 index 00000000..a378cf3f --- /dev/null +++ b/93_23_Matches/vbnet/TwentyThreeMatches.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "TwentyThreeMatches", "TwentyThreeMatches.vbproj", "{DEAA537A-6F73-4C2E-A85C-4B797B3D1900}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DEAA537A-6F73-4C2E-A85C-4B797B3D1900}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DEAA537A-6F73-4C2E-A85C-4B797B3D1900}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DEAA537A-6F73-4C2E-A85C-4B797B3D1900}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DEAA537A-6F73-4C2E-A85C-4B797B3D1900}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/93_23_Matches/vbnet/TwentyThreeMatches.vbproj b/93_23_Matches/vbnet/TwentyThreeMatches.vbproj new file mode 100644 index 00000000..cf8620c9 --- /dev/null +++ b/93_23_Matches/vbnet/TwentyThreeMatches.vbproj @@ -0,0 +1,8 @@ + + + Exe + TwentyThreeMatches + net6.0 + 16.9 + + diff --git a/94_War/vbnet/War.sln b/94_War/vbnet/War.sln new file mode 100644 index 00000000..3c0895ad --- /dev/null +++ b/94_War/vbnet/War.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "War", "War.vbproj", "{36D070A1-08CB-424E-AB8E-E782B0A6654B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {36D070A1-08CB-424E-AB8E-E782B0A6654B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {36D070A1-08CB-424E-AB8E-E782B0A6654B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {36D070A1-08CB-424E-AB8E-E782B0A6654B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {36D070A1-08CB-424E-AB8E-E782B0A6654B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/94_War/vbnet/War.vbproj b/94_War/vbnet/War.vbproj new file mode 100644 index 00000000..e62cda47 --- /dev/null +++ b/94_War/vbnet/War.vbproj @@ -0,0 +1,8 @@ + + + Exe + War + net6.0 + 16.9 + + diff --git a/95_Weekday/csharp/Weekday.csproj b/95_Weekday/csharp/Weekday.csproj new file mode 100644 index 00000000..d3fe4757 --- /dev/null +++ b/95_Weekday/csharp/Weekday.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + 10 + enable + enable + + diff --git a/95_Weekday/csharp/Weekday.sln b/95_Weekday/csharp/Weekday.sln new file mode 100644 index 00000000..4aad7c31 --- /dev/null +++ b/95_Weekday/csharp/Weekday.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Weekday", "Weekday.csproj", "{6E93B1EC-5E19-47DB-821A-D19F1D0DA982}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6E93B1EC-5E19-47DB-821A-D19F1D0DA982}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E93B1EC-5E19-47DB-821A-D19F1D0DA982}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E93B1EC-5E19-47DB-821A-D19F1D0DA982}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E93B1EC-5E19-47DB-821A-D19F1D0DA982}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/95_Weekday/vbnet/Weekday.sln b/95_Weekday/vbnet/Weekday.sln new file mode 100644 index 00000000..7bbbb17a --- /dev/null +++ b/95_Weekday/vbnet/Weekday.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Weekday", "Weekday.vbproj", "{3BE031BE-D032-477A-A419-48FA7D3C2DD2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3BE031BE-D032-477A-A419-48FA7D3C2DD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3BE031BE-D032-477A-A419-48FA7D3C2DD2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3BE031BE-D032-477A-A419-48FA7D3C2DD2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3BE031BE-D032-477A-A419-48FA7D3C2DD2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/95_Weekday/vbnet/Weekday.vbproj b/95_Weekday/vbnet/Weekday.vbproj new file mode 100644 index 00000000..dfa9996c --- /dev/null +++ b/95_Weekday/vbnet/Weekday.vbproj @@ -0,0 +1,8 @@ + + + Exe + Weekday + net6.0 + 16.9 + + From 61478149ed92d293b4e11f08f3844ebb3c625adb Mon Sep 17 00:00:00 2001 From: Bastiaan Veelo Date: Sun, 16 Jan 2022 13:47:43 +0100 Subject: [PATCH 185/337] Add D version of War (94). --- 94_War/d/.gitignore | 2 + 94_War/d/README.md | 125 ++++++++++++++++++++++++++++++++++++++++++++ 94_War/d/war.d | 80 ++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 94_War/d/.gitignore create mode 100644 94_War/d/README.md create mode 100644 94_War/d/war.d diff --git a/94_War/d/.gitignore b/94_War/d/.gitignore new file mode 100644 index 00000000..d969f6b2 --- /dev/null +++ b/94_War/d/.gitignore @@ -0,0 +1,2 @@ +*.exe +*.obj diff --git a/94_War/d/README.md b/94_War/d/README.md new file mode 100644 index 00000000..2bc48a12 --- /dev/null +++ b/94_War/d/README.md @@ -0,0 +1,125 @@ +Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html) + +Converted to [D](https://dlang.org/) by [Bastiaan Veelo](https://github.com/veelo). + +## Running the code + +Assuming the reference [dmd](https://dlang.org/download.html#dmd) compiler: +```shell +dmd -preview=dip1000 -run war.d +``` + +[Other compilers](https://dlang.org/download.html) also exist. + +## Specialties explained + +This game code contains some specialties that you might want to know more about. Here goes. + +### Suits + +Most modern consoles are capable of displaying more than just ASCII, and so I have chosen to display the actual ♠, ♥, ♦ +and ♣ instead of substituting them by letters like the BASIC original did. Only the Windows console needs a nudge in +the right direction with these instructions: +```d +SetConsoleOutputCP(CP_UTF8); // Set code page +SetConsoleOutputCP(GetACP); // Restore the default +``` +Instead of cluttering the `main()` function with these lesser important details, we can move them into a +[module constructor and module destructor](https://dlang.org/spec/module.html#staticorder), which run before and after +`main()` respectively. And because order of declaration is irrelevant in a D module, we can push those all the way +down to the bottom of the file. This is of course only necessary on Windows (and won't even work anywhere else) so +we'll need to wrap this in a `version (Windows)` conditional code block: +```d +version (Windows) +{ + import core.sys.windows.windows; + + shared static this() @trusted + { + SetConsoleOutputCP(CP_UTF8); + } + + shared static ~this() @trusted + { + SetConsoleOutputCP(GetACP); + } +} +``` +Although it doesn't matter much in this single-threaded program, the `shared` attribute makes that these +constructors/destructors are run once per program invocation; non-shared module constructors and module destructors are +run for every thread. The `@trusted` annotation is necessary because these are system API calls; The compiler cannot +check these for memory-safety, and so we must indicate that we have reviewed the safety manually. + +### Uniform Function Call Syntax + +In case you wonder why this line works: +```d +if ("Do you want instructions?".yes) + // ... +``` +then it is because this is equivalent to +```d +if (yes("Do you want instructions?")) + // ... +``` +where `yes()` is a Boolean function that is defined below `main()`. This is made possible by the language feature that +is called [uniform function call syntax (UFCS)](https://dlang.org/spec/function.html#pseudo-member). UFCS works by +passing what is in front of the dot as the first parameter to the function, and it was invented to make it possible to +call free functions on objects as if they were member functions. UFCS can also be used to obtain a more natural order +of function calls, such as this line inside `yes()`: +```d +return trustedReadln.strip.toLower.startsWith("y"); +``` +which reads easier than the equivalent +```d +return startsWith(toLower(strip(trustedReadln())), "y"); +``` + +### Type a lot or not? + +It would have been straight forward to define the `cards` array explicitly like so: +```d +const cards = ["2♠", "2♥", "2♦", "2♣", "3♠", "3♥", "3♦", "3♣", + "4♠", "4♥", "4♦", "4♣", "5♠", "5♥", "5♦", "5♣", + "6♠", "6♥", "6♦", "6♣", "7♠", "7♥", "7♦", "7♣", + "8♠", "8♥", "8♦", "8♣", "9♠", "9♥", "9♦", "9♣", + "10♠", "10♥", "10♦", "10♣", "J♥", "J♦", "J♣", "J♣", + "Q♠", "Q♥", "Q♦", "Q♣", "K♠", "K♥", "K♦", "K♣", + "A♠", "A♥", "A♦", "A♣"]; +``` +but that's tedious, difficult to spot errors in (*can you?*) and looks like something a computer can automate. Indeed +it can: +```d +static const cards = cartesianProduct(["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"], + ["♠", "♥", "♦", "♣"]).map!(a => a.expand.only.join).array; +``` +The function [`cartesianProduct`](https://dlang.org/phobos/std_algorithm_setops.html#cartesianProduct) takes two +ranges, like the horizontal and vertical headers of a spreadsheet, and fills the table with the combinations that form +the coordinates of the cells. But the output of that function is in the form of an array of +[`Tuple`](https://dlang.org/phobos/std_typecons.html#Tuple)s, which looks like `[Tuple!(string, string)("2", "♠"), +Tuple!(string, string)("2", "♥"), ... etc]`. [`map`](https://dlang.org/phobos/std_algorithm_iteration.html#map) +comes to the rescue, converting each Tuple to a string, by calling +[`expand`](https://dlang.org/phobos/std_typecons.html#.Tuple.expand), then +[`only`](https://dlang.org/phobos/std_range.html#only) and then [`join`](https://dlang.org/phobos/std_array.html#join) +on them. The result is a lazily evaluated range of strings. Finally, +[`array`](https://dlang.org/phobos/std_array.html#array) turns the range into a random access array. The `static` +attribute makes that all this is performed at compile-time, so the result is exactly the same as the manually entered +data, but without the typo's. + +### Shuffle the cards or not? + +The original BASIC code works with a constant array of cards, ordered by increasing numerical value, and indexing it +with indices that have been shuffled. This is efficient because in comparing who wins, the indices can be compared +directly, since a higher index correlates to a card with a higher numerical value (when divided by the number of suits, +4). Some of the other reimplementations in other languages have been written in a lesser efficient way by shuffling the +array of cards itself. This then requires the use of a lookup table or searching for equality in an auxiliary array +when comparing cards. + +I find the original more elegant, so that's what you see here: +```d +const indices = iota(0, cards.length).array.randomShuffle; +``` +[`iota`](https://dlang.org/phobos/std_range.html#iota) produces a range of integers, in this case starting at 0 and +increasing up to the number of cards in the deck (exclusive). [`array`](https://dlang.org/phobos/std_array.html#array) +turns the range into an array, so that [`randomShuffle`](https://dlang.org/phobos/std_random.html#randomShuffle) can +do its work. diff --git a/94_War/d/war.d b/94_War/d/war.d new file mode 100644 index 00000000..d5a453fa --- /dev/null +++ b/94_War/d/war.d @@ -0,0 +1,80 @@ +@safe: // Make @safe the default for this file, enforcing memory-safety. +import std; + +void main() +{ + enum width = 50; + writeln(center("War", width)); + writeln(center("(After Creative Computing Morristown, New Jersey)\n\n", width)); + writeln(wrap("This is the card game of war. Each card is given by suit-# " ~ + "as 7♠ for seven of spades. ", width)); + + if ("Do you want instructions?".yes) + writeln("\n", wrap("The computer gives you and it a 'card'. The higher card " ~ + "(numerically) wins. The game ends when you choose not to " ~ + "continue or when you have finished the pack.\n", width)); + + static const cards = cartesianProduct(["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"], + ["♠", "♥", "♦", "♣"]).map!(a => a.expand.only.join).array; + const indices = iota(0, cards.length).array.randomShuffle; + int yourScore = 0, compScore = 0, i = 0; + while (i < indices.length) + { + size_t your = indices[i++], comp = indices[i++]; + writeln("\nYou: ", cards[your].leftJustify(9), "Computer: ", cards[comp]); + your /= 4; comp /= 4; + if (your == comp) + writeln("Tie. No score change."); + else if (your < comp) + writeln("The computer wins!!! You have ", yourScore, + " and the computer has ", ++compScore, "."); + else + writeln("You win. You have ", ++yourScore, + " and the computer has ", compScore, "."); + if (i == indices.length) + writeln("\nWe have run out of cards. Final score: You: ", yourScore, + ", the computer: ", compScore, "."); + else if (!"Do you want to continue?".yes) + break; + } + writeln("\nThanks for playing. It was fun."); +} + +/// Returns whether question was answered positively. +bool yes(string question) +{ + writef!"%s "(question); + try + return trustedReadln.strip.toLower.startsWith("y"); + catch (Exception) // readln throws on I/O and Unicode errors, which we handle here. + return false; +} + +/** An @trusted wrapper around readln. +* +* This is the only function that formally requires manual review for memory-safety. +* [Arguably readln should be safe already](https://forum.dlang.org/post/rab398$1up$1@digitalmars.com) +* which would remove the need to have any @trusted code in this program. +*/ +string trustedReadln() @trusted +{ + return readln; +} + +version (Windows) +{ + // Make the Windows console do a better job at printing UTF-8 strings, + // and restore the default upon termination. + + import core.sys.windows.windows; + + shared static this() @trusted + { + SetConsoleOutputCP(CP_UTF8); + } + + shared static ~this() @trusted + { + SetConsoleOutputCP(GetACP); + } +} From f1c35db0f74a8d577b20e2e8bef6bbdbc8302117 Mon Sep 17 00:00:00 2001 From: Aldrin Misquitta Date: Sun, 16 Jan 2022 14:21:17 +0000 Subject: [PATCH 186/337] Use a tree structure instead of a list (Fix for issue #369) --- 03_Animal/java/Animal.java | 343 +++++++++++++++++++++++-------------- 1 file changed, 214 insertions(+), 129 deletions(-) diff --git a/03_Animal/java/Animal.java b/03_Animal/java/Animal.java index 11e9e889..681425c1 100644 --- a/03_Animal/java/Animal.java +++ b/03_Animal/java/Animal.java @@ -2,159 +2,244 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Scanner; +import java.util.stream.Collectors; /** * ANIMAL *

* Converted from BASIC to Java by Aldrin Misquitta (@aldrinm) + * The original BASIC program uses an array to maintain the questions and answers and to decide which question to + * ask next. Updated this Java implementation to use a tree instead of the earlier faulty one based on a list (thanks @patimen). */ public class Animal { - public static void main(String[] args) { - printIntro(); - Scanner scan = new Scanner(System.in); + public static void main(String[] args) { + printIntro(); + Scanner scan = new Scanner(System.in); - List questions = new ArrayList<>(); - questions.add(new Question("DOES IT SWIM", "FISH", "BIRD")); + Node root = new QuestionNode("DOES IT SWIM", + new AnimalNode("FISH"), new AnimalNode("BIRD")); - boolean stopGame = false; - while (!stopGame) { - String choice = readMainChoice(scan); - switch (choice) { - case "LIST": - printKnownAnimals(questions); - break; - case "Q": - case "QUIT": - stopGame = true; - break; - default: - if (choice.toUpperCase(Locale.ROOT).startsWith("Y")) { - int k = 0; - boolean correctGuess = false; - while (questions.size() > k && !correctGuess) { - Question question = questions.get(k); - correctGuess = askQuestion(question, scan); - if (correctGuess) { - System.out.println("WHY NOT TRY ANOTHER ANIMAL?"); - } else { - k++; - } - } + boolean stopGame = false; + while (!stopGame) { + String choice = readMainChoice(scan); + switch (choice) { + case "TREE": + printTree(root); + break; + case "LIST": + printKnownAnimals(root); + break; + case "Q": + case "QUIT": + stopGame = true; + break; + default: + if (choice.toUpperCase(Locale.ROOT).startsWith("Y")) { + Node current = root; //where we are in the question tree + Node previous; //keep track of parent of current in order to place new questions later on. - if (!correctGuess) { - askForInformationAndSave(scan, questions); - } - } - } - } + while (current instanceof QuestionNode) { + var currentQuestion = (QuestionNode) current; + var reply = askQuestionAndGetReply(currentQuestion, scan); - } + previous = current; + current = reply ? currentQuestion.getTrueAnswer() : currentQuestion.getFalseAnswer(); + if (current instanceof AnimalNode) { + //We have reached a animal node, so offer it as the guess + var currentAnimal = (AnimalNode) current; + System.out.printf("IS IT A %s ? ", currentAnimal.getAnimal()); + var animalGuessResponse = readYesOrNo(scan); + if (animalGuessResponse) { + //we guessed right! end this round + System.out.println("WHY NOT TRY ANOTHER ANIMAL?"); + } else { + //we guessed wrong :(, ask for feedback + //cast previous to QuestionNode since we know at this point that it is not a leaf node + askForInformationAndSave(scan, currentAnimal, (QuestionNode) previous, reply); + } + } + } + } + } + } + } - private static void askForInformationAndSave(Scanner scan, List questions) { - //Failed to get it right and ran out of questions - //Let's ask the user for the new information - System.out.print("THE ANIMAL YOU WERE THINKING OF WAS A "); - String animal = scan.nextLine(); - System.out.printf("PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A %s FROM A %s ", animal, questions.get( - questions.size() - 1).falseAnswer); - String newQuestion = scan.nextLine(); - System.out.printf("FOR A %s THE ANSWER WOULD BE ", animal); - boolean newAnswer = readYesOrNo(scan); - //Add it to our list - addNewAnimal(questions, animal, newQuestion, newAnswer); - } + /** + * Prompt for information about the animal we got wrong + * @param current The animal that we guessed wrong + * @param previous The root of current + * @param previousToCurrentDecisionChoice Whether it was a Y or N answer that got us here. true = Y, false = N + */ + private static void askForInformationAndSave(Scanner scan, AnimalNode current, QuestionNode previous, boolean previousToCurrentDecisionChoice) { + //Failed to get it right and ran out of questions + //Let's ask the user for the new information + System.out.print("THE ANIMAL YOU WERE THINKING OF WAS A "); + String animal = scan.nextLine(); + System.out.printf("PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A %s FROM A %s ", animal, current.getAnimal()); + String newQuestion = scan.nextLine(); + System.out.printf("FOR A %s THE ANSWER WOULD BE ", animal); + boolean newAnswer = readYesOrNo(scan); + //Add it to our question store + addNewAnimal(current, previous, animal, newQuestion, newAnswer, previousToCurrentDecisionChoice); + } - private static void addNewAnimal(List questions, String animal, String newQuestion, boolean newAnswer) { - Question lastQuestion = questions.get(questions.size() - 1); - String lastAnimal = lastQuestion.falseAnswer; - lastQuestion.falseAnswer = null; //remove the false option to indicate that there is a next question + private static void addNewAnimal(Node current, + QuestionNode previous, + String animal, + String newQuestion, + boolean newAnswer, + boolean previousToCurrentDecisionChoice) { + var animalNode = new AnimalNode(animal); + var questionNode = new QuestionNode(newQuestion, + newAnswer ? animalNode : current, + !newAnswer ? animalNode : current); - Question newOption; - if (newAnswer) { - newOption = new Question(newQuestion, animal, lastAnimal); - } else { - newOption = new Question(newQuestion, lastAnimal, animal); - } - questions.add(newOption); - } + if (previous != null) { + if (previousToCurrentDecisionChoice) { + previous.setTrueAnswer(questionNode); + } else { + previous.setFalseAnswer(questionNode); + } + } + } - private static boolean askQuestion(Question question, Scanner scanner) { - System.out.printf("%s ? ", question.question); + private static boolean askQuestionAndGetReply(QuestionNode questionNode, Scanner scanner) { + System.out.printf("%s ? ", questionNode.question); + return readYesOrNo(scanner); + } - boolean chosenAnswer = readYesOrNo(scanner); - if (chosenAnswer) { - if (question.trueAnswer != null) { - System.out.printf("IS IT A %s ? ", question.trueAnswer); - return readYesOrNo(scanner); - } - //else go to the next question - } else { - if (question.falseAnswer != null) { - System.out.printf("IS IT A %s ? ", question.falseAnswer); - return readYesOrNo(scanner); - } - //else go to the next question - } - return false; - } + private static boolean readYesOrNo(Scanner scanner) { + boolean validAnswer = false; + Boolean choseAnswer = null; + while (!validAnswer) { + String answer = scanner.nextLine(); + if (answer.toUpperCase(Locale.ROOT).startsWith("Y")) { + validAnswer = true; + choseAnswer = true; + } else if (answer.toUpperCase(Locale.ROOT).startsWith("N")) { + validAnswer = true; + choseAnswer = false; + } + } + return choseAnswer; + } - private static boolean readYesOrNo(Scanner scanner) { - boolean validAnswer = false; - Boolean choseAnswer = null; - while (!validAnswer) { - String answer = scanner.nextLine(); - if (answer.toUpperCase(Locale.ROOT).startsWith("Y")) { - validAnswer = true; - choseAnswer = true; - } else if (answer.toUpperCase(Locale.ROOT).startsWith("N")) { - validAnswer = true; - choseAnswer = false; - } - } - return choseAnswer; - } + private static void printKnownAnimals(Node root) { + System.out.println("\nANIMALS I ALREADY KNOW ARE:"); - private static void printKnownAnimals(List questions) { - System.out.println("\nANIMALS I ALREADY KNOW ARE:"); - List animals = new ArrayList<>(); - questions.forEach(q -> { - if (q.trueAnswer != null) { - animals.add(q.trueAnswer); - } - if (q.falseAnswer != null) { - animals.add(q.falseAnswer); - } - }); - System.out.println(String.join("\t\t", animals)); - } + List leafNodes = collectLeafNodes(root); + String allAnimalsString = leafNodes.stream().map(AnimalNode::getAnimal).collect(Collectors.joining("\t\t")); - private static String readMainChoice(Scanner scan) { - System.out.print("ARE YOU THINKING OF AN ANIMAL ? "); - return scan.nextLine(); - } + System.out.println(allAnimalsString); + } - private static void printIntro() { - System.out.println(" ANIMAL"); - System.out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); - System.out.println("\n\n"); - System.out.println("PLAY 'GUESS THE ANIMAL'"); - System.out.println("\n"); - System.out.println("THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT."); - } + //Traverse the tree and collect all the leaf nodes, which basically have all the animals. + private static List collectLeafNodes(Node root) { + List collectedNodes = new ArrayList<>(); + if (root instanceof AnimalNode) { + collectedNodes.add((AnimalNode) root); + } else { + var q = (QuestionNode) root; + collectedNodes.addAll(collectLeafNodes(q.getTrueAnswer())); + collectedNodes.addAll(collectLeafNodes(q.getFalseAnswer())); + } + return collectedNodes; + } + + private static String readMainChoice(Scanner scan) { + System.out.print("ARE YOU THINKING OF AN ANIMAL ? "); + return scan.nextLine(); + } + + private static void printIntro() { + System.out.println(" ANIMAL"); + System.out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println("\n\n"); + System.out.println("PLAY 'GUESS THE ANIMAL'"); + System.out.println("\n"); + System.out.println("THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT."); + } + + //Based on https://stackoverflow.com/a/8948691/74057 + private static void printTree(Node root) { + StringBuilder buffer = new StringBuilder(50); + print(root, buffer, "", ""); + System.out.println(buffer); + } + + private static void print(Node root, StringBuilder buffer, String prefix, String childrenPrefix) { + buffer.append(prefix); + buffer.append(root.toString()); + buffer.append('\n'); + + if (root instanceof QuestionNode) { + var questionNode = (QuestionNode) root; + print(questionNode.getTrueAnswer(), buffer, childrenPrefix + "├─Y─ ", childrenPrefix + "│ "); + print(questionNode.getFalseAnswer(), buffer, childrenPrefix + "└─N─ ", childrenPrefix + " "); + } + } - public static class Question { - String question; - String trueAnswer; - String falseAnswer; + /** + * Base interface for all nodes in our question tree + */ + private interface Node { + } - public Question(String question, String trueAnswer, String falseAnswer) { - this.question = question; - this.trueAnswer = trueAnswer; - this.falseAnswer = falseAnswer; - } - } + private static class QuestionNode implements Node { + private final String question; + private Node trueAnswer; + private Node falseAnswer; + + public QuestionNode(String question, Node trueAnswer, Node falseAnswer) { + this.question = question; + this.trueAnswer = trueAnswer; + this.falseAnswer = falseAnswer; + } + + public String getQuestion() { + return question; + } + + public Node getTrueAnswer() { + return trueAnswer; + } + + public void setTrueAnswer(Node trueAnswer) { + this.trueAnswer = trueAnswer; + } + + public Node getFalseAnswer() { + return falseAnswer; + } + + public void setFalseAnswer(Node falseAnswer) { + this.falseAnswer = falseAnswer; + } + + @Override + public String toString() { + return "Question{'" + question + "'}"; + } + } + + private static class AnimalNode implements Node { + private final String animal; + + public AnimalNode(String animal) { + this.animal = animal; + } + + public String getAnimal() { + return animal; + } + + @Override + public String toString() { + return "Animal{'" + animal + "'}"; + } + } } From 6f8e876dbb3131cc1a3241cd114c224f835b7cb5 Mon Sep 17 00:00:00 2001 From: ribtips Date: Sun, 16 Jan 2022 11:18:43 -0500 Subject: [PATCH 187/337] Ruby implementation of game 61 math_dice --- 61_Math_Dice/ruby/mathdice.rb | 115 ++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 61_Math_Dice/ruby/mathdice.rb diff --git a/61_Math_Dice/ruby/mathdice.rb b/61_Math_Dice/ruby/mathdice.rb new file mode 100644 index 00000000..60853d45 --- /dev/null +++ b/61_Math_Dice/ruby/mathdice.rb @@ -0,0 +1,115 @@ +def intro + puts " MATH DICE + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + +THIS PROGRAM GENERATES SUCCESSIVE PICTURES OF TWO DICE. +WHEN TWO DICE AND AN EQUAL SIGN FOLLOWED BY A QUESTION +MARK HAVE BEEN PRINTED, TYPE YOUR ANSWER AND THE RETURN KEY. +TO CONCLUDE THE LESSON, TYPE '0' AS YOUR ANSWER. +" +end + +def game_play + num = 0 + sum = 0 + tries = 0 + until num == 2 do + num+=1 + roll = rand(6) + 1 + print_dice(roll) + sum = sum + roll + if num == 1 + print "\n +\n\n" + end + if num == 2 + print "\n =? " + ans = gets.chomp + if ans.to_i == 0 + #END GAME + exit(0) + elsif ans.to_i == sum + puts "RIGHT!" + puts "THE DICE ROLL AGAIN" + else + puts "NO, COUNT THE SPOTS AND GIVE ANOTHER ANSWER" + print "\n =? " + ans = gets.chomp + if ans.to_i == sum + puts "RIGHT!" + puts "THE DICE ROLL AGAIN" + elsif ans.to_i == 0 + exit(0) + else + puts "NO, THE ANSWER IS #{sum}" + end + end + end + end +end + + + +def print_dice(roll) + puts " -----" + if roll == 1 + print_blank + print_one_mid + print_blank + elsif roll == 2 + print_one_left + print_blank + print_one_right + elsif roll == 3 + print_one_left + print_one_mid + print_one_right + elsif roll == 4 + print_two + print_blank + print_two + elsif roll == 5 + print_two + print_one_mid + print_two + elsif roll == 6 + print_two + print_two + print_two + else + puts "not a legit dice roll" + end + puts " -----" +end + + +def print_one_left + puts "I * I" +end + +def print_one_mid + puts "I * I" +end + +def print_one_right + puts "I * I" +end + +def print_two + puts "I * * I" +end + +def print_blank + puts "I I" +end + + + +def main + intro + #Continue playing forever until it terminates with exit in game_play + while 1 == 1 do + game_play + end +end + +main From b2735b1d2e43895aab13a4ce6fcc7b4887ef8d43 Mon Sep 17 00:00:00 2001 From: Stefan Waldmann Date: Sun, 16 Jan 2022 18:10:28 +0100 Subject: [PATCH 188/337] Add Java implementation --- 55_Life/java/src/java/Life.java | 127 ++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 55_Life/java/src/java/Life.java diff --git a/55_Life/java/src/java/Life.java b/55_Life/java/src/java/Life.java new file mode 100644 index 00000000..3b592c14 --- /dev/null +++ b/55_Life/java/src/java/Life.java @@ -0,0 +1,127 @@ +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +record Transition(int y, int x, byte newState) { } + +public class Life { + + private static final byte DEAD = 0; + private static final byte ALIVE = 1; + + private final byte[][] matrix = new byte[21][67]; + private int generation = 0; + private int population = 0; + boolean invalid = false; + + private void start() throws Exception { + Scanner s = new Scanner(System.in); + printGameHeader(); + readPattern(); + while (true) { + printPattern(); + advanceToNextGeneration(); + s.nextLine(); +// Thread.sleep(1000); + } + } + + private void advanceToNextGeneration() { + List transitions = new ArrayList<>(); + for (int y = 0; y < matrix.length; y++) { + for (int x = 0; x < matrix[y].length; x++) { + int neighbours = countNeighbours(y, x); + if (matrix[y][x] == DEAD) { + if (neighbours == 3) { + transitions.add(new Transition(y, x, ALIVE)); + population++; + } + } else { + // cell is alive + if (neighbours < 2 || neighbours > 3) { + transitions.add(new Transition(y, x, DEAD)); + population--; + } + } + } + } + transitions.forEach(t -> matrix[t.y()][t.x()] = t.newState()); + generation++; + } + + private int countNeighbours(int y, int x) { + int neighbours = 0; + for (int row = Math.max(y - 1, 0); row <= Math.min(y + 1, matrix.length - 1); row++) { + for (int col = Math.max(x - 1, 0); col <= Math.min(x + 1, matrix[row].length - 1); col++) { + if (row == y && col == x) { + continue; + } + if (matrix[row][col] == ALIVE) { + neighbours++; + } + } + } + return neighbours; + } + + private void readPattern() { + System.out.println("ENTER YOUR PATTERN:"); + Scanner s = new Scanner(System.in); + List lines = new ArrayList<>(); + String line; + int maxLineLength = 0; + boolean reading = true; + while (reading) { + System.out.print("? "); + line = s.nextLine(); + if (line.equalsIgnoreCase("done")) { + reading = false; + } else { + // optional support for the '.' that is needed in the BASIC version + lines.add(line.replace('.', ' ')); + maxLineLength = Math.max(maxLineLength, line.length()); + } + } + fillMatrix(lines, maxLineLength); + } + + private void fillMatrix(List lines, int maxLineLength) { + float xMin = 33 - maxLineLength / 2f; + float yMin = 11 - lines.size() / 2f; + System.out.println("lines=" + lines.size() + " columns=" + maxLineLength + " yMin=" + yMin + " xMin=" + xMin); + for (int y = 0; y < lines.size(); y++) { + String line = lines.get(y); + for (int x = 1; x <= line.length(); x++) { + if (line.charAt(x-1) == '*') { + matrix[round(yMin + y)][round(xMin + x)] = ALIVE; + population++; + } + } + } + } + + private int round(float f) { + return (int) Math.floor(f); + } + + private void printGameHeader() { + System.out.println(" ".repeat(34) + "LIFE"); + System.out.println(" ".repeat(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println("\n\n\n"); + } + + private void printPattern() { + System.out.println("GENERATION: " + generation + " POPULATION: " + population); + for (int y = 0; y < matrix.length; y++) { + for (int x = 0; x < matrix[y].length; x++) { + System.out.print(matrix[y][x] == 1 ? "*" : " "); + } + System.out.println(); + } + } + + public static void main(String[] args) throws Exception { + new Life().start(); + } + +} From 0996f041b95b46cbf0900422c6a180c06e439806 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sun, 16 Jan 2022 18:44:43 +0000 Subject: [PATCH 189/337] Deminify --- 84_Super_Star_Trek/superstartrek.bas | 438 +++++++++++++-------------- 1 file changed, 219 insertions(+), 219 deletions(-) diff --git a/84_Super_Star_Trek/superstartrek.bas b/84_Super_Star_Trek/superstartrek.bas index 74300763..72fb4f5d 100644 --- a/84_Super_Star_Trek/superstartrek.bas +++ b/84_Super_Star_Trek/superstartrek.bas @@ -37,23 +37,23 @@ 475 DEF FNR(R)=INT(RND(R)*7.98+1.01) 480 REM INITIALIZE ENTERPRIZE'S POSITION 490 Q1=FNR(1):Q2=FNR(1):S1=FNR(1):S2=FNR(1) -530 FORI=1TO9:C(I,1)=0:C(I,2)=0:NEXTI +530 FOR I=1 TO 9:C(I,1)=0:C(I,2)=0:NEXT I 540 C(3,1)=-1:C(2,1)=-1:C(4,1)=-1:C(4,2)=-1:C(5,2)=-1:C(6,2)=-1 600 C(1,2)=1:C(2,2)=1:C(6,1)=1:C(7,1)=1:C(8,1)=1:C(8,2)=1:C(9,2)=1 -670 FORI=1TO8:D(I)=0:NEXTI +670 FOR I=1 TO 8:D(I)=0:NEXT I 710 A1$="NAVSRSLRSPHATORSHEDAMCOMXXX" 810 REM SETUP WHAT EXHISTS IN GALAXY . . . 815 REM K3= # KLINGONS B3= # STARBASES S3 = # STARS -820 FORI=1TO8:FORJ=1TO8:K3=0:Z(I,J)=0:R1=RND(1) -850 IFR1>.98THENK3=3:K9=K9+3:GOTO980 -860 IFR1>.95THENK3=2:K9=K9+2:GOTO980 -870 IFR1>.80THENK3=1:K9=K9+1 -980 B3=0:IFRND(1)>.96THENB3=1:B9=B9+1 -1040 G(I,J)=K3*100+B3*10+FNR(1):NEXTJ:NEXTI:IFK9>T9THENT9=K9+1 -1100 IFB9<>0THEN1200 -1150 IFG(Q1,Q2)<200THENG(Q1,Q2)=G(Q1,Q2)+120:K9=K9+1 +820 FOR I=1 TO 8:FOR J=1 TO 8:K3=0:Z(I,J)=0:R1=RND(1) +850 IF R1>.98 THEN K3=3:K9=K9+3:GOTO 980 +860 IF R1>.95 THEN K3=2:K9=K9+2:GOTO 980 +870 IF R1>.80 THEN K3=1:K9=K9+1 +980 B3=0:IF RND(1)>.96 THEN B3=1:B9=B9+1 +1040 G(I,J)=K3*100+B3*10+FNR(1):NEXT J:NEXT I:IF K9>T9 THEN T9=K9+1 +1100 IF B9<>0 THEN 1200 +1150 IF G(Q1,Q2)<200 THEN G(Q1,Q2)=G(Q1,Q2)+120:K9=K9+1 1160 B9=1:G(Q1,Q2)=G(Q1,Q2)+10:Q1=FNR(1):Q2=FNR(1) -1200 K7=K9:IFB9<>1THENX$="S":X0$=" ARE " +1200 K7=K9:IF B9<>1 THEN X$="S":X0$=" ARE " 1230 PRINT"YOUR ORDERS ARE AS FOLLOWS:" 1240 PRINT" DESTROY THE";K9;"KLINGON WARSHIPS WHICH HAVE INVADED" 1252 PRINT" THE GALAXY BEFORE THEY CAN ATTACK FEDERATION HEADQUARTERS" @@ -63,35 +63,35 @@ 1300 I=RND(1):REM IF INP(1)=13 THEN 1300 1310 REM HERE ANY TIME NEW QUADRANT ENTERED 1320 Z4=Q1:Z5=Q2:K3=0:B3=0:S3=0:G5=0:D4=.5*RND(1):Z(Q1,Q2)=G(Q1,Q2) -1390 IFQ1<1ORQ1>8ORQ2<1ORQ2>8THEN1600 +1390 IF Q1<1 OR Q1>8 OR Q2<1 OR Q2>8 THEN 1600 1430 GOSUB 9030:PRINT:IF T0<>T THEN 1490 1460 PRINT"YOUR MISSION BEGINS WITH YOUR STARSHIP LOCATED" 1470 PRINT"IN THE GALACTIC QUADRANT, '";G2$;"'.":GOTO 1500 1490 PRINT"NOW ENTERING ";G2$;" QUADRANT . . ." 1500 PRINT:K3=INT(G(Q1,Q2)*.01):B3=INT(G(Q1,Q2)*.1)-10*K3 -1540 S3=G(Q1,Q2)-100*K3-10*B3:IFK3=0THEN1590 -1560 PRINT"COMBAT AREA CONDITION RED":IFS>200THEN1590 +1540 S3=G(Q1,Q2)-100*K3-10*B3:IF K3=0 THEN 1590 +1560 PRINT"COMBAT AREA CONDITION RED":IF S>200 THEN 1590 1580 PRINT" SHIELDS DANGEROUSLY LOW" -1590 FORI=1TO3:K(I,1)=0:K(I,2)=0:NEXTI -1600 FORI=1TO3:K(I,3)=0:NEXTI:Q$=Z$+Z$+Z$+Z$+Z$+Z$+Z$+LEFT$(Z$,17) +1590 FOR I=1 TO 3:K(I,1)=0:K(I,2)=0:NEXT I +1600 FOR I=1 TO 3:K(I,3)=0:NEXT I:Q$=Z$+Z$+Z$+Z$+Z$+Z$+Z$+LEFT$(Z$,17) 1660 REM POSITION ENTERPRISE IN QUADRANT, THEN PLACE "K3" KLINGONS, & 1670 REM "B3" STARBASES, & "S3" STARS ELSEWHERE. -1680 A$="<*>":Z1=S1:Z2=S2:GOSUB8670:IFK3<1THEN1820 -1720 FORI=1TOK3:GOSUB8590:A$="+K+":Z1=R1:Z2=R2 -1780 GOSUB8670:K(I,1)=R1:K(I,2)=R2:K(I,3)=S9*(0.5+RND(1)):NEXTI -1820 IFB3<1THEN1910 -1880 GOSUB8590:A$=">!<":Z1=R1:B4=R1:Z2=R2:B5=R2:GOSUB8670 -1910 FORI=1TOS3:GOSUB8590:A$=" * ":Z1=R1:Z2=R2:GOSUB8670:NEXTI -1980 GOSUB6430 -1990 IFS+E>10THENIFE>10ORD(7)=0THEN2060 +1680 A$="<*>":Z1=S1:Z2=S2:GOSUB 8670:IF K3<1 THEN 1820 +1720 FOR I=1 TO K3:GOSUB 8590:A$="+K+":Z1=R1:Z2=R2 +1780 GOSUB 8670:K(I,1)=R1:K(I,2)=R2:K(I,3)=S9*(0.5+RND(1)):NEXT I +1820 IF B3<1 THEN 1910 +1880 GOSUB 8590:A$=">!<":Z1=R1:B4=R1:Z2=R2:B5=R2:GOSUB 8670 +1910 FOR I=1 TO S3:GOSUB 8590:A$=" * ":Z1=R1:Z2=R2:GOSUB 8670:NEXT I +1980 GOSUB 6430 +1990 IF S+E>10 THEN IF E>10 OR D(7)=0 THEN 2060 2020 PRINT:PRINT"** FATAL ERROR ** YOU'VE JUST STRANDED YOUR SHIP IN " 2030 PRINT"SPACE":PRINT"YOU HAVE INSUFFICIENT MANEUVERING ENERGY,"; 2040 PRINT" AND SHIELD CONTROL":PRINT"IS PRESENTLY INCAPABLE OF CROSS"; -2050 PRINT"-CIRCUITING TO ENGINE ROOM!!":GOTO6220 +2050 PRINT"-CIRCUITING TO ENGINE ROOM!!":GOTO 6220 2060 INPUT"COMMAND";A$ -2080 FORI=1TO9:IFLEFT$(A$,3)<>MID$(A1$,3*I-2,3)THEN2160 -2140 ONIGOTO2300,1980,4000,4260,4700,5530,5690,7290,6270 -2160 NEXTI:PRINT"ENTER ONE OF THE FOLLOWING:" +2080 FOR I=1 TO 9:IF LEFT$(A$,3)<>MID$(A1$,3*I-2,3) THEN 2160 +2140 ONIGOTO 2300,1980,4000,4260,4700,5530,5690,7290,6270 +2160 NEXT I:PRINT"ENTER ONE OF THE FOLLOWING:" 2180 PRINT" NAV (TO SET COURSE)" 2190 PRINT" SRS (FOR SHORT RANGE SENSOR SCAN)" 2200 PRINT" LRS (FOR LONG RANGE SENSOR SCAN)" @@ -102,288 +102,288 @@ 2250 PRINT" COM (TO CALL ON LIBRARY-COMPUTER)" 2260 PRINT" XXX (TO RESIGN YOUR COMMAND)":PRINT:GOTO 1990 2290 REM COURSE CONTROL BEGINS HERE -2300 INPUT"COURSE (0-9)";C1:IFC1=9THENC1=1 -2310 IFC1>=1ANDC1<9THEN2350 -2330 PRINT" LT. SULU REPORTS, 'INCORRECT COURSE DATA, SIR!'":GOTO1990 -2350 X$="8":IFD(1)<0THENX$="0.2" -2360 PRINT"WARP FACTOR (0-";X$;")";:INPUTW1:IFD(1)<0ANDW1>.2THEN2470 -2380 IFW1>0ANDW1<=8THEN2490 -2390 IFW1=0THEN1990 +2300 INPUT"COURSE (0-9)";C1:IF C1=9 THEN C1=1 +2310 IF C1>=1 AND C1<9 THEN 2350 +2330 PRINT" LT. SULU REPORTS, 'INCORRECT COURSE DATA, SIR!'":GOTO 1990 +2350 X$="8":IF D(1)<0 THEN X$="0.2" +2360 PRINT"WARP FACTOR (0-";X$;")";:INPUT W1:IF D(1)<0 AND W1>.2 THEN 2470 +2380 IF W1>0 AND W1<=8 THEN 2490 +2390 IF W1=0 THEN 1990 2420 PRINT" CHIEF ENGINEER SCOTT REPORTS 'THE ENGINES WON'T TAKE"; -2430 PRINT" WARP ";W1;"!'":GOTO1990 -2470 PRINT"WARP ENGINES ARE DAMAGED. MAXIUM SPEED = WARP 0.2":GOTO1990 -2490 N=INT(W1*8+.5):IFE-N>=0THEN2590 +2430 PRINT" WARP ";W1;"!'":GOTO 1990 +2470 PRINT"WARP ENGINES ARE DAMAGED. MAXIUM SPEED = WARP 0.2":GOTO 1990 +2490 N=INT(W1*8+.5):IF E-N>=0 THEN 2590 2500 PRINT"ENGINEERING REPORTS 'INSUFFICIENT ENERGY AVAILABLE" 2510 PRINT" FOR MANEUVERING AT WARP";W1;"!'" -2530 IFS=1THEND6=1 -2770 FORI=1TO8:IFD(I)>=0THEN2880 -2790 D(I)=D(I)+D6:IFD(I)>-.1ANDD(I)<0THEND(I)=-.1:GOTO2880 -2800 IFD(I)<0THEN2880 -2810 IFD1<>1THEND1=1:PRINT"DAMAGE CONTROL REPORT: "; -2840 PRINTTAB(8);:R1=I:GOSUB8790:PRINTG2$;" REPAIR COMPLETED." -2880 NEXTI:IFRND(1)>.2THEN3070 -2910 R1=FNR(1):IFRND(1)>=.6THEN3000 +2590 FOR I=1 TO K3:IF K(I,3)=0 THEN 2700 +2610 A$=" ":Z1=K(I,1):Z2=K(I,2):GOSUB 8670:GOSUB 8590 +2660 K(I,1)=Z1:K(I,2)=Z2:A$="+K+":GOSUB 8670 +2700 NEXT I:GOSUB 6000:D1=0:D6=W1:IF W1>=1 THEN D6=1 +2770 FOR I=1 TO 8:IF D(I)>=0 THEN 2880 +2790 D(I)=D(I)+D6:IF D(I)>-.1 AND D(I)<0 THEN D(I)=-.1:GOTO 2880 +2800 IF D(I)<0 THEN 2880 +2810 IF D1<>1 THEN D1=1:PRINT"DAMAGE CONTROL REPORT: "; +2840 PRINTTAB(8);:R1=I:GOSUB 8790:PRINT G2$;" REPAIR COMPLETED." +2880 NEXT I:IF RND(1)>.2 THEN 3070 +2910 R1=FNR(1):IF RND(1)>=.6 THEN 3000 2930 D(R1)=D(R1)-(RND(1)*5+1):PRINT"DAMAGE CONTROL REPORT: "; -2960 GOSUB8790:PRINTG2$;" DAMAGED":PRINT:GOTO3070 +2960 GOSUB 8790:PRINTG2$;" DAMAGED":PRINT:GOTO 3070 3000 D(R1)=D(R1)+RND(1)*3+1:PRINT"DAMAGE CONTROL REPORT: "; -3030 GOSUB8790:PRINTG2$;" STATE OF REPAIR IMPROVED":PRINT +3030 GOSUB 8790:PRINTG2$;" STATE OF REPAIR IMPROVED":PRINT 3060 REM BEGIN MOVING STARSHIP -3070 A$=" ":Z1=INT(S1):Z2=INT(S2):GOSUB8670 +3070 A$=" ":Z1=INT(S1):Z2=INT(S2):GOSUB 8670 3110 X1=C(C1,1)+(C(C1+1,1)-C(C1,1))*(C1-INT(C1)):X=S1:Y=S2 3140 X2=C(C1,2)+(C(C1+1,2)-C(C1,2))*(C1-INT(C1)):Q4=Q1:Q5=Q2 -3170 FORI=1TON:S1=S1+X1:S2=S2+X2:IFS1<1ORS1>=9ORS2<1ORS2>=9THEN3500 -3240 S8=INT(S1)*24+INT(S2)*3-26:IFMID$(Q$,S8,2)=" "THEN3360 +3170 FOR I=1 TO N:S1=S1+X1:S2=S2+X2:IF S1<1ORS1>=9 OR S2<1 OR S2>=9 THEN 3500 +3240 S8=INT(S1)*24+INT(S2)*3-26:IF MID$(Q$,S8,2)=" " THEN 3360 3320 S1=INT(S1-X1):S2=INT(S2-X2):PRINT"WARP ENGINES SHUT DOWN AT "; -3350 PRINT"SECTOR";S1;",";S2;"DUE TO BAD NAVAGATION":GOTO3370 -3360 NEXTI:S1=INT(S1):S2=INT(S2) -3370 A$="<*>":Z1=INT(S1):Z2=INT(S2):GOSUB8670:GOSUB3910:T8=1 -3430 IFW1<1THENT8=.1*INT(10*W1) -3450 T=T+T8:IFT>T0+T9THEN6220 +3350 PRINT"SECTOR";S1;",";S2;"DUE TO BAD NAVAGATION":GOTO 3370 +3360 NEXT I:S1=INT(S1):S2=INT(S2) +3370 A$="<*>":Z1=INT(S1):Z2=INT(S2):GOSUB 8670:GOSUB 3910:T8=1 +3430 IF W1<1 THEN T8=.1*INT(10*W1) +3450 T=T+T8:IF T>T0+T9 THEN 6220 3470 REM SEE IF DOCKED, THEN GET COMMAND -3480 GOTO1980 +3480 GOTO 1980 3490 REM EXCEEDED QUADRANT LIMITS 3500 X=8*Q1+X+N*X1:Y=8*Q2+Y+N*X2:Q1=INT(X/8):Q2=INT(Y/8):S1=INT(X-Q1*8) -3550 S2=INT(Y-Q2*8):IFS1=0THENQ1=Q1-1:S1=8 -3590 IFS2=0THENQ2=Q2-1:S2=8 -3620 X5=0:IFQ1<1THENX5=1:Q1=1:S1=1 -3670 IFQ1>8THENX5=1:Q1=8:S1=8 -3710 IFQ2<1THENX5=1:Q2=1:S2=1 -3750 IFQ2>8THENX5=1:Q2=8:S2=8 -3790 IFX5=0THEN3860 +3550 S2=INT(Y-Q2*8):IF S1=0 THEN Q1=Q1-1:S1=8 +3590 IF S2=0 THEN Q2=Q2-1:S2=8 +3620 X5=0:IF Q1<1 THEN X5=1:Q1=1:S1=1 +3670 IF Q1>8 THEN X5=1:Q1=8:S1=8 +3710 IF Q2<1 THEN X5=1:Q2=1:S2=1 +3750 IF Q2>8 THEN X5=1:Q2=8:S2=8 +3790 IF X5=0 THEN 3860 3800 PRINT"LT. UHURA REPORTS MESSAGE FROM STARFLEET COMMAND:" 3810 PRINT" 'PERMISSION TO ATTEMPT CROSSING OF GALACTIC PERIMETER" 3820 PRINT" IS HEREBY *DENIED*. SHUT DOWN YOUR ENGINES.'" 3830 PRINT"CHIEF ENGINEER SCOTT REPORTS 'WARP ENGINES SHUT DOWN" 3840 PRINT" AT SECTOR";S1;",";S2;"OF QUADRANT";Q1;",";Q2;".'" -3850 IFT>T0+T9THEN6220 -3860 IF8*Q1+Q2=8*Q4+Q5THEN3370 -3870 T=T+1:GOSUB3910:GOTO1320 +3850 IF T>T0+T9 THEN 6220 +3860 IF 8*Q1+Q2=8*Q4+Q5 THEN 3370 +3870 T=T+1:GOSUB 3910:GOTO 1320 3900 REM MANEUVER ENERGY S/R ** -3910 E=E-N-10:IFE>=0THENRETURN +3910 E=E-N-10:IF E>=0THEN RETURN 3930 PRINT"SHIELD CONTROL SUPPLIES ENERGY TO COMPLETE THE MANEUVER." -3940 S=S+E:E=0:IFS<=0THENS=0 +3940 S=S+E:E=0:IF S<=0 THEN S=0 3980 RETURN 3990 REM LONG RANGE SENSOR SCAN CODE -4000 IFD(3)<0THENPRINT"LONG RANGE SENSORS ARE INOPERABLE":GOTO1990 +4000 IF D(3)<0 THEN PRINT"LONG RANGE SENSORS ARE INOPERABLE":GOTO 1990 4030 PRINT"LONG RANGE SCAN FOR QUADRANT";Q1;",";Q2 -4040 O1$="-------------------":PRINTO1$ -4060 FORI=Q1-1TOQ1+1:N(1)=-1:N(2)=-2:N(3)=-3:FORJ=Q2-1TOQ2+1 -4120 IFI>0ANDI<9ANDJ>0ANDJ<9THENN(J-Q2+2)=G(I,J):Z(I,J)=G(I,J) -4180 NEXTJ:FORL=1TO3:PRINT": ";:IFN(L)<0THENPRINT"*** ";:GOTO4230 +4040 O1$="-------------------":PRINT O1$ +4060 FOR I=Q1-1TOQ1+1:N(1)=-1:N(2)=-2:N(3)=-3:FOR J=Q2-1TOQ2+1 +4120 IF I>0ANDI<9ANDJ>0ANDJ<9 THEN N(J-Q2+2)=G(I,J):Z(I,J)=G(I,J) +4180 NEXT J:FOR L=1TO3:PRINT": ";:IF N(L)<0 THEN PRINT"*** ";:GOTO 4230 4210 PRINTRIGHT$(STR$(N(L)+1000),3);" "; -4230 NEXTL:PRINT":":PRINTO1$:NEXTI:GOTO1990 +4230 NEXT L:PRINT":":PRINTO1$:NEXT I:GOTO 1990 4250 REM PHASER CONTROL CODE BEGINS HERE -4260 IFD(4)<0THENPRINT"PHASERS INOPERATIVE":GOTO1990 -4265 IFK3>0THEN4330 +4260 IF D(4)<0 THEN PRINT"PHASERS INOPERATIVE":GOTO 1990 +4265 IF K3>0 THEN 4330 4270 PRINT"SCIENCE OFFICER SPOCK REPORTS 'SENSORS SHOW NO ENEMY SHIPS" -4280 PRINT" IN THIS QUADRANT'":GOTO1990 -4330 IFD(8)<0THENPRINT"COMPUTER FAILURE HAMPERS ACCURACY" +4280 PRINT" IN THIS QUADRANT'":GOTO 1990 +4330 IF D(8)<0 THEN PRINT"COMPUTER FAILURE HAMPERS ACCURACY" 4350 PRINT"PHASERS LOCKED ON TARGET; "; 4360 PRINT"ENERGY AVAILABLE =";E;"UNITS" -4370 INPUT"NUMBER OF UNITS TO FIRE";X:IFX<=0THEN1990 -4400 IFE-X<0THEN4360 -4410 E=E-X:IFD(7)<0THENX=X*RND(1) -4450 H1=INT(X/K3):FORI=1TO3:IFK(I,3)<=0THEN4670 -4480 H=INT((H1/FND(0))*(RND(1)+2)):IFH>.15*K(I,3)THEN4530 -4500 PRINT"SENSORS SHOW NO DAMAGE TO ENEMY AT ";K(I,1);",";K(I,2):GOTO4670 +4370 INPUT"NUMBER OF UNITS TO FIRE";X:IF X<=0 THEN 1990 +4400 IF E-X<0 THEN 4360 +4410 E=E-X:IF D(7)<0 THEN X=X*RND(1) +4450 H1=INT(X/K3):FOR I=1TO3:IF K(I,3)<=0 THEN 4670 +4480 H=INT((H1/FND(0))*(RND(1)+2)):IF H>.15*K(I,3) THEN 4530 +4500 PRINT"SENSORS SHOW NO DAMAGE TO ENEMY AT ";K(I,1);",";K(I,2):GOTO 4670 4530 K(I,3)=K(I,3)-H:PRINTH;"UNIT HIT ON KLINGON AT SECTOR";K(I,1);","; -4550 PRINTK(I,2):IFK(I,3)<=0THENPRINT"*** KLINGON DESTROYED ***":GOTO4580 -4560 PRINT" (SENSORS SHOW";K(I,3);"UNITS REMAINING)":GOTO4670 -4580 K3=K3-1:K9=K9-1:Z1=K(I,1):Z2=K(I,2):A$=" ":GOSUB8670 -4650 K(I,3)=0:G(Q1,Q2)=G(Q1,Q2)-100:Z(Q1,Q2)=G(Q1,Q2):IFK9<=0THEN6370 -4670 NEXTI:GOSUB6000:GOTO1990 +4550 PRINTK(I,2):IF K(I,3)<=0 THEN PRINT"*** KLINGON DESTROYED ***":GOTO 4580 +4560 PRINT" (SENSORS SHOW";K(I,3);"UNITS REMAINING)":GOTO 4670 +4580 K3=K3-1:K9=K9-1:Z1=K(I,1):Z2=K(I,2):A$=" ":GOSUB 8670 +4650 K(I,3)=0:G(Q1,Q2)=G(Q1,Q2)-100:Z(Q1,Q2)=G(Q1,Q2):IF K9<=0 THEN 6370 +4670 NEXT I:GOSUB 6000:GOTO 1990 4690 REM PHOTON TORPEDO CODE BEGINS HERE -4700 IFP<=0THENPRINT"ALL PHOTON TORPEDOES EXPENDED":GOTO 1990 -4730 IFD(5)<0THENPRINT"PHOTON TUBES ARE NOT OPERATIONAL":GOTO1990 -4760 INPUT"PHOTON TORPEDO COURSE (1-9)";C1:IFC1=9THENC1=1 -4780 IFC1>=1ANDC1<9THEN4850 +4700 IF P<=0 THEN PRINT"ALL PHOTON TORPEDOES EXPENDED":GOTO 1990 +4730 IF D(5)<0 THEN PRINT"PHOTON TUBES ARE NOT OPERATIONAL":GOTO 1990 +4760 INPUT"PHOTON TORPEDO COURSE (1-9)";C1:IF C1=9 THEN C1=1 +4780 IF C1>=1ANDC1<9 THEN 4850 4790 PRINT"ENSIGN CHEKOV REPORTS, 'INCORRECT COURSE DATA, SIR!'" -4800 GOTO1990 +4800 GOTO 1990 4850 X1=C(C1,1)+(C(C1+1,1)-C(C1,1))*(C1-INT(C1)):E=E-2:P=P-1 4860 X2=C(C1,2)+(C(C1+1,2)-C(C1,2))*(C1-INT(C1)):X=S1:Y=S2 4910 PRINT"TORPEDO TRACK:" 4920 X=X+X1:Y=Y+X2:X3=INT(X+.5):Y3=INT(Y+.5) -4960 IFX3<1ORX3>8ORY3<1ORY3>8THEN5490 -5000 PRINT" ";X3;",";Y3:A$=" ":Z1=X:Z2=Y:GOSUB8830 -5050 IFZ3<>0THEN4920 -5060 A$="+K+":Z1=X:Z2=Y:GOSUB8830:IFZ3=0THEN5210 -5110 PRINT"*** KLINGON DESTROYED ***":K3=K3-1:K9=K9-1:IFK9<=0THEN6370 -5150 FORI=1TO3:IFX3=K(I,1)ANDY3=K(I,2)THEN5190 -5180 NEXTI:I=3 -5190 K(I,3)=0:GOTO5430 -5210 A$=" * ":Z1=X:Z2=Y:GOSUB8830:IFZ3=0THEN5280 -5260 PRINT"STAR AT";X3;",";Y3;"ABSORBED TORPEDO ENERGY.":GOSUB6000:GOTO1990 -5280 A$=">!<":Z1=X:Z2=Y:GOSUB8830:IFZ3=0THEN4760 +4960 IF X3<1ORX3>8ORY3<1ORY3>8 THEN 5490 +5000 PRINT" ";X3;",";Y3:A$=" ":Z1=X:Z2=Y:GOSUB 8830 +5050 IF Z3<>0 THEN 4920 +5060 A$="+K+":Z1=X:Z2=Y:GOSUB 8830:IF Z3=0 THEN 5210 +5110 PRINT"*** KLINGON DESTROYED ***":K3=K3-1:K9=K9-1:IF K9<=0 THEN 6370 +5150 FOR I=1TO3:IF X3=K(I,1)ANDY3=K(I,2) THEN 5190 +5180 NEXT I:I=3 +5190 K(I,3)=0:GOTO 5430 +5210 A$=" * ":Z1=X:Z2=Y:GOSUB 8830:IF Z3=0 THEN 5280 +5260 PRINT"STAR AT";X3;",";Y3;"ABSORBED TORPEDO ENERGY.":GOSUB 6000:GOTO 1990 +5280 A$=">!<":Z1=X:Z2=Y:GOSUB 8830:IF Z3=0 THEN 4760 5330 PRINT"*** STARBASE DESTROYED ***":B3=B3-1:B9=B9-1 -5360 IFB9>0ORK9>T-T0-T9THEN5400 +5360 IF B9>0ORK9>T-T0-T9 THEN 5400 5370 PRINT"THAT DOES IT, CAPTAIN!! YOU ARE HEREBY RELIEVED OF COMMAND" 5380 PRINT"AND SENTENCED TO 99 STARDATES AT HARD LABOR ON CYGNUS 12!!" 5390 GOTO 6270 5400 PRINT"STARFLEET COMMAND REVIEWING YOUR RECORD TO CONSIDER" 5410 PRINT"COURT MARTIAL!":D0=0 -5430 Z1=X:Z2=Y:A$=" ":GOSUB8670 -5470 G(Q1,Q2)=K3*100+B3*10+S3:Z(Q1,Q2)=G(Q1,Q2):GOSUB6000:GOTO1990 -5490 PRINT"TORPEDO MISSED":GOSUB6000:GOTO1990 +5430 Z1=X:Z2=Y:A$=" ":GOSUB 8670 +5470 G(Q1,Q2)=K3*100+B3*10+S3:Z(Q1,Q2)=G(Q1,Q2):GOSUB 6000:GOTO 1990 +5490 PRINT"TORPEDO MISSED":GOSUB 6000:GOTO 1990 5520 REM SHIELD CONTROL -5530 IFD(7)<0THENPRINT"SHIELD CONTROL INOPERABLE":GOTO1990 +5530 IF D(7)<0 THEN PRINT"SHIELD CONTROL INOPERABLE":GOTO 1990 5560 PRINT"ENERGY AVAILABLE =";E+S;:INPUT"NUMBER OF UNITS TO SHIELDS";X -5580 IFX<0ORS=XTHENPRINT"":GOTO1990 -5590 IFX<=E+STHEN5630 +5580 IF X<0ORS=X THEN PRINT"":GOTO 1990 +5590 IF X<=E+S THEN 5630 5600 PRINT"SHIELD CONTROL REPORTS 'THIS IS NOT THE FEDERATION TREASURY.'" -5610 PRINT"":GOTO1990 +5610 PRINT"":GOTO 1990 5630 E=E+S-X:S=X:PRINT"DEFLECTOR CONTROL ROOM REPORT:" -5660 PRINT" 'SHIELDS NOW AT";INT(S);"UNITS PER YOUR COMMAND.'":GOTO1990 +5660 PRINT" 'SHIELDS NOW AT";INT(S);"UNITS PER YOUR COMMAND.'":GOTO 1990 5680 REM DAMAGE CONTROL -5690 IFD(6)>=0THEN5910 -5700 PRINT"DAMAGE CONTROL REPORT NOT AVAILABLE":IFD0=0THEN1990 -5720 D3=0:FORI=1TO8:IFD(I)<0THEND3=D3+.1 -5760 NEXTI:IFD3=0THEN1990 -5780 PRINT:D3=D3+D4:IFD3>=1THEND3=.9 +5690 IF D(6)>=0 THEN 5910 +5700 PRINT"DAMAGE CONTROL REPORT NOT AVAILABLE":IF D0=0 THEN 1990 +5720 D3=0:FOR I=1TO8:IF D(I)<0 THEN D3=D3+.1 +5760 NEXT I:IF D3=0 THEN 1990 +5780 PRINT:D3=D3+D4:IF D3>=1 THEN D3=.9 5810 PRINT"TECHNICIANS STANDING BY TO EFFECT REPAIRS TO YOUR SHIP;" 5820 PRINT"ESTIMATED TIME TO REPAIR:";.01*INT(100*D3);"STARDATES" 5840 INPUT "WILL YOU AUTHORIZE THE REPAIR ORDER (Y/N)";A$ -5860 IFA$<>"Y"THEN 1990 -5870 FORI=1TO8:IFD(I)<0THEND(I)=0 -5890 NEXTI:T=T+D3+.1 -5910 PRINT:PRINT"DEVICE STATE OF REPAIR":FORR1=1TO8 -5920 GOSUB8790:PRINTG2$;LEFT$(Z$,25-LEN(G2$));INT(D(R1)*100)*.01 -5950 NEXTR1:PRINT:IFD0<>0THEN5720 +5860 IF A$<>"Y"THEN 1990 +5870 FOR I=1TO8:IF D(I)<0 THEN D(I)=0 +5890 NEXT I:T=T+D3+.1 +5910 PRINT:PRINT"DEVICE STATE OF REPAIR":FOR R1=1TO8 +5920 GOSUB 8790:PRINTG2$;LEFT$(Z$,25-LEN(G2$));INT(D(R1)*100)*.01 +5950 NEXT R1:PRINT:IF D0<>0 THEN 5720 5980 GOTO 1990 5990 REM KLINGONS SHOOTING -6000 IFK3<=0THENRETURN -6010 IFD0<>0THENPRINT"STARBASE SHIELDS PROTECT THE ENTERPRISE":RETURN -6040 FORI=1TO3:IFK(I,3)<=0THEN6200 +6000 IF K3<=0THEN RETURN +6010 IF D0<>0 THEN PRINT"STARBASE SHIELDS PROTECT THE ENTERPRISE":RETURN +6040 FOR I=1TO3:IF K(I,3)<=0 THEN 6200 6060 H=INT((K(I,3)/FND(1))*(2+RND(1))):S=S-H:K(I,3)=K(I,3)/(3+RND(0)) 6080 PRINTH;"UNIT HIT ON ENTERPRISE FROM SECTOR";K(I,1);",";K(I,2) -6090 IFS<=0THEN6240 -6100 PRINT" ":IFH<20THEN6200 -6120 IFRND(1)>.6ORH/S<=.02THEN6200 -6140 R1=FNR(1):D(R1)=D(R1)-H/S-.5*RND(1):GOSUB8790 +6090 IF S<=0 THEN 6240 +6100 PRINT" ":IF H<20 THEN 6200 +6120 IF RND(1)>.6ORH/S<=.02 THEN 6200 +6140 R1=FNR(1):D(R1)=D(R1)-H/S-.5*RND(1):GOSUB 8790 6170 PRINT"DAMAGE CONTROL REPORTS ";G2$;" DAMAGED BY THE HIT'" -6200 NEXTI:RETURN +6200 NEXT I:RETURN 6210 REM END OF GAME 6220 PRINT"IT IS STARDATE";T:GOTO 6270 6240 PRINT:PRINT"THE ENTERPRISE HAS BEEN DESTROYED. THEN FEDERATION "; 6250 PRINT"WILL BE CONQUERED":GOTO 6220 6270 PRINT"THERE WERE";K9;"KLINGON BATTLE CRUISERS LEFT AT" 6280 PRINT"THE END OF YOUR MISSION." -6290 PRINT:PRINT:IFB9=0THEN6360 +6290 PRINT:PRINT:IF B9=0 THEN 6360 6310 PRINT"THE FEDERATION IS IN NEED OF A NEW STARSHIP COMMANDER" 6320 PRINT"FOR A SIMILAR MISSION -- IF THERE IS A VOLUNTEER," -6330 INPUT"LET HIM STEP FORWARD AND ENTER 'AYE'";A$:IFA$="AYE"THEN10 +6330 INPUT"LET HIM STEP FORWARD AND ENTER 'AYE'";A$:IF A$="AYE" THEN 10 6360 END 6370 PRINT"CONGRULATION, CAPTAIN! THEN LAST KLINGON BATTLE CRUISER" 6380 PRINT"MENACING THE FDERATION HAS BEEN DESTROYED.":PRINT -6400 PRINT"YOUR EFFICIENCY RATING IS";1000*(K7/(T-T0))^2:GOTO6290 +6400 PRINT"YOUR EFFICIENCY RATING IS";1000*(K7/(T-T0))^2:GOTO 6290 6420 REM SHORT RANGE SENSOR SCAN & STARTUP SUBROUTINE -6430 FORI=S1-1TOS1+1:FORJ=S2-1TOS2+1 -6450 IFINT(I+.5)<1ORINT(I+.5)>8ORINT(J+.5)<1ORINT(J+.5)>8THEN6540 -6490 A$=">!<":Z1=I:Z2=J:GOSUB8830:IFZ3=1THEN6580 -6540 NEXTJ:NEXTI:D0=0:GOTO6650 +6430 FOR I=S1-1TOS1+1:FOR J=S2-1 TO S2+1 +6450 IF INT(I+.5)<1ORINT(I+.5)>8ORINT(J+.5)<1ORINT(J+.5)>8 THEN 6540 +6490 A$=">!<":Z1=I:Z2=J:GOSUB 8830:IF Z3=1 THEN 6580 +6540 NEXT J:NEXT I:D0=0:GOTO 6650 6580 D0=1:C$="DOCKED":E=E0:P=P0 -6620 PRINT"SHIELDS DROPPED FOR DOCKING PURPOSES":S=0:GOTO6720 -6650 IFK3>0THENC$="*RED*":GOTO6720 -6660 C$="GREEN":IFE=0THEN6770 +6620 PRINT"SHIELDS DROPPED FOR DOCKING PURPOSES":S=0:GOTO 6720 +6650 IF K3>0 THEN C$="*RED*":GOTO 6720 +6660 C$="GREEN":IF E=0 THEN 6770 6730 PRINT:PRINT"*** SHORT RANGE SENSORS ARE OUT ***":PRINT:RETURN -6770 O1$="---------------------------------":PRINTO1$:FORI=1TO8 -6820 FORJ=(I-1)*24+1TO(I-1)*24+22STEP3:PRINT" ";MID$(Q$,J,3);:NEXTJ -6830 ONIGOTO6850,6900,6960,7020,7070,7120,7180,7240 -6850 PRINT" STARDATE ";INT(T*10)*.1:GOTO7260 -6900 PRINT" CONDITION ";C$:GOTO7260 -6960 PRINT" QUADRANT ";Q1;",";Q2:GOTO7260 -7020 PRINT" SECTOR ";S1;",";S2:GOTO7260 -7070 PRINT" PHOTON TORPEDOES ";INT(P):GOTO7260 -7120 PRINT" TOTAL ENERGY ";INT(E+S):GOTO7260 -7180 PRINT" SHIELDS ";INT(S):GOTO7260 +6770 O1$="---------------------------------":PRINTO1$:FOR I=1 TO 8 +6820 FOR J=(I-1)*24+1 TO (I-1)*24+22STEP3:PRINT" ";MID$(Q$,J,3);:NEXT J +6830 ONIGOTO 6850,6900,6960,7020,7070,7120,7180,7240 +6850 PRINT" STARDATE ";INT(T*10)*.1:GOTO 7260 +6900 PRINT" CONDITION ";C$:GOTO 7260 +6960 PRINT" QUADRANT ";Q1;",";Q2:GOTO 7260 +7020 PRINT" SECTOR ";S1;",";S2:GOTO 7260 +7070 PRINT" PHOTON TORPEDOES ";INT(P):GOTO 7260 +7120 PRINT" TOTAL ENERGY ";INT(E+S):GOTO 7260 +7180 PRINT" SHIELDS ";INT(S):GOTO 7260 7240 PRINT" KLINGONS REMAINING";INT(K9) -7260 NEXTI:PRINTO1$:RETURN +7260 NEXT I:PRINT O1$:RETURN 7280 REM LIBRARY COMPUTER CODE -7290 IFD(8)<0THENPRINT"COMPUTER DISABLED":GOTO1990 -7320 INPUT"COMPUTER ACTIVE AND AWAITING COMMAND";A:IFA<0THEN1990 -7350 PRINT:H8=1:ONA+1GOTO7540,7900,8070,8500,8150,7400 +7290 IF D(8)<0 THEN PRINT"COMPUTER DISABLED":GOTO 1990 +7320 INPUT"COMPUTER ACTIVE AND AWAITING COMMAND";A:IF A<0 THEN 1990 +7350 PRINT:H8=1:ONA+1GOTO 7540,7900,8070,8500,8150,7400 7360 PRINT"FUNCTIONS AVAILABLE FROM LIBRARY-COMPUTER:" 7370 PRINT" 0 = CUMULATIVE GALACTIC RECORD" 7372 PRINT" 1 = STATUS REPORT" 7374 PRINT" 2 = PHOTON TORPEDO DATA" 7376 PRINT" 3 = STARBASE NAV DATA" 7378 PRINT" 4 = DIRECTION/DISTANCE CALCULATOR" -7380 PRINT" 5 = GALAXY 'REGION NAME' MAP":PRINT:GOTO7320 +7380 PRINT" 5 = GALAXY 'REGION NAME' MAP":PRINT:GOTO 7320 7390 REM SETUP TO CHANGE CUM GAL RECORD TO GALAXY MAP -7400 H8=0:G5=1:PRINT" THE GALAXY":GOTO7550 +7400 H8=0:G5=1:PRINT" THE GALAXY":GOTO 7550 7530 REM CUM GALACTIC RECORD 7540 REM INPUT"DO YOU WANT A HARDCOPY? IS THE TTY ON (Y/N)";A$ -7542 REM IFA$="Y"THENPOKE1229,2:POKE1237,3:NULL1 +7542 REM IF A$="Y" THEN POKE1229,2:POKE1237,3:NULL1 7543 PRINT:PRINT" "; 7544 PRINT"COMPUTER RECORD OF GALAXY FOR QUADRANT";Q1;",";Q2 7546 PRINT 7550 PRINT" 1 2 3 4 5 6 7 8" 7560 O1$=" ----- ----- ----- ----- ----- ----- ----- -----" -7570 PRINTO1$:FORI=1TO8:PRINTI;:IFH8=0THEN7740 -7630 FORJ=1TO8:PRINT" ";:IFZ(I,J)=0THENPRINT"***";:GOTO7720 +7570 PRINT O1$:FOR I=1 TO 8:PRINTI;:IF H8=0 THEN 7740 +7630 FOR J=1 TO 8:PRINT" ";:IF Z(I,J)=0 THEN PRINT"***";:GOTO 7720 7700 PRINTRIGHT$(STR$(Z(I,J)+1000),3); -7720 NEXTJ:GOTO7850 -7740 Z4=I:Z5=1:GOSUB9030:J0=INT(15-.5*LEN(G2$)):PRINTTAB(J0);G2$; +7720 NEXT J:GOTO 7850 +7740 Z4=I:Z5=1:GOSUB 9030:J0=INT(15-.5*LEN(G2$)):PRINTTAB(J0);G2$; 7800 Z5=5:GOSUB 9030:J0=INT(39-.5*LEN(G2$)):PRINTTAB(J0);G2$; -7850 PRINT:PRINTO1$:NEXTI:PRINT:GOTO1990 +7850 PRINT:PRINT O1$:NEXT I:PRINT:GOTO 1990 7890 REM STATUS REPORT -7900 PRINT " STATUS REPORT:":X$="":IFK9>1THENX$="S" +7900 PRINT " STATUS REPORT:":X$="":IF K9>1 THEN X$="S" 7940 PRINT"KLINGON";X$;" LEFT: ";K9 7960 PRINT"MISSION MUST BE COMPLETED IN";.1*INT((T0+T9-T)*10);"STARDATES" -7970 X$="S":IFB9<2THENX$="":IFB9<1THEN8010 +7970 X$="S":IF B9<2 THEN X$="":IF B9<1 THEN 8010 7980 PRINT"THE FEDERATION IS MAINTAINING";B9;"STARBASE";X$;" IN THE GALAXY" -7990 GOTO5690 +7990 GOTO 5690 8010 PRINT"YOUR STUPIDITY HAS LEFT YOU ON YOUR ON IN" -8020 PRINT" THE GALAXY -- YOU HAVE NO STARBASES LEFT!":GOTO5690 +8020 PRINT" THE GALAXY -- YOU HAVE NO STARBASES LEFT!":GOTO 5690 8060 REM TORPEDO, BASE NAV, D/D CALCULATOR -8070 IFK3<=0THEN4270 -8080 X$="":IFK3>1THENX$="S" +8070 IF K3<=0 THEN 4270 +8080 X$="":IF K3>1 THEN X$="S" 8090 PRINT"FROM ENTERPRISE TO KLINGON BATTLE CRUSER";X$ -8100 H8=0:FORI=1TO3:IFK(I,3)<=0THEN8480 +8100 H8=0:FOR I=1 TO 3:IF K(I,3)<=0 THEN 8480 8110 W1=K(I,1):X=K(I,2) -8120 C1=S1:A=S2:GOTO8220 +8120 C1=S1:A=S2:GOTO 8220 8150 PRINT"DIRECTION/DISTANCE CALCULATOR:" 8160 PRINT"YOU ARE AT QUADRANT ";Q1;",";Q2;" SECTOR ";S1;",";S2 8170 PRINT"PLEASE ENTER":INPUT" INITIAL COORDINATES (X,Y)";C1,A 8200 INPUT" FINAL COORDINATES (X,Y)";W1,X -8220 X=X-A:A=C1-W1:IFX<0THEN8350 -8250 IFA<0THEN8410 -8260 IFX>0THEN8280 -8270 IFA=0THENC1=5:GOTO8290 +8220 X=X-A:A=C1-W1:IF X<0 THEN 8350 +8250 IF A<0 THEN 8410 +8260 IF X>0 THEN 8280 +8270 IF A=0 THEN C1=5:GOTO 8290 8280 C1=1 -8290 IFABS(A)<=ABS(X)THEN8330 -8310 PRINT"DIRECTION =";C1+(((ABS(A)-ABS(X))+ABS(A))/ABS(A)):GOTO8460 -8330 PRINT"DIRECTION =";C1+(ABS(A)/ABS(X)):GOTO8460 -8350 IFA>0THENC1=3:GOTO8420 -8360 IFX<>0THENC1=5:GOTO8290 +8290 IF ABS(A)<=ABS(X) THEN 8330 +8310 PRINT"DIRECTION =";C1+(((ABS(A)-ABS(X))+ABS(A))/ABS(A)):GOTO 8460 +8330 PRINT"DIRECTION =";C1+(ABS(A)/ABS(X)):GOTO 8460 +8350 IF A>0 THEN C1=3:GOTO 8420 +8360 IF X<>0 THEN C1=5:GOTO 8290 8410 C1=7 -8420 IFABS(A)>=ABS(X)THEN8450 -8430 PRINT"DIRECTION =";C1+(((ABS(X)-ABS(A))+ABS(X))/ABS(X)):GOTO8460 +8420 IF ABS(A)>=ABS(X) THEN 8450 +8430 PRINT"DIRECTION =";C1+(((ABS(X)-ABS(A))+ABS(X))/ABS(X)):GOTO 8460 8450 PRINT"DIRECTION =";C1+(ABS(X)/ABS(A)) -8460 PRINT"DISTANCE =";SQR(X^2+A^2):IFH8=1THEN1990 -8480 NEXTI:GOTO1990 -8500 IFB3<>0THENPRINT"FROM ENTERPRISE TO STARBASE:":W1=B4:X=B5:GOTO8120 +8460 PRINT"DISTANCE =";SQR(X^2+A^2):IF H8=1 THEN 1990 +8480 NEXT I:GOTO 1990 +8500 IF B3<>0 THEN PRINT"FROM ENTERPRISE TO STARBASE:":W1=B4:X=B5:GOTO 8120 8510 PRINT"MR. SPOCK REPORTS, 'SENSORS SHOW NO STARBASES IN THIS"; -8520 PRINT" QUADRANT.'":GOTO1990 +8520 PRINT" QUADRANT.'":GOTO 1990 8580 REM FIND EMPTY PLACE IN QUADRANT (FOR THINGS) -8590 R1=FNR(1):R2=FNR(1):A$=" ":Z1=R1:Z2=R2:GOSUB8830:IFZ3=0THEN8590 +8590 R1=FNR(1):R2=FNR(1):A$=" ":Z1=R1:Z2=R2:GOSUB 8830:IF Z3=0 THEN 8590 8600 RETURN 8660 REM INSERT IN STRING ARRAY FOR QUADRANT 8670 S8=INT(Z2-.5)*3+INT(Z1-.5)*24+1 8675 IF LEN(A$)<>3THEN PRINT"ERROR":STOP -8680 IFS8=1THENQ$=A$+RIGHT$(Q$,189):RETURN -8690 IFS8=190THENQ$=LEFT$(Q$,189)+A$:RETURN +8680 IF S8=1 THEN Q$=A$+RIGHT$(Q$,189):RETURN +8690 IF S8=190 THEN Q$=LEFT$(Q$,189)+A$:RETURN 8700 Q$=LEFT$(Q$,S8-1)+A$+RIGHT$(Q$,190-S8):RETURN 8780 REM PRINTS DEVICE NAME -8790 ONR1GOTO8792,8794,8796,8798,8800,8802,8804,8806 +8790 ON R1 GOTO 8792,8794,8796,8798,8800,8802,8804,8806 8792 G2$="WARP ENGINES":RETURN 8794 G2$="SHORT RANGE SENSORS":RETURN 8796 G2$="LONG RANGE SENSORS":RETURN @@ -394,30 +394,30 @@ 8806 G2$="LIBRARY-COMPUTER":RETURN 8820 REM STRING COMPARISON IN QUADRANT ARRAY 8830 Z1=INT(Z1+.5):Z2=INT(Z2+.5):S8=(Z2-1)*3+(Z1-1)*24+1:Z3=0 -8890 IFMID$(Q$,S8,3)<>A$THENRETURN +8890 IF MID$(Q$,S8,3)<>A$ THEN RETURN 8900 Z3=1:RETURN 9010 REM QUADRANT NAME IN G2$ FROM Z4,Z5 (=Q1,Q2) 9020 REM CALL WITH G5=1 TO GET REGION NAME ONLY -9030 IFZ5<=4THENONZ4GOTO9040,9050,9060,9070,9080,9090,9100,9110 -9035 GOTO9120 -9040 G2$="ANTARES":GOTO9210 -9050 G2$="RIGEL":GOTO9210 -9060 G2$="PROCYON":GOTO9210 -9070 G2$="VEGA":GOTO9210 -9080 G2$="CANOPUS":GOTO9210 -9090 G2$="ALTAIR":GOTO9210 -9100 G2$="SAGITTARIUS":GOTO9210 -9110 G2$="POLLUX":GOTO9210 -9120 ONZ4GOTO9130,9140,9150,9160,9170,9180,9190,9200 -9130 G2$="SIRIUS":GOTO9210 -9140 G2$="DENEB":GOTO9210 -9150 G2$="CAPELLA":GOTO9210 -9160 G2$="BETELGEUSE":GOTO9210 -9170 G2$="ALDEBARAN":GOTO9210 -9180 G2$="REGULUS":GOTO9210 -9190 G2$="ARCTURUS":GOTO9210 +9030 IF Z5<=4 THEN ON Z4 GOTO 9040,9050,9060,9070,9080,9090,9100,9110 +9035 GOTO 9120 +9040 G2$="ANTARES":GOTO 9210 +9050 G2$="RIGEL":GOTO 9210 +9060 G2$="PROCYON":GOTO 9210 +9070 G2$="VEGA":GOTO 9210 +9080 G2$="CANOPUS":GOTO 9210 +9090 G2$="ALTAIR":GOTO 9210 +9100 G2$="SAGITTARIUS":GOTO 9210 +9110 G2$="POLLUX":GOTO 9210 +9120 ON Z4 GOTO 9130,9140,9150,9160,9170,9180,9190,9200 +9130 G2$="SIRIUS":GOTO 9210 +9140 G2$="DENEB":GOTO 9210 +9150 G2$="CAPELLA":GOTO 9210 +9160 G2$="BETELGEUSE":GOTO 9210 +9170 G2$="ALDEBARAN":GOTO 9210 +9180 G2$="REGULUS":GOTO 9210 +9190 G2$="ARCTURUS":GOTO 9210 9200 G2$="SPICA" -9210 IFG5<>1THENONZ5GOTO9230,9240,9250,9260,9230,9240,9250,9260 +9210 IF G5<>1 THEN ON Z5 GOTO 9230,9240,9250,9260,9230,9240,9250,9260 9220 RETURN 9230 G2$=G2$+" I":RETURN 9240 G2$=G2$+" II":RETURN From c17bfa5dd062b5960516e17b87c4d260a62fb524 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sun, 16 Jan 2022 18:48:01 +0000 Subject: [PATCH 190/337] Clean up PRINT commands --- 84_Super_Star_Trek/superstartrek.bas | 322 +++++++++++++-------------- 1 file changed, 161 insertions(+), 161 deletions(-) diff --git a/84_Super_Star_Trek/superstartrek.bas b/84_Super_Star_Trek/superstartrek.bas index 72fb4f5d..cddc6dd8 100644 --- a/84_Super_Star_Trek/superstartrek.bas +++ b/84_Super_Star_Trek/superstartrek.bas @@ -18,15 +18,15 @@ 190 REM *** LINE NUMBERS FROM VERSION STREK7 OF 1/12/75 PRESERVED AS 200 REM *** MUCH AS POSSIBLE WHILE USING MULTIPLE STATEMENTS PER LINE 205 REM *** SOME LINES ARE LONGER THAN 72 CHARACTERS; THIS WAS DONE -210 REM *** BY USING "?" INSTEAD OF "PRINT" WHEN ENTERING LINES +210 REM *** BY USING "?" INSTEAD OF "PRINT " WHEN ENTERING LINES 215 REM *** 220 PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT -221 PRINT" ,------*------," -222 PRINT" ,------------- '--- ------'" -223 PRINT" '-------- --' / /" -224 PRINT" ,---' '-------/ /--," -225 PRINT" '----------------'":PRINT -226 PRINT" THE USS ENTERPRISE --- NCC-1701" +221 PRINT " ,------*------," +222 PRINT " ,------------- '--- ------'" +223 PRINT " '-------- --' / /" +224 PRINT " ,---' '-------/ /--," +225 PRINT " '----------------'":PRINT +226 PRINT " THE USS ENTERPRISE --- NCC-1701" 227 PRINT:PRINT:PRINT:PRINT:PRINT 260 REM CLEAR 600 270 Z$=" " @@ -54,24 +54,24 @@ 1150 IF G(Q1,Q2)<200 THEN G(Q1,Q2)=G(Q1,Q2)+120:K9=K9+1 1160 B9=1:G(Q1,Q2)=G(Q1,Q2)+10:Q1=FNR(1):Q2=FNR(1) 1200 K7=K9:IF B9<>1 THEN X$="S":X0$=" ARE " -1230 PRINT"YOUR ORDERS ARE AS FOLLOWS:" -1240 PRINT" DESTROY THE";K9;"KLINGON WARSHIPS WHICH HAVE INVADED" -1252 PRINT" THE GALAXY BEFORE THEY CAN ATTACK FEDERATION HEADQUARTERS" -1260 PRINT" ON STARDATE";T0+T9;" THIS GIVES YOU";T9;"DAYS. THERE";X0$ -1272 PRINT" ";B9;"STARBASE";X$;" IN THE GALAXY FOR RESUPPLYING YOUR SHIP" -1280 PRINT:REM PRINT"HIT ANY KEY EXCEPT RETURN WHEN READY TO ACCEPT COMMAND" +1230 PRINT "YOUR ORDERS ARE AS FOLLOWS:" +1240 PRINT " DESTROY THE";K9;"KLINGON WARSHIPS WHICH HAVE INVADED" +1252 PRINT " THE GALAXY BEFORE THEY CAN ATTACK FEDERATION HEADQUARTERS" +1260 PRINT " ON STARDATE";T0+T9;" THIS GIVES YOU";T9;"DAYS. THERE";X0$ +1272 PRINT " ";B9;"STARBASE";X$;" IN THE GALAXY FOR RESUPPLYING YOUR SHIP" +1280 PRINT:REM PRINT "HIT ANY KEY EXCEPT RETURN WHEN READY TO ACCEPT COMMAND" 1300 I=RND(1):REM IF INP(1)=13 THEN 1300 1310 REM HERE ANY TIME NEW QUADRANT ENTERED 1320 Z4=Q1:Z5=Q2:K3=0:B3=0:S3=0:G5=0:D4=.5*RND(1):Z(Q1,Q2)=G(Q1,Q2) 1390 IF Q1<1 OR Q1>8 OR Q2<1 OR Q2>8 THEN 1600 1430 GOSUB 9030:PRINT:IF T0<>T THEN 1490 -1460 PRINT"YOUR MISSION BEGINS WITH YOUR STARSHIP LOCATED" -1470 PRINT"IN THE GALACTIC QUADRANT, '";G2$;"'.":GOTO 1500 -1490 PRINT"NOW ENTERING ";G2$;" QUADRANT . . ." +1460 PRINT "YOUR MISSION BEGINS WITH YOUR STARSHIP LOCATED" +1470 PRINT "IN THE GALACTIC QUADRANT, '";G2$;"'.":GOTO 1500 +1490 PRINT "NOW ENTERING ";G2$;" QUADRANT . . ." 1500 PRINT:K3=INT(G(Q1,Q2)*.01):B3=INT(G(Q1,Q2)*.1)-10*K3 1540 S3=G(Q1,Q2)-100*K3-10*B3:IF K3=0 THEN 1590 -1560 PRINT"COMBAT AREA CONDITION RED":IF S>200 THEN 1590 -1580 PRINT" SHIELDS DANGEROUSLY LOW" +1560 PRINT "COMBAT AREA CONDITION RED":IF S>200 THEN 1590 +1580 PRINT " SHIELDS DANGEROUSLY LOW" 1590 FOR I=1 TO 3:K(I,1)=0:K(I,2)=0:NEXT I 1600 FOR I=1 TO 3:K(I,3)=0:NEXT I:Q$=Z$+Z$+Z$+Z$+Z$+Z$+Z$+LEFT$(Z$,17) 1660 REM POSITION ENTERPRISE IN QUADRANT, THEN PLACE "K3" KLINGONS, & @@ -84,40 +84,40 @@ 1910 FOR I=1 TO S3:GOSUB 8590:A$=" * ":Z1=R1:Z2=R2:GOSUB 8670:NEXT I 1980 GOSUB 6430 1990 IF S+E>10 THEN IF E>10 OR D(7)=0 THEN 2060 -2020 PRINT:PRINT"** FATAL ERROR ** YOU'VE JUST STRANDED YOUR SHIP IN " -2030 PRINT"SPACE":PRINT"YOU HAVE INSUFFICIENT MANEUVERING ENERGY,"; -2040 PRINT" AND SHIELD CONTROL":PRINT"IS PRESENTLY INCAPABLE OF CROSS"; -2050 PRINT"-CIRCUITING TO ENGINE ROOM!!":GOTO 6220 +2020 PRINT:PRINT "** FATAL ERROR ** YOU'VE JUST STRANDED YOUR SHIP IN " +2030 PRINT "SPACE":PRINT "YOU HAVE INSUFFICIENT MANEUVERING ENERGY,"; +2040 PRINT " AND SHIELD CONTROL":PRINT "IS PRESENTLY INCAPABLE OF CROSS"; +2050 PRINT "-CIRCUITING TO ENGINE ROOM!!":GOTO 6220 2060 INPUT"COMMAND";A$ 2080 FOR I=1 TO 9:IF LEFT$(A$,3)<>MID$(A1$,3*I-2,3) THEN 2160 2140 ONIGOTO 2300,1980,4000,4260,4700,5530,5690,7290,6270 -2160 NEXT I:PRINT"ENTER ONE OF THE FOLLOWING:" -2180 PRINT" NAV (TO SET COURSE)" -2190 PRINT" SRS (FOR SHORT RANGE SENSOR SCAN)" -2200 PRINT" LRS (FOR LONG RANGE SENSOR SCAN)" -2210 PRINT" PHA (TO FIRE PHASERS)" -2220 PRINT" TOR (TO FIRE PHOTON TORPEDOES)" -2230 PRINT" SHE (TO RAISE OR LOWER SHIELDS)" -2240 PRINT" DAM (FOR DAMAGE CONTROL REPORTS)" -2250 PRINT" COM (TO CALL ON LIBRARY-COMPUTER)" -2260 PRINT" XXX (TO RESIGN YOUR COMMAND)":PRINT:GOTO 1990 +2160 NEXT I:PRINT "ENTER ONE OF THE FOLLOWING:" +2180 PRINT " NAV (TO SET COURSE)" +2190 PRINT " SRS (FOR SHORT RANGE SENSOR SCAN)" +2200 PRINT " LRS (FOR LONG RANGE SENSOR SCAN)" +2210 PRINT " PHA (TO FIRE PHASERS)" +2220 PRINT " TOR (TO FIRE PHOTON TORPEDOES)" +2230 PRINT " SHE (TO RAISE OR LOWER SHIELDS)" +2240 PRINT " DAM (FOR DAMAGE CONTROL REPORTS)" +2250 PRINT " COM (TO CALL ON LIBRARY-COMPUTER)" +2260 PRINT " XXX (TO RESIGN YOUR COMMAND)":PRINT:GOTO 1990 2290 REM COURSE CONTROL BEGINS HERE 2300 INPUT"COURSE (0-9)";C1:IF C1=9 THEN C1=1 2310 IF C1>=1 AND C1<9 THEN 2350 -2330 PRINT" LT. SULU REPORTS, 'INCORRECT COURSE DATA, SIR!'":GOTO 1990 +2330 PRINT " LT. SULU REPORTS, 'INCORRECT COURSE DATA, SIR!'":GOTO 1990 2350 X$="8":IF D(1)<0 THEN X$="0.2" -2360 PRINT"WARP FACTOR (0-";X$;")";:INPUT W1:IF D(1)<0 AND W1>.2 THEN 2470 +2360 PRINT "WARP FACTOR (0-";X$;")";:INPUT W1:IF D(1)<0 AND W1>.2 THEN 2470 2380 IF W1>0 AND W1<=8 THEN 2490 2390 IF W1=0 THEN 1990 -2420 PRINT" CHIEF ENGINEER SCOTT REPORTS 'THE ENGINES WON'T TAKE"; -2430 PRINT" WARP ";W1;"!'":GOTO 1990 -2470 PRINT"WARP ENGINES ARE DAMAGED. MAXIUM SPEED = WARP 0.2":GOTO 1990 +2420 PRINT " CHIEF ENGINEER SCOTT REPORTS 'THE ENGINES WON'T TAKE"; +2430 PRINT " WARP ";W1;"!'":GOTO 1990 +2470 PRINT "WARP ENGINES ARE DAMAGED. MAXIUM SPEED = WARP 0.2":GOTO 1990 2490 N=INT(W1*8+.5):IF E-N>=0 THEN 2590 -2500 PRINT"ENGINEERING REPORTS 'INSUFFICIENT ENERGY AVAILABLE" -2510 PRINT" FOR MANEUVERING AT WARP";W1;"!'" +2500 PRINT "ENGINEERING REPORTS 'INSUFFICIENT ENERGY AVAILABLE" +2510 PRINT " FOR MANEUVERING AT WARP";W1;"!'" 2530 IF S=0 THEN 2880 2790 D(I)=D(I)+D6:IF D(I)>-.1 AND D(I)<0 THEN D(I)=-.1:GOTO 2880 2800 IF D(I)<0 THEN 2880 -2810 IF D1<>1 THEN D1=1:PRINT"DAMAGE CONTROL REPORT: "; -2840 PRINTTAB(8);:R1=I:GOSUB 8790:PRINT G2$;" REPAIR COMPLETED." +2810 IF D1<>1 THEN D1=1:PRINT "DAMAGE CONTROL REPORT: "; +2840 PRINT TAB(8);:R1=I:GOSUB 8790:PRINT G2$;" REPAIR COMPLETED." 2880 NEXT I:IF RND(1)>.2 THEN 3070 2910 R1=FNR(1):IF RND(1)>=.6 THEN 3000 -2930 D(R1)=D(R1)-(RND(1)*5+1):PRINT"DAMAGE CONTROL REPORT: "; -2960 GOSUB 8790:PRINTG2$;" DAMAGED":PRINT:GOTO 3070 -3000 D(R1)=D(R1)+RND(1)*3+1:PRINT"DAMAGE CONTROL REPORT: "; -3030 GOSUB 8790:PRINTG2$;" STATE OF REPAIR IMPROVED":PRINT +2930 D(R1)=D(R1)-(RND(1)*5+1):PRINT "DAMAGE CONTROL REPORT: "; +2960 GOSUB 8790:PRINT G2$;" DAMAGED":PRINT:GOTO 3070 +3000 D(R1)=D(R1)+RND(1)*3+1:PRINT "DAMAGE CONTROL REPORT: "; +3030 GOSUB 8790:PRINT G2$;" STATE OF REPAIR IMPROVED":PRINT 3060 REM BEGIN MOVING STARSHIP 3070 A$=" ":Z1=INT(S1):Z2=INT(S2):GOSUB 8670 3110 X1=C(C1,1)+(C(C1+1,1)-C(C1,1))*(C1-INT(C1)):X=S1:Y=S2 3140 X2=C(C1,2)+(C(C1+1,2)-C(C1,2))*(C1-INT(C1)):Q4=Q1:Q5=Q2 3170 FOR I=1 TO N:S1=S1+X1:S2=S2+X2:IF S1<1ORS1>=9 OR S2<1 OR S2>=9 THEN 3500 3240 S8=INT(S1)*24+INT(S2)*3-26:IF MID$(Q$,S8,2)=" " THEN 3360 -3320 S1=INT(S1-X1):S2=INT(S2-X2):PRINT"WARP ENGINES SHUT DOWN AT "; -3350 PRINT"SECTOR";S1;",";S2;"DUE TO BAD NAVAGATION":GOTO 3370 +3320 S1=INT(S1-X1):S2=INT(S2-X2):PRINT "WARP ENGINES SHUT DOWN AT "; +3350 PRINT "SECTOR";S1;",";S2;"DUE TO BAD NAVAGATION":GOTO 3370 3360 NEXT I:S1=INT(S1):S2=INT(S2) 3370 A$="<*>":Z1=INT(S1):Z2=INT(S2):GOSUB 8670:GOSUB 3910:T8=1 3430 IF W1<1 THEN T8=.1*INT(10*W1) @@ -158,201 +158,201 @@ 3710 IF Q2<1 THEN X5=1:Q2=1:S2=1 3750 IF Q2>8 THEN X5=1:Q2=8:S2=8 3790 IF X5=0 THEN 3860 -3800 PRINT"LT. UHURA REPORTS MESSAGE FROM STARFLEET COMMAND:" -3810 PRINT" 'PERMISSION TO ATTEMPT CROSSING OF GALACTIC PERIMETER" -3820 PRINT" IS HEREBY *DENIED*. SHUT DOWN YOUR ENGINES.'" -3830 PRINT"CHIEF ENGINEER SCOTT REPORTS 'WARP ENGINES SHUT DOWN" -3840 PRINT" AT SECTOR";S1;",";S2;"OF QUADRANT";Q1;",";Q2;".'" +3800 PRINT "LT. UHURA REPORTS MESSAGE FROM STARFLEET COMMAND:" +3810 PRINT " 'PERMISSION TO ATTEMPT CROSSING OF GALACTIC PERIMETER" +3820 PRINT " IS HEREBY *DENIED*. SHUT DOWN YOUR ENGINES.'" +3830 PRINT "CHIEF ENGINEER SCOTT REPORTS 'WARP ENGINES SHUT DOWN" +3840 PRINT " AT SECTOR";S1;",";S2;"OF QUADRANT";Q1;",";Q2;".'" 3850 IF T>T0+T9 THEN 6220 3860 IF 8*Q1+Q2=8*Q4+Q5 THEN 3370 3870 T=T+1:GOSUB 3910:GOTO 1320 3900 REM MANEUVER ENERGY S/R ** -3910 E=E-N-10:IF E>=0THEN RETURN -3930 PRINT"SHIELD CONTROL SUPPLIES ENERGY TO COMPLETE THE MANEUVER." +3910 E=E-N-10:IF E>=0 THEN RETURN +3930 PRINT "SHIELD CONTROL SUPPLIES ENERGY TO COMPLETE THE MANEUVER." 3940 S=S+E:E=0:IF S<=0 THEN S=0 3980 RETURN 3990 REM LONG RANGE SENSOR SCAN CODE -4000 IF D(3)<0 THEN PRINT"LONG RANGE SENSORS ARE INOPERABLE":GOTO 1990 -4030 PRINT"LONG RANGE SCAN FOR QUADRANT";Q1;",";Q2 +4000 IF D(3)<0 THEN PRINT "LONG RANGE SENSORS ARE INOPERABLE":GOTO 1990 +4030 PRINT "LONG RANGE SCAN FOR QUADRANT";Q1;",";Q2 4040 O1$="-------------------":PRINT O1$ 4060 FOR I=Q1-1TOQ1+1:N(1)=-1:N(2)=-2:N(3)=-3:FOR J=Q2-1TOQ2+1 -4120 IF I>0ANDI<9ANDJ>0ANDJ<9 THEN N(J-Q2+2)=G(I,J):Z(I,J)=G(I,J) -4180 NEXT J:FOR L=1TO3:PRINT": ";:IF N(L)<0 THEN PRINT"*** ";:GOTO 4230 -4210 PRINTRIGHT$(STR$(N(L)+1000),3);" "; -4230 NEXT L:PRINT":":PRINTO1$:NEXT I:GOTO 1990 +4120 IF I>0 AND I<9 AND J>0 AND J<9 THEN N(J-Q2+2)=G(I,J):Z(I,J)=G(I,J) +4180 NEXT J:FOR L=1 TO 3:PRINT ": ";:IF N(L)<0 THEN PRINT "*** ";:GOTO 4230 +4210 PRINT RIGHT$(STR$(N(L)+1000),3);" "; +4230 NEXT L:PRINT ":":PRINT O1$:NEXT I:GOTO 1990 4250 REM PHASER CONTROL CODE BEGINS HERE -4260 IF D(4)<0 THEN PRINT"PHASERS INOPERATIVE":GOTO 1990 +4260 IF D(4)<0 THEN PRINT "PHASERS INOPERATIVE":GOTO 1990 4265 IF K3>0 THEN 4330 -4270 PRINT"SCIENCE OFFICER SPOCK REPORTS 'SENSORS SHOW NO ENEMY SHIPS" -4280 PRINT" IN THIS QUADRANT'":GOTO 1990 -4330 IF D(8)<0 THEN PRINT"COMPUTER FAILURE HAMPERS ACCURACY" -4350 PRINT"PHASERS LOCKED ON TARGET; "; -4360 PRINT"ENERGY AVAILABLE =";E;"UNITS" +4270 PRINT "SCIENCE OFFICER SPOCK REPORTS 'SENSORS SHOW NO ENEMY SHIPS" +4280 PRINT " IN THIS QUADRANT'":GOTO 1990 +4330 IF D(8)<0 THEN PRINT "COMPUTER FAILURE HAMPERS ACCURACY" +4350 PRINT "PHASERS LOCKED ON TARGET; "; +4360 PRINT "ENERGY AVAILABLE =";E;"UNITS" 4370 INPUT"NUMBER OF UNITS TO FIRE";X:IF X<=0 THEN 1990 4400 IF E-X<0 THEN 4360 4410 E=E-X:IF D(7)<0 THEN X=X*RND(1) 4450 H1=INT(X/K3):FOR I=1TO3:IF K(I,3)<=0 THEN 4670 4480 H=INT((H1/FND(0))*(RND(1)+2)):IF H>.15*K(I,3) THEN 4530 -4500 PRINT"SENSORS SHOW NO DAMAGE TO ENEMY AT ";K(I,1);",";K(I,2):GOTO 4670 -4530 K(I,3)=K(I,3)-H:PRINTH;"UNIT HIT ON KLINGON AT SECTOR";K(I,1);","; -4550 PRINTK(I,2):IF K(I,3)<=0 THEN PRINT"*** KLINGON DESTROYED ***":GOTO 4580 -4560 PRINT" (SENSORS SHOW";K(I,3);"UNITS REMAINING)":GOTO 4670 +4500 PRINT "SENSORS SHOW NO DAMAGE TO ENEMY AT ";K(I,1);",";K(I,2):GOTO 4670 +4530 K(I,3)=K(I,3)-H:PRINT H;"UNIT HIT ON KLINGON AT SECTOR";K(I,1);","; +4550 PRINT K(I,2):IF K(I,3)<=0 THEN PRINT "*** KLINGON DESTROYED ***":GOTO 4580 +4560 PRINT " (SENSORS SHOW";K(I,3);"UNITS REMAINING)":GOTO 4670 4580 K3=K3-1:K9=K9-1:Z1=K(I,1):Z2=K(I,2):A$=" ":GOSUB 8670 4650 K(I,3)=0:G(Q1,Q2)=G(Q1,Q2)-100:Z(Q1,Q2)=G(Q1,Q2):IF K9<=0 THEN 6370 4670 NEXT I:GOSUB 6000:GOTO 1990 4690 REM PHOTON TORPEDO CODE BEGINS HERE -4700 IF P<=0 THEN PRINT"ALL PHOTON TORPEDOES EXPENDED":GOTO 1990 -4730 IF D(5)<0 THEN PRINT"PHOTON TUBES ARE NOT OPERATIONAL":GOTO 1990 +4700 IF P<=0 THEN PRINT "ALL PHOTON TORPEDOES EXPENDED":GOTO 1990 +4730 IF D(5)<0 THEN PRINT "PHOTON TUBES ARE NOT OPERATIONAL":GOTO 1990 4760 INPUT"PHOTON TORPEDO COURSE (1-9)";C1:IF C1=9 THEN C1=1 4780 IF C1>=1ANDC1<9 THEN 4850 -4790 PRINT"ENSIGN CHEKOV REPORTS, 'INCORRECT COURSE DATA, SIR!'" +4790 PRINT "ENSIGN CHEKOV REPORTS, 'INCORRECT COURSE DATA, SIR!'" 4800 GOTO 1990 4850 X1=C(C1,1)+(C(C1+1,1)-C(C1,1))*(C1-INT(C1)):E=E-2:P=P-1 4860 X2=C(C1,2)+(C(C1+1,2)-C(C1,2))*(C1-INT(C1)):X=S1:Y=S2 -4910 PRINT"TORPEDO TRACK:" +4910 PRINT "TORPEDO TRACK:" 4920 X=X+X1:Y=Y+X2:X3=INT(X+.5):Y3=INT(Y+.5) 4960 IF X3<1ORX3>8ORY3<1ORY3>8 THEN 5490 -5000 PRINT" ";X3;",";Y3:A$=" ":Z1=X:Z2=Y:GOSUB 8830 +5000 PRINT " ";X3;",";Y3:A$=" ":Z1=X:Z2=Y:GOSUB 8830 5050 IF Z3<>0 THEN 4920 5060 A$="+K+":Z1=X:Z2=Y:GOSUB 8830:IF Z3=0 THEN 5210 -5110 PRINT"*** KLINGON DESTROYED ***":K3=K3-1:K9=K9-1:IF K9<=0 THEN 6370 -5150 FOR I=1TO3:IF X3=K(I,1)ANDY3=K(I,2) THEN 5190 +5110 PRINT "*** KLINGON DESTROYED ***":K3=K3-1:K9=K9-1:IF K9<=0 THEN 6370 +5150 FOR I=1TO3:IF X3=K(I,1) AND Y3=K(I,2) THEN 5190 5180 NEXT I:I=3 5190 K(I,3)=0:GOTO 5430 5210 A$=" * ":Z1=X:Z2=Y:GOSUB 8830:IF Z3=0 THEN 5280 -5260 PRINT"STAR AT";X3;",";Y3;"ABSORBED TORPEDO ENERGY.":GOSUB 6000:GOTO 1990 +5260 PRINT "STAR AT";X3;",";Y3;"ABSORBED TORPEDO ENERGY.":GOSUB 6000:GOTO 1990 5280 A$=">!<":Z1=X:Z2=Y:GOSUB 8830:IF Z3=0 THEN 4760 -5330 PRINT"*** STARBASE DESTROYED ***":B3=B3-1:B9=B9-1 +5330 PRINT "*** STARBASE DESTROYED ***":B3=B3-1:B9=B9-1 5360 IF B9>0ORK9>T-T0-T9 THEN 5400 -5370 PRINT"THAT DOES IT, CAPTAIN!! YOU ARE HEREBY RELIEVED OF COMMAND" -5380 PRINT"AND SENTENCED TO 99 STARDATES AT HARD LABOR ON CYGNUS 12!!" +5370 PRINT "THAT DOES IT, CAPTAIN!! YOU ARE HEREBY RELIEVED OF COMMAND" +5380 PRINT "AND SENTENCED TO 99 STARDATES AT HARD LABOR ON CYGNUS 12!!" 5390 GOTO 6270 -5400 PRINT"STARFLEET COMMAND REVIEWING YOUR RECORD TO CONSIDER" -5410 PRINT"COURT MARTIAL!":D0=0 +5400 PRINT "STARFLEET COMMAND REVIEWING YOUR RECORD TO CONSIDER" +5410 PRINT "COURT MARTIAL!":D0=0 5430 Z1=X:Z2=Y:A$=" ":GOSUB 8670 5470 G(Q1,Q2)=K3*100+B3*10+S3:Z(Q1,Q2)=G(Q1,Q2):GOSUB 6000:GOTO 1990 -5490 PRINT"TORPEDO MISSED":GOSUB 6000:GOTO 1990 +5490 PRINT "TORPEDO MISSED":GOSUB 6000:GOTO 1990 5520 REM SHIELD CONTROL -5530 IF D(7)<0 THEN PRINT"SHIELD CONTROL INOPERABLE":GOTO 1990 -5560 PRINT"ENERGY AVAILABLE =";E+S;:INPUT"NUMBER OF UNITS TO SHIELDS";X -5580 IF X<0ORS=X THEN PRINT"":GOTO 1990 +5530 IF D(7)<0 THEN PRINT "SHIELD CONTROL INOPERABLE":GOTO 1990 +5560 PRINT "ENERGY AVAILABLE =";E+S;:INPUT"NUMBER OF UNITS TO SHIELDS";X +5580 IF X<0ORS=X THEN PRINT "":GOTO 1990 5590 IF X<=E+S THEN 5630 -5600 PRINT"SHIELD CONTROL REPORTS 'THIS IS NOT THE FEDERATION TREASURY.'" -5610 PRINT"":GOTO 1990 -5630 E=E+S-X:S=X:PRINT"DEFLECTOR CONTROL ROOM REPORT:" -5660 PRINT" 'SHIELDS NOW AT";INT(S);"UNITS PER YOUR COMMAND.'":GOTO 1990 +5600 PRINT "SHIELD CONTROL REPORTS 'THIS IS NOT THE FEDERATION TREASURY.'" +5610 PRINT "":GOTO 1990 +5630 E=E+S-X:S=X:PRINT "DEFLECTOR CONTROL ROOM REPORT:" +5660 PRINT " 'SHIELDS NOW AT";INT(S);"UNITS PER YOUR COMMAND.'":GOTO 1990 5680 REM DAMAGE CONTROL 5690 IF D(6)>=0 THEN 5910 -5700 PRINT"DAMAGE CONTROL REPORT NOT AVAILABLE":IF D0=0 THEN 1990 +5700 PRINT "DAMAGE CONTROL REPORT NOT AVAILABLE":IF D0=0 THEN 1990 5720 D3=0:FOR I=1TO8:IF D(I)<0 THEN D3=D3+.1 5760 NEXT I:IF D3=0 THEN 1990 5780 PRINT:D3=D3+D4:IF D3>=1 THEN D3=.9 -5810 PRINT"TECHNICIANS STANDING BY TO EFFECT REPAIRS TO YOUR SHIP;" -5820 PRINT"ESTIMATED TIME TO REPAIR:";.01*INT(100*D3);"STARDATES" +5810 PRINT "TECHNICIANS STANDING BY TO EFFECT REPAIRS TO YOUR SHIP;" +5820 PRINT "ESTIMATED TIME TO REPAIR:";.01*INT(100*D3);"STARDATES" 5840 INPUT "WILL YOU AUTHORIZE THE REPAIR ORDER (Y/N)";A$ -5860 IF A$<>"Y"THEN 1990 +5860 IF A$<>"Y" THEN 1990 5870 FOR I=1TO8:IF D(I)<0 THEN D(I)=0 5890 NEXT I:T=T+D3+.1 -5910 PRINT:PRINT"DEVICE STATE OF REPAIR":FOR R1=1TO8 -5920 GOSUB 8790:PRINTG2$;LEFT$(Z$,25-LEN(G2$));INT(D(R1)*100)*.01 +5910 PRINT:PRINT "DEVICE STATE OF REPAIR":FOR R1=1TO8 +5920 GOSUB 8790:PRINT G2$;LEFT$(Z$,25-LEN(G2$));INT(D(R1)*100)*.01 5950 NEXT R1:PRINT:IF D0<>0 THEN 5720 5980 GOTO 1990 5990 REM KLINGONS SHOOTING -6000 IF K3<=0THEN RETURN -6010 IF D0<>0 THEN PRINT"STARBASE SHIELDS PROTECT THE ENTERPRISE":RETURN +6000 IF K3<=0 THEN RETURN +6010 IF D0<>0 THEN PRINT "STARBASE SHIELDS PROTECT THE ENTERPRISE":RETURN 6040 FOR I=1TO3:IF K(I,3)<=0 THEN 6200 6060 H=INT((K(I,3)/FND(1))*(2+RND(1))):S=S-H:K(I,3)=K(I,3)/(3+RND(0)) -6080 PRINTH;"UNIT HIT ON ENTERPRISE FROM SECTOR";K(I,1);",";K(I,2) +6080 PRINT H;"UNIT HIT ON ENTERPRISE FROM SECTOR";K(I,1);",";K(I,2) 6090 IF S<=0 THEN 6240 -6100 PRINT" ":IF H<20 THEN 6200 +6100 PRINT " ":IF H<20 THEN 6200 6120 IF RND(1)>.6ORH/S<=.02 THEN 6200 6140 R1=FNR(1):D(R1)=D(R1)-H/S-.5*RND(1):GOSUB 8790 -6170 PRINT"DAMAGE CONTROL REPORTS ";G2$;" DAMAGED BY THE HIT'" +6170 PRINT "DAMAGE CONTROL REPORTS ";G2$;" DAMAGED BY THE HIT'" 6200 NEXT I:RETURN 6210 REM END OF GAME -6220 PRINT"IT IS STARDATE";T:GOTO 6270 -6240 PRINT:PRINT"THE ENTERPRISE HAS BEEN DESTROYED. THEN FEDERATION "; -6250 PRINT"WILL BE CONQUERED":GOTO 6220 -6270 PRINT"THERE WERE";K9;"KLINGON BATTLE CRUISERS LEFT AT" -6280 PRINT"THE END OF YOUR MISSION." +6220 PRINT "IT IS STARDATE";T:GOTO 6270 +6240 PRINT:PRINT "THE ENTERPRISE HAS BEEN DESTROYED. THEN FEDERATION "; +6250 PRINT "WILL BE CONQUERED":GOTO 6220 +6270 PRINT "THERE WERE";K9;"KLINGON BATTLE CRUISERS LEFT AT" +6280 PRINT "THE END OF YOUR MISSION." 6290 PRINT:PRINT:IF B9=0 THEN 6360 -6310 PRINT"THE FEDERATION IS IN NEED OF A NEW STARSHIP COMMANDER" -6320 PRINT"FOR A SIMILAR MISSION -- IF THERE IS A VOLUNTEER," +6310 PRINT "THE FEDERATION IS IN NEED OF A NEW STARSHIP COMMANDER" +6320 PRINT "FOR A SIMILAR MISSION -- IF THERE IS A VOLUNTEER," 6330 INPUT"LET HIM STEP FORWARD AND ENTER 'AYE'";A$:IF A$="AYE" THEN 10 6360 END -6370 PRINT"CONGRULATION, CAPTAIN! THEN LAST KLINGON BATTLE CRUISER" -6380 PRINT"MENACING THE FDERATION HAS BEEN DESTROYED.":PRINT -6400 PRINT"YOUR EFFICIENCY RATING IS";1000*(K7/(T-T0))^2:GOTO 6290 +6370 PRINT "CONGRULATION, CAPTAIN! THEN LAST KLINGON BATTLE CRUISER" +6380 PRINT "MENACING THE FDERATION HAS BEEN DESTROYED.":PRINT +6400 PRINT "YOUR EFFICIENCY RATING IS";1000*(K7/(T-T0))^2:GOTO 6290 6420 REM SHORT RANGE SENSOR SCAN & STARTUP SUBROUTINE 6430 FOR I=S1-1TOS1+1:FOR J=S2-1 TO S2+1 6450 IF INT(I+.5)<1ORINT(I+.5)>8ORINT(J+.5)<1ORINT(J+.5)>8 THEN 6540 6490 A$=">!<":Z1=I:Z2=J:GOSUB 8830:IF Z3=1 THEN 6580 6540 NEXT J:NEXT I:D0=0:GOTO 6650 6580 D0=1:C$="DOCKED":E=E0:P=P0 -6620 PRINT"SHIELDS DROPPED FOR DOCKING PURPOSES":S=0:GOTO 6720 +6620 PRINT "SHIELDS DROPPED FOR DOCKING PURPOSES":S=0:GOTO 6720 6650 IF K3>0 THEN C$="*RED*":GOTO 6720 6660 C$="GREEN":IF E=0 THEN 6770 -6730 PRINT:PRINT"*** SHORT RANGE SENSORS ARE OUT ***":PRINT:RETURN -6770 O1$="---------------------------------":PRINTO1$:FOR I=1 TO 8 -6820 FOR J=(I-1)*24+1 TO (I-1)*24+22STEP3:PRINT" ";MID$(Q$,J,3);:NEXT J +6730 PRINT:PRINT "*** SHORT RANGE SENSORS ARE OUT ***":PRINT:RETURN +6770 O1$="---------------------------------":PRINT O1$:FOR I=1 TO 8 +6820 FOR J=(I-1)*24+1 TO (I-1)*24+22STEP3:PRINT " ";MID$(Q$,J,3);:NEXT J 6830 ONIGOTO 6850,6900,6960,7020,7070,7120,7180,7240 -6850 PRINT" STARDATE ";INT(T*10)*.1:GOTO 7260 -6900 PRINT" CONDITION ";C$:GOTO 7260 -6960 PRINT" QUADRANT ";Q1;",";Q2:GOTO 7260 -7020 PRINT" SECTOR ";S1;",";S2:GOTO 7260 -7070 PRINT" PHOTON TORPEDOES ";INT(P):GOTO 7260 -7120 PRINT" TOTAL ENERGY ";INT(E+S):GOTO 7260 -7180 PRINT" SHIELDS ";INT(S):GOTO 7260 -7240 PRINT" KLINGONS REMAINING";INT(K9) +6850 PRINT " STARDATE ";INT(T*10)*.1:GOTO 7260 +6900 PRINT " CONDITION ";C$:GOTO 7260 +6960 PRINT " QUADRANT ";Q1;",";Q2:GOTO 7260 +7020 PRINT " SECTOR ";S1;",";S2:GOTO 7260 +7070 PRINT " PHOTON TORPEDOES ";INT(P):GOTO 7260 +7120 PRINT " TOTAL ENERGY ";INT(E+S):GOTO 7260 +7180 PRINT " SHIELDS ";INT(S):GOTO 7260 +7240 PRINT " KLINGONS REMAINING";INT(K9) 7260 NEXT I:PRINT O1$:RETURN 7280 REM LIBRARY COMPUTER CODE -7290 IF D(8)<0 THEN PRINT"COMPUTER DISABLED":GOTO 1990 +7290 IF D(8)<0 THEN PRINT "COMPUTER DISABLED":GOTO 1990 7320 INPUT"COMPUTER ACTIVE AND AWAITING COMMAND";A:IF A<0 THEN 1990 7350 PRINT:H8=1:ONA+1GOTO 7540,7900,8070,8500,8150,7400 -7360 PRINT"FUNCTIONS AVAILABLE FROM LIBRARY-COMPUTER:" -7370 PRINT" 0 = CUMULATIVE GALACTIC RECORD" -7372 PRINT" 1 = STATUS REPORT" -7374 PRINT" 2 = PHOTON TORPEDO DATA" -7376 PRINT" 3 = STARBASE NAV DATA" -7378 PRINT" 4 = DIRECTION/DISTANCE CALCULATOR" -7380 PRINT" 5 = GALAXY 'REGION NAME' MAP":PRINT:GOTO 7320 +7360 PRINT "FUNCTIONS AVAILABLE FROM LIBRARY-COMPUTER:" +7370 PRINT " 0 = CUMULATIVE GALACTIC RECORD" +7372 PRINT " 1 = STATUS REPORT" +7374 PRINT " 2 = PHOTON TORPEDO DATA" +7376 PRINT " 3 = STARBASE NAV DATA" +7378 PRINT " 4 = DIRECTION/DISTANCE CALCULATOR" +7380 PRINT " 5 = GALAXY 'REGION NAME' MAP":PRINT:GOTO 7320 7390 REM SETUP TO CHANGE CUM GAL RECORD TO GALAXY MAP -7400 H8=0:G5=1:PRINT" THE GALAXY":GOTO 7550 +7400 H8=0:G5=1:PRINT " THE GALAXY":GOTO 7550 7530 REM CUM GALACTIC RECORD 7540 REM INPUT"DO YOU WANT A HARDCOPY? IS THE TTY ON (Y/N)";A$ 7542 REM IF A$="Y" THEN POKE1229,2:POKE1237,3:NULL1 -7543 PRINT:PRINT" "; -7544 PRINT"COMPUTER RECORD OF GALAXY FOR QUADRANT";Q1;",";Q2 +7543 PRINT:PRINT " "; +7544 PRINT "COMPUTER RECORD OF GALAXY FOR QUADRANT";Q1;",";Q2 7546 PRINT -7550 PRINT" 1 2 3 4 5 6 7 8" +7550 PRINT " 1 2 3 4 5 6 7 8" 7560 O1$=" ----- ----- ----- ----- ----- ----- ----- -----" -7570 PRINT O1$:FOR I=1 TO 8:PRINTI;:IF H8=0 THEN 7740 -7630 FOR J=1 TO 8:PRINT" ";:IF Z(I,J)=0 THEN PRINT"***";:GOTO 7720 -7700 PRINTRIGHT$(STR$(Z(I,J)+1000),3); +7570 PRINT O1$:FOR I=1 TO 8:PRINT I;:IF H8=0 THEN 7740 +7630 FOR J=1 TO 8:PRINT " ";:IF Z(I,J)=0 THEN PRINT "***";:GOTO 7720 +7700 PRINT RIGHT$(STR$(Z(I,J)+1000),3); 7720 NEXT J:GOTO 7850 -7740 Z4=I:Z5=1:GOSUB 9030:J0=INT(15-.5*LEN(G2$)):PRINTTAB(J0);G2$; -7800 Z5=5:GOSUB 9030:J0=INT(39-.5*LEN(G2$)):PRINTTAB(J0);G2$; +7740 Z4=I:Z5=1:GOSUB 9030:J0=INT(15-.5*LEN(G2$)):PRINT TAB(J0);G2$; +7800 Z5=5:GOSUB 9030:J0=INT(39-.5*LEN(G2$)):PRINT TAB(J0);G2$; 7850 PRINT:PRINT O1$:NEXT I:PRINT:GOTO 1990 7890 REM STATUS REPORT 7900 PRINT " STATUS REPORT:":X$="":IF K9>1 THEN X$="S" -7940 PRINT"KLINGON";X$;" LEFT: ";K9 -7960 PRINT"MISSION MUST BE COMPLETED IN";.1*INT((T0+T9-T)*10);"STARDATES" +7940 PRINT "KLINGON";X$;" LEFT: ";K9 +7960 PRINT "MISSION MUST BE COMPLETED IN";.1*INT((T0+T9-T)*10);"STARDATES" 7970 X$="S":IF B9<2 THEN X$="":IF B9<1 THEN 8010 -7980 PRINT"THE FEDERATION IS MAINTAINING";B9;"STARBASE";X$;" IN THE GALAXY" +7980 PRINT "THE FEDERATION IS MAINTAINING";B9;"STARBASE";X$;" IN THE GALAXY" 7990 GOTO 5690 -8010 PRINT"YOUR STUPIDITY HAS LEFT YOU ON YOUR ON IN" -8020 PRINT" THE GALAXY -- YOU HAVE NO STARBASES LEFT!":GOTO 5690 +8010 PRINT "YOUR STUPIDITY HAS LEFT YOU ON YOUR ON IN" +8020 PRINT " THE GALAXY -- YOU HAVE NO STARBASES LEFT!":GOTO 5690 8060 REM TORPEDO, BASE NAV, D/D CALCULATOR 8070 IF K3<=0 THEN 4270 8080 X$="":IF K3>1 THEN X$="S" -8090 PRINT"FROM ENTERPRISE TO KLINGON BATTLE CRUSER";X$ +8090 PRINT "FROM ENTERPRISE TO KLINGON BATTLE CRUSER";X$ 8100 H8=0:FOR I=1 TO 3:IF K(I,3)<=0 THEN 8480 8110 W1=K(I,1):X=K(I,2) 8120 C1=S1:A=S2:GOTO 8220 -8150 PRINT"DIRECTION/DISTANCE CALCULATOR:" -8160 PRINT"YOU ARE AT QUADRANT ";Q1;",";Q2;" SECTOR ";S1;",";S2 -8170 PRINT"PLEASE ENTER":INPUT" INITIAL COORDINATES (X,Y)";C1,A +8150 PRINT "DIRECTION/DISTANCE CALCULATOR:" +8160 PRINT "YOU ARE AT QUADRANT ";Q1;",";Q2;" SECTOR ";S1;",";S2 +8170 PRINT "PLEASE ENTER":INPUT" INITIAL COORDINATES (X,Y)";C1,A 8200 INPUT" FINAL COORDINATES (X,Y)";W1,X 8220 X=X-A:A=C1-W1:IF X<0 THEN 8350 8250 IF A<0 THEN 8410 @@ -360,25 +360,25 @@ 8270 IF A=0 THEN C1=5:GOTO 8290 8280 C1=1 8290 IF ABS(A)<=ABS(X) THEN 8330 -8310 PRINT"DIRECTION =";C1+(((ABS(A)-ABS(X))+ABS(A))/ABS(A)):GOTO 8460 -8330 PRINT"DIRECTION =";C1+(ABS(A)/ABS(X)):GOTO 8460 +8310 PRINT "DIRECTION =";C1+(((ABS(A)-ABS(X))+ABS(A))/ABS(A)):GOTO 8460 +8330 PRINT "DIRECTION =";C1+(ABS(A)/ABS(X)):GOTO 8460 8350 IF A>0 THEN C1=3:GOTO 8420 8360 IF X<>0 THEN C1=5:GOTO 8290 8410 C1=7 8420 IF ABS(A)>=ABS(X) THEN 8450 -8430 PRINT"DIRECTION =";C1+(((ABS(X)-ABS(A))+ABS(X))/ABS(X)):GOTO 8460 -8450 PRINT"DIRECTION =";C1+(ABS(X)/ABS(A)) -8460 PRINT"DISTANCE =";SQR(X^2+A^2):IF H8=1 THEN 1990 +8430 PRINT "DIRECTION =";C1+(((ABS(X)-ABS(A))+ABS(X))/ABS(X)):GOTO 8460 +8450 PRINT "DIRECTION =";C1+(ABS(X)/ABS(A)) +8460 PRINT "DISTANCE =";SQR(X^2+A^2):IF H8=1 THEN 1990 8480 NEXT I:GOTO 1990 -8500 IF B3<>0 THEN PRINT"FROM ENTERPRISE TO STARBASE:":W1=B4:X=B5:GOTO 8120 -8510 PRINT"MR. SPOCK REPORTS, 'SENSORS SHOW NO STARBASES IN THIS"; -8520 PRINT" QUADRANT.'":GOTO 1990 +8500 IF B3<>0 THEN PRINT "FROM ENTERPRISE TO STARBASE:":W1=B4:X=B5:GOTO 8120 +8510 PRINT "MR. SPOCK REPORTS, 'SENSORS SHOW NO STARBASES IN THIS"; +8520 PRINT " QUADRANT.'":GOTO 1990 8580 REM FIND EMPTY PLACE IN QUADRANT (FOR THINGS) 8590 R1=FNR(1):R2=FNR(1):A$=" ":Z1=R1:Z2=R2:GOSUB 8830:IF Z3=0 THEN 8590 8600 RETURN 8660 REM INSERT IN STRING ARRAY FOR QUADRANT 8670 S8=INT(Z2-.5)*3+INT(Z1-.5)*24+1 -8675 IF LEN(A$)<>3THEN PRINT"ERROR":STOP +8675 IF LEN(A$)<>3 THEN PRINT "ERROR":STOP 8680 IF S8=1 THEN Q$=A$+RIGHT$(Q$,189):RETURN 8690 IF S8=190 THEN Q$=LEFT$(Q$,189)+A$:RETURN 8700 Q$=LEFT$(Q$,S8-1)+A$+RIGHT$(Q$,190-S8):RETURN From 55edf2169360b49070e8957e59555412ae658d99 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sun, 16 Jan 2022 18:51:00 +0000 Subject: [PATCH 191/337] Clean up ON --- 84_Super_Star_Trek/superstartrek.bas | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/84_Super_Star_Trek/superstartrek.bas b/84_Super_Star_Trek/superstartrek.bas index cddc6dd8..53892159 100644 --- a/84_Super_Star_Trek/superstartrek.bas +++ b/84_Super_Star_Trek/superstartrek.bas @@ -90,7 +90,7 @@ 2050 PRINT "-CIRCUITING TO ENGINE ROOM!!":GOTO 6220 2060 INPUT"COMMAND";A$ 2080 FOR I=1 TO 9:IF LEFT$(A$,3)<>MID$(A1$,3*I-2,3) THEN 2160 -2140 ONIGOTO 2300,1980,4000,4260,4700,5530,5690,7290,6270 +2140 ON I GOTO 2300,1980,4000,4260,4700,5530,5690,7290,6270 2160 NEXT I:PRINT "ENTER ONE OF THE FOLLOWING:" 2180 PRINT " NAV (TO SET COURSE)" 2190 PRINT " SRS (FOR SHORT RANGE SENSOR SCAN)" @@ -296,7 +296,7 @@ 6730 PRINT:PRINT "*** SHORT RANGE SENSORS ARE OUT ***":PRINT:RETURN 6770 O1$="---------------------------------":PRINT O1$:FOR I=1 TO 8 6820 FOR J=(I-1)*24+1 TO (I-1)*24+22STEP3:PRINT " ";MID$(Q$,J,3);:NEXT J -6830 ONIGOTO 6850,6900,6960,7020,7070,7120,7180,7240 +6830 ON I GOTO 6850,6900,6960,7020,7070,7120,7180,7240 6850 PRINT " STARDATE ";INT(T*10)*.1:GOTO 7260 6900 PRINT " CONDITION ";C$:GOTO 7260 6960 PRINT " QUADRANT ";Q1;",";Q2:GOTO 7260 @@ -309,7 +309,7 @@ 7280 REM LIBRARY COMPUTER CODE 7290 IF D(8)<0 THEN PRINT "COMPUTER DISABLED":GOTO 1990 7320 INPUT"COMPUTER ACTIVE AND AWAITING COMMAND";A:IF A<0 THEN 1990 -7350 PRINT:H8=1:ONA+1GOTO 7540,7900,8070,8500,8150,7400 +7350 PRINT:H8=1:ON A+1 GOTO 7540,7900,8070,8500,8150,7400 7360 PRINT "FUNCTIONS AVAILABLE FROM LIBRARY-COMPUTER:" 7370 PRINT " 0 = CUMULATIVE GALACTIC RECORD" 7372 PRINT " 1 = STATUS REPORT" From 379bee8b800f4cecd9ca74c6b5e9416734b4efb6 Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sun, 16 Jan 2022 18:53:55 +0000 Subject: [PATCH 192/337] Fix some ORs --- 84_Super_Star_Trek/superstartrek.bas | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/84_Super_Star_Trek/superstartrek.bas b/84_Super_Star_Trek/superstartrek.bas index 53892159..084f0919 100644 --- a/84_Super_Star_Trek/superstartrek.bas +++ b/84_Super_Star_Trek/superstartrek.bas @@ -139,7 +139,7 @@ 3070 A$=" ":Z1=INT(S1):Z2=INT(S2):GOSUB 8670 3110 X1=C(C1,1)+(C(C1+1,1)-C(C1,1))*(C1-INT(C1)):X=S1:Y=S2 3140 X2=C(C1,2)+(C(C1+1,2)-C(C1,2))*(C1-INT(C1)):Q4=Q1:Q5=Q2 -3170 FOR I=1 TO N:S1=S1+X1:S2=S2+X2:IF S1<1ORS1>=9 OR S2<1 OR S2>=9 THEN 3500 +3170 FOR I=1 TO N:S1=S1+X1:S2=S2+X2:IF S1<1 OR S1>=9 OR S2<1 OR S2>=9 THEN 3500 3240 S8=INT(S1)*24+INT(S2)*3-26:IF MID$(Q$,S8,2)=" " THEN 3360 3320 S1=INT(S1-X1):S2=INT(S2-X2):PRINT "WARP ENGINES SHUT DOWN AT "; 3350 PRINT "SECTOR";S1;",";S2;"DUE TO BAD NAVAGATION":GOTO 3370 @@ -211,7 +211,7 @@ 4860 X2=C(C1,2)+(C(C1+1,2)-C(C1,2))*(C1-INT(C1)):X=S1:Y=S2 4910 PRINT "TORPEDO TRACK:" 4920 X=X+X1:Y=Y+X2:X3=INT(X+.5):Y3=INT(Y+.5) -4960 IF X3<1ORX3>8ORY3<1ORY3>8 THEN 5490 +4960 IF X3<1 OR X3>8 OR Y3<1 OR Y3>8 THEN 5490 5000 PRINT " ";X3;",";Y3:A$=" ":Z1=X:Z2=Y:GOSUB 8830 5050 IF Z3<>0 THEN 4920 5060 A$="+K+":Z1=X:Z2=Y:GOSUB 8830:IF Z3=0 THEN 5210 @@ -223,7 +223,7 @@ 5260 PRINT "STAR AT";X3;",";Y3;"ABSORBED TORPEDO ENERGY.":GOSUB 6000:GOTO 1990 5280 A$=">!<":Z1=X:Z2=Y:GOSUB 8830:IF Z3=0 THEN 4760 5330 PRINT "*** STARBASE DESTROYED ***":B3=B3-1:B9=B9-1 -5360 IF B9>0ORK9>T-T0-T9 THEN 5400 +5360 IF B9>0 OR K9>T-T0-T9 THEN 5400 5370 PRINT "THAT DOES IT, CAPTAIN!! YOU ARE HEREBY RELIEVED OF COMMAND" 5380 PRINT "AND SENTENCED TO 99 STARDATES AT HARD LABOR ON CYGNUS 12!!" 5390 GOTO 6270 @@ -235,7 +235,7 @@ 5520 REM SHIELD CONTROL 5530 IF D(7)<0 THEN PRINT "SHIELD CONTROL INOPERABLE":GOTO 1990 5560 PRINT "ENERGY AVAILABLE =";E+S;:INPUT"NUMBER OF UNITS TO SHIELDS";X -5580 IF X<0ORS=X THEN PRINT "":GOTO 1990 +5580 IF X<0 OR S=X THEN PRINT "":GOTO 1990 5590 IF X<=E+S THEN 5630 5600 PRINT "SHIELD CONTROL REPORTS 'THIS IS NOT THE FEDERATION TREASURY.'" 5610 PRINT "":GOTO 1990 @@ -265,7 +265,7 @@ 6080 PRINT H;"UNIT HIT ON ENTERPRISE FROM SECTOR";K(I,1);",";K(I,2) 6090 IF S<=0 THEN 6240 6100 PRINT " ":IF H<20 THEN 6200 -6120 IF RND(1)>.6ORH/S<=.02 THEN 6200 +6120 IF RND(1)>.6 OR H/S<=.02 THEN 6200 6140 R1=FNR(1):D(R1)=D(R1)-H/S-.5*RND(1):GOSUB 8790 6170 PRINT "DAMAGE CONTROL REPORTS ";G2$;" DAMAGED BY THE HIT'" 6200 NEXT I:RETURN @@ -285,7 +285,7 @@ 6400 PRINT "YOUR EFFICIENCY RATING IS";1000*(K7/(T-T0))^2:GOTO 6290 6420 REM SHORT RANGE SENSOR SCAN & STARTUP SUBROUTINE 6430 FOR I=S1-1TOS1+1:FOR J=S2-1 TO S2+1 -6450 IF INT(I+.5)<1ORINT(I+.5)>8ORINT(J+.5)<1ORINT(J+.5)>8 THEN 6540 +6450 IF INT(I+.5)<1 OR INT(I+.5)>8 OR INT(J+.5)<1 OR INT(J+.5)>8 THEN 6540 6490 A$=">!<":Z1=I:Z2=J:GOSUB 8830:IF Z3=1 THEN 6580 6540 NEXT J:NEXT I:D0=0:GOTO 6650 6580 D0=1:C$="DOCKED":E=E0:P=P0 From 31c856d86720e85473ce502d006ad5feee6e180b Mon Sep 17 00:00:00 2001 From: Andrew Regan Date: Sun, 16 Jan 2022 19:06:45 +0000 Subject: [PATCH 193/337] Update superstartrek.bas --- 84_Super_Star_Trek/superstartrek.bas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/84_Super_Star_Trek/superstartrek.bas b/84_Super_Star_Trek/superstartrek.bas index 084f0919..efd74cb0 100644 --- a/84_Super_Star_Trek/superstartrek.bas +++ b/84_Super_Star_Trek/superstartrek.bas @@ -18,7 +18,7 @@ 190 REM *** LINE NUMBERS FROM VERSION STREK7 OF 1/12/75 PRESERVED AS 200 REM *** MUCH AS POSSIBLE WHILE USING MULTIPLE STATEMENTS PER LINE 205 REM *** SOME LINES ARE LONGER THAN 72 CHARACTERS; THIS WAS DONE -210 REM *** BY USING "?" INSTEAD OF "PRINT " WHEN ENTERING LINES +210 REM *** BY USING "?" INSTEAD OF "PRINT" WHEN ENTERING LINES 215 REM *** 220 PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT 221 PRINT " ,------*------," From 18284fa3d415336f607a3094756e02af060eb462 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 00:03:14 +0200 Subject: [PATCH 194/337] Check that .NET ports have at least one executable project; and some project properties --- .../DotnetUtils/DotnetUtils/Functions.cs | 21 ++++++ .../DotnetUtils/DotnetUtils/Methods.cs | 32 +++++++++ .../DotnetUtils/DotnetUtils/Program.cs | 72 +++++++++++++++++-- 3 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 00_Utilities/DotnetUtils/DotnetUtils/Functions.cs diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs b/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs new file mode 100644 index 00000000..7fa3115c --- /dev/null +++ b/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs @@ -0,0 +1,21 @@ +using System.Xml.Linq; + +namespace DotnetUtils; + +public static class Functions { + public static string? getValue(string path, params string[] names) { + if (names.Length == 0) { throw new InvalidOperationException(); } + var parent = XDocument.Load(path).Element("Project")?.Element("PropertyGroup"); + return getValue(parent, names); + } + + public static string? getValue(XElement? parent, params string[] names) { + if (names.Length == 0) { throw new InvalidOperationException(); } + XElement? elem = null; + foreach (var name in names) { + elem = parent?.Element(name); + if (elem != null) { break; } + } + return elem?.Value; + } +} diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs b/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs index 2aafa800..a8d3532b 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs @@ -44,6 +44,38 @@ public static class Methods { process.WaitForExit(); return new ProcessResult(process.ExitCode, output, error); } + + public static Task RunProcessAsync(Process process, string input = "") { + var tcs = new TaskCompletionSource(); + var (output, error) = ("", ""); + var (redirectOut, redirectErr) = ( + process.StartInfo.RedirectStandardOutput, + process.StartInfo.RedirectStandardError + ); + + process.Exited += (s, e) => tcs.SetResult(new ProcessResult(process.ExitCode, output, error)); + + if (redirectOut) { + process.OutputDataReceived += (s, ea) => output += ea.Data + "\n"; + } + if (redirectErr) { + process.ErrorDataReceived += (s, ea) => error += ea.Data + "\n"; + } + + if (!process.Start()) { + // what happens to the Exited event if process doesn't start successfully? + throw new InvalidOperationException(); + } + + if (redirectOut) { process.BeginOutputReadLine(); } + if (redirectErr) { process.BeginErrorReadLine(); } + if (!string.IsNullOrEmpty(input)) { + process.StandardInput.WriteLine(input); + process.StandardInput.Close(); + } + + return tcs.Task; + } } public sealed record ProcessResult(int ExitCode, string StdOut, string StdErr) { diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index e8ea235e..6121d131 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -1,7 +1,9 @@ -using DotnetUtils; +using System.Xml.Linq; +using DotnetUtils; using static System.Console; using static System.IO.Path; using static DotnetUtils.Methods; +using static DotnetUtils.Functions; var infos = PortInfos.Get; @@ -13,6 +15,8 @@ var actions = new (Action action, string description)[] { (missingProj, "Output missing project file"), (unexpectedProjName, "Output misnamed project files"), (multipleProjs, "Output multiple project files"), + (checkProjects, "Check .csproj/.vbproj files for target framework, nullability etc."), + (checkExecutableProject, "Check that there is at least one executable project per port"), (generateMissingSlns, "Generate solution files when missing"), (generateMissingProjs, "Generate project files when missing") @@ -220,12 +224,66 @@ void generateMissingProjs() { } void checkProjects() { - // warn if project files do not: - // target .NET 6 - // implicit using - // nullable enable - // warn if none og the projects have: - // output type exe + foreach (var (proj,item) in infos.SelectMany(item => item.Projs.Select(proj => (proj,item)))) { + var warnings = new List(); + var parent = XDocument.Load(proj).Element("Project")?.Element("PropertyGroup"); + + var ( + framework, + nullable, + implicitUsing, + rootNamespace, + langVersion + ) = ( + getValue(parent, "TargetFramework", "TargetFrameworks"), + getValue(parent, "Nullable"), + getValue(parent, "ImplicitUsings"), + getValue(parent, "RootNamespace"), + getValue(parent, "LangVersion") + ); + + if (framework != "net6.0") { + warnings.Add($"Target: {framework}"); + } + + if (item.Lang == "csharp") { + if (nullable != "enable") { + warnings.Add($"Nullable: {nullable}"); + } + if (implicitUsing != "enable") { + warnings.Add($"ImplicitUsings: {implicitUsing}"); + } + if (rootNamespace != null && rootNamespace != item.GameName) { + warnings.Add($"RootNamespace: {rootNamespace}"); + } + if (langVersion != "10") { + warnings.Add($"LangVersion: {langVersion}"); + } + } + + if (item.Lang == "vbnet") { + if (rootNamespace != item.GameName) { + warnings.Add($"RootNamespace: {rootNamespace}"); + } + if (langVersion != "16.9") { + warnings.Add($"LangVersion: {langVersion}"); + } + } + + if (warnings.Any()) { + WriteLine(proj); + WriteLine(string.Join("\n", warnings)); + WriteLine(); + } + } +} + +void checkExecutableProject() { + foreach (var item in infos) { + if (item.Projs.All(proj => getValue(proj,"OutputType") != "Exe")) { + WriteLine($"{item.LangPath}"); + } + } } void tryBuild() { From f1107ac1fee9454c57dc368dddb66c368d51fdf3 Mon Sep 17 00:00:00 2001 From: Mark Wieder Date: Sun, 16 Jan 2022 14:15:59 -0800 Subject: [PATCH 195/337] craps game in ruby --- 29_Craps/ruby/craps.rb | 125 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 29_Craps/ruby/craps.rb diff --git a/29_Craps/ruby/craps.rb b/29_Craps/ruby/craps.rb new file mode 100644 index 00000000..dc53813b --- /dev/null +++ b/29_Craps/ruby/craps.rb @@ -0,0 +1,125 @@ +class CRAPSGAME + + # class variables start with a double "@" + @@standings = 0 + + def displayHeading + puts "CRAPS".center(80) + puts "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY".center(80) + puts "\n\n\n" + puts "2,3,12 are losers" + puts "4,5,6,8,9,10 are points" + puts "7,11 are natural winners.\n\n" + end + + def displayStanding + if @@standings < 0 + print "you are in the hole by " + elsif @@standings == 0 + print "you currently have " + else + # show how much money we currently have + print "you now have won " + end + # print the absolute value of the amount in the standings + puts @@standings.abs.to_s + " dollars" + end + + # dice can come up 2 through 12 + # so return a minimum of 2 and add 0 through 10 to that + def rollDice + puts "I will now throw the dice" + return rand(5) + rand(5) + 2 + end + + def placeBet + print "How much do you want to wager? " + wager = gets.strip.to_i + return wager + end + + def loseBetBy amount + @@standings -= amount + end + + def winBetBy amount + @@standings += amount + end + + def askQuit? + print "\nDo you want to play again? " + # just the first character, make it uppercase + again = gets.strip.upcase[0] + return again != "Y" + end + + def pointRoll point, wager + while true do + puts " is the point." + puts " I will roll again when you press Enter." + waitForIt = gets + roll = rollDice + print roll.to_s + + # the only critical rolls here are 7 and the previous roll + # if anything else comes up we roll again. + case roll.to_i + when 7 + puts " craps - you lose" + loseBetBy wager + break + when point + puts " is a winner! congrats!" + puts "at 2 to 1 odds pays you " + (2 * wager).to_s + " dollars" + winBetBy 2 * wager + break + else + print " no point - " + point.to_s + end + end + end + + def play + displayHeading + + while true do + wagerAmount = placeBet + roll = rollDice + print roll.to_s + case roll + when 2 + puts " snake eyes - you lose" + loseBetBy wagerAmount + when 3, 12 + puts " craps - you lose" + loseBetBy wagerAmount + when 4, 5, 6, 8, 9, 10 + pointRoll roll, wagerAmount + when 7, 11 + puts " a natural - a winner" + puts "pays even money: " + wagerAmount.to_s + " dollars" + winBetBy wagerAmount + end + displayStanding + if askQuit? + endPlay + end + end + end + + def endPlay + case + when @@standings < 0 + puts "Too bad. You are in the hole " + @@standings.abs.to_s + " dollars. Come again." + when @@standings > 0 + puts "Congratulations --- You came out a winner of " + @@standings.to_s + " dollars. Come again!" + when @@standings == 0 + puts "Congratulations --- You came out even, not bad for an amateur" + end + exit + end +end + +craps = CRAPSGAME.new +craps.play + From 57b71a059dec38b171cf23581053a21dbaaeeb50 Mon Sep 17 00:00:00 2001 From: ribtips Date: Sun, 16 Jan 2022 19:24:20 -0500 Subject: [PATCH 196/337] Game 41 Guess in Ruby --- 41_Guess/ruby/guess.rb | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 41_Guess/ruby/guess.rb diff --git a/41_Guess/ruby/guess.rb b/41_Guess/ruby/guess.rb new file mode 100644 index 00000000..cf2deea2 --- /dev/null +++ b/41_Guess/ruby/guess.rb @@ -0,0 +1,48 @@ +def print_intro + print " " * 31 + "GUESS\n" + print " " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n" + print "THIS IS A NUMBER GUESSING GAME. I'LL THINK\nOF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT.\nTHEN YOU HAVE TO GUESS WHAT IT IS.\n" +end + +def game_play(limit,choice_limit) + random = rand(limit.to_i)+1 + puts "I'M THINKING OF A NUMBER BETWEEN 1 and #{limit}" + puts "NOW YOU TRY TO GUESS WHAT IT IS." + print "? " + ans=0 + guesses=0 + until ans.to_i == random.to_i + ans = gets.chomp + guesses += 1 + if ans.to_i > random.to_i + puts "TOO HIGH. TRY A SMALLER ANSWER." + print "? " + elsif ans.to_i < random.to_i + puts "TOO LOW. TRY A BIGGER ANSWER." + print "? " + elsif ans.to_i == random.to_i + puts "THAT'S IT! YOU GOT IT IN #{guesses} TRIES." + if guesses.to_i < choice_limit.to_i + puts "VERY GOOD." + elsif guesses.to_i == choice_limit.to_i + puts "GOOD." + else + puts "YOU SHOULD HAVE BEEN ABLE TO GET IT IN ONLY #{choice_limit}" + end + print "\n\n\n\n\n" + end + end +end + + +def main + print_intro + puts "WHAT LIMIT DO YOU WANT" + limit = gets.chomp + choice_limit = (Math.log(limit.to_i)/Math.log(2)+1).to_i + while 1 + game_play(limit,choice_limit) + end +end + +main From bdd4a459a2296448450dc685d8082e1b018a0f94 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 02:55:36 +0200 Subject: [PATCH 197/337] Script - output info on a single port --- .../DotnetUtils/DotnetUtils/Functions.cs | 14 +++ .../DotnetUtils/DotnetUtils/PortInfo.cs | 31 +++--- .../DotnetUtils/DotnetUtils/PortInfos.cs | 4 +- .../DotnetUtils/DotnetUtils/Program.cs | 94 +++++++++++++++---- 4 files changed, 107 insertions(+), 36 deletions(-) diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs b/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs index 7fa3115c..cc31170e 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs @@ -1,4 +1,5 @@ using System.Xml.Linq; +using static System.Console; namespace DotnetUtils; @@ -18,4 +19,17 @@ public static class Functions { } return elem?.Value; } + + public static int getChoice(int maxValue) => getChoice(0, maxValue); + + public static int getChoice(int minValue, int maxValue) { + int result; + do { + Write("? "); + } while (!int.TryParse(ReadLine(), out result) || result < minValue || result > maxValue); + //WriteLine(); + return result; + } + + } diff --git a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs index a1caaf15..1cb0ba03 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs @@ -5,7 +5,7 @@ using static DotnetUtils.Globals; namespace DotnetUtils; public record PortInfo( - string FullPath, string FolderName, int Index, string GameName, + string GamePath, string FolderName, int Index, string GameName, string LangPath, string Lang, string Ext, string ProjExt, string[] CodeFiles, string[] Slns, string[] Projs ) { @@ -24,33 +24,32 @@ public record PortInfo( { "23_Matches", "TwentyThreeMatches"} }; - public static PortInfo? Create(string fullPath, string langKeyword) { - var folderName = GetFileName(fullPath); + public static PortInfo? Create(string gamePath, string langKeyword) { + var folderName = GetFileName(gamePath); var parts = folderName.Split('_', 2); - var index = - parts.Length > 0 && int.TryParse(parts[0], out var n) ? + if (parts.Length <= 1) { return null; } + + var (index, gameName) = ( + int.TryParse(parts[0], out var n) && n > 0 ? // ignore utilities folder n : - (int?)null; + (int?)null, + specialGameNames.TryGetValue(parts[1], out var specialName) ? + specialName : + parts[1].Replace("_", "").Replace("-", "") + ); - var gameName = - parts.Length <= 1 ? - null : - specialGameNames.TryGetValue(parts[1], out var specialName) ? - specialName : - parts[1].Replace("_", "").Replace("-", ""); - - if (index is 0 or null || gameName is null) { return null; } + if (index is null || gameName is null) { return null; } var (ext, projExt) = LangData[langKeyword]; - var langPath = Combine(fullPath, langKeyword); + var langPath = Combine(gamePath, langKeyword); var codeFiles = GetFiles(langPath, $"*.{ext}", enumerationOptions) .Where(x => !x.Contains("\\bin\\") && !x.Contains("\\obj\\")) .ToArray(); return new PortInfo( - fullPath, folderName, index.Value, gameName, + gamePath, folderName, index.Value, gameName, langPath, langKeyword, ext, projExt, codeFiles, GetFiles(langPath, "*.sln", enumerationOptions), diff --git a/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs b/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs index b8c1afd3..af824b33 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs @@ -12,8 +12,8 @@ public static class PortInfos { Root = Root[..Root.IndexOf(@"\00_Utilities")]; Get = GetDirectories(Root) - .SelectMany(fullPath => LangData.Keys.Select(keyword => (fullPath, keyword))) - .SelectT((fullPath, keyword) => PortInfo.Create(fullPath, keyword)) + .SelectMany(gamePath => LangData.Keys.Select(keyword => (gamePath, keyword))) + .SelectT((gamePath, keyword) => PortInfo.Create(gamePath, keyword)) .Where(x => x is not null) .ToArray()!; } diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index 6121d131..ab59bd9e 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -17,6 +17,7 @@ var actions = new (Action action, string description)[] { (multipleProjs, "Output multiple project files"), (checkProjects, "Check .csproj/.vbproj files for target framework, nullability etc."), (checkExecutableProject, "Check that there is at least one executable project per port"), + (printPortInfo, "Print info about a single port"), (generateMissingSlns, "Generate solution files when missing"), (generateMissingProjs, "Generate project files when missing") @@ -30,15 +31,6 @@ WriteLine(); actions[getChoice(actions.Length - 1)].action(); -int getChoice(int maxValue) { - int result; - do { - Write("? "); - } while (!int.TryParse(ReadLine(), out result) || result < 0 || result > maxValue); - WriteLine(); - return result; -} - void printSlns(PortInfo pi) { switch (pi.Slns.Length) { case 0: @@ -73,7 +65,6 @@ void printProjs(PortInfo pi) { } break; } - WriteLine(); } void printInfos() { @@ -215,7 +206,7 @@ void generateMissingProjs() { }; var projFullPath = Combine(item.LangPath, $"{item.GameName}.{item.ProjExt}"); File.WriteAllText(projFullPath, projText); - + if (item.Slns.Length == 1) { var result = RunProcess("dotnet", $"sln {item.Slns[0]} add {projFullPath}"); WriteLine(result); @@ -224,7 +215,15 @@ void generateMissingProjs() { } void checkProjects() { - foreach (var (proj,item) in infos.SelectMany(item => item.Projs.Select(proj => (proj,item)))) { + foreach (var info in infos) { + printProjectWarnings(info); + WriteLine(); + } +} + +// TODO make this run on a single project +void printProjectWarnings(PortInfo info) { + foreach (var proj in info.Projs) { var warnings = new List(); var parent = XDocument.Load(proj).Element("Project")?.Element("PropertyGroup"); @@ -246,14 +245,14 @@ void checkProjects() { warnings.Add($"Target: {framework}"); } - if (item.Lang == "csharp") { + if (info.Lang == "csharp") { if (nullable != "enable") { warnings.Add($"Nullable: {nullable}"); } if (implicitUsing != "enable") { warnings.Add($"ImplicitUsings: {implicitUsing}"); } - if (rootNamespace != null && rootNamespace != item.GameName) { + if (rootNamespace != null && rootNamespace != info.GameName) { warnings.Add($"RootNamespace: {rootNamespace}"); } if (langVersion != "10") { @@ -261,8 +260,8 @@ void checkProjects() { } } - if (item.Lang == "vbnet") { - if (rootNamespace != item.GameName) { + if (info.Lang == "vbnet") { + if (rootNamespace != info.GameName) { warnings.Add($"RootNamespace: {rootNamespace}"); } if (langVersion != "16.9") { @@ -271,7 +270,7 @@ void checkProjects() { } if (warnings.Any()) { - WriteLine(proj); + WriteLine(proj.RelativePath(info.LangPath)); WriteLine(string.Join("\n", warnings)); WriteLine(); } @@ -280,7 +279,7 @@ void checkProjects() { void checkExecutableProject() { foreach (var item in infos) { - if (item.Projs.All(proj => getValue(proj,"OutputType") != "Exe")) { + if (item.Projs.All(proj => getValue(proj, "OutputType") != "Exe")) { WriteLine($"{item.LangPath}"); } } @@ -289,3 +288,62 @@ void checkExecutableProject() { void tryBuild() { // if has code files, try to build } + +void printPortInfo() { + // prompt for port number + Write("Enter number from 1 to 96 "); + var index = getChoice(1, 96); + + Write("Enter 0 for C#, 1 for VB "); + var lang = getChoice(1) switch { + 0 => "csharp", + 1 => "vbnet", + _ => throw new InvalidOperationException() + }; + + WriteLine(); + + var info = infos.Single(x => x.Index == index && x.Lang == lang); + + WriteLine(info.LangPath); + WriteLine(new string('-', 50)); + + // print solutions + printSlns(info); + + // mismatched solution name/location? (expected x) + var expectedSlnName = Combine(info.LangPath, $"{info.GameName}.sln"); + if (!info.Slns.Contains(expectedSlnName)) { + WriteLine($"Expected name/path: {expectedSlnName.RelativePath(info.LangPath)}"); + } + + // has executable project? + if (info.Projs.All(proj => getValue(proj, "OutputType") != "Exe")) { + WriteLine("No executable project"); + } + + WriteLine(); + + // print projects + printProjs(info); + + // mimsatched project name/location? (expected x) + var expectedProjName = Combine(info.LangPath, $"{info.GameName}.{info.ProjExt}"); + if (info.Projs.Length < 2 && !info.Projs.Contains(expectedProjName)) { + WriteLine($"Expected name/path: {expectedProjName.RelativePath(info.LangPath)}"); + } + + WriteLine(); + + // verify project properties + printProjectWarnings(info); + + WriteLine("Code files:"); + + // list code files + foreach (var codeFile in info.CodeFiles) { + WriteLine(codeFile.RelativePath(info.LangPath)); + } + + // try build +} From b6373c2525e43ca448e33c4de48872e554a43d40 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 03:13:27 +0200 Subject: [PATCH 198/337] Rename AceyDucey; fix folder structure --- 00_Utilities/DotnetUtils/DotnetUtils/Program.cs | 1 - 01_Acey_Ducey/vbnet/{AceyDucy.sln => AceyDucey.sln} | 10 +++++----- .../{AceyDucy/AceyDucy.vbproj => AceyDucey.vbproj} | 3 ++- 01_Acey_Ducey/vbnet/{AceyDucy => }/Program.vb | 0 4 files changed, 7 insertions(+), 7 deletions(-) rename 01_Acey_Ducey/vbnet/{AceyDucy.sln => AceyDucey.sln} (64%) rename 01_Acey_Ducey/vbnet/{AceyDucy/AceyDucy.vbproj => AceyDucey.vbproj} (66%) rename 01_Acey_Ducey/vbnet/{AceyDucy => }/Program.vb (100%) diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index ab59bd9e..7f350f55 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -221,7 +221,6 @@ void checkProjects() { } } -// TODO make this run on a single project void printProjectWarnings(PortInfo info) { foreach (var proj in info.Projs) { var warnings = new List(); diff --git a/01_Acey_Ducey/vbnet/AceyDucy.sln b/01_Acey_Ducey/vbnet/AceyDucey.sln similarity index 64% rename from 01_Acey_Ducey/vbnet/AceyDucy.sln rename to 01_Acey_Ducey/vbnet/AceyDucey.sln index 881d7c9c..1c5cafb6 100644 --- a/01_Acey_Ducey/vbnet/AceyDucy.sln +++ b/01_Acey_Ducey/vbnet/AceyDucey.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "AceyDucy", "AceyDucy\AceyDucy.vbproj", "{37496710-B458-4502-ADCB-4C57203866F9}" +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "AceyDucey", "AceyDucey.vbproj", "{54C05475-238D-4A82-A67B-B6C1BF2CA337}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {37496710-B458-4502-ADCB-4C57203866F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {37496710-B458-4502-ADCB-4C57203866F9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {37496710-B458-4502-ADCB-4C57203866F9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {37496710-B458-4502-ADCB-4C57203866F9}.Release|Any CPU.Build.0 = Release|Any CPU + {54C05475-238D-4A82-A67B-B6C1BF2CA337}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54C05475-238D-4A82-A67B-B6C1BF2CA337}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54C05475-238D-4A82-A67B-B6C1BF2CA337}.Release|Any CPU.ActiveCfg = Release|Any CPU + {54C05475-238D-4A82-A67B-B6C1BF2CA337}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/01_Acey_Ducey/vbnet/AceyDucy/AceyDucy.vbproj b/01_Acey_Ducey/vbnet/AceyDucey.vbproj similarity index 66% rename from 01_Acey_Ducey/vbnet/AceyDucy/AceyDucy.vbproj rename to 01_Acey_Ducey/vbnet/AceyDucey.vbproj index 98a07001..88e8cd5e 100644 --- a/01_Acey_Ducey/vbnet/AceyDucy/AceyDucy.vbproj +++ b/01_Acey_Ducey/vbnet/AceyDucey.vbproj @@ -2,8 +2,9 @@ Exe - AceyDucy + AceyDucey net6.0 + 16.9 diff --git a/01_Acey_Ducey/vbnet/AceyDucy/Program.vb b/01_Acey_Ducey/vbnet/Program.vb similarity index 100% rename from 01_Acey_Ducey/vbnet/AceyDucy/Program.vb rename to 01_Acey_Ducey/vbnet/Program.vb From 6172d6f6485c252153f2d4e61ed478dba38ae7eb Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 08:16:42 +0200 Subject: [PATCH 199/337] Simplify Chemist (C#) folder structure --- 24_Chemist/csharp/{Chemist/Chemist => }/Chemist.csproj | 0 24_Chemist/csharp/{Chemist => }/Chemist.sln | 10 +++++----- 24_Chemist/csharp/{Chemist/Chemist => }/Program.cs | 0 3 files changed, 5 insertions(+), 5 deletions(-) rename 24_Chemist/csharp/{Chemist/Chemist => }/Chemist.csproj (100%) rename 24_Chemist/csharp/{Chemist => }/Chemist.sln (64%) rename 24_Chemist/csharp/{Chemist/Chemist => }/Program.cs (100%) diff --git a/24_Chemist/csharp/Chemist/Chemist/Chemist.csproj b/24_Chemist/csharp/Chemist.csproj similarity index 100% rename from 24_Chemist/csharp/Chemist/Chemist/Chemist.csproj rename to 24_Chemist/csharp/Chemist.csproj diff --git a/24_Chemist/csharp/Chemist/Chemist.sln b/24_Chemist/csharp/Chemist.sln similarity index 64% rename from 24_Chemist/csharp/Chemist/Chemist.sln rename to 24_Chemist/csharp/Chemist.sln index 6dc7bfa2..bac78435 100644 --- a/24_Chemist/csharp/Chemist/Chemist.sln +++ b/24_Chemist/csharp/Chemist.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31005.135 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chemist", "Chemist\Chemist.csproj", "{8CC70F80-F2D6-47B6-8976-079352AC6C85}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Chemist", "Chemist.csproj", "{C16545E8-E078-4C69-B7CA-9D821C944252}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8CC70F80-F2D6-47B6-8976-079352AC6C85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8CC70F80-F2D6-47B6-8976-079352AC6C85}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8CC70F80-F2D6-47B6-8976-079352AC6C85}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8CC70F80-F2D6-47B6-8976-079352AC6C85}.Release|Any CPU.Build.0 = Release|Any CPU + {C16545E8-E078-4C69-B7CA-9D821C944252}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C16545E8-E078-4C69-B7CA-9D821C944252}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C16545E8-E078-4C69-B7CA-9D821C944252}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C16545E8-E078-4C69-B7CA-9D821C944252}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/24_Chemist/csharp/Chemist/Chemist/Program.cs b/24_Chemist/csharp/Program.cs similarity index 100% rename from 24_Chemist/csharp/Chemist/Chemist/Program.cs rename to 24_Chemist/csharp/Program.cs From d4fac2463e8a43a6af30016ba3ae177831328e20 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 08:19:24 +0200 Subject: [PATCH 200/337] Simplify CivilWar (C#) folder structure --- 27_Civil_War/csharp/{CivilWar/CivilWar => }/Army.cs | 0 27_Civil_War/csharp/{CivilWar/CivilWar => }/Battle.cs | 0 .../csharp/{CivilWar/CivilWar => }/CivilWar.csproj | 0 27_Civil_War/csharp/{CivilWar => }/CivilWar.sln | 10 +++++----- .../csharp/{CivilWar/CivilWar => }/ConsoleUtils.cs | 0 .../csharp/{CivilWar/CivilWar => }/GameOptions.cs | 0 27_Civil_War/csharp/{CivilWar/CivilWar => }/Program.cs | 0 7 files changed, 5 insertions(+), 5 deletions(-) rename 27_Civil_War/csharp/{CivilWar/CivilWar => }/Army.cs (100%) rename 27_Civil_War/csharp/{CivilWar/CivilWar => }/Battle.cs (100%) rename 27_Civil_War/csharp/{CivilWar/CivilWar => }/CivilWar.csproj (100%) rename 27_Civil_War/csharp/{CivilWar => }/CivilWar.sln (64%) rename 27_Civil_War/csharp/{CivilWar/CivilWar => }/ConsoleUtils.cs (100%) rename 27_Civil_War/csharp/{CivilWar/CivilWar => }/GameOptions.cs (100%) rename 27_Civil_War/csharp/{CivilWar/CivilWar => }/Program.cs (100%) diff --git a/27_Civil_War/csharp/CivilWar/CivilWar/Army.cs b/27_Civil_War/csharp/Army.cs similarity index 100% rename from 27_Civil_War/csharp/CivilWar/CivilWar/Army.cs rename to 27_Civil_War/csharp/Army.cs diff --git a/27_Civil_War/csharp/CivilWar/CivilWar/Battle.cs b/27_Civil_War/csharp/Battle.cs similarity index 100% rename from 27_Civil_War/csharp/CivilWar/CivilWar/Battle.cs rename to 27_Civil_War/csharp/Battle.cs diff --git a/27_Civil_War/csharp/CivilWar/CivilWar/CivilWar.csproj b/27_Civil_War/csharp/CivilWar.csproj similarity index 100% rename from 27_Civil_War/csharp/CivilWar/CivilWar/CivilWar.csproj rename to 27_Civil_War/csharp/CivilWar.csproj diff --git a/27_Civil_War/csharp/CivilWar/CivilWar.sln b/27_Civil_War/csharp/CivilWar.sln similarity index 64% rename from 27_Civil_War/csharp/CivilWar/CivilWar.sln rename to 27_Civil_War/csharp/CivilWar.sln index 17da385e..d013f7ed 100644 --- a/27_Civil_War/csharp/CivilWar/CivilWar.sln +++ b/27_Civil_War/csharp/CivilWar.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31005.135 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CivilWar", "CivilWar\CivilWar.csproj", "{09C22BBE-8480-4B8C-9A07-E2DAA24B692B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CivilWar", "CivilWar.csproj", "{4EE5EFE7-2D60-464A-9F8D-4BBD2A14AAC7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {09C22BBE-8480-4B8C-9A07-E2DAA24B692B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {09C22BBE-8480-4B8C-9A07-E2DAA24B692B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {09C22BBE-8480-4B8C-9A07-E2DAA24B692B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {09C22BBE-8480-4B8C-9A07-E2DAA24B692B}.Release|Any CPU.Build.0 = Release|Any CPU + {4EE5EFE7-2D60-464A-9F8D-4BBD2A14AAC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EE5EFE7-2D60-464A-9F8D-4BBD2A14AAC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EE5EFE7-2D60-464A-9F8D-4BBD2A14AAC7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EE5EFE7-2D60-464A-9F8D-4BBD2A14AAC7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/27_Civil_War/csharp/CivilWar/CivilWar/ConsoleUtils.cs b/27_Civil_War/csharp/ConsoleUtils.cs similarity index 100% rename from 27_Civil_War/csharp/CivilWar/CivilWar/ConsoleUtils.cs rename to 27_Civil_War/csharp/ConsoleUtils.cs diff --git a/27_Civil_War/csharp/CivilWar/CivilWar/GameOptions.cs b/27_Civil_War/csharp/GameOptions.cs similarity index 100% rename from 27_Civil_War/csharp/CivilWar/CivilWar/GameOptions.cs rename to 27_Civil_War/csharp/GameOptions.cs diff --git a/27_Civil_War/csharp/CivilWar/CivilWar/Program.cs b/27_Civil_War/csharp/Program.cs similarity index 100% rename from 27_Civil_War/csharp/CivilWar/CivilWar/Program.cs rename to 27_Civil_War/csharp/Program.cs From 7e480f946194e0ee69cfbf9d63e07542b2dc7e0a Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 08:24:39 +0200 Subject: [PATCH 201/337] Simplify Craps (C#) folder structure --- 29_Craps/csharp/{Craps => }/.gitignore | 0 29_Craps/csharp/{Craps => }/Craps.sln | 0 29_Craps/csharp/Craps/{Craps => }/Craps.csproj | 0 29_Craps/csharp/Craps/{Craps => }/CrapsGame.cs | 0 29_Craps/csharp/Craps/{Craps => }/Dice.cs | 0 29_Craps/csharp/Craps/{Craps => }/Program.cs | 0 29_Craps/csharp/Craps/{Craps => }/UserInterface.cs | 0 29_Craps/csharp/{Craps => }/CrapsTester/CrapsTester.csproj | 0 29_Craps/csharp/{Craps => }/CrapsTester/CrapsTests.cs | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename 29_Craps/csharp/{Craps => }/.gitignore (100%) rename 29_Craps/csharp/{Craps => }/Craps.sln (100%) rename 29_Craps/csharp/Craps/{Craps => }/Craps.csproj (100%) rename 29_Craps/csharp/Craps/{Craps => }/CrapsGame.cs (100%) rename 29_Craps/csharp/Craps/{Craps => }/Dice.cs (100%) rename 29_Craps/csharp/Craps/{Craps => }/Program.cs (100%) rename 29_Craps/csharp/Craps/{Craps => }/UserInterface.cs (100%) rename 29_Craps/csharp/{Craps => }/CrapsTester/CrapsTester.csproj (100%) rename 29_Craps/csharp/{Craps => }/CrapsTester/CrapsTests.cs (100%) diff --git a/29_Craps/csharp/Craps/.gitignore b/29_Craps/csharp/.gitignore similarity index 100% rename from 29_Craps/csharp/Craps/.gitignore rename to 29_Craps/csharp/.gitignore diff --git a/29_Craps/csharp/Craps/Craps.sln b/29_Craps/csharp/Craps.sln similarity index 100% rename from 29_Craps/csharp/Craps/Craps.sln rename to 29_Craps/csharp/Craps.sln diff --git a/29_Craps/csharp/Craps/Craps/Craps.csproj b/29_Craps/csharp/Craps/Craps.csproj similarity index 100% rename from 29_Craps/csharp/Craps/Craps/Craps.csproj rename to 29_Craps/csharp/Craps/Craps.csproj diff --git a/29_Craps/csharp/Craps/Craps/CrapsGame.cs b/29_Craps/csharp/Craps/CrapsGame.cs similarity index 100% rename from 29_Craps/csharp/Craps/Craps/CrapsGame.cs rename to 29_Craps/csharp/Craps/CrapsGame.cs diff --git a/29_Craps/csharp/Craps/Craps/Dice.cs b/29_Craps/csharp/Craps/Dice.cs similarity index 100% rename from 29_Craps/csharp/Craps/Craps/Dice.cs rename to 29_Craps/csharp/Craps/Dice.cs diff --git a/29_Craps/csharp/Craps/Craps/Program.cs b/29_Craps/csharp/Craps/Program.cs similarity index 100% rename from 29_Craps/csharp/Craps/Craps/Program.cs rename to 29_Craps/csharp/Craps/Program.cs diff --git a/29_Craps/csharp/Craps/Craps/UserInterface.cs b/29_Craps/csharp/Craps/UserInterface.cs similarity index 100% rename from 29_Craps/csharp/Craps/Craps/UserInterface.cs rename to 29_Craps/csharp/Craps/UserInterface.cs diff --git a/29_Craps/csharp/Craps/CrapsTester/CrapsTester.csproj b/29_Craps/csharp/CrapsTester/CrapsTester.csproj similarity index 100% rename from 29_Craps/csharp/Craps/CrapsTester/CrapsTester.csproj rename to 29_Craps/csharp/CrapsTester/CrapsTester.csproj diff --git a/29_Craps/csharp/Craps/CrapsTester/CrapsTests.cs b/29_Craps/csharp/CrapsTester/CrapsTests.cs similarity index 100% rename from 29_Craps/csharp/Craps/CrapsTester/CrapsTests.cs rename to 29_Craps/csharp/CrapsTester/CrapsTests.cs From 516c8dbc34347c88580ab3a34f8178a7d3ebf036 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 08:28:25 +0200 Subject: [PATCH 202/337] Simplify Hangman folder structure --- 44_Hangman/csharp/{Hangman => }/Graphic.cs | 0 44_Hangman/csharp/{Hangman => }/Hangman.csproj | 0 44_Hangman/csharp/{Hangman => }/Hangman.sln | 0 44_Hangman/csharp/{Hangman => }/Program.cs | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename 44_Hangman/csharp/{Hangman => }/Graphic.cs (100%) rename 44_Hangman/csharp/{Hangman => }/Hangman.csproj (100%) rename 44_Hangman/csharp/{Hangman => }/Hangman.sln (100%) rename 44_Hangman/csharp/{Hangman => }/Program.cs (100%) diff --git a/44_Hangman/csharp/Hangman/Graphic.cs b/44_Hangman/csharp/Graphic.cs similarity index 100% rename from 44_Hangman/csharp/Hangman/Graphic.cs rename to 44_Hangman/csharp/Graphic.cs diff --git a/44_Hangman/csharp/Hangman/Hangman.csproj b/44_Hangman/csharp/Hangman.csproj similarity index 100% rename from 44_Hangman/csharp/Hangman/Hangman.csproj rename to 44_Hangman/csharp/Hangman.csproj diff --git a/44_Hangman/csharp/Hangman/Hangman.sln b/44_Hangman/csharp/Hangman.sln similarity index 100% rename from 44_Hangman/csharp/Hangman/Hangman.sln rename to 44_Hangman/csharp/Hangman.sln diff --git a/44_Hangman/csharp/Hangman/Program.cs b/44_Hangman/csharp/Program.cs similarity index 100% rename from 44_Hangman/csharp/Hangman/Program.cs rename to 44_Hangman/csharp/Program.cs From 83c053fbd1024bfc0488da13471acf0c89d13d5a Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 08:31:36 +0200 Subject: [PATCH 203/337] Simplify Pizza (C#) folder structure --- 69_Pizza/csharp/{Pizza => }/CustomerMap.cs | 0 69_Pizza/csharp/{Pizza => }/Pizza.csproj | 0 69_Pizza/csharp/{Pizza => }/Pizza.sln | 0 69_Pizza/csharp/{Pizza => }/PizzaGame.cs | 0 69_Pizza/csharp/{Pizza => }/Program.cs | 0 69_Pizza/csharp/{Pizza => }/StringBuilderExtensions.cs | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename 69_Pizza/csharp/{Pizza => }/CustomerMap.cs (100%) rename 69_Pizza/csharp/{Pizza => }/Pizza.csproj (100%) rename 69_Pizza/csharp/{Pizza => }/Pizza.sln (100%) rename 69_Pizza/csharp/{Pizza => }/PizzaGame.cs (100%) rename 69_Pizza/csharp/{Pizza => }/Program.cs (100%) rename 69_Pizza/csharp/{Pizza => }/StringBuilderExtensions.cs (100%) diff --git a/69_Pizza/csharp/Pizza/CustomerMap.cs b/69_Pizza/csharp/CustomerMap.cs similarity index 100% rename from 69_Pizza/csharp/Pizza/CustomerMap.cs rename to 69_Pizza/csharp/CustomerMap.cs diff --git a/69_Pizza/csharp/Pizza/Pizza.csproj b/69_Pizza/csharp/Pizza.csproj similarity index 100% rename from 69_Pizza/csharp/Pizza/Pizza.csproj rename to 69_Pizza/csharp/Pizza.csproj diff --git a/69_Pizza/csharp/Pizza/Pizza.sln b/69_Pizza/csharp/Pizza.sln similarity index 100% rename from 69_Pizza/csharp/Pizza/Pizza.sln rename to 69_Pizza/csharp/Pizza.sln diff --git a/69_Pizza/csharp/Pizza/PizzaGame.cs b/69_Pizza/csharp/PizzaGame.cs similarity index 100% rename from 69_Pizza/csharp/Pizza/PizzaGame.cs rename to 69_Pizza/csharp/PizzaGame.cs diff --git a/69_Pizza/csharp/Pizza/Program.cs b/69_Pizza/csharp/Program.cs similarity index 100% rename from 69_Pizza/csharp/Pizza/Program.cs rename to 69_Pizza/csharp/Program.cs diff --git a/69_Pizza/csharp/Pizza/StringBuilderExtensions.cs b/69_Pizza/csharp/StringBuilderExtensions.cs similarity index 100% rename from 69_Pizza/csharp/Pizza/StringBuilderExtensions.cs rename to 69_Pizza/csharp/StringBuilderExtensions.cs From 2028e9576456e4e6ae8bfb13b6be4a8ae1bc83f2 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 08:34:09 +0200 Subject: [PATCH 204/337] Simplify Reverse (C#) folder structure --- .../Reverse.Tests/Generators/PositiveIntegerGenerator.cs | 0 .../csharp/{Reverse => }/Reverse.Tests/Reverse.Tests.csproj | 0 73_Reverse/csharp/{Reverse => }/Reverse.Tests/ReverserTests.cs | 0 73_Reverse/csharp/{Reverse => }/Reverse.Tests/TestReverser.cs | 0 73_Reverse/csharp/{Reverse => }/Reverse.sln | 0 73_Reverse/csharp/Reverse/{Reverse => }/Program.cs | 0 73_Reverse/csharp/Reverse/{Reverse => }/Reverse.csproj | 0 73_Reverse/csharp/Reverse/{Reverse => }/Reverser.cs | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename 73_Reverse/csharp/{Reverse => }/Reverse.Tests/Generators/PositiveIntegerGenerator.cs (100%) rename 73_Reverse/csharp/{Reverse => }/Reverse.Tests/Reverse.Tests.csproj (100%) rename 73_Reverse/csharp/{Reverse => }/Reverse.Tests/ReverserTests.cs (100%) rename 73_Reverse/csharp/{Reverse => }/Reverse.Tests/TestReverser.cs (100%) rename 73_Reverse/csharp/{Reverse => }/Reverse.sln (100%) rename 73_Reverse/csharp/Reverse/{Reverse => }/Program.cs (100%) rename 73_Reverse/csharp/Reverse/{Reverse => }/Reverse.csproj (100%) rename 73_Reverse/csharp/Reverse/{Reverse => }/Reverser.cs (100%) diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/Generators/PositiveIntegerGenerator.cs b/73_Reverse/csharp/Reverse.Tests/Generators/PositiveIntegerGenerator.cs similarity index 100% rename from 73_Reverse/csharp/Reverse/Reverse.Tests/Generators/PositiveIntegerGenerator.cs rename to 73_Reverse/csharp/Reverse.Tests/Generators/PositiveIntegerGenerator.cs diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj b/73_Reverse/csharp/Reverse.Tests/Reverse.Tests.csproj similarity index 100% rename from 73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj rename to 73_Reverse/csharp/Reverse.Tests/Reverse.Tests.csproj diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs b/73_Reverse/csharp/Reverse.Tests/ReverserTests.cs similarity index 100% rename from 73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs rename to 73_Reverse/csharp/Reverse.Tests/ReverserTests.cs diff --git a/73_Reverse/csharp/Reverse/Reverse.Tests/TestReverser.cs b/73_Reverse/csharp/Reverse.Tests/TestReverser.cs similarity index 100% rename from 73_Reverse/csharp/Reverse/Reverse.Tests/TestReverser.cs rename to 73_Reverse/csharp/Reverse.Tests/TestReverser.cs diff --git a/73_Reverse/csharp/Reverse/Reverse.sln b/73_Reverse/csharp/Reverse.sln similarity index 100% rename from 73_Reverse/csharp/Reverse/Reverse.sln rename to 73_Reverse/csharp/Reverse.sln diff --git a/73_Reverse/csharp/Reverse/Reverse/Program.cs b/73_Reverse/csharp/Reverse/Program.cs similarity index 100% rename from 73_Reverse/csharp/Reverse/Reverse/Program.cs rename to 73_Reverse/csharp/Reverse/Program.cs diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverse.csproj b/73_Reverse/csharp/Reverse/Reverse.csproj similarity index 100% rename from 73_Reverse/csharp/Reverse/Reverse/Reverse.csproj rename to 73_Reverse/csharp/Reverse/Reverse.csproj diff --git a/73_Reverse/csharp/Reverse/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverser.cs similarity index 100% rename from 73_Reverse/csharp/Reverse/Reverse/Reverser.cs rename to 73_Reverse/csharp/Reverse/Reverser.cs From d901e48f248e01882f53c1bb97ef50f25aec9864 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 08:35:11 +0200 Subject: [PATCH 205/337] Simplify RussianRoulette (C#) folder structure --- 76_Russian_Roulette/csharp/{RussianRoulette => }/Program.cs | 0 .../csharp/{RussianRoulette => }/RussianRoulette.csproj | 0 .../csharp/{RussianRoulette => }/RussianRoulette.sln | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename 76_Russian_Roulette/csharp/{RussianRoulette => }/Program.cs (100%) rename 76_Russian_Roulette/csharp/{RussianRoulette => }/RussianRoulette.csproj (100%) rename 76_Russian_Roulette/csharp/{RussianRoulette => }/RussianRoulette.sln (100%) diff --git a/76_Russian_Roulette/csharp/RussianRoulette/Program.cs b/76_Russian_Roulette/csharp/Program.cs similarity index 100% rename from 76_Russian_Roulette/csharp/RussianRoulette/Program.cs rename to 76_Russian_Roulette/csharp/Program.cs diff --git a/76_Russian_Roulette/csharp/RussianRoulette/RussianRoulette.csproj b/76_Russian_Roulette/csharp/RussianRoulette.csproj similarity index 100% rename from 76_Russian_Roulette/csharp/RussianRoulette/RussianRoulette.csproj rename to 76_Russian_Roulette/csharp/RussianRoulette.csproj diff --git a/76_Russian_Roulette/csharp/RussianRoulette/RussianRoulette.sln b/76_Russian_Roulette/csharp/RussianRoulette.sln similarity index 100% rename from 76_Russian_Roulette/csharp/RussianRoulette/RussianRoulette.sln rename to 76_Russian_Roulette/csharp/RussianRoulette.sln From 79c04373f4d94939757ec2a98be3f1f84fa0b32c Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 08:37:17 +0200 Subject: [PATCH 206/337] Simplfy SineWave (C#) folder structure --- 78_Sine_Wave/csharp/{SineWave/SineWave => }/Program.cs | 0 .../csharp/{SineWave/SineWave => }/SineWave.csproj | 0 78_Sine_Wave/csharp/{SineWave => }/SineWave.sln | 10 +++++----- 3 files changed, 5 insertions(+), 5 deletions(-) rename 78_Sine_Wave/csharp/{SineWave/SineWave => }/Program.cs (100%) rename 78_Sine_Wave/csharp/{SineWave/SineWave => }/SineWave.csproj (100%) rename 78_Sine_Wave/csharp/{SineWave => }/SineWave.sln (64%) diff --git a/78_Sine_Wave/csharp/SineWave/SineWave/Program.cs b/78_Sine_Wave/csharp/Program.cs similarity index 100% rename from 78_Sine_Wave/csharp/SineWave/SineWave/Program.cs rename to 78_Sine_Wave/csharp/Program.cs diff --git a/78_Sine_Wave/csharp/SineWave/SineWave/SineWave.csproj b/78_Sine_Wave/csharp/SineWave.csproj similarity index 100% rename from 78_Sine_Wave/csharp/SineWave/SineWave/SineWave.csproj rename to 78_Sine_Wave/csharp/SineWave.csproj diff --git a/78_Sine_Wave/csharp/SineWave/SineWave.sln b/78_Sine_Wave/csharp/SineWave.sln similarity index 64% rename from 78_Sine_Wave/csharp/SineWave/SineWave.sln rename to 78_Sine_Wave/csharp/SineWave.sln index f32a06cd..adcc993f 100644 --- a/78_Sine_Wave/csharp/SineWave/SineWave.sln +++ b/78_Sine_Wave/csharp/SineWave.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31005.135 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SineWave", "SineWave\SineWave.csproj", "{B316DD7F-5755-4216-AFDC-D83720F8ACA2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SineWave", "SineWave.csproj", "{730FA2CC-5AA5-4BE2-8DF9-8E55FDC8FB30}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Release|Any CPU.Build.0 = Release|Any CPU + {730FA2CC-5AA5-4BE2-8DF9-8E55FDC8FB30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {730FA2CC-5AA5-4BE2-8DF9-8E55FDC8FB30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {730FA2CC-5AA5-4BE2-8DF9-8E55FDC8FB30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {730FA2CC-5AA5-4BE2-8DF9-8E55FDC8FB30}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 9deb45db960f002aa6021bd6d19dc97b69bbc40f Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 08:44:09 +0200 Subject: [PATCH 207/337] Simplify Train (C#) folder structure --- 91_Train/csharp/{Train => }/Train.sln | 12 ++++++------ 91_Train/csharp/Train/{Train => }/TrainGame.cs | 0 91_Train/csharp/Train/{Train => }/TrainGame.csproj | 0 .../TrainTests/{TrainTests => }/TrainGameTests.cs | 0 .../TrainTests/{TrainTests => }/TrainTests.csproj | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) rename 91_Train/csharp/{Train => }/Train.sln (70%) rename 91_Train/csharp/Train/{Train => }/TrainGame.cs (100%) rename 91_Train/csharp/Train/{Train => }/TrainGame.csproj (100%) rename 91_Train/csharp/TrainTests/{TrainTests => }/TrainGameTests.cs (100%) rename 91_Train/csharp/TrainTests/{TrainTests => }/TrainTests.csproj (92%) diff --git a/91_Train/csharp/Train/Train.sln b/91_Train/csharp/Train.sln similarity index 70% rename from 91_Train/csharp/Train/Train.sln rename to 91_Train/csharp/Train.sln index 7735a737..29c49c59 100644 --- a/91_Train/csharp/Train/Train.sln +++ b/91_Train/csharp/Train.sln @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31129.286 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrainGame", "Train\TrainGame.csproj", "{42617537-4E7C-4082-A17B-7F18DFA04C35}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TrainGame", "Train\TrainGame.csproj", "{42617537-4E7C-4082-A17B-7F18DFA04C35}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrainTests", "..\TrainTests\TrainTests\TrainTests.csproj", "{7C740A47-99C6-44E1-BDEE-140086BCFE8B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TrainTests", "TrainTests\TrainTests.csproj", "{B967AA46-78F2-44F8-A30D-85D35F625991}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -17,10 +17,10 @@ Global {42617537-4E7C-4082-A17B-7F18DFA04C35}.Debug|Any CPU.Build.0 = Debug|Any CPU {42617537-4E7C-4082-A17B-7F18DFA04C35}.Release|Any CPU.ActiveCfg = Release|Any CPU {42617537-4E7C-4082-A17B-7F18DFA04C35}.Release|Any CPU.Build.0 = Release|Any CPU - {7C740A47-99C6-44E1-BDEE-140086BCFE8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7C740A47-99C6-44E1-BDEE-140086BCFE8B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7C740A47-99C6-44E1-BDEE-140086BCFE8B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7C740A47-99C6-44E1-BDEE-140086BCFE8B}.Release|Any CPU.Build.0 = Release|Any CPU + {B967AA46-78F2-44F8-A30D-85D35F625991}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B967AA46-78F2-44F8-A30D-85D35F625991}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B967AA46-78F2-44F8-A30D-85D35F625991}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B967AA46-78F2-44F8-A30D-85D35F625991}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/91_Train/csharp/Train/Train/TrainGame.cs b/91_Train/csharp/Train/TrainGame.cs similarity index 100% rename from 91_Train/csharp/Train/Train/TrainGame.cs rename to 91_Train/csharp/Train/TrainGame.cs diff --git a/91_Train/csharp/Train/Train/TrainGame.csproj b/91_Train/csharp/Train/TrainGame.csproj similarity index 100% rename from 91_Train/csharp/Train/Train/TrainGame.csproj rename to 91_Train/csharp/Train/TrainGame.csproj diff --git a/91_Train/csharp/TrainTests/TrainTests/TrainGameTests.cs b/91_Train/csharp/TrainTests/TrainGameTests.cs similarity index 100% rename from 91_Train/csharp/TrainTests/TrainTests/TrainGameTests.cs rename to 91_Train/csharp/TrainTests/TrainGameTests.cs diff --git a/91_Train/csharp/TrainTests/TrainTests/TrainTests.csproj b/91_Train/csharp/TrainTests/TrainTests.csproj similarity index 92% rename from 91_Train/csharp/TrainTests/TrainTests/TrainTests.csproj rename to 91_Train/csharp/TrainTests/TrainTests.csproj index a8de6dde..fb6ab9fb 100644 --- a/91_Train/csharp/TrainTests/TrainTests/TrainTests.csproj +++ b/91_Train/csharp/TrainTests/TrainTests.csproj @@ -20,7 +20,7 @@ - + From 59c8666c7a1fb11569249ffde6bbb6302b5ece47 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 08:48:34 +0200 Subject: [PATCH 208/337] Simplify War (C#) folder structure --- 94_War/csharp/{War => }/War.sln | 0 94_War/csharp/War/{War => }/Cards.cs | 0 94_War/csharp/War/{War => }/Program.cs | 0 94_War/csharp/War/{War => }/UserInterface.cs | 0 94_War/csharp/War/{War => }/War.csproj | 0 94_War/csharp/{War => }/WarTester/Tests.cs | 0 94_War/csharp/{War => }/WarTester/WarTester.csproj | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename 94_War/csharp/{War => }/War.sln (100%) rename 94_War/csharp/War/{War => }/Cards.cs (100%) rename 94_War/csharp/War/{War => }/Program.cs (100%) rename 94_War/csharp/War/{War => }/UserInterface.cs (100%) rename 94_War/csharp/War/{War => }/War.csproj (100%) rename 94_War/csharp/{War => }/WarTester/Tests.cs (100%) rename 94_War/csharp/{War => }/WarTester/WarTester.csproj (100%) diff --git a/94_War/csharp/War/War.sln b/94_War/csharp/War.sln similarity index 100% rename from 94_War/csharp/War/War.sln rename to 94_War/csharp/War.sln diff --git a/94_War/csharp/War/War/Cards.cs b/94_War/csharp/War/Cards.cs similarity index 100% rename from 94_War/csharp/War/War/Cards.cs rename to 94_War/csharp/War/Cards.cs diff --git a/94_War/csharp/War/War/Program.cs b/94_War/csharp/War/Program.cs similarity index 100% rename from 94_War/csharp/War/War/Program.cs rename to 94_War/csharp/War/Program.cs diff --git a/94_War/csharp/War/War/UserInterface.cs b/94_War/csharp/War/UserInterface.cs similarity index 100% rename from 94_War/csharp/War/War/UserInterface.cs rename to 94_War/csharp/War/UserInterface.cs diff --git a/94_War/csharp/War/War/War.csproj b/94_War/csharp/War/War.csproj similarity index 100% rename from 94_War/csharp/War/War/War.csproj rename to 94_War/csharp/War/War.csproj diff --git a/94_War/csharp/War/WarTester/Tests.cs b/94_War/csharp/WarTester/Tests.cs similarity index 100% rename from 94_War/csharp/War/WarTester/Tests.cs rename to 94_War/csharp/WarTester/Tests.cs diff --git a/94_War/csharp/War/WarTester/WarTester.csproj b/94_War/csharp/WarTester/WarTester.csproj similarity index 100% rename from 94_War/csharp/War/WarTester/WarTester.csproj rename to 94_War/csharp/WarTester/WarTester.csproj From ae9a0b1c5ef6c5a5e0a3104aa8899e6c2a3dab4e Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 08:59:24 +0200 Subject: [PATCH 209/337] Fix capitalization mismatch --- 00_Utilities/DotnetUtils/DotnetUtils/Program.cs | 2 +- 06_Banner/csharp/banner.sln | 10 +++++----- 06_Banner/vbnet/banner.sln | 10 +++++----- 08_Batnum/vbnet/batnum.sln | 6 +++--- 96_Word/csharp/word.sln | 6 +++--- 96_Word/vbnet/word.sln | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index 7f350f55..550250b1 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -101,7 +101,7 @@ void unexpectedSlnName() { if (!item.Slns.Any()) { continue; } var expectedSlnName = $"{item.GameName}.sln"; - if (item.Slns.Contains(Combine(item.LangPath, expectedSlnName))) { continue; } + if (item.Slns.Contains(Combine(item.LangPath, expectedSlnName), StringComparer.InvariantCultureIgnoreCase)) { continue; } counter += 1; WriteLine(item.LangPath); diff --git a/06_Banner/csharp/banner.sln b/06_Banner/csharp/banner.sln index 34f63984..9beeb9b3 100644 --- a/06_Banner/csharp/banner.sln +++ b/06_Banner/csharp/banner.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31321.278 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "banner", "banner.csproj", "{9E24FA30-F2AC-4BF3-ADFB-92D3F796561C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Banner", "Banner.csproj", "{7E8612AB-AFFD-4F72-855F-8172786F28FD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9E24FA30-F2AC-4BF3-ADFB-92D3F796561C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9E24FA30-F2AC-4BF3-ADFB-92D3F796561C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9E24FA30-F2AC-4BF3-ADFB-92D3F796561C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9E24FA30-F2AC-4BF3-ADFB-92D3F796561C}.Release|Any CPU.Build.0 = Release|Any CPU + {7E8612AB-AFFD-4F72-855F-8172786F28FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7E8612AB-AFFD-4F72-855F-8172786F28FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7E8612AB-AFFD-4F72-855F-8172786F28FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7E8612AB-AFFD-4F72-855F-8172786F28FD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/06_Banner/vbnet/banner.sln b/06_Banner/vbnet/banner.sln index 5fdc8737..8a782a2f 100644 --- a/06_Banner/vbnet/banner.sln +++ b/06_Banner/vbnet/banner.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31321.278 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "banner", "banner.vbproj", "{1738D297-A04C-4E6E-8219-D9E72982C39D}" +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Banner", "Banner.vbproj", "{091ABE13-3E70-4848-B836-592F725915A3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1738D297-A04C-4E6E-8219-D9E72982C39D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1738D297-A04C-4E6E-8219-D9E72982C39D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1738D297-A04C-4E6E-8219-D9E72982C39D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1738D297-A04C-4E6E-8219-D9E72982C39D}.Release|Any CPU.Build.0 = Release|Any CPU + {091ABE13-3E70-4848-B836-592F725915A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {091ABE13-3E70-4848-B836-592F725915A3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {091ABE13-3E70-4848-B836-592F725915A3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {091ABE13-3E70-4848-B836-592F725915A3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/08_Batnum/vbnet/batnum.sln b/08_Batnum/vbnet/batnum.sln index b3f63f59..ca05e41b 100644 --- a/08_Batnum/vbnet/batnum.sln +++ b/08_Batnum/vbnet/batnum.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31321.278 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "batnum", "batnum.vbproj", "{D577E429-F84D-4E84-86E7-E6526CFD5FD9}" +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Batnum", "Batnum.vbproj", "{D577E429-F84D-4E84-86E7-E6526CFD5FD9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/96_Word/csharp/word.sln b/96_Word/csharp/word.sln index 59bdec97..77360e81 100644 --- a/96_Word/csharp/word.sln +++ b/96_Word/csharp/word.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31321.278 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "word", "word.csproj", "{E2CF183B-EBC3-497C-8D34-32EBEE4E2B73}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Word", "Word.csproj", "{E2CF183B-EBC3-497C-8D34-32EBEE4E2B73}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/96_Word/vbnet/word.sln b/96_Word/vbnet/word.sln index 16584104..73674ee4 100644 --- a/96_Word/vbnet/word.sln +++ b/96_Word/vbnet/word.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31321.278 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "word", "word.vbproj", "{F0D2422C-983F-4DF3-9D17-D2480839DF07}" +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Word", "Word.vbproj", "{F0D2422C-983F-4DF3-9D17-D2480839DF07}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 827f2b0cb3cf75a26bbb76f49af1c491e7b670d9 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 09:07:59 +0200 Subject: [PATCH 210/337] Simplify Bullfight (C#) folder structure --- 17_Bullfight/csharp/{src => }/Action.cs | 0 17_Bullfight/csharp/{src => }/ActionResult.cs | 0 17_Bullfight/csharp/{src => }/BullFight.cs | 0 17_Bullfight/csharp/{Game.csproj => Bullfight.csproj} | 0 17_Bullfight/csharp/Bullfight.sln | 10 +++++----- 17_Bullfight/csharp/{src => }/Controller.cs | 0 17_Bullfight/csharp/{src => }/Events/BullCharging.cs | 0 17_Bullfight/csharp/{src => }/Events/Event.cs | 0 17_Bullfight/csharp/{src => }/Events/MatchCompleted.cs | 0 17_Bullfight/csharp/{src => }/Events/MatchStarted.cs | 0 17_Bullfight/csharp/{src => }/Events/PlayerGored.cs | 0 17_Bullfight/csharp/{src => }/Events/PlayerSurvived.cs | 0 17_Bullfight/csharp/{src => }/Mediator.cs | 0 17_Bullfight/csharp/{src => }/Program.cs | 0 17_Bullfight/csharp/{src => }/Quality.cs | 0 17_Bullfight/csharp/{src => }/Reward.cs | 0 17_Bullfight/csharp/{src => }/RiskLevel.cs | 0 17_Bullfight/csharp/{src => }/View.cs | 0 18 files changed, 5 insertions(+), 5 deletions(-) rename 17_Bullfight/csharp/{src => }/Action.cs (100%) rename 17_Bullfight/csharp/{src => }/ActionResult.cs (100%) rename 17_Bullfight/csharp/{src => }/BullFight.cs (100%) rename 17_Bullfight/csharp/{Game.csproj => Bullfight.csproj} (100%) rename 17_Bullfight/csharp/{src => }/Controller.cs (100%) rename 17_Bullfight/csharp/{src => }/Events/BullCharging.cs (100%) rename 17_Bullfight/csharp/{src => }/Events/Event.cs (100%) rename 17_Bullfight/csharp/{src => }/Events/MatchCompleted.cs (100%) rename 17_Bullfight/csharp/{src => }/Events/MatchStarted.cs (100%) rename 17_Bullfight/csharp/{src => }/Events/PlayerGored.cs (100%) rename 17_Bullfight/csharp/{src => }/Events/PlayerSurvived.cs (100%) rename 17_Bullfight/csharp/{src => }/Mediator.cs (100%) rename 17_Bullfight/csharp/{src => }/Program.cs (100%) rename 17_Bullfight/csharp/{src => }/Quality.cs (100%) rename 17_Bullfight/csharp/{src => }/Reward.cs (100%) rename 17_Bullfight/csharp/{src => }/RiskLevel.cs (100%) rename 17_Bullfight/csharp/{src => }/View.cs (100%) diff --git a/17_Bullfight/csharp/src/Action.cs b/17_Bullfight/csharp/Action.cs similarity index 100% rename from 17_Bullfight/csharp/src/Action.cs rename to 17_Bullfight/csharp/Action.cs diff --git a/17_Bullfight/csharp/src/ActionResult.cs b/17_Bullfight/csharp/ActionResult.cs similarity index 100% rename from 17_Bullfight/csharp/src/ActionResult.cs rename to 17_Bullfight/csharp/ActionResult.cs diff --git a/17_Bullfight/csharp/src/BullFight.cs b/17_Bullfight/csharp/BullFight.cs similarity index 100% rename from 17_Bullfight/csharp/src/BullFight.cs rename to 17_Bullfight/csharp/BullFight.cs diff --git a/17_Bullfight/csharp/Game.csproj b/17_Bullfight/csharp/Bullfight.csproj similarity index 100% rename from 17_Bullfight/csharp/Game.csproj rename to 17_Bullfight/csharp/Bullfight.csproj diff --git a/17_Bullfight/csharp/Bullfight.sln b/17_Bullfight/csharp/Bullfight.sln index 29f5276f..8c819db1 100644 --- a/17_Bullfight/csharp/Bullfight.sln +++ b/17_Bullfight/csharp/Bullfight.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31321.278 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game.csproj", "{8F7C450E-5F3A-45BA-9DB9-329744214931}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bullfight", "Bullfight.csproj", "{502A672C-F7D7-4A85-973A-B5EA8761008A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8F7C450E-5F3A-45BA-9DB9-329744214931}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8F7C450E-5F3A-45BA-9DB9-329744214931}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8F7C450E-5F3A-45BA-9DB9-329744214931}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8F7C450E-5F3A-45BA-9DB9-329744214931}.Release|Any CPU.Build.0 = Release|Any CPU + {502A672C-F7D7-4A85-973A-B5EA8761008A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {502A672C-F7D7-4A85-973A-B5EA8761008A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {502A672C-F7D7-4A85-973A-B5EA8761008A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {502A672C-F7D7-4A85-973A-B5EA8761008A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/17_Bullfight/csharp/src/Controller.cs b/17_Bullfight/csharp/Controller.cs similarity index 100% rename from 17_Bullfight/csharp/src/Controller.cs rename to 17_Bullfight/csharp/Controller.cs diff --git a/17_Bullfight/csharp/src/Events/BullCharging.cs b/17_Bullfight/csharp/Events/BullCharging.cs similarity index 100% rename from 17_Bullfight/csharp/src/Events/BullCharging.cs rename to 17_Bullfight/csharp/Events/BullCharging.cs diff --git a/17_Bullfight/csharp/src/Events/Event.cs b/17_Bullfight/csharp/Events/Event.cs similarity index 100% rename from 17_Bullfight/csharp/src/Events/Event.cs rename to 17_Bullfight/csharp/Events/Event.cs diff --git a/17_Bullfight/csharp/src/Events/MatchCompleted.cs b/17_Bullfight/csharp/Events/MatchCompleted.cs similarity index 100% rename from 17_Bullfight/csharp/src/Events/MatchCompleted.cs rename to 17_Bullfight/csharp/Events/MatchCompleted.cs diff --git a/17_Bullfight/csharp/src/Events/MatchStarted.cs b/17_Bullfight/csharp/Events/MatchStarted.cs similarity index 100% rename from 17_Bullfight/csharp/src/Events/MatchStarted.cs rename to 17_Bullfight/csharp/Events/MatchStarted.cs diff --git a/17_Bullfight/csharp/src/Events/PlayerGored.cs b/17_Bullfight/csharp/Events/PlayerGored.cs similarity index 100% rename from 17_Bullfight/csharp/src/Events/PlayerGored.cs rename to 17_Bullfight/csharp/Events/PlayerGored.cs diff --git a/17_Bullfight/csharp/src/Events/PlayerSurvived.cs b/17_Bullfight/csharp/Events/PlayerSurvived.cs similarity index 100% rename from 17_Bullfight/csharp/src/Events/PlayerSurvived.cs rename to 17_Bullfight/csharp/Events/PlayerSurvived.cs diff --git a/17_Bullfight/csharp/src/Mediator.cs b/17_Bullfight/csharp/Mediator.cs similarity index 100% rename from 17_Bullfight/csharp/src/Mediator.cs rename to 17_Bullfight/csharp/Mediator.cs diff --git a/17_Bullfight/csharp/src/Program.cs b/17_Bullfight/csharp/Program.cs similarity index 100% rename from 17_Bullfight/csharp/src/Program.cs rename to 17_Bullfight/csharp/Program.cs diff --git a/17_Bullfight/csharp/src/Quality.cs b/17_Bullfight/csharp/Quality.cs similarity index 100% rename from 17_Bullfight/csharp/src/Quality.cs rename to 17_Bullfight/csharp/Quality.cs diff --git a/17_Bullfight/csharp/src/Reward.cs b/17_Bullfight/csharp/Reward.cs similarity index 100% rename from 17_Bullfight/csharp/src/Reward.cs rename to 17_Bullfight/csharp/Reward.cs diff --git a/17_Bullfight/csharp/src/RiskLevel.cs b/17_Bullfight/csharp/RiskLevel.cs similarity index 100% rename from 17_Bullfight/csharp/src/RiskLevel.cs rename to 17_Bullfight/csharp/RiskLevel.cs diff --git a/17_Bullfight/csharp/src/View.cs b/17_Bullfight/csharp/View.cs similarity index 100% rename from 17_Bullfight/csharp/src/View.cs rename to 17_Bullfight/csharp/View.cs From 66d4c9b8af3b3bd34dc1f70bb137dba5971b5c63 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 09:12:50 +0200 Subject: [PATCH 211/337] Simplify Combat (C#) folder structure --- 28_Combat/csharp/{src => }/ArmedForces.cs | 0 28_Combat/csharp/{src => }/Ceasefire.cs | 0 28_Combat/csharp/{Game.csproj => Combat.csproj} | 0 28_Combat/csharp/Combat.sln | 10 +++++----- 28_Combat/csharp/{src => }/Controller.cs | 0 28_Combat/csharp/{src => }/FinalCampaign.cs | 0 28_Combat/csharp/{src => }/InitialCampaign.cs | 0 28_Combat/csharp/{src => }/MilitaryBranch.cs | 0 28_Combat/csharp/{src => }/Program.cs | 0 28_Combat/csharp/{src => }/View.cs | 0 28_Combat/csharp/{src => }/WarResult.cs | 0 28_Combat/csharp/{src => }/WarState.cs | 0 12 files changed, 5 insertions(+), 5 deletions(-) rename 28_Combat/csharp/{src => }/ArmedForces.cs (100%) rename 28_Combat/csharp/{src => }/Ceasefire.cs (100%) rename 28_Combat/csharp/{Game.csproj => Combat.csproj} (100%) rename 28_Combat/csharp/{src => }/Controller.cs (100%) rename 28_Combat/csharp/{src => }/FinalCampaign.cs (100%) rename 28_Combat/csharp/{src => }/InitialCampaign.cs (100%) rename 28_Combat/csharp/{src => }/MilitaryBranch.cs (100%) rename 28_Combat/csharp/{src => }/Program.cs (100%) rename 28_Combat/csharp/{src => }/View.cs (100%) rename 28_Combat/csharp/{src => }/WarResult.cs (100%) rename 28_Combat/csharp/{src => }/WarState.cs (100%) diff --git a/28_Combat/csharp/src/ArmedForces.cs b/28_Combat/csharp/ArmedForces.cs similarity index 100% rename from 28_Combat/csharp/src/ArmedForces.cs rename to 28_Combat/csharp/ArmedForces.cs diff --git a/28_Combat/csharp/src/Ceasefire.cs b/28_Combat/csharp/Ceasefire.cs similarity index 100% rename from 28_Combat/csharp/src/Ceasefire.cs rename to 28_Combat/csharp/Ceasefire.cs diff --git a/28_Combat/csharp/Game.csproj b/28_Combat/csharp/Combat.csproj similarity index 100% rename from 28_Combat/csharp/Game.csproj rename to 28_Combat/csharp/Combat.csproj diff --git a/28_Combat/csharp/Combat.sln b/28_Combat/csharp/Combat.sln index 522b680e..99233316 100644 --- a/28_Combat/csharp/Combat.sln +++ b/28_Combat/csharp/Combat.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31321.278 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game.csproj", "{054A1718-1B7D-4954-81A7-EEA390713439}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Combat", "Combat.csproj", "{F7CEEC00-CF2C-436C-883B-55A20C21AB93}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {054A1718-1B7D-4954-81A7-EEA390713439}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {054A1718-1B7D-4954-81A7-EEA390713439}.Debug|Any CPU.Build.0 = Debug|Any CPU - {054A1718-1B7D-4954-81A7-EEA390713439}.Release|Any CPU.ActiveCfg = Release|Any CPU - {054A1718-1B7D-4954-81A7-EEA390713439}.Release|Any CPU.Build.0 = Release|Any CPU + {F7CEEC00-CF2C-436C-883B-55A20C21AB93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F7CEEC00-CF2C-436C-883B-55A20C21AB93}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F7CEEC00-CF2C-436C-883B-55A20C21AB93}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F7CEEC00-CF2C-436C-883B-55A20C21AB93}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/28_Combat/csharp/src/Controller.cs b/28_Combat/csharp/Controller.cs similarity index 100% rename from 28_Combat/csharp/src/Controller.cs rename to 28_Combat/csharp/Controller.cs diff --git a/28_Combat/csharp/src/FinalCampaign.cs b/28_Combat/csharp/FinalCampaign.cs similarity index 100% rename from 28_Combat/csharp/src/FinalCampaign.cs rename to 28_Combat/csharp/FinalCampaign.cs diff --git a/28_Combat/csharp/src/InitialCampaign.cs b/28_Combat/csharp/InitialCampaign.cs similarity index 100% rename from 28_Combat/csharp/src/InitialCampaign.cs rename to 28_Combat/csharp/InitialCampaign.cs diff --git a/28_Combat/csharp/src/MilitaryBranch.cs b/28_Combat/csharp/MilitaryBranch.cs similarity index 100% rename from 28_Combat/csharp/src/MilitaryBranch.cs rename to 28_Combat/csharp/MilitaryBranch.cs diff --git a/28_Combat/csharp/src/Program.cs b/28_Combat/csharp/Program.cs similarity index 100% rename from 28_Combat/csharp/src/Program.cs rename to 28_Combat/csharp/Program.cs diff --git a/28_Combat/csharp/src/View.cs b/28_Combat/csharp/View.cs similarity index 100% rename from 28_Combat/csharp/src/View.cs rename to 28_Combat/csharp/View.cs diff --git a/28_Combat/csharp/src/WarResult.cs b/28_Combat/csharp/WarResult.cs similarity index 100% rename from 28_Combat/csharp/src/WarResult.cs rename to 28_Combat/csharp/WarResult.cs diff --git a/28_Combat/csharp/src/WarState.cs b/28_Combat/csharp/WarState.cs similarity index 100% rename from 28_Combat/csharp/src/WarState.cs rename to 28_Combat/csharp/WarState.cs From cea4a9cdd09ad04275ede4d3f3664349ed82fbeb Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 09:15:40 +0200 Subject: [PATCH 212/337] Simplify DepthCharge (C#) folder structure --- 31_Depth_Charge/csharp/{src => }/Controller.cs | 0 .../csharp/{Game.csproj => DepthCharge.csproj} | 0 31_Depth_Charge/csharp/DepthCharge.sln | 10 +++++----- 31_Depth_Charge/csharp/{src => }/Program.cs | 0 31_Depth_Charge/csharp/{src => }/View.cs | 0 5 files changed, 5 insertions(+), 5 deletions(-) rename 31_Depth_Charge/csharp/{src => }/Controller.cs (100%) rename 31_Depth_Charge/csharp/{Game.csproj => DepthCharge.csproj} (100%) rename 31_Depth_Charge/csharp/{src => }/Program.cs (100%) rename 31_Depth_Charge/csharp/{src => }/View.cs (100%) diff --git a/31_Depth_Charge/csharp/src/Controller.cs b/31_Depth_Charge/csharp/Controller.cs similarity index 100% rename from 31_Depth_Charge/csharp/src/Controller.cs rename to 31_Depth_Charge/csharp/Controller.cs diff --git a/31_Depth_Charge/csharp/Game.csproj b/31_Depth_Charge/csharp/DepthCharge.csproj similarity index 100% rename from 31_Depth_Charge/csharp/Game.csproj rename to 31_Depth_Charge/csharp/DepthCharge.csproj diff --git a/31_Depth_Charge/csharp/DepthCharge.sln b/31_Depth_Charge/csharp/DepthCharge.sln index 8d56c717..2f11d18c 100644 --- a/31_Depth_Charge/csharp/DepthCharge.sln +++ b/31_Depth_Charge/csharp/DepthCharge.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31129.286 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game.csproj", "{CBC9D8D9-9EDE-4D34-A20E-C90D929ABF8F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DepthCharge", "DepthCharge.csproj", "{15CF71F3-72F3-4C81-B54F-139F2A1E3920}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CBC9D8D9-9EDE-4D34-A20E-C90D929ABF8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CBC9D8D9-9EDE-4D34-A20E-C90D929ABF8F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CBC9D8D9-9EDE-4D34-A20E-C90D929ABF8F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CBC9D8D9-9EDE-4D34-A20E-C90D929ABF8F}.Release|Any CPU.Build.0 = Release|Any CPU + {15CF71F3-72F3-4C81-B54F-139F2A1E3920}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15CF71F3-72F3-4C81-B54F-139F2A1E3920}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15CF71F3-72F3-4C81-B54F-139F2A1E3920}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15CF71F3-72F3-4C81-B54F-139F2A1E3920}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/31_Depth_Charge/csharp/src/Program.cs b/31_Depth_Charge/csharp/Program.cs similarity index 100% rename from 31_Depth_Charge/csharp/src/Program.cs rename to 31_Depth_Charge/csharp/Program.cs diff --git a/31_Depth_Charge/csharp/src/View.cs b/31_Depth_Charge/csharp/View.cs similarity index 100% rename from 31_Depth_Charge/csharp/src/View.cs rename to 31_Depth_Charge/csharp/View.cs From 56679d99d6fd6a24ab2154afe5bbb7a773935137 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 09:21:33 +0200 Subject: [PATCH 213/337] Simplify Hammurabi (C#) folder structure --- 43_Hammurabi/csharp/{src => }/ActionResult.cs | 0 43_Hammurabi/csharp/{src => }/Controller.cs | 0 43_Hammurabi/csharp/{src => }/GameResult.cs | 0 43_Hammurabi/csharp/{src => }/GameState.cs | 0 43_Hammurabi/csharp/{src => }/GreatOffence.cs | 0 .../csharp/{Game.csproj => Hammurabi.csproj} | 0 43_Hammurabi/csharp/Hammurabi.sln | 14 +++++++------- 43_Hammurabi/csharp/{src => }/PerformanceRating.cs | 0 43_Hammurabi/csharp/{src => }/Program.cs | 0 43_Hammurabi/csharp/{src => }/Rules.cs | 0 43_Hammurabi/csharp/{src => }/View.cs | 0 11 files changed, 7 insertions(+), 7 deletions(-) rename 43_Hammurabi/csharp/{src => }/ActionResult.cs (100%) rename 43_Hammurabi/csharp/{src => }/Controller.cs (100%) rename 43_Hammurabi/csharp/{src => }/GameResult.cs (100%) rename 43_Hammurabi/csharp/{src => }/GameState.cs (100%) rename 43_Hammurabi/csharp/{src => }/GreatOffence.cs (100%) rename 43_Hammurabi/csharp/{Game.csproj => Hammurabi.csproj} (100%) rename 43_Hammurabi/csharp/{src => }/PerformanceRating.cs (100%) rename 43_Hammurabi/csharp/{src => }/Program.cs (100%) rename 43_Hammurabi/csharp/{src => }/Rules.cs (100%) rename 43_Hammurabi/csharp/{src => }/View.cs (100%) diff --git a/43_Hammurabi/csharp/src/ActionResult.cs b/43_Hammurabi/csharp/ActionResult.cs similarity index 100% rename from 43_Hammurabi/csharp/src/ActionResult.cs rename to 43_Hammurabi/csharp/ActionResult.cs diff --git a/43_Hammurabi/csharp/src/Controller.cs b/43_Hammurabi/csharp/Controller.cs similarity index 100% rename from 43_Hammurabi/csharp/src/Controller.cs rename to 43_Hammurabi/csharp/Controller.cs diff --git a/43_Hammurabi/csharp/src/GameResult.cs b/43_Hammurabi/csharp/GameResult.cs similarity index 100% rename from 43_Hammurabi/csharp/src/GameResult.cs rename to 43_Hammurabi/csharp/GameResult.cs diff --git a/43_Hammurabi/csharp/src/GameState.cs b/43_Hammurabi/csharp/GameState.cs similarity index 100% rename from 43_Hammurabi/csharp/src/GameState.cs rename to 43_Hammurabi/csharp/GameState.cs diff --git a/43_Hammurabi/csharp/src/GreatOffence.cs b/43_Hammurabi/csharp/GreatOffence.cs similarity index 100% rename from 43_Hammurabi/csharp/src/GreatOffence.cs rename to 43_Hammurabi/csharp/GreatOffence.cs diff --git a/43_Hammurabi/csharp/Game.csproj b/43_Hammurabi/csharp/Hammurabi.csproj similarity index 100% rename from 43_Hammurabi/csharp/Game.csproj rename to 43_Hammurabi/csharp/Hammurabi.csproj diff --git a/43_Hammurabi/csharp/Hammurabi.sln b/43_Hammurabi/csharp/Hammurabi.sln index feeae212..7475f8fd 100644 --- a/43_Hammurabi/csharp/Hammurabi.sln +++ b/43_Hammurabi/csharp/Hammurabi.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31129.286 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game.csproj", "{20599300-7C6E-48A2-AB24-EC7CCF224A5C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hammurabi", "Hammurabi.csproj", "{2C4407AF-5ED6-4C9F-833E-35461DF7DBBB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {20599300-7C6E-48A2-AB24-EC7CCF224A5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {20599300-7C6E-48A2-AB24-EC7CCF224A5C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {20599300-7C6E-48A2-AB24-EC7CCF224A5C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {20599300-7C6E-48A2-AB24-EC7CCF224A5C}.Release|Any CPU.Build.0 = Release|Any CPU + {2C4407AF-5ED6-4C9F-833E-35461DF7DBBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C4407AF-5ED6-4C9F-833E-35461DF7DBBB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C4407AF-5ED6-4C9F-833E-35461DF7DBBB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C4407AF-5ED6-4C9F-833E-35461DF7DBBB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/43_Hammurabi/csharp/src/PerformanceRating.cs b/43_Hammurabi/csharp/PerformanceRating.cs similarity index 100% rename from 43_Hammurabi/csharp/src/PerformanceRating.cs rename to 43_Hammurabi/csharp/PerformanceRating.cs diff --git a/43_Hammurabi/csharp/src/Program.cs b/43_Hammurabi/csharp/Program.cs similarity index 100% rename from 43_Hammurabi/csharp/src/Program.cs rename to 43_Hammurabi/csharp/Program.cs diff --git a/43_Hammurabi/csharp/src/Rules.cs b/43_Hammurabi/csharp/Rules.cs similarity index 100% rename from 43_Hammurabi/csharp/src/Rules.cs rename to 43_Hammurabi/csharp/Rules.cs diff --git a/43_Hammurabi/csharp/src/View.cs b/43_Hammurabi/csharp/View.cs similarity index 100% rename from 43_Hammurabi/csharp/src/View.cs rename to 43_Hammurabi/csharp/View.cs From 35bfd114e06c0c5385fc6d4991f435c9d6cf7139 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 10:48:54 +0200 Subject: [PATCH 214/337] Simplify Hexapawn (C#) folder structure --- 46_Hexapawn/csharp/{Hexapawn => }/Board.cs | 0 46_Hexapawn/csharp/{Hexapawn => }/Cell.cs | 0 46_Hexapawn/csharp/{Hexapawn => }/Computer.cs | 0 46_Hexapawn/csharp/{Hexapawn => }/Game.cs | 0 .../csharp/{Hexapawn => }/GameSeries.cs | 0 .../csharp/{Hexapawn => }/Hexapawn.csproj | 0 46_Hexapawn/csharp/Hexapawn.sln | 31 +++++++------------ 46_Hexapawn/csharp/{Hexapawn => }/Human.cs | 0 46_Hexapawn/csharp/{Hexapawn => }/IPlayer.cs | 0 46_Hexapawn/csharp/{Hexapawn => }/Input.cs | 0 46_Hexapawn/csharp/{Hexapawn => }/Move.cs | 0 46_Hexapawn/csharp/{Hexapawn => }/Pawn.cs | 0 46_Hexapawn/csharp/{Hexapawn => }/Program.cs | 0 13 files changed, 11 insertions(+), 20 deletions(-) rename 46_Hexapawn/csharp/{Hexapawn => }/Board.cs (100%) rename 46_Hexapawn/csharp/{Hexapawn => }/Cell.cs (100%) rename 46_Hexapawn/csharp/{Hexapawn => }/Computer.cs (100%) rename 46_Hexapawn/csharp/{Hexapawn => }/Game.cs (100%) rename 46_Hexapawn/csharp/{Hexapawn => }/GameSeries.cs (100%) rename 46_Hexapawn/csharp/{Hexapawn => }/Hexapawn.csproj (100%) rename 46_Hexapawn/csharp/{Hexapawn => }/Human.cs (100%) rename 46_Hexapawn/csharp/{Hexapawn => }/IPlayer.cs (100%) rename 46_Hexapawn/csharp/{Hexapawn => }/Input.cs (100%) rename 46_Hexapawn/csharp/{Hexapawn => }/Move.cs (100%) rename 46_Hexapawn/csharp/{Hexapawn => }/Pawn.cs (100%) rename 46_Hexapawn/csharp/{Hexapawn => }/Program.cs (100%) diff --git a/46_Hexapawn/csharp/Hexapawn/Board.cs b/46_Hexapawn/csharp/Board.cs similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/Board.cs rename to 46_Hexapawn/csharp/Board.cs diff --git a/46_Hexapawn/csharp/Hexapawn/Cell.cs b/46_Hexapawn/csharp/Cell.cs similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/Cell.cs rename to 46_Hexapawn/csharp/Cell.cs diff --git a/46_Hexapawn/csharp/Hexapawn/Computer.cs b/46_Hexapawn/csharp/Computer.cs similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/Computer.cs rename to 46_Hexapawn/csharp/Computer.cs diff --git a/46_Hexapawn/csharp/Hexapawn/Game.cs b/46_Hexapawn/csharp/Game.cs similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/Game.cs rename to 46_Hexapawn/csharp/Game.cs diff --git a/46_Hexapawn/csharp/Hexapawn/GameSeries.cs b/46_Hexapawn/csharp/GameSeries.cs similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/GameSeries.cs rename to 46_Hexapawn/csharp/GameSeries.cs diff --git a/46_Hexapawn/csharp/Hexapawn/Hexapawn.csproj b/46_Hexapawn/csharp/Hexapawn.csproj similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/Hexapawn.csproj rename to 46_Hexapawn/csharp/Hexapawn.csproj diff --git a/46_Hexapawn/csharp/Hexapawn.sln b/46_Hexapawn/csharp/Hexapawn.sln index 6cfc8a8f..06e7b32f 100644 --- a/46_Hexapawn/csharp/Hexapawn.sln +++ b/46_Hexapawn/csharp/Hexapawn.sln @@ -1,34 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hexapawn", "Hexapawn\Hexapawn.csproj", "{679D95BE-6E0C-4D8C-A2D4-0957576B63F3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hexapawn", "Hexapawn.csproj", "{785DA416-2609-4DB1-9F18-63CF6AC9927E}" 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(ProjectConfigurationPlatforms) = postSolution + {785DA416-2609-4DB1-9F18-63CF6AC9927E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {785DA416-2609-4DB1-9F18-63CF6AC9927E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {785DA416-2609-4DB1-9F18-63CF6AC9927E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {785DA416-2609-4DB1-9F18-63CF6AC9927E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Debug|x64.ActiveCfg = Debug|Any CPU - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Debug|x64.Build.0 = Debug|Any CPU - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Debug|x86.ActiveCfg = Debug|Any CPU - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Debug|x86.Build.0 = Debug|Any CPU - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Release|Any CPU.Build.0 = Release|Any CPU - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Release|x64.ActiveCfg = Release|Any CPU - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Release|x64.Build.0 = Release|Any CPU - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Release|x86.ActiveCfg = Release|Any CPU - {679D95BE-6E0C-4D8C-A2D4-0957576B63F3}.Release|x86.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D662AD9F-88B1-4AC9-83AD-DBFC08F384A8} EndGlobalSection EndGlobal diff --git a/46_Hexapawn/csharp/Hexapawn/Human.cs b/46_Hexapawn/csharp/Human.cs similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/Human.cs rename to 46_Hexapawn/csharp/Human.cs diff --git a/46_Hexapawn/csharp/Hexapawn/IPlayer.cs b/46_Hexapawn/csharp/IPlayer.cs similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/IPlayer.cs rename to 46_Hexapawn/csharp/IPlayer.cs diff --git a/46_Hexapawn/csharp/Hexapawn/Input.cs b/46_Hexapawn/csharp/Input.cs similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/Input.cs rename to 46_Hexapawn/csharp/Input.cs diff --git a/46_Hexapawn/csharp/Hexapawn/Move.cs b/46_Hexapawn/csharp/Move.cs similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/Move.cs rename to 46_Hexapawn/csharp/Move.cs diff --git a/46_Hexapawn/csharp/Hexapawn/Pawn.cs b/46_Hexapawn/csharp/Pawn.cs similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/Pawn.cs rename to 46_Hexapawn/csharp/Pawn.cs diff --git a/46_Hexapawn/csharp/Hexapawn/Program.cs b/46_Hexapawn/csharp/Program.cs similarity index 100% rename from 46_Hexapawn/csharp/Hexapawn/Program.cs rename to 46_Hexapawn/csharp/Program.cs From 3eed84264f18700c34c982494fc72102cdb017d8 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 11:09:11 +0200 Subject: [PATCH 215/337] Simplify Hurkle (C#) folder structure --- .../{src/hurkle => }/CardinalDirection.cs | 0 .../{src/hurkle => }/ConsoleHurkleView.cs | 0 .../{src/hurkle => }/FailedGuessViewModel.cs | 0 .../csharp/{src/hurkle => }/GamePoint.cs | 0 .../csharp/{src/hurkle => }/GuessViewModel.cs | 0 .../hurkle/hurkle.csproj => Hurkle.csproj} | 16 +-- 51_Hurkle/csharp/Hurkle.sln | 20 ++- .../csharp/{src/hurkle => }/HurkleGame.cs | 0 .../csharp/{src/hurkle => }/IHurkleView.cs | 0 .../csharp/{src/hurkle => }/LossViewModel.cs | 0 51_Hurkle/csharp/{src/hurkle => }/Program.cs | 128 +++++++++--------- .../{src/hurkle => }/VictoryViewModel.cs | 0 12 files changed, 81 insertions(+), 83 deletions(-) rename 51_Hurkle/csharp/{src/hurkle => }/CardinalDirection.cs (100%) rename 51_Hurkle/csharp/{src/hurkle => }/ConsoleHurkleView.cs (100%) rename 51_Hurkle/csharp/{src/hurkle => }/FailedGuessViewModel.cs (100%) rename 51_Hurkle/csharp/{src/hurkle => }/GamePoint.cs (100%) rename 51_Hurkle/csharp/{src/hurkle => }/GuessViewModel.cs (100%) rename 51_Hurkle/csharp/{src/hurkle/hurkle.csproj => Hurkle.csproj} (95%) rename 51_Hurkle/csharp/{src/hurkle => }/HurkleGame.cs (100%) rename 51_Hurkle/csharp/{src/hurkle => }/IHurkleView.cs (100%) rename 51_Hurkle/csharp/{src/hurkle => }/LossViewModel.cs (100%) rename 51_Hurkle/csharp/{src/hurkle => }/Program.cs (97%) rename 51_Hurkle/csharp/{src/hurkle => }/VictoryViewModel.cs (100%) diff --git a/51_Hurkle/csharp/src/hurkle/CardinalDirection.cs b/51_Hurkle/csharp/CardinalDirection.cs similarity index 100% rename from 51_Hurkle/csharp/src/hurkle/CardinalDirection.cs rename to 51_Hurkle/csharp/CardinalDirection.cs diff --git a/51_Hurkle/csharp/src/hurkle/ConsoleHurkleView.cs b/51_Hurkle/csharp/ConsoleHurkleView.cs similarity index 100% rename from 51_Hurkle/csharp/src/hurkle/ConsoleHurkleView.cs rename to 51_Hurkle/csharp/ConsoleHurkleView.cs diff --git a/51_Hurkle/csharp/src/hurkle/FailedGuessViewModel.cs b/51_Hurkle/csharp/FailedGuessViewModel.cs similarity index 100% rename from 51_Hurkle/csharp/src/hurkle/FailedGuessViewModel.cs rename to 51_Hurkle/csharp/FailedGuessViewModel.cs diff --git a/51_Hurkle/csharp/src/hurkle/GamePoint.cs b/51_Hurkle/csharp/GamePoint.cs similarity index 100% rename from 51_Hurkle/csharp/src/hurkle/GamePoint.cs rename to 51_Hurkle/csharp/GamePoint.cs diff --git a/51_Hurkle/csharp/src/hurkle/GuessViewModel.cs b/51_Hurkle/csharp/GuessViewModel.cs similarity index 100% rename from 51_Hurkle/csharp/src/hurkle/GuessViewModel.cs rename to 51_Hurkle/csharp/GuessViewModel.cs diff --git a/51_Hurkle/csharp/src/hurkle/hurkle.csproj b/51_Hurkle/csharp/Hurkle.csproj similarity index 95% rename from 51_Hurkle/csharp/src/hurkle/hurkle.csproj rename to 51_Hurkle/csharp/Hurkle.csproj index 1d2d39a9..20827042 100644 --- a/51_Hurkle/csharp/src/hurkle/hurkle.csproj +++ b/51_Hurkle/csharp/Hurkle.csproj @@ -1,8 +1,8 @@ - - - - Exe - net5.0 - - - + + + + Exe + net5.0 + + + diff --git a/51_Hurkle/csharp/Hurkle.sln b/51_Hurkle/csharp/Hurkle.sln index e1792677..d1a6fb25 100644 --- a/51_Hurkle/csharp/Hurkle.sln +++ b/51_Hurkle/csharp/Hurkle.sln @@ -3,25 +3,23 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30114.105 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EBE7BC2B-8F2E-41D5-AF36-7AAC7CE0E1BF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "hurkle", "src\hurkle\hurkle.csproj", "{47578EC1-A012-4BF7-8709-64F675E72DB0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hurkle", "Hurkle.csproj", "{BE321D5B-93BD-4F91-A875-564DC9D4094F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BE321D5B-93BD-4F91-A875-564DC9D4094F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE321D5B-93BD-4F91-A875-564DC9D4094F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE321D5B-93BD-4F91-A875-564DC9D4094F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE321D5B-93BD-4F91-A875-564DC9D4094F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {47578EC1-A012-4BF7-8709-64F675E72DB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {47578EC1-A012-4BF7-8709-64F675E72DB0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {47578EC1-A012-4BF7-8709-64F675E72DB0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {47578EC1-A012-4BF7-8709-64F675E72DB0}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {47578EC1-A012-4BF7-8709-64F675E72DB0} = {EBE7BC2B-8F2E-41D5-AF36-7AAC7CE0E1BF} + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {42DC6AE5-5127-4B1B-BD5E-F3B1CCDC3822} EndGlobalSection EndGlobal diff --git a/51_Hurkle/csharp/src/hurkle/HurkleGame.cs b/51_Hurkle/csharp/HurkleGame.cs similarity index 100% rename from 51_Hurkle/csharp/src/hurkle/HurkleGame.cs rename to 51_Hurkle/csharp/HurkleGame.cs diff --git a/51_Hurkle/csharp/src/hurkle/IHurkleView.cs b/51_Hurkle/csharp/IHurkleView.cs similarity index 100% rename from 51_Hurkle/csharp/src/hurkle/IHurkleView.cs rename to 51_Hurkle/csharp/IHurkleView.cs diff --git a/51_Hurkle/csharp/src/hurkle/LossViewModel.cs b/51_Hurkle/csharp/LossViewModel.cs similarity index 100% rename from 51_Hurkle/csharp/src/hurkle/LossViewModel.cs rename to 51_Hurkle/csharp/LossViewModel.cs diff --git a/51_Hurkle/csharp/src/hurkle/Program.cs b/51_Hurkle/csharp/Program.cs similarity index 97% rename from 51_Hurkle/csharp/src/hurkle/Program.cs rename to 51_Hurkle/csharp/Program.cs index 148308d1..e5c3f6af 100644 --- a/51_Hurkle/csharp/src/hurkle/Program.cs +++ b/51_Hurkle/csharp/Program.cs @@ -1,64 +1,64 @@ -using System; - -namespace hurkle -{ - class Program - { - static void Main(string[] args) - { - /* - Original source transscription - 10 PRINT TAB(33);"HURKLE" - 20 PRINT TAB(15);"CREATIVE COMPUTING NORRISTOWN, NEW JERSEY" - 30 PRINT;PRINT;PRINT - */ - Console.WriteLine(new string(' ', 33) + @"HURKLE"); - Console.WriteLine(new string(' ', 15) + @"CREATIVE COMPUTING NORRISTOWN, NEW JERSEY"); - /* - 110 N=5 - 120 G=10 - */ - var N=5; - var G=10; - /* - 210 PRINT - 220 PRINT "A HURKLE IS HIDING ON A";G;"BY";G;"GRID. HOMEBASE" - 230 PRINT "ON THE GRID IS POINT 0,0 AND ANY GRIDPOINT IS A" - 240 PRINT "PAIR OF WHOLE NUMBERS SEPERATED BY A COMMA. TRY TO" - 250 PRINT "GUESS THE HURKLE'S GRIDPOINT. YOU GET";N;"TRIES." - 260 PRINT "AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE" - 270 PRINT "DIRECTION TO GO TO LOOK FOR THE HURKLE." - 280 PRINT - */ - // Using string formatting via the '$' string - Console.WriteLine(); - Console.WriteLine($"A HURKLE IS HIDING ON A {G} BY {G} GRID. HOMEBASE"); - Console.WriteLine(@"ON THE GRID IS POINT 0,0 AND ANY GRIDPOINT IS A"); - Console.WriteLine(@"PAIR OF WHOLE NUMBERS SEPERATED BY A COMMA. TRY TO"); - Console.WriteLine($"GUESS THE HURKLE'S GRIDPOINT. YOU GET {N} TRIES."); - Console.WriteLine(@"AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE"); - Console.WriteLine(@"DIRECTION TO GO TO LOOK FOR THE HURKLE."); - Console.WriteLine(); - - var view = new ConsoleHurkleView(); - var hurkle = new HurkleGame(N,G, view); - while(true) - { - hurkle.PlayGame(); - - Console.WriteLine("PLAY AGAIN? (Y)ES/(N)O"); - var playAgainResponse = Console.ReadLine(); - if(playAgainResponse.Trim().StartsWith("y", StringComparison.InvariantCultureIgnoreCase)) - { - Console.WriteLine(); - Console.WriteLine("LET'S PLAY AGAIN. HURKLE IS HIDING"); - Console.WriteLine(); - }else{ - Console.WriteLine("THANKS FOR PLAYING!"); - break; - } - - } - } - } -} +using System; + +namespace hurkle +{ + class Program + { + static void Main(string[] args) + { + /* + Original source transscription + 10 PRINT TAB(33);"HURKLE" + 20 PRINT TAB(15);"CREATIVE COMPUTING NORRISTOWN, NEW JERSEY" + 30 PRINT;PRINT;PRINT + */ + Console.WriteLine(new string(' ', 33) + @"HURKLE"); + Console.WriteLine(new string(' ', 15) + @"CREATIVE COMPUTING NORRISTOWN, NEW JERSEY"); + /* + 110 N=5 + 120 G=10 + */ + var N=5; + var G=10; + /* + 210 PRINT + 220 PRINT "A HURKLE IS HIDING ON A";G;"BY";G;"GRID. HOMEBASE" + 230 PRINT "ON THE GRID IS POINT 0,0 AND ANY GRIDPOINT IS A" + 240 PRINT "PAIR OF WHOLE NUMBERS SEPERATED BY A COMMA. TRY TO" + 250 PRINT "GUESS THE HURKLE'S GRIDPOINT. YOU GET";N;"TRIES." + 260 PRINT "AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE" + 270 PRINT "DIRECTION TO GO TO LOOK FOR THE HURKLE." + 280 PRINT + */ + // Using string formatting via the '$' string + Console.WriteLine(); + Console.WriteLine($"A HURKLE IS HIDING ON A {G} BY {G} GRID. HOMEBASE"); + Console.WriteLine(@"ON THE GRID IS POINT 0,0 AND ANY GRIDPOINT IS A"); + Console.WriteLine(@"PAIR OF WHOLE NUMBERS SEPERATED BY A COMMA. TRY TO"); + Console.WriteLine($"GUESS THE HURKLE'S GRIDPOINT. YOU GET {N} TRIES."); + Console.WriteLine(@"AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE"); + Console.WriteLine(@"DIRECTION TO GO TO LOOK FOR THE HURKLE."); + Console.WriteLine(); + + var view = new ConsoleHurkleView(); + var hurkle = new HurkleGame(N,G, view); + while(true) + { + hurkle.PlayGame(); + + Console.WriteLine("PLAY AGAIN? (Y)ES/(N)O"); + var playAgainResponse = Console.ReadLine(); + if(playAgainResponse.Trim().StartsWith("y", StringComparison.InvariantCultureIgnoreCase)) + { + Console.WriteLine(); + Console.WriteLine("LET'S PLAY AGAIN. HURKLE IS HIDING"); + Console.WriteLine(); + }else{ + Console.WriteLine("THANKS FOR PLAYING!"); + break; + } + + } + } + } +} diff --git a/51_Hurkle/csharp/src/hurkle/VictoryViewModel.cs b/51_Hurkle/csharp/VictoryViewModel.cs similarity index 100% rename from 51_Hurkle/csharp/src/hurkle/VictoryViewModel.cs rename to 51_Hurkle/csharp/VictoryViewModel.cs From df8269fd0c8a4235e9fbd474d7102cdc5eff0050 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 11:12:56 +0200 Subject: [PATCH 216/337] Simplify Love (C#) folder structure --- 58_Love/csharp/{Love => }/Input.cs | 0 58_Love/csharp/{Love => }/Love.csproj | 0 58_Love/csharp/Love.sln | 31 +++++++------------ 58_Love/csharp/{Love => }/LovePattern.cs | 0 58_Love/csharp/{Love => }/Program.cs | 0 58_Love/csharp/{Love => }/SourceCharacters.cs | 0 58_Love/csharp/{Love => }/Strings/Intro.txt | 0 7 files changed, 11 insertions(+), 20 deletions(-) rename 58_Love/csharp/{Love => }/Input.cs (100%) rename 58_Love/csharp/{Love => }/Love.csproj (100%) rename 58_Love/csharp/{Love => }/LovePattern.cs (100%) rename 58_Love/csharp/{Love => }/Program.cs (100%) rename 58_Love/csharp/{Love => }/SourceCharacters.cs (100%) rename 58_Love/csharp/{Love => }/Strings/Intro.txt (100%) diff --git a/58_Love/csharp/Love/Input.cs b/58_Love/csharp/Input.cs similarity index 100% rename from 58_Love/csharp/Love/Input.cs rename to 58_Love/csharp/Input.cs diff --git a/58_Love/csharp/Love/Love.csproj b/58_Love/csharp/Love.csproj similarity index 100% rename from 58_Love/csharp/Love/Love.csproj rename to 58_Love/csharp/Love.csproj diff --git a/58_Love/csharp/Love.sln b/58_Love/csharp/Love.sln index a89fd1d8..813af0f2 100644 --- a/58_Love/csharp/Love.sln +++ b/58_Love/csharp/Love.sln @@ -1,34 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Love", "Love\Love.csproj", "{FC74E025-A50D-4E19-9337-87F2E4A9F83E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Love", "Love.csproj", "{1C02A3CA-615B-42CF-B696-4514770CA67F}" 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(ProjectConfigurationPlatforms) = postSolution + {1C02A3CA-615B-42CF-B696-4514770CA67F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C02A3CA-615B-42CF-B696-4514770CA67F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1C02A3CA-615B-42CF-B696-4514770CA67F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1C02A3CA-615B-42CF-B696-4514770CA67F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Debug|x64.ActiveCfg = Debug|Any CPU - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Debug|x64.Build.0 = Debug|Any CPU - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Debug|x86.ActiveCfg = Debug|Any CPU - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Debug|x86.Build.0 = Debug|Any CPU - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Release|Any CPU.Build.0 = Release|Any CPU - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Release|x64.ActiveCfg = Release|Any CPU - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Release|x64.Build.0 = Release|Any CPU - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Release|x86.ActiveCfg = Release|Any CPU - {FC74E025-A50D-4E19-9337-87F2E4A9F83E}.Release|x86.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F9C55508-108B-4EA1-ADD7-4BA8EC915E68} EndGlobalSection EndGlobal diff --git a/58_Love/csharp/Love/LovePattern.cs b/58_Love/csharp/LovePattern.cs similarity index 100% rename from 58_Love/csharp/Love/LovePattern.cs rename to 58_Love/csharp/LovePattern.cs diff --git a/58_Love/csharp/Love/Program.cs b/58_Love/csharp/Program.cs similarity index 100% rename from 58_Love/csharp/Love/Program.cs rename to 58_Love/csharp/Program.cs diff --git a/58_Love/csharp/Love/SourceCharacters.cs b/58_Love/csharp/SourceCharacters.cs similarity index 100% rename from 58_Love/csharp/Love/SourceCharacters.cs rename to 58_Love/csharp/SourceCharacters.cs diff --git a/58_Love/csharp/Love/Strings/Intro.txt b/58_Love/csharp/Strings/Intro.txt similarity index 100% rename from 58_Love/csharp/Love/Strings/Intro.txt rename to 58_Love/csharp/Strings/Intro.txt From ca9fafc7585fd5d2ad6b0a201cabc3f3756c582b Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 11:48:01 +0200 Subject: [PATCH 217/337] Simplify Mastermind (C#) folder structure --- 60_Mastermind/csharp/{Game/src => }/Code.cs | 0 60_Mastermind/csharp/{Game/src => }/CodeFactory.cs | 0 60_Mastermind/csharp/{Game/src => }/ColorInfo.cs | 0 60_Mastermind/csharp/{Game/src => }/Colors.cs | 0 60_Mastermind/csharp/{Game/src => }/Command.cs | 0 60_Mastermind/csharp/{Game/src => }/Controller.cs | 0 .../csharp/{Game/src => }/EnumerableExtensions.cs | 0 .../csharp/{Game/Game.csproj => Mastermind.csproj} | 0 60_Mastermind/csharp/Mastermind.sln | 14 +++++++------- 60_Mastermind/csharp/{Game/src => }/Program.cs | 0 60_Mastermind/csharp/{Game/src => }/TurnResult.cs | 0 60_Mastermind/csharp/{Game/src => }/View.cs | 0 12 files changed, 7 insertions(+), 7 deletions(-) rename 60_Mastermind/csharp/{Game/src => }/Code.cs (100%) rename 60_Mastermind/csharp/{Game/src => }/CodeFactory.cs (100%) rename 60_Mastermind/csharp/{Game/src => }/ColorInfo.cs (100%) rename 60_Mastermind/csharp/{Game/src => }/Colors.cs (100%) rename 60_Mastermind/csharp/{Game/src => }/Command.cs (100%) rename 60_Mastermind/csharp/{Game/src => }/Controller.cs (100%) rename 60_Mastermind/csharp/{Game/src => }/EnumerableExtensions.cs (100%) rename 60_Mastermind/csharp/{Game/Game.csproj => Mastermind.csproj} (100%) rename 60_Mastermind/csharp/{Game/src => }/Program.cs (100%) rename 60_Mastermind/csharp/{Game/src => }/TurnResult.cs (100%) rename 60_Mastermind/csharp/{Game/src => }/View.cs (100%) diff --git a/60_Mastermind/csharp/Game/src/Code.cs b/60_Mastermind/csharp/Code.cs similarity index 100% rename from 60_Mastermind/csharp/Game/src/Code.cs rename to 60_Mastermind/csharp/Code.cs diff --git a/60_Mastermind/csharp/Game/src/CodeFactory.cs b/60_Mastermind/csharp/CodeFactory.cs similarity index 100% rename from 60_Mastermind/csharp/Game/src/CodeFactory.cs rename to 60_Mastermind/csharp/CodeFactory.cs diff --git a/60_Mastermind/csharp/Game/src/ColorInfo.cs b/60_Mastermind/csharp/ColorInfo.cs similarity index 100% rename from 60_Mastermind/csharp/Game/src/ColorInfo.cs rename to 60_Mastermind/csharp/ColorInfo.cs diff --git a/60_Mastermind/csharp/Game/src/Colors.cs b/60_Mastermind/csharp/Colors.cs similarity index 100% rename from 60_Mastermind/csharp/Game/src/Colors.cs rename to 60_Mastermind/csharp/Colors.cs diff --git a/60_Mastermind/csharp/Game/src/Command.cs b/60_Mastermind/csharp/Command.cs similarity index 100% rename from 60_Mastermind/csharp/Game/src/Command.cs rename to 60_Mastermind/csharp/Command.cs diff --git a/60_Mastermind/csharp/Game/src/Controller.cs b/60_Mastermind/csharp/Controller.cs similarity index 100% rename from 60_Mastermind/csharp/Game/src/Controller.cs rename to 60_Mastermind/csharp/Controller.cs diff --git a/60_Mastermind/csharp/Game/src/EnumerableExtensions.cs b/60_Mastermind/csharp/EnumerableExtensions.cs similarity index 100% rename from 60_Mastermind/csharp/Game/src/EnumerableExtensions.cs rename to 60_Mastermind/csharp/EnumerableExtensions.cs diff --git a/60_Mastermind/csharp/Game/Game.csproj b/60_Mastermind/csharp/Mastermind.csproj similarity index 100% rename from 60_Mastermind/csharp/Game/Game.csproj rename to 60_Mastermind/csharp/Mastermind.csproj diff --git a/60_Mastermind/csharp/Mastermind.sln b/60_Mastermind/csharp/Mastermind.sln index c3827fb7..0da53b6d 100644 --- a/60_Mastermind/csharp/Mastermind.sln +++ b/60_Mastermind/csharp/Mastermind.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31321.278 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game\Game.csproj", "{E8D63140-971D-4FBF-8138-964E54CCB7DD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mastermind", "Mastermind.csproj", "{AEC839CD-C6D3-4476-AA85-79B160AF78BE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E8D63140-971D-4FBF-8138-964E54CCB7DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E8D63140-971D-4FBF-8138-964E54CCB7DD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E8D63140-971D-4FBF-8138-964E54CCB7DD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E8D63140-971D-4FBF-8138-964E54CCB7DD}.Release|Any CPU.Build.0 = Release|Any CPU + {AEC839CD-C6D3-4476-AA85-79B160AF78BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AEC839CD-C6D3-4476-AA85-79B160AF78BE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AEC839CD-C6D3-4476-AA85-79B160AF78BE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AEC839CD-C6D3-4476-AA85-79B160AF78BE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/60_Mastermind/csharp/Game/src/Program.cs b/60_Mastermind/csharp/Program.cs similarity index 100% rename from 60_Mastermind/csharp/Game/src/Program.cs rename to 60_Mastermind/csharp/Program.cs diff --git a/60_Mastermind/csharp/Game/src/TurnResult.cs b/60_Mastermind/csharp/TurnResult.cs similarity index 100% rename from 60_Mastermind/csharp/Game/src/TurnResult.cs rename to 60_Mastermind/csharp/TurnResult.cs diff --git a/60_Mastermind/csharp/Game/src/View.cs b/60_Mastermind/csharp/View.cs similarity index 100% rename from 60_Mastermind/csharp/Game/src/View.cs rename to 60_Mastermind/csharp/View.cs From b83307572254c5c4f3a55bf0631d51897e8463df Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 11:50:17 +0200 Subject: [PATCH 218/337] Simplify Mugwump (C#) folder structure --- 62_Mugwump/csharp/{Mugwump => }/Game.cs | 0 62_Mugwump/csharp/{Mugwump => }/Grid.cs | 0 62_Mugwump/csharp/{Mugwump => }/Input.cs | 0 62_Mugwump/csharp/{Mugwump => }/Mugwump.cs | 0 .../csharp/{Mugwump => }/Mugwump.csproj | 0 62_Mugwump/csharp/Mugwump.sln | 31 +++++++------------ 62_Mugwump/csharp/{Mugwump => }/Offset.cs | 0 62_Mugwump/csharp/{Mugwump => }/Position.cs | 0 62_Mugwump/csharp/{Mugwump => }/Program.cs | 0 .../csharp/{Mugwump => }/Strings/Intro.txt | 0 10 files changed, 11 insertions(+), 20 deletions(-) rename 62_Mugwump/csharp/{Mugwump => }/Game.cs (100%) rename 62_Mugwump/csharp/{Mugwump => }/Grid.cs (100%) rename 62_Mugwump/csharp/{Mugwump => }/Input.cs (100%) rename 62_Mugwump/csharp/{Mugwump => }/Mugwump.cs (100%) rename 62_Mugwump/csharp/{Mugwump => }/Mugwump.csproj (100%) rename 62_Mugwump/csharp/{Mugwump => }/Offset.cs (100%) rename 62_Mugwump/csharp/{Mugwump => }/Position.cs (100%) rename 62_Mugwump/csharp/{Mugwump => }/Program.cs (100%) rename 62_Mugwump/csharp/{Mugwump => }/Strings/Intro.txt (100%) diff --git a/62_Mugwump/csharp/Mugwump/Game.cs b/62_Mugwump/csharp/Game.cs similarity index 100% rename from 62_Mugwump/csharp/Mugwump/Game.cs rename to 62_Mugwump/csharp/Game.cs diff --git a/62_Mugwump/csharp/Mugwump/Grid.cs b/62_Mugwump/csharp/Grid.cs similarity index 100% rename from 62_Mugwump/csharp/Mugwump/Grid.cs rename to 62_Mugwump/csharp/Grid.cs diff --git a/62_Mugwump/csharp/Mugwump/Input.cs b/62_Mugwump/csharp/Input.cs similarity index 100% rename from 62_Mugwump/csharp/Mugwump/Input.cs rename to 62_Mugwump/csharp/Input.cs diff --git a/62_Mugwump/csharp/Mugwump/Mugwump.cs b/62_Mugwump/csharp/Mugwump.cs similarity index 100% rename from 62_Mugwump/csharp/Mugwump/Mugwump.cs rename to 62_Mugwump/csharp/Mugwump.cs diff --git a/62_Mugwump/csharp/Mugwump/Mugwump.csproj b/62_Mugwump/csharp/Mugwump.csproj similarity index 100% rename from 62_Mugwump/csharp/Mugwump/Mugwump.csproj rename to 62_Mugwump/csharp/Mugwump.csproj diff --git a/62_Mugwump/csharp/Mugwump.sln b/62_Mugwump/csharp/Mugwump.sln index bc3cfbff..ab99858a 100644 --- a/62_Mugwump/csharp/Mugwump.sln +++ b/62_Mugwump/csharp/Mugwump.sln @@ -1,34 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mugwump", "Mugwump\Mugwump.csproj", "{83F42802-4E7C-49B5-A022-DB9B6A65F2C6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mugwump", "Mugwump.csproj", "{DB23BDB0-10A4-4771-B942-E646A1A5C416}" 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(ProjectConfigurationPlatforms) = postSolution + {DB23BDB0-10A4-4771-B942-E646A1A5C416}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DB23BDB0-10A4-4771-B942-E646A1A5C416}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DB23BDB0-10A4-4771-B942-E646A1A5C416}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DB23BDB0-10A4-4771-B942-E646A1A5C416}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Debug|x64.ActiveCfg = Debug|Any CPU - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Debug|x64.Build.0 = Debug|Any CPU - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Debug|x86.ActiveCfg = Debug|Any CPU - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Debug|x86.Build.0 = Debug|Any CPU - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Release|Any CPU.Build.0 = Release|Any CPU - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Release|x64.ActiveCfg = Release|Any CPU - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Release|x64.Build.0 = Release|Any CPU - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Release|x86.ActiveCfg = Release|Any CPU - {83F42802-4E7C-49B5-A022-DB9B6A65F2C6}.Release|x86.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1FE34948-9066-4F57-A4C1-423293A430C5} EndGlobalSection EndGlobal diff --git a/62_Mugwump/csharp/Mugwump/Offset.cs b/62_Mugwump/csharp/Offset.cs similarity index 100% rename from 62_Mugwump/csharp/Mugwump/Offset.cs rename to 62_Mugwump/csharp/Offset.cs diff --git a/62_Mugwump/csharp/Mugwump/Position.cs b/62_Mugwump/csharp/Position.cs similarity index 100% rename from 62_Mugwump/csharp/Mugwump/Position.cs rename to 62_Mugwump/csharp/Position.cs diff --git a/62_Mugwump/csharp/Mugwump/Program.cs b/62_Mugwump/csharp/Program.cs similarity index 100% rename from 62_Mugwump/csharp/Mugwump/Program.cs rename to 62_Mugwump/csharp/Program.cs diff --git a/62_Mugwump/csharp/Mugwump/Strings/Intro.txt b/62_Mugwump/csharp/Strings/Intro.txt similarity index 100% rename from 62_Mugwump/csharp/Mugwump/Strings/Intro.txt rename to 62_Mugwump/csharp/Strings/Intro.txt From 66393f12358c3f0a51acc05c3ee631132b6fc50a Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 11:52:48 +0200 Subject: [PATCH 219/337] Simplify Stars (C#) folder structure --- 82_Stars/csharp/{Stars => }/Game.cs | 0 82_Stars/csharp/{Stars => }/Input.cs | 0 82_Stars/csharp/{Stars => }/Program.cs | 0 82_Stars/csharp/{Stars => }/Stars.csproj | 0 82_Stars/csharp/Stars.sln | 31 +++++++++--------------- 5 files changed, 11 insertions(+), 20 deletions(-) rename 82_Stars/csharp/{Stars => }/Game.cs (100%) rename 82_Stars/csharp/{Stars => }/Input.cs (100%) rename 82_Stars/csharp/{Stars => }/Program.cs (100%) rename 82_Stars/csharp/{Stars => }/Stars.csproj (100%) diff --git a/82_Stars/csharp/Stars/Game.cs b/82_Stars/csharp/Game.cs similarity index 100% rename from 82_Stars/csharp/Stars/Game.cs rename to 82_Stars/csharp/Game.cs diff --git a/82_Stars/csharp/Stars/Input.cs b/82_Stars/csharp/Input.cs similarity index 100% rename from 82_Stars/csharp/Stars/Input.cs rename to 82_Stars/csharp/Input.cs diff --git a/82_Stars/csharp/Stars/Program.cs b/82_Stars/csharp/Program.cs similarity index 100% rename from 82_Stars/csharp/Stars/Program.cs rename to 82_Stars/csharp/Program.cs diff --git a/82_Stars/csharp/Stars/Stars.csproj b/82_Stars/csharp/Stars.csproj similarity index 100% rename from 82_Stars/csharp/Stars/Stars.csproj rename to 82_Stars/csharp/Stars.csproj diff --git a/82_Stars/csharp/Stars.sln b/82_Stars/csharp/Stars.sln index 5f85e6b7..19c3a265 100644 --- a/82_Stars/csharp/Stars.sln +++ b/82_Stars/csharp/Stars.sln @@ -1,34 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stars", "Stars\Stars.csproj", "{5832C21C-4DE5-475E-893D-745DA15F1AAC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stars", "Stars.csproj", "{F03C19DA-0F5D-45F4-B85E-E3ABCA197D4B}" 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(ProjectConfigurationPlatforms) = postSolution + {F03C19DA-0F5D-45F4-B85E-E3ABCA197D4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F03C19DA-0F5D-45F4-B85E-E3ABCA197D4B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F03C19DA-0F5D-45F4-B85E-E3ABCA197D4B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F03C19DA-0F5D-45F4-B85E-E3ABCA197D4B}.Release|Any CPU.Build.0 = Release|Any CPU 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 + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0752CA22-85F0-43AE-8B79-7A611531CAF7} EndGlobalSection EndGlobal From e69a3d4b3f14f4d731be997fdc51aa96d62e2378 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 11:56:20 +0200 Subject: [PATCH 220/337] Simplify StockMarket (C#) folder structure --- 83_Stock_Market/csharp/{src => }/Assets.cs | 0 83_Stock_Market/csharp/{src => }/Broker.cs | 0 83_Stock_Market/csharp/{src => }/Company.cs | 0 83_Stock_Market/csharp/{src => }/Controller.cs | 0 .../{src => }/Extensions/EnumerableExtensions.cs | 0 .../Extensions/ImmutableArrayExtensions.cs | 0 .../{src => }/Extensions/RandomExtensions.cs | 0 83_Stock_Market/csharp/{src => }/Program.cs | 0 83_Stock_Market/csharp/{src => }/StockMarket.cs | 0 .../csharp/{Game.csproj => StockMarket.csproj} | 0 83_Stock_Market/csharp/StockMarket.sln | 14 +++++++------- 83_Stock_Market/csharp/{src => }/TradingDay.cs | 0 .../csharp/{src => }/TransactionResult.cs | 0 83_Stock_Market/csharp/{src => }/View.cs | 0 14 files changed, 7 insertions(+), 7 deletions(-) rename 83_Stock_Market/csharp/{src => }/Assets.cs (100%) rename 83_Stock_Market/csharp/{src => }/Broker.cs (100%) rename 83_Stock_Market/csharp/{src => }/Company.cs (100%) rename 83_Stock_Market/csharp/{src => }/Controller.cs (100%) rename 83_Stock_Market/csharp/{src => }/Extensions/EnumerableExtensions.cs (100%) rename 83_Stock_Market/csharp/{src => }/Extensions/ImmutableArrayExtensions.cs (100%) rename 83_Stock_Market/csharp/{src => }/Extensions/RandomExtensions.cs (100%) rename 83_Stock_Market/csharp/{src => }/Program.cs (100%) rename 83_Stock_Market/csharp/{src => }/StockMarket.cs (100%) rename 83_Stock_Market/csharp/{Game.csproj => StockMarket.csproj} (100%) rename 83_Stock_Market/csharp/{src => }/TradingDay.cs (100%) rename 83_Stock_Market/csharp/{src => }/TransactionResult.cs (100%) rename 83_Stock_Market/csharp/{src => }/View.cs (100%) diff --git a/83_Stock_Market/csharp/src/Assets.cs b/83_Stock_Market/csharp/Assets.cs similarity index 100% rename from 83_Stock_Market/csharp/src/Assets.cs rename to 83_Stock_Market/csharp/Assets.cs diff --git a/83_Stock_Market/csharp/src/Broker.cs b/83_Stock_Market/csharp/Broker.cs similarity index 100% rename from 83_Stock_Market/csharp/src/Broker.cs rename to 83_Stock_Market/csharp/Broker.cs diff --git a/83_Stock_Market/csharp/src/Company.cs b/83_Stock_Market/csharp/Company.cs similarity index 100% rename from 83_Stock_Market/csharp/src/Company.cs rename to 83_Stock_Market/csharp/Company.cs diff --git a/83_Stock_Market/csharp/src/Controller.cs b/83_Stock_Market/csharp/Controller.cs similarity index 100% rename from 83_Stock_Market/csharp/src/Controller.cs rename to 83_Stock_Market/csharp/Controller.cs diff --git a/83_Stock_Market/csharp/src/Extensions/EnumerableExtensions.cs b/83_Stock_Market/csharp/Extensions/EnumerableExtensions.cs similarity index 100% rename from 83_Stock_Market/csharp/src/Extensions/EnumerableExtensions.cs rename to 83_Stock_Market/csharp/Extensions/EnumerableExtensions.cs diff --git a/83_Stock_Market/csharp/src/Extensions/ImmutableArrayExtensions.cs b/83_Stock_Market/csharp/Extensions/ImmutableArrayExtensions.cs similarity index 100% rename from 83_Stock_Market/csharp/src/Extensions/ImmutableArrayExtensions.cs rename to 83_Stock_Market/csharp/Extensions/ImmutableArrayExtensions.cs diff --git a/83_Stock_Market/csharp/src/Extensions/RandomExtensions.cs b/83_Stock_Market/csharp/Extensions/RandomExtensions.cs similarity index 100% rename from 83_Stock_Market/csharp/src/Extensions/RandomExtensions.cs rename to 83_Stock_Market/csharp/Extensions/RandomExtensions.cs diff --git a/83_Stock_Market/csharp/src/Program.cs b/83_Stock_Market/csharp/Program.cs similarity index 100% rename from 83_Stock_Market/csharp/src/Program.cs rename to 83_Stock_Market/csharp/Program.cs diff --git a/83_Stock_Market/csharp/src/StockMarket.cs b/83_Stock_Market/csharp/StockMarket.cs similarity index 100% rename from 83_Stock_Market/csharp/src/StockMarket.cs rename to 83_Stock_Market/csharp/StockMarket.cs diff --git a/83_Stock_Market/csharp/Game.csproj b/83_Stock_Market/csharp/StockMarket.csproj similarity index 100% rename from 83_Stock_Market/csharp/Game.csproj rename to 83_Stock_Market/csharp/StockMarket.csproj diff --git a/83_Stock_Market/csharp/StockMarket.sln b/83_Stock_Market/csharp/StockMarket.sln index 5bfb67aa..ab159a5b 100644 --- a/83_Stock_Market/csharp/StockMarket.sln +++ b/83_Stock_Market/csharp/StockMarket.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31321.278 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game.csproj", "{BADD262D-D540-431F-8803-2A6F80C22033}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StockMarket", "StockMarket.csproj", "{B4C15C31-EB2D-4AAF-8380-5F2EBC0DD9D0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {BADD262D-D540-431F-8803-2A6F80C22033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BADD262D-D540-431F-8803-2A6F80C22033}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BADD262D-D540-431F-8803-2A6F80C22033}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BADD262D-D540-431F-8803-2A6F80C22033}.Release|Any CPU.Build.0 = Release|Any CPU + {B4C15C31-EB2D-4AAF-8380-5F2EBC0DD9D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B4C15C31-EB2D-4AAF-8380-5F2EBC0DD9D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4C15C31-EB2D-4AAF-8380-5F2EBC0DD9D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B4C15C31-EB2D-4AAF-8380-5F2EBC0DD9D0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/83_Stock_Market/csharp/src/TradingDay.cs b/83_Stock_Market/csharp/TradingDay.cs similarity index 100% rename from 83_Stock_Market/csharp/src/TradingDay.cs rename to 83_Stock_Market/csharp/TradingDay.cs diff --git a/83_Stock_Market/csharp/src/TransactionResult.cs b/83_Stock_Market/csharp/TransactionResult.cs similarity index 100% rename from 83_Stock_Market/csharp/src/TransactionResult.cs rename to 83_Stock_Market/csharp/TransactionResult.cs diff --git a/83_Stock_Market/csharp/src/View.cs b/83_Stock_Market/csharp/View.cs similarity index 100% rename from 83_Stock_Market/csharp/src/View.cs rename to 83_Stock_Market/csharp/View.cs From eded164f64ac1409539b09d7a8386327a33e18b2 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 11:59:02 +0200 Subject: [PATCH 221/337] Simplify Target (C#) folder strucure --- 86_Target/csharp/{Target => }/Angle.cs | 0 86_Target/csharp/{Target => }/Explosion.cs | 0 86_Target/csharp/{Target => }/FiringRange.cs | 0 86_Target/csharp/{Target => }/Game.cs | 0 86_Target/csharp/{Target => }/Input.cs | 0 86_Target/csharp/{Target => }/Offset.cs | 0 86_Target/csharp/{Target => }/Point.cs | 0 86_Target/csharp/{Target => }/Program.cs | 0 .../csharp/{Target => }/RandomExtensions.cs | 0 .../Strings/TitleAndInstructions.txt | 0 86_Target/csharp/{Target => }/Target.csproj | 0 86_Target/csharp/Target.sln | 31 +++++++------------ 12 files changed, 11 insertions(+), 20 deletions(-) rename 86_Target/csharp/{Target => }/Angle.cs (100%) rename 86_Target/csharp/{Target => }/Explosion.cs (100%) rename 86_Target/csharp/{Target => }/FiringRange.cs (100%) rename 86_Target/csharp/{Target => }/Game.cs (100%) rename 86_Target/csharp/{Target => }/Input.cs (100%) rename 86_Target/csharp/{Target => }/Offset.cs (100%) rename 86_Target/csharp/{Target => }/Point.cs (100%) rename 86_Target/csharp/{Target => }/Program.cs (100%) rename 86_Target/csharp/{Target => }/RandomExtensions.cs (100%) rename 86_Target/csharp/{Target => }/Strings/TitleAndInstructions.txt (100%) rename 86_Target/csharp/{Target => }/Target.csproj (100%) diff --git a/86_Target/csharp/Target/Angle.cs b/86_Target/csharp/Angle.cs similarity index 100% rename from 86_Target/csharp/Target/Angle.cs rename to 86_Target/csharp/Angle.cs diff --git a/86_Target/csharp/Target/Explosion.cs b/86_Target/csharp/Explosion.cs similarity index 100% rename from 86_Target/csharp/Target/Explosion.cs rename to 86_Target/csharp/Explosion.cs diff --git a/86_Target/csharp/Target/FiringRange.cs b/86_Target/csharp/FiringRange.cs similarity index 100% rename from 86_Target/csharp/Target/FiringRange.cs rename to 86_Target/csharp/FiringRange.cs diff --git a/86_Target/csharp/Target/Game.cs b/86_Target/csharp/Game.cs similarity index 100% rename from 86_Target/csharp/Target/Game.cs rename to 86_Target/csharp/Game.cs diff --git a/86_Target/csharp/Target/Input.cs b/86_Target/csharp/Input.cs similarity index 100% rename from 86_Target/csharp/Target/Input.cs rename to 86_Target/csharp/Input.cs diff --git a/86_Target/csharp/Target/Offset.cs b/86_Target/csharp/Offset.cs similarity index 100% rename from 86_Target/csharp/Target/Offset.cs rename to 86_Target/csharp/Offset.cs diff --git a/86_Target/csharp/Target/Point.cs b/86_Target/csharp/Point.cs similarity index 100% rename from 86_Target/csharp/Target/Point.cs rename to 86_Target/csharp/Point.cs diff --git a/86_Target/csharp/Target/Program.cs b/86_Target/csharp/Program.cs similarity index 100% rename from 86_Target/csharp/Target/Program.cs rename to 86_Target/csharp/Program.cs diff --git a/86_Target/csharp/Target/RandomExtensions.cs b/86_Target/csharp/RandomExtensions.cs similarity index 100% rename from 86_Target/csharp/Target/RandomExtensions.cs rename to 86_Target/csharp/RandomExtensions.cs diff --git a/86_Target/csharp/Target/Strings/TitleAndInstructions.txt b/86_Target/csharp/Strings/TitleAndInstructions.txt similarity index 100% rename from 86_Target/csharp/Target/Strings/TitleAndInstructions.txt rename to 86_Target/csharp/Strings/TitleAndInstructions.txt diff --git a/86_Target/csharp/Target/Target.csproj b/86_Target/csharp/Target.csproj similarity index 100% rename from 86_Target/csharp/Target/Target.csproj rename to 86_Target/csharp/Target.csproj diff --git a/86_Target/csharp/Target.sln b/86_Target/csharp/Target.sln index 3e111702..9aa2c86d 100644 --- a/86_Target/csharp/Target.sln +++ b/86_Target/csharp/Target.sln @@ -1,34 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Target", "Target\Target.csproj", "{8B0B5114-1D05-4F8D-B328-EA2FB89992E7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Target", "Target.csproj", "{DF03CFDB-2857-4416-A07A-80D84874F46E}" 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(ProjectConfigurationPlatforms) = postSolution + {DF03CFDB-2857-4416-A07A-80D84874F46E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DF03CFDB-2857-4416-A07A-80D84874F46E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DF03CFDB-2857-4416-A07A-80D84874F46E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DF03CFDB-2857-4416-A07A-80D84874F46E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Debug|x64.ActiveCfg = Debug|Any CPU - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Debug|x64.Build.0 = Debug|Any CPU - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Debug|x86.ActiveCfg = Debug|Any CPU - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Debug|x86.Build.0 = Debug|Any CPU - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Release|Any CPU.Build.0 = Release|Any CPU - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Release|x64.ActiveCfg = Release|Any CPU - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Release|x64.Build.0 = Release|Any CPU - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Release|x86.ActiveCfg = Release|Any CPU - {8B0B5114-1D05-4F8D-B328-EA2FB89992E7}.Release|x86.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B49DF932-4DF9-44C3-B63F-FD9443B4DDD2} EndGlobalSection EndGlobal From eaed38c036e6794ad73e607a4cfeaee6def94718 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 15:11:35 +0200 Subject: [PATCH 222/337] Simplify 3-D Plot (C#) folder structure --- 87_3-D_Plot/csharp/{Plot => }/Function.cs | 0 87_3-D_Plot/csharp/{Plot => }/Plot.csproj | 0 87_3-D_Plot/csharp/Plot.sln | 31 ++++++++--------------- 87_3-D_Plot/csharp/{Plot => }/Program.cs | 0 4 files changed, 11 insertions(+), 20 deletions(-) rename 87_3-D_Plot/csharp/{Plot => }/Function.cs (100%) rename 87_3-D_Plot/csharp/{Plot => }/Plot.csproj (100%) rename 87_3-D_Plot/csharp/{Plot => }/Program.cs (100%) diff --git a/87_3-D_Plot/csharp/Plot/Function.cs b/87_3-D_Plot/csharp/Function.cs similarity index 100% rename from 87_3-D_Plot/csharp/Plot/Function.cs rename to 87_3-D_Plot/csharp/Function.cs diff --git a/87_3-D_Plot/csharp/Plot/Plot.csproj b/87_3-D_Plot/csharp/Plot.csproj similarity index 100% rename from 87_3-D_Plot/csharp/Plot/Plot.csproj rename to 87_3-D_Plot/csharp/Plot.csproj diff --git a/87_3-D_Plot/csharp/Plot.sln b/87_3-D_Plot/csharp/Plot.sln index 1402bc2a..b296ace9 100644 --- a/87_3-D_Plot/csharp/Plot.sln +++ b/87_3-D_Plot/csharp/Plot.sln @@ -1,34 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plot", "Plot\Plot.csproj", "{8857AE83-F481-43B0-AA51-D78E1340BD93}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Plot", "Plot.csproj", "{8000A3CF-612D-4FB7-B53D-885BB6E5492B}" 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(ProjectConfigurationPlatforms) = postSolution + {8000A3CF-612D-4FB7-B53D-885BB6E5492B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8000A3CF-612D-4FB7-B53D-885BB6E5492B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8000A3CF-612D-4FB7-B53D-885BB6E5492B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8000A3CF-612D-4FB7-B53D-885BB6E5492B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Debug|x64.ActiveCfg = Debug|Any CPU - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Debug|x64.Build.0 = Debug|Any CPU - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Debug|x86.ActiveCfg = Debug|Any CPU - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Debug|x86.Build.0 = Debug|Any CPU - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Release|Any CPU.Build.0 = Release|Any CPU - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Release|x64.ActiveCfg = Release|Any CPU - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Release|x64.Build.0 = Release|Any CPU - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Release|x86.ActiveCfg = Release|Any CPU - {8857AE83-F481-43B0-AA51-D78E1340BD93}.Release|x86.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5DE8E572-67C9-4DE3-B851-447B78FE983A} EndGlobalSection EndGlobal diff --git a/87_3-D_Plot/csharp/Plot/Program.cs b/87_3-D_Plot/csharp/Program.cs similarity index 100% rename from 87_3-D_Plot/csharp/Plot/Program.cs rename to 87_3-D_Plot/csharp/Program.cs From d35fa5a54694ed79160d133f314d13e0cf2fade3 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 15:17:54 +0200 Subject: [PATCH 223/337] Simplify TicTacToe (C#) folder structure --- .../csharp/{tictactoe1 => }/Program.cs | 0 .../tictactoe1.csproj => TicTacToe.csproj} | 0 89_Tic-Tac-Toe/csharp/TicTacToe.sln | 19 +++++++++++-------- 3 files changed, 11 insertions(+), 8 deletions(-) rename 89_Tic-Tac-Toe/csharp/{tictactoe1 => }/Program.cs (100%) rename 89_Tic-Tac-Toe/csharp/{tictactoe1/tictactoe1.csproj => TicTacToe.csproj} (100%) diff --git a/89_Tic-Tac-Toe/csharp/tictactoe1/Program.cs b/89_Tic-Tac-Toe/csharp/Program.cs similarity index 100% rename from 89_Tic-Tac-Toe/csharp/tictactoe1/Program.cs rename to 89_Tic-Tac-Toe/csharp/Program.cs diff --git a/89_Tic-Tac-Toe/csharp/tictactoe1/tictactoe1.csproj b/89_Tic-Tac-Toe/csharp/TicTacToe.csproj similarity index 100% rename from 89_Tic-Tac-Toe/csharp/tictactoe1/tictactoe1.csproj rename to 89_Tic-Tac-Toe/csharp/TicTacToe.csproj diff --git a/89_Tic-Tac-Toe/csharp/TicTacToe.sln b/89_Tic-Tac-Toe/csharp/TicTacToe.sln index c26bd1b4..f334433a 100644 --- a/89_Tic-Tac-Toe/csharp/TicTacToe.sln +++ b/89_Tic-Tac-Toe/csharp/TicTacToe.sln @@ -1,22 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30114.105 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tictactoe1", "tictactoe1\tictactoe1.csproj", "{FE9379CF-AF73-43DA-8FEC-2BCA7FA13A5E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TicTacToe", "TicTacToe.csproj", "{A318881A-DA1A-499C-8820-69A1BF02B824}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A318881A-DA1A-499C-8820-69A1BF02B824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A318881A-DA1A-499C-8820-69A1BF02B824}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A318881A-DA1A-499C-8820-69A1BF02B824}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A318881A-DA1A-499C-8820-69A1BF02B824}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FE9379CF-AF73-43DA-8FEC-2BCA7FA13A5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FE9379CF-AF73-43DA-8FEC-2BCA7FA13A5E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FE9379CF-AF73-43DA-8FEC-2BCA7FA13A5E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FE9379CF-AF73-43DA-8FEC-2BCA7FA13A5E}.Release|Any CPU.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B5343227-EE3B-4829-AC09-DF6702D24501} EndGlobalSection EndGlobal From 3b896fc1447f640313fc50eaed91ce7d624a341f Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 15:25:01 +0200 Subject: [PATCH 224/337] Simplify Tower (C#) folder structure --- 90_Tower/csharp/{Tower => }/Game.cs | 0 90_Tower/csharp/{Tower => }/Models/Needle.cs | 0 90_Tower/csharp/{Tower => }/Models/Towers.cs | 0 90_Tower/csharp/{Tower => }/Program.cs | 0 .../{Tower => }/Resources/Congratulations.txt | 0 .../{Tower => }/Resources/DiskCountPrompt.txt | 0 .../{Tower => }/Resources/DiskCountQuit.txt | 0 .../{Tower => }/Resources/DiskCountRetry.txt | 0 .../{Tower => }/Resources/DiskNotInPlay.txt | 0 .../{Tower => }/Resources/DiskPrompt.txt | 0 .../csharp/{Tower => }/Resources/DiskQuit.txt | 0 .../{Tower => }/Resources/DiskRetry.txt | 0 .../{Tower => }/Resources/DiskUnavailable.txt | 0 .../{Tower => }/Resources/IllegalMove.txt | 0 .../{Tower => }/Resources/Instructions.txt | 0 .../csharp/{Tower => }/Resources/Intro.txt | 0 .../{Tower => }/Resources/NeedlePrompt.txt | 0 .../{Tower => }/Resources/NeedleQuit.txt | 0 .../{Tower => }/Resources/NeedleRetry.txt | 0 .../{Tower => }/Resources/PlayAgainPrompt.txt | 0 .../csharp/{Tower => }/Resources/Strings.cs | 0 .../{Tower => }/Resources/TaskFinished.txt | 0 .../csharp/{Tower => }/Resources/Thanks.txt | 0 .../csharp/{Tower => }/Resources/Title.txt | 0 .../{Tower => }/Resources/TooManyMoves.txt | 0 .../{Tower => }/Resources/YesNoPrompt.txt | 0 90_Tower/csharp/{Tower => }/Tower.csproj | 0 90_Tower/csharp/Tower.sln | 31 +++++++------------ 90_Tower/csharp/{Tower => }/UI/Input.cs | 0 90_Tower/csharp/{Tower => }/UI/Prompt.cs | 0 .../csharp/{Tower => }/UI/TowerDisplay.cs | 0 31 files changed, 11 insertions(+), 20 deletions(-) rename 90_Tower/csharp/{Tower => }/Game.cs (100%) rename 90_Tower/csharp/{Tower => }/Models/Needle.cs (100%) rename 90_Tower/csharp/{Tower => }/Models/Towers.cs (100%) rename 90_Tower/csharp/{Tower => }/Program.cs (100%) rename 90_Tower/csharp/{Tower => }/Resources/Congratulations.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/DiskCountPrompt.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/DiskCountQuit.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/DiskCountRetry.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/DiskNotInPlay.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/DiskPrompt.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/DiskQuit.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/DiskRetry.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/DiskUnavailable.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/IllegalMove.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/Instructions.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/Intro.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/NeedlePrompt.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/NeedleQuit.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/NeedleRetry.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/PlayAgainPrompt.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/Strings.cs (100%) rename 90_Tower/csharp/{Tower => }/Resources/TaskFinished.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/Thanks.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/Title.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/TooManyMoves.txt (100%) rename 90_Tower/csharp/{Tower => }/Resources/YesNoPrompt.txt (100%) rename 90_Tower/csharp/{Tower => }/Tower.csproj (100%) rename 90_Tower/csharp/{Tower => }/UI/Input.cs (100%) rename 90_Tower/csharp/{Tower => }/UI/Prompt.cs (100%) rename 90_Tower/csharp/{Tower => }/UI/TowerDisplay.cs (100%) diff --git a/90_Tower/csharp/Tower/Game.cs b/90_Tower/csharp/Game.cs similarity index 100% rename from 90_Tower/csharp/Tower/Game.cs rename to 90_Tower/csharp/Game.cs diff --git a/90_Tower/csharp/Tower/Models/Needle.cs b/90_Tower/csharp/Models/Needle.cs similarity index 100% rename from 90_Tower/csharp/Tower/Models/Needle.cs rename to 90_Tower/csharp/Models/Needle.cs diff --git a/90_Tower/csharp/Tower/Models/Towers.cs b/90_Tower/csharp/Models/Towers.cs similarity index 100% rename from 90_Tower/csharp/Tower/Models/Towers.cs rename to 90_Tower/csharp/Models/Towers.cs diff --git a/90_Tower/csharp/Tower/Program.cs b/90_Tower/csharp/Program.cs similarity index 100% rename from 90_Tower/csharp/Tower/Program.cs rename to 90_Tower/csharp/Program.cs diff --git a/90_Tower/csharp/Tower/Resources/Congratulations.txt b/90_Tower/csharp/Resources/Congratulations.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/Congratulations.txt rename to 90_Tower/csharp/Resources/Congratulations.txt diff --git a/90_Tower/csharp/Tower/Resources/DiskCountPrompt.txt b/90_Tower/csharp/Resources/DiskCountPrompt.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/DiskCountPrompt.txt rename to 90_Tower/csharp/Resources/DiskCountPrompt.txt diff --git a/90_Tower/csharp/Tower/Resources/DiskCountQuit.txt b/90_Tower/csharp/Resources/DiskCountQuit.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/DiskCountQuit.txt rename to 90_Tower/csharp/Resources/DiskCountQuit.txt diff --git a/90_Tower/csharp/Tower/Resources/DiskCountRetry.txt b/90_Tower/csharp/Resources/DiskCountRetry.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/DiskCountRetry.txt rename to 90_Tower/csharp/Resources/DiskCountRetry.txt diff --git a/90_Tower/csharp/Tower/Resources/DiskNotInPlay.txt b/90_Tower/csharp/Resources/DiskNotInPlay.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/DiskNotInPlay.txt rename to 90_Tower/csharp/Resources/DiskNotInPlay.txt diff --git a/90_Tower/csharp/Tower/Resources/DiskPrompt.txt b/90_Tower/csharp/Resources/DiskPrompt.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/DiskPrompt.txt rename to 90_Tower/csharp/Resources/DiskPrompt.txt diff --git a/90_Tower/csharp/Tower/Resources/DiskQuit.txt b/90_Tower/csharp/Resources/DiskQuit.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/DiskQuit.txt rename to 90_Tower/csharp/Resources/DiskQuit.txt diff --git a/90_Tower/csharp/Tower/Resources/DiskRetry.txt b/90_Tower/csharp/Resources/DiskRetry.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/DiskRetry.txt rename to 90_Tower/csharp/Resources/DiskRetry.txt diff --git a/90_Tower/csharp/Tower/Resources/DiskUnavailable.txt b/90_Tower/csharp/Resources/DiskUnavailable.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/DiskUnavailable.txt rename to 90_Tower/csharp/Resources/DiskUnavailable.txt diff --git a/90_Tower/csharp/Tower/Resources/IllegalMove.txt b/90_Tower/csharp/Resources/IllegalMove.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/IllegalMove.txt rename to 90_Tower/csharp/Resources/IllegalMove.txt diff --git a/90_Tower/csharp/Tower/Resources/Instructions.txt b/90_Tower/csharp/Resources/Instructions.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/Instructions.txt rename to 90_Tower/csharp/Resources/Instructions.txt diff --git a/90_Tower/csharp/Tower/Resources/Intro.txt b/90_Tower/csharp/Resources/Intro.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/Intro.txt rename to 90_Tower/csharp/Resources/Intro.txt diff --git a/90_Tower/csharp/Tower/Resources/NeedlePrompt.txt b/90_Tower/csharp/Resources/NeedlePrompt.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/NeedlePrompt.txt rename to 90_Tower/csharp/Resources/NeedlePrompt.txt diff --git a/90_Tower/csharp/Tower/Resources/NeedleQuit.txt b/90_Tower/csharp/Resources/NeedleQuit.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/NeedleQuit.txt rename to 90_Tower/csharp/Resources/NeedleQuit.txt diff --git a/90_Tower/csharp/Tower/Resources/NeedleRetry.txt b/90_Tower/csharp/Resources/NeedleRetry.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/NeedleRetry.txt rename to 90_Tower/csharp/Resources/NeedleRetry.txt diff --git a/90_Tower/csharp/Tower/Resources/PlayAgainPrompt.txt b/90_Tower/csharp/Resources/PlayAgainPrompt.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/PlayAgainPrompt.txt rename to 90_Tower/csharp/Resources/PlayAgainPrompt.txt diff --git a/90_Tower/csharp/Tower/Resources/Strings.cs b/90_Tower/csharp/Resources/Strings.cs similarity index 100% rename from 90_Tower/csharp/Tower/Resources/Strings.cs rename to 90_Tower/csharp/Resources/Strings.cs diff --git a/90_Tower/csharp/Tower/Resources/TaskFinished.txt b/90_Tower/csharp/Resources/TaskFinished.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/TaskFinished.txt rename to 90_Tower/csharp/Resources/TaskFinished.txt diff --git a/90_Tower/csharp/Tower/Resources/Thanks.txt b/90_Tower/csharp/Resources/Thanks.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/Thanks.txt rename to 90_Tower/csharp/Resources/Thanks.txt diff --git a/90_Tower/csharp/Tower/Resources/Title.txt b/90_Tower/csharp/Resources/Title.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/Title.txt rename to 90_Tower/csharp/Resources/Title.txt diff --git a/90_Tower/csharp/Tower/Resources/TooManyMoves.txt b/90_Tower/csharp/Resources/TooManyMoves.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/TooManyMoves.txt rename to 90_Tower/csharp/Resources/TooManyMoves.txt diff --git a/90_Tower/csharp/Tower/Resources/YesNoPrompt.txt b/90_Tower/csharp/Resources/YesNoPrompt.txt similarity index 100% rename from 90_Tower/csharp/Tower/Resources/YesNoPrompt.txt rename to 90_Tower/csharp/Resources/YesNoPrompt.txt diff --git a/90_Tower/csharp/Tower/Tower.csproj b/90_Tower/csharp/Tower.csproj similarity index 100% rename from 90_Tower/csharp/Tower/Tower.csproj rename to 90_Tower/csharp/Tower.csproj diff --git a/90_Tower/csharp/Tower.sln b/90_Tower/csharp/Tower.sln index 2c6e524d..6f87b0b9 100644 --- a/90_Tower/csharp/Tower.sln +++ b/90_Tower/csharp/Tower.sln @@ -1,34 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tower", "tower\Tower.csproj", "{2E14FCD5-A52C-4292-A7F4-0C7E5780C962}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tower", "Tower.csproj", "{EEED33AD-3DE2-49AA-8AF1-2174C510E128}" 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(ProjectConfigurationPlatforms) = postSolution + {EEED33AD-3DE2-49AA-8AF1-2174C510E128}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EEED33AD-3DE2-49AA-8AF1-2174C510E128}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EEED33AD-3DE2-49AA-8AF1-2174C510E128}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EEED33AD-3DE2-49AA-8AF1-2174C510E128}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Debug|x64.ActiveCfg = Debug|Any CPU - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Debug|x64.Build.0 = Debug|Any CPU - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Debug|x86.ActiveCfg = Debug|Any CPU - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Debug|x86.Build.0 = Debug|Any CPU - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Release|Any CPU.Build.0 = Release|Any CPU - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Release|x64.ActiveCfg = Release|Any CPU - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Release|x64.Build.0 = Release|Any CPU - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Release|x86.ActiveCfg = Release|Any CPU - {2E14FCD5-A52C-4292-A7F4-0C7E5780C962}.Release|x86.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BDCB8278-62ED-46E3-92C2-FF572E0E3ED3} EndGlobalSection EndGlobal diff --git a/90_Tower/csharp/Tower/UI/Input.cs b/90_Tower/csharp/UI/Input.cs similarity index 100% rename from 90_Tower/csharp/Tower/UI/Input.cs rename to 90_Tower/csharp/UI/Input.cs diff --git a/90_Tower/csharp/Tower/UI/Prompt.cs b/90_Tower/csharp/UI/Prompt.cs similarity index 100% rename from 90_Tower/csharp/Tower/UI/Prompt.cs rename to 90_Tower/csharp/UI/Prompt.cs diff --git a/90_Tower/csharp/Tower/UI/TowerDisplay.cs b/90_Tower/csharp/UI/TowerDisplay.cs similarity index 100% rename from 90_Tower/csharp/Tower/UI/TowerDisplay.cs rename to 90_Tower/csharp/UI/TowerDisplay.cs From 33f0a2b5aae2dd264ca859fb2ff27c6d36562349 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 15:29:38 +0200 Subject: [PATCH 225/337] Rename some projects to match game name --- .../DotnetUtils/DotnetUtils/PortInfo.cs | 2 +- .../csharp/{csharp.csproj => Awari.csproj} | 0 04_Awari/csharp/Awari.sln | 19 +++++++++++-------- .../{21_calendar.csproj => Calendar.csproj} | 0 .../csharp/{21_calendar.sln => Calendar.sln} | 10 +++++----- .../csharp/{csharp.csproj => Gunner.csproj} | 0 42_Gunner/csharp/Gunner.sln | 15 +++++++++------ 47_Hi-Lo/csharp/{hi-lo.csproj => HiLo.csproj} | 0 47_Hi-Lo/csharp/HiLo.sln | 15 +++++++++------ 47_Hi-Lo/csharp/{hi-lo.cs => Program.cs} | 0 .../vbnet/{ThreeDPlot.sln => Plot.sln} | 15 +++++++++------ .../vbnet/{ThreeDPlot.vbproj => Plot.vbproj} | 2 +- 12 files changed, 45 insertions(+), 33 deletions(-) rename 04_Awari/csharp/{csharp.csproj => Awari.csproj} (100%) rename 21_Calendar/csharp/{21_calendar.csproj => Calendar.csproj} (100%) rename 21_Calendar/csharp/{21_calendar.sln => Calendar.sln} (64%) rename 42_Gunner/csharp/{csharp.csproj => Gunner.csproj} (100%) rename 47_Hi-Lo/csharp/{hi-lo.csproj => HiLo.csproj} (100%) rename 47_Hi-Lo/csharp/{hi-lo.cs => Program.cs} (100%) rename 87_3-D_Plot/vbnet/{ThreeDPlot.sln => Plot.sln} (54%) rename 87_3-D_Plot/vbnet/{ThreeDPlot.vbproj => Plot.vbproj} (81%) diff --git a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs index 1cb0ba03..535c0ca0 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs @@ -19,7 +19,7 @@ public record PortInfo( // .NET namespaces cannot have a digit as the first character // For games whose name starts with a digit, we map the name to a specific string private static readonly Dictionary specialGameNames = new() { - { "3-D_Plot", "ThreeDPlot" }, + { "3-D_Plot", "Plot" }, { "3-D_Tic-Tac-Toe", "ThreeDTicTacToe" }, { "23_Matches", "TwentyThreeMatches"} }; diff --git a/04_Awari/csharp/csharp.csproj b/04_Awari/csharp/Awari.csproj similarity index 100% rename from 04_Awari/csharp/csharp.csproj rename to 04_Awari/csharp/Awari.csproj diff --git a/04_Awari/csharp/Awari.sln b/04_Awari/csharp/Awari.sln index 816cfcc9..492aa580 100644 --- a/04_Awari/csharp/Awari.sln +++ b/04_Awari/csharp/Awari.sln @@ -1,22 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30114.105 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp", "csharp.csproj", "{4E2057CB-0BFE-41A4-910C-798DFABF7FE9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Awari", "Awari.csproj", "{DD161F58-D90F-481A-8275-96E01D229A70}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DD161F58-D90F-481A-8275-96E01D229A70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DD161F58-D90F-481A-8275-96E01D229A70}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DD161F58-D90F-481A-8275-96E01D229A70}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DD161F58-D90F-481A-8275-96E01D229A70}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4E2057CB-0BFE-41A4-910C-798DFABF7FE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4E2057CB-0BFE-41A4-910C-798DFABF7FE9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4E2057CB-0BFE-41A4-910C-798DFABF7FE9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4E2057CB-0BFE-41A4-910C-798DFABF7FE9}.Release|Any CPU.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7F5C288A-A6C6-4AC0-96E3-6A3B482A0947} EndGlobalSection EndGlobal diff --git a/21_Calendar/csharp/21_calendar.csproj b/21_Calendar/csharp/Calendar.csproj similarity index 100% rename from 21_Calendar/csharp/21_calendar.csproj rename to 21_Calendar/csharp/Calendar.csproj diff --git a/21_Calendar/csharp/21_calendar.sln b/21_Calendar/csharp/Calendar.sln similarity index 64% rename from 21_Calendar/csharp/21_calendar.sln rename to 21_Calendar/csharp/Calendar.sln index d8330a26..8b2be04b 100644 --- a/21_Calendar/csharp/21_calendar.sln +++ b/21_Calendar/csharp/Calendar.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31613.86 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "21_calendar", "21_calendar.csproj", "{99AB85E1-A42B-4FEF-8BA6-0ED877F05249}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Calendar", "Calendar.csproj", "{1EADFB6C-4496-42C2-A80F-84FEC3F061D1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {99AB85E1-A42B-4FEF-8BA6-0ED877F05249}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {99AB85E1-A42B-4FEF-8BA6-0ED877F05249}.Debug|Any CPU.Build.0 = Debug|Any CPU - {99AB85E1-A42B-4FEF-8BA6-0ED877F05249}.Release|Any CPU.ActiveCfg = Release|Any CPU - {99AB85E1-A42B-4FEF-8BA6-0ED877F05249}.Release|Any CPU.Build.0 = Release|Any CPU + {1EADFB6C-4496-42C2-A80F-84FEC3F061D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1EADFB6C-4496-42C2-A80F-84FEC3F061D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1EADFB6C-4496-42C2-A80F-84FEC3F061D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1EADFB6C-4496-42C2-A80F-84FEC3F061D1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/42_Gunner/csharp/csharp.csproj b/42_Gunner/csharp/Gunner.csproj similarity index 100% rename from 42_Gunner/csharp/csharp.csproj rename to 42_Gunner/csharp/Gunner.csproj diff --git a/42_Gunner/csharp/Gunner.sln b/42_Gunner/csharp/Gunner.sln index bbc80af3..5fadb359 100644 --- a/42_Gunner/csharp/Gunner.sln +++ b/42_Gunner/csharp/Gunner.sln @@ -3,20 +3,23 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30114.105 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp", "csharp.csproj", "{83323E98-D981-4AC2-A74B-36804C9C2497}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gunner", "Gunner.csproj", "{0279F69D-A69A-49B6-867C-78AA4F4DB962}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0279F69D-A69A-49B6-867C-78AA4F4DB962}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0279F69D-A69A-49B6-867C-78AA4F4DB962}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0279F69D-A69A-49B6-867C-78AA4F4DB962}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0279F69D-A69A-49B6-867C-78AA4F4DB962}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {83323E98-D981-4AC2-A74B-36804C9C2497}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {83323E98-D981-4AC2-A74B-36804C9C2497}.Debug|Any CPU.Build.0 = Debug|Any CPU - {83323E98-D981-4AC2-A74B-36804C9C2497}.Release|Any CPU.ActiveCfg = Release|Any CPU - {83323E98-D981-4AC2-A74B-36804C9C2497}.Release|Any CPU.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {09C668DA-38D4-4EF4-9FCA-EB1FF9EF6067} EndGlobalSection EndGlobal diff --git a/47_Hi-Lo/csharp/hi-lo.csproj b/47_Hi-Lo/csharp/HiLo.csproj similarity index 100% rename from 47_Hi-Lo/csharp/hi-lo.csproj rename to 47_Hi-Lo/csharp/HiLo.csproj diff --git a/47_Hi-Lo/csharp/HiLo.sln b/47_Hi-Lo/csharp/HiLo.sln index b735d83d..225235b8 100644 --- a/47_Hi-Lo/csharp/HiLo.sln +++ b/47_Hi-Lo/csharp/HiLo.sln @@ -3,20 +3,23 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30114.105 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "hi-lo", "hi-lo.csproj", "{59721819-A474-4348-8E3D-5F2FCA5D95FA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HiLo", "HiLo.csproj", "{C4D0FAB6-056D-4DD2-827D-3383BE0AA382}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C4D0FAB6-056D-4DD2-827D-3383BE0AA382}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C4D0FAB6-056D-4DD2-827D-3383BE0AA382}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C4D0FAB6-056D-4DD2-827D-3383BE0AA382}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C4D0FAB6-056D-4DD2-827D-3383BE0AA382}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {59721819-A474-4348-8E3D-5F2FCA5D95FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {59721819-A474-4348-8E3D-5F2FCA5D95FA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {59721819-A474-4348-8E3D-5F2FCA5D95FA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {59721819-A474-4348-8E3D-5F2FCA5D95FA}.Release|Any CPU.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BF77DB59-426B-4A01-A8AC-09AAF42DA633} EndGlobalSection EndGlobal diff --git a/47_Hi-Lo/csharp/hi-lo.cs b/47_Hi-Lo/csharp/Program.cs similarity index 100% rename from 47_Hi-Lo/csharp/hi-lo.cs rename to 47_Hi-Lo/csharp/Program.cs diff --git a/87_3-D_Plot/vbnet/ThreeDPlot.sln b/87_3-D_Plot/vbnet/Plot.sln similarity index 54% rename from 87_3-D_Plot/vbnet/ThreeDPlot.sln rename to 87_3-D_Plot/vbnet/Plot.sln index b2ea1dbe..a0dcbfcb 100644 --- a/87_3-D_Plot/vbnet/ThreeDPlot.sln +++ b/87_3-D_Plot/vbnet/Plot.sln @@ -3,20 +3,23 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30114.105 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ThreeDPlot", "ThreeDPlot.vbproj", "{FF54B85E-8AD1-4AD5-BB54-2E3DABAA0998}" +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Plot", "Plot.vbproj", "{534355CC-A2C1-4138-9EB5-09D658DD4504}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {534355CC-A2C1-4138-9EB5-09D658DD4504}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {534355CC-A2C1-4138-9EB5-09D658DD4504}.Debug|Any CPU.Build.0 = Debug|Any CPU + {534355CC-A2C1-4138-9EB5-09D658DD4504}.Release|Any CPU.ActiveCfg = Release|Any CPU + {534355CC-A2C1-4138-9EB5-09D658DD4504}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FF54B85E-8AD1-4AD5-BB54-2E3DABAA0998}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FF54B85E-8AD1-4AD5-BB54-2E3DABAA0998}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FF54B85E-8AD1-4AD5-BB54-2E3DABAA0998}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FF54B85E-8AD1-4AD5-BB54-2E3DABAA0998}.Release|Any CPU.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CAD09CCC-4522-438E-A8C6-514A866D90DE} EndGlobalSection EndGlobal diff --git a/87_3-D_Plot/vbnet/ThreeDPlot.vbproj b/87_3-D_Plot/vbnet/Plot.vbproj similarity index 81% rename from 87_3-D_Plot/vbnet/ThreeDPlot.vbproj rename to 87_3-D_Plot/vbnet/Plot.vbproj index 903ea6aa..be687f57 100644 --- a/87_3-D_Plot/vbnet/ThreeDPlot.vbproj +++ b/87_3-D_Plot/vbnet/Plot.vbproj @@ -1,7 +1,7 @@ Exe - ThreeDPlot + Plot net6.0 16.9 From a0c2565adaa6dfc2d81de4771174f17edb4ce5f3 Mon Sep 17 00:00:00 2001 From: Claus Volko <49327712+adokhugi@users.noreply.github.com> Date: Mon, 17 Jan 2022 17:17:34 +0100 Subject: [PATCH 226/337] Kotlin implementation of the Acey Ducey game --- 01_Acey_Ducey/aceyducey.kt | 74 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 01_Acey_Ducey/aceyducey.kt diff --git a/01_Acey_Ducey/aceyducey.kt b/01_Acey_Ducey/aceyducey.kt new file mode 100644 index 00000000..ccc5eb0a --- /dev/null +++ b/01_Acey_Ducey/aceyducey.kt @@ -0,0 +1,74 @@ +import java.util.Random + +fun printCard(a: Int) { + if (a < 11) println(a) + if (a == 11) println("JACK") + if (a == 12) println("QUEEN") + if (a == 13) println("KING") + if (a == 14) println("ACE") +} + +fun main() { + println("ACEY DUCEY CARD GAME") + println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + println() + println() + println("ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER ") + println("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP") + println("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING") + println("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE") + println("A VALUE BETWEEN THE FIRST TWO.") + println("IF YOU DO NOT WANT TO BET, INPUT A 0") + var random = Random() + do { + var q = 100 + var a : Int + var b : Int + var m : Int + println("YOU NOW HAVE " + q + " DOLLARS.") + println() + do { + do { + do { + println("HERE ARE YOUR NEXT TWO CARDS: ") + do { + a = random.nextInt(12) + 2 + b = random.nextInt(12) + 2 + } while (a >= b); + printCard(a) + printCard(b) + println() + println() + print("WHAT IS YOUR BET") + m = readLine()!!.toInt() + if (m == 0) { + println("CHICKEN!!") + println() + } + } while (m == 0); + if (m > q) { + println("SORRY, MY FRIEND, BUT YOU BET TOO MUCH.") + println("YOU HAVE ONLY " + q + " DOLLARS TO BET.") + } + } while (m > q); + var c = random.nextInt(12) + 2 + printCard(c) + println() + if (c > a && c < b) { + println("YOU WIN!!!") + q += m + } + else { + println("SORRY, YOU LOSE") + if (m < q) q -= m + } + } while (m < q); + println() + println() + println("SORRY, FRIEND, BUT YOU BLEW YOUR WAD.") + println() + println() + println("TRY AGAIN (YES OR NO)") + } while (readLine() == "YES"); + println("O.K., HOPE YOU HAD FUN!") +} From 8df8eb6165dbb9c8bfa02de9463e212704506689 Mon Sep 17 00:00:00 2001 From: Stefan Waldmann Date: Mon, 17 Jan 2022 18:48:29 +0100 Subject: [PATCH 227/337] Refactor, add Javadoc --- 55_Life/java/src/java/Life.java | 63 ++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/55_Life/java/src/java/Life.java b/55_Life/java/src/java/Life.java index 3b592c14..41b30c8d 100644 --- a/55_Life/java/src/java/Life.java +++ b/55_Life/java/src/java/Life.java @@ -2,49 +2,69 @@ import java.util.ArrayList; import java.util.List; import java.util.Scanner; +/** + * Represents a state change for a single cell within the matrix. + * + * @param y the y coordinate (row) of the cell + * @param x the x coordinate (column) of the cell + * @param newState the new state of the cell (either DEAD or ALIVE) + */ record Transition(int y, int x, byte newState) { } +/** + * The Game of Life class.
+ *
+ * Mimics the behaviour of the BASIC version, however the Java code does not have much in common with the original. + *
+ * Differences in behaviour: + *

    + *
  • Input supports the "." character, but it's optional.
  • + *
  • Input regarding the "DONE" string is case insensitive.
  • + *
+ */ public class Life { private static final byte DEAD = 0; private static final byte ALIVE = 1; + private final Scanner consoleReader = new Scanner(System.in); + private final byte[][] matrix = new byte[21][67]; private int generation = 0; private int population = 0; boolean invalid = false; private void start() throws Exception { - Scanner s = new Scanner(System.in); printGameHeader(); readPattern(); while (true) { - printPattern(); + printGeneration(); advanceToNextGeneration(); - s.nextLine(); + consoleReader.nextLine(); // Thread.sleep(1000); } } private void advanceToNextGeneration() { + // store all transitions of cells in a list, i.e. if a dead cell becomes alive, or a living cell dies List transitions = new ArrayList<>(); for (int y = 0; y < matrix.length; y++) { for (int x = 0; x < matrix[y].length; x++) { int neighbours = countNeighbours(y, x); - if (matrix[y][x] == DEAD) { - if (neighbours == 3) { - transitions.add(new Transition(y, x, ALIVE)); - population++; - } - } else { - // cell is alive + if (matrix[y][x] == ALIVE) { if (neighbours < 2 || neighbours > 3) { transitions.add(new Transition(y, x, DEAD)); population--; } + } else { // cell is dead + if (neighbours == 3) { + transitions.add(new Transition(y, x, ALIVE)); + population++; + } } } } + // apply all transitions to the matrix transitions.forEach(t -> matrix[t.y()][t.x()] = t.newState()); generation++; } @@ -66,14 +86,13 @@ public class Life { private void readPattern() { System.out.println("ENTER YOUR PATTERN:"); - Scanner s = new Scanner(System.in); List lines = new ArrayList<>(); String line; int maxLineLength = 0; boolean reading = true; while (reading) { System.out.print("? "); - line = s.nextLine(); + line = consoleReader.nextLine(); if (line.equalsIgnoreCase("done")) { reading = false; } else { @@ -93,24 +112,28 @@ public class Life { String line = lines.get(y); for (int x = 1; x <= line.length(); x++) { if (line.charAt(x-1) == '*') { - matrix[round(yMin + y)][round(xMin + x)] = ALIVE; + matrix[floor(yMin + y)][floor(xMin + x)] = ALIVE; population++; } } } } - private int round(float f) { + private int floor(float f) { return (int) Math.floor(f); } private void printGameHeader() { - System.out.println(" ".repeat(34) + "LIFE"); - System.out.println(" ".repeat(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + printIndented(34, "LIFE"); + printIndented(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n\n"); } - private void printPattern() { + private void printIndented(int spaces, String str) { + System.out.println(" ".repeat(spaces) + str); + } + + private void printGeneration() { System.out.println("GENERATION: " + generation + " POPULATION: " + population); for (int y = 0; y < matrix.length; y++) { for (int x = 0; x < matrix[y].length; x++) { @@ -120,6 +143,12 @@ public class Life { } } + /** + * Main method that starts the program. + * + * @param args the command line arguments. + * @throws Exception if something goes wrong. + */ public static void main(String[] args) throws Exception { new Life().start(); } From 064907c83ef9cd9e784a37a0d1e33e8df9586db4 Mon Sep 17 00:00:00 2001 From: Stefan Waldmann Date: Mon, 17 Jan 2022 19:08:19 +0100 Subject: [PATCH 228/337] Print generation header formatted correctly --- 55_Life/java/src/java/Life.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/55_Life/java/src/java/Life.java b/55_Life/java/src/java/Life.java index 41b30c8d..d3477c66 100644 --- a/55_Life/java/src/java/Life.java +++ b/55_Life/java/src/java/Life.java @@ -134,7 +134,7 @@ public class Life { } private void printGeneration() { - System.out.println("GENERATION: " + generation + " POPULATION: " + population); + printGenerationHeader(); for (int y = 0; y < matrix.length; y++) { for (int x = 0; x < matrix[y].length; x++) { System.out.print(matrix[y][x] == 1 ? "*" : " "); @@ -143,6 +143,11 @@ public class Life { } } + private void printGenerationHeader() { + String invalidText = invalid ? "INVALID!" : ""; + System.out.printf("GENERATION: %-13d POPULATION: %d %s\n", generation, population, invalidText); + } + /** * Main method that starts the program. * From 2d44db49a41ea083efd4538bd352262d652cb7de Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 23:01:42 +0200 Subject: [PATCH 229/337] Fix RootNamespace and LangVersion --- 00_Utilities/DotnetUtils/DotnetUtils/Program.cs | 2 +- 05_Bagels/csharp/Bagels.csproj | 1 - 06_Banner/vbnet/banner.vbproj | 3 ++- 08_Batnum/vbnet/batnum.vbproj | 3 ++- 21_Calendar/csharp/Calendar.csproj | 1 - 96_Word/vbnet/word.vbproj | 3 ++- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index 550250b1..5a3a70e5 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -216,8 +216,8 @@ void generateMissingProjs() { void checkProjects() { foreach (var info in infos) { + WriteLine(info.LangPath); printProjectWarnings(info); - WriteLine(); } } diff --git a/05_Bagels/csharp/Bagels.csproj b/05_Bagels/csharp/Bagels.csproj index 68fa11ec..54cdbe42 100644 --- a/05_Bagels/csharp/Bagels.csproj +++ b/05_Bagels/csharp/Bagels.csproj @@ -3,7 +3,6 @@ Exe net5.0 - BasicComputerGames.Bagels diff --git a/06_Banner/vbnet/banner.vbproj b/06_Banner/vbnet/banner.vbproj index 659fea7b..e825a636 100644 --- a/06_Banner/vbnet/banner.vbproj +++ b/06_Banner/vbnet/banner.vbproj @@ -2,8 +2,9 @@ Exe - banner + Banner netcoreapp3.1 + 16.9 diff --git a/08_Batnum/vbnet/batnum.vbproj b/08_Batnum/vbnet/batnum.vbproj index 3c21499c..aad6e218 100644 --- a/08_Batnum/vbnet/batnum.vbproj +++ b/08_Batnum/vbnet/batnum.vbproj @@ -2,8 +2,9 @@ Exe - batnum + Batnum netcoreapp3.1 + 16.9 diff --git a/21_Calendar/csharp/Calendar.csproj b/21_Calendar/csharp/Calendar.csproj index 895f2f3f..20827042 100644 --- a/21_Calendar/csharp/Calendar.csproj +++ b/21_Calendar/csharp/Calendar.csproj @@ -3,7 +3,6 @@ Exe net5.0 - _21_calendar diff --git a/96_Word/vbnet/word.vbproj b/96_Word/vbnet/word.vbproj index 9868dd3e..f80094e4 100644 --- a/96_Word/vbnet/word.vbproj +++ b/96_Word/vbnet/word.vbproj @@ -2,8 +2,9 @@ Exe - word + Word netcoreapp3.1 + 16.9 From 06e1ca2ffc36051551e4a9df38566528530f7164 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Mon, 17 Jan 2022 23:09:30 +0200 Subject: [PATCH 230/337] Script -- output ports with no code files; replace !...Any with None --- .../DotnetUtils/DotnetUtils/Extensions.cs | 5 +++++ .../DotnetUtils/DotnetUtils/Program.cs | 22 ++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs b/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs index a0f52bee..11f05177 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs @@ -10,6 +10,11 @@ public static class Extensions { src.Select(x => selector(x.Item1, x.Item2, x.Item3)); public static IEnumerable<(T1, T2, int)> WithIndex(this IEnumerable<(T1, T2)> src) => src.Select((x, index) => (x.Item1, x.Item2, index)); + public static bool None(this IEnumerable src, Func? predicate = null) => + predicate is null ? + !src.Any() : + !src.Any(predicate); + public static bool IsNullOrWhitespace([NotNullWhen(false)] this string? s) => string.IsNullOrWhiteSpace(s); [return: NotNullIfNotNull("path")] diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index 5a3a70e5..560a7207 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -17,6 +17,7 @@ var actions = new (Action action, string description)[] { (multipleProjs, "Output multiple project files"), (checkProjects, "Check .csproj/.vbproj files for target framework, nullability etc."), (checkExecutableProject, "Check that there is at least one executable project per port"), + (noCodeFiles, "Output ports without any code files"), (printPortInfo, "Print info about a single port"), (generateMissingSlns, "Generate solution files when missing"), @@ -87,7 +88,7 @@ void printInfos() { } void missingSln() { - var data = infos.Where(x => !x.Slns.Any()).ToArray(); + var data = infos.Where(x => x.Slns.None()).ToArray(); foreach (var item in data) { WriteLine(item.LangPath); } @@ -98,7 +99,7 @@ void missingSln() { void unexpectedSlnName() { var counter = 0; foreach (var item in infos) { - if (!item.Slns.Any()) { continue; } + if (item.Slns.None()) { continue; } var expectedSlnName = $"{item.GameName}.sln"; if (item.Slns.Contains(Combine(item.LangPath, expectedSlnName), StringComparer.InvariantCultureIgnoreCase)) { continue; } @@ -125,7 +126,7 @@ void multipleSlns() { } void missingProj() { - var data = infos.Where(x => !x.Projs.Any()).ToArray(); + var data = infos.Where(x => x.Projs.None()).ToArray(); foreach (var item in data) { WriteLine(item.LangPath); } @@ -136,7 +137,7 @@ void missingProj() { void unexpectedProjName() { var counter = 0; foreach (var item in infos) { - if (!item.Projs.Any()) { continue; } + if (item.Projs.None()) { continue; } var expectedProjName = $"{item.GameName}.{item.ProjExt}"; if (item.Projs.Contains(Combine(item.LangPath, expectedProjName))) { continue; } @@ -164,7 +165,7 @@ void multipleProjs() { } void generateMissingSlns() { - foreach (var item in infos.Where(x => !x.Slns.Any())) { + foreach (var item in infos.Where(x => x.Slns.None())) { var result = RunProcess("dotnet", $"new sln -n {item.GameName} -o {item.LangPath}"); WriteLine(result); @@ -177,7 +178,7 @@ void generateMissingSlns() { } void generateMissingProjs() { - foreach (var item in infos.Where(x => !x.Projs.Any())) { + foreach (var item in infos.Where(x => x.Projs.None())) { // We can't use the dotnet command to create a new project using the built-in console template, because part of that template // is a Program.cs / Program.vb file. If there already are code files, there's no need to add a new empty one; and // if there's already such a file, it might try to overwrite it. @@ -284,6 +285,15 @@ void checkExecutableProject() { } } +void noCodeFiles() { + var qry = infos + .Where(x => x.CodeFiles.None()) + .OrderBy(x => x.Lang); + foreach (var item in qry) { + WriteLine(item.LangPath); + } +} + void tryBuild() { // if has code files, try to build } From d05bdd13e7e9680cc945e02df1e73847100fefd0 Mon Sep 17 00:00:00 2001 From: Noah Pauls Date: Mon, 17 Jan 2022 18:06:22 -0800 Subject: [PATCH 231/337] completed csharp version --- 88_3-D_Tic-Tac-Toe/csharp/Program.cs | 10 + 88_3-D_Tic-Tac-Toe/csharp/Qubic.cs | 1178 ++++++++++++++++++++++++ 88_3-D_Tic-Tac-Toe/csharp/QubicData.cs | 559 +++++++++++ 3 files changed, 1747 insertions(+) create mode 100644 88_3-D_Tic-Tac-Toe/csharp/Program.cs create mode 100644 88_3-D_Tic-Tac-Toe/csharp/Qubic.cs create mode 100644 88_3-D_Tic-Tac-Toe/csharp/QubicData.cs diff --git a/88_3-D_Tic-Tac-Toe/csharp/Program.cs b/88_3-D_Tic-Tac-Toe/csharp/Program.cs new file mode 100644 index 00000000..12c6ca83 --- /dev/null +++ b/88_3-D_Tic-Tac-Toe/csharp/Program.cs @@ -0,0 +1,10 @@ +namespace ThreeDTicTacToe +{ + class Program + { + static void Main() + { + new Qubic().Run(); + } + } +} diff --git a/88_3-D_Tic-Tac-Toe/csharp/Qubic.cs b/88_3-D_Tic-Tac-Toe/csharp/Qubic.cs new file mode 100644 index 00000000..595db661 --- /dev/null +++ b/88_3-D_Tic-Tac-Toe/csharp/Qubic.cs @@ -0,0 +1,1178 @@ +using System.Text; + +namespace ThreeDTicTacToe +{ + /// + /// Qubic is a 3D Tic-Tac-Toe game played on a 4x4x4 cube. This code allows + /// a player to compete against a deterministic AI that is surprisingly + /// difficult to beat. + /// + internal class Qubic + { + // The Y variable in the original BASIC. + private static readonly int[] CornersAndCenters = QubicData.CornersAndCenters; + // The M variable in the original BASIC. + private static readonly int[,] RowsByPlane = QubicData.RowsByPlane; + + // Board spaces are filled in with numeric values. A space could be: + // + // - EMPTY: no one has moved here yet. + // - PLAYER: the player moved here. + // - MACHINE: the machine moved here. + // - POTENTIAL: the machine, in the middle of its move, + // might fill a space with a potential move marker, which + // prioritizes the space once it finally chooses where to move. + // + // The numeric values allow the program to determine what moves have + // been made in a row by summing the values in a row. In theory, the + // individual values could be any positive numbers that satisfy the + // following: + // + // - EMPTY = 0 + // - POTENTIAL * 4 < PLAYER + // - PLAYER * 4 < MACHINE + private const double PLAYER = 1.0; + private const double MACHINE = 5.0; + private const double POTENTIAL = 0.125; + private const double EMPTY = 0.0; + + // The X variable in the original BASIC. This is the Qubic board, + // flattened into a 1D array. + private readonly double[] Board = new double[64]; + + // The L variable in the original BASIC. There are 76 unique winning rows + // in the board, so each gets an entry in RowSums. A row sum can be used + // to check what moves have been made to that row in the board. + // + // Example: if RowSums[i] == PLAYER * 4, the player won with row i! + private readonly double[] RowSums = new double[76]; + + public Qubic() { } + + /// + /// Run the Qubic game. + /// + /// Show the title, prompt for instructions, then begin the game loop. + /// + public void Run() + { + Title(); + Instructions(); + Loop(); + } + + /*********************************************************************** + /* Terminal Text/Prompts + /**********************************************************************/ + #region TerminalText + + /// + /// Display title and attribution. + /// + /// Original BASIC: 50-120 + /// + private static void Title() + { + Console.WriteLine( + "\n" + + " QUBIC\n\n" + + " CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n" + ); + } + + /// + /// Prompt user for game instructions. + /// + /// Original BASIC: 210-313 + /// + private static void Instructions() + { + Console.Write("DO YOU WANT INSTRUCTIONS? "); + var yes = ReadYesNo(); + + if (yes) + { + Console.WriteLine( + "\n" + + "THE GAME IS TIC-TAC-TOE IN A 4 X 4 X 4 CUBE.\n" + + "EACH MOVE IS INDICATED BY A 3 DIGIT NUMBER, WITH EACH\n" + + "DIGIT BETWEEN 1 AND 4 INCLUSIVE. THE DIGITS INDICATE THE\n" + + "LEVEL, ROW, AND COLUMN, RESPECTIVELY, OF THE OCCUPIED\n" + + "PLACE.\n" + + "\n" + + "TO PRINT THE PLAYING BOARD, TYPE 0 (ZERO) AS YOUR MOVE.\n" + + "THE PROGRAM WILL PRINT THE BOARD WITH YOUR MOVES INDI-\n" + + "CATED WITH A (Y), THE MACHINE'S MOVES WITH AN (M), AND\n" + + "UNUSED SQUARES WITH A ( ). OUTPUT IS ON PAPER.\n" + + "\n" + + "TO STOP THE PROGRAM RUN, TYPE 1 AS YOUR MOVE.\n\n" + ); + } + } + + /// + /// Prompt player for whether they would like to move first, or allow + /// the machine to make the first move. + /// + /// Original BASIC: 440-490 + /// + /// true if the player wants to move first + private static bool PlayerMovePreference() + { + Console.Write("DO YOU WANT TO MOVE FIRST? "); + var result = ReadYesNo(); + Console.WriteLine(); + return result; + } + + /// + /// Run the Qubic program loop. + /// + private void Loop() + { + // The "retry" loop; ends if player quits or chooses not to retry + // after game ends. + while (true) + { + ClearBoard(); + var playerNext = PlayerMovePreference(); + + // The "game" loop; ends if player quits, player/machine wins, + // or game ends in draw. + while (true) + { + if (playerNext) + { + // Player makes a move. + var playerAction = PlayerMove(); + if (playerAction == PlayerAction.Move) + { + playerNext = !playerNext; + } + else + { + return; + } + } + else + { + // Check for wins, if any. + RefreshRowSums(); + if (CheckPlayerWin() || CheckMachineWin()) + { + break; + } + + // Machine makes a move. + var machineAction = MachineMove(); + if (machineAction == MachineAction.Move) + { + playerNext = !playerNext; + } + else if (machineAction == MachineAction.End) + { + break; + } + else + { + throw new Exception("unreachable; machine should always move or end game in game loop"); + } + } + } + + var retry = RetryPrompt(); + + if (!retry) + { + return; + } + } + } + + /// + /// Prompt the user to try another game. + /// + /// Original BASIC: 1490-1560 + /// + /// true if the user wants to play again + private static bool RetryPrompt() + { + Console.Write("DO YOU WANT TO TRY ANOTHER GAME? "); + return ReadYesNo(); + } + + /// + /// Read a yes/no from the terminal. This method accepts anything that + /// starts with N/n as no and Y/y as yes. + /// + /// true if the player answered yes + private static bool ReadYesNo() + { + while (true) + { + var response = Console.ReadLine() ?? " "; + if (response.ToLower().StartsWith("y")) + { + return true; + } + else if (response.ToLower().StartsWith("n")) + { + return false; + } + else + { + Console.Write("INCORRECT ANSWER. PLEASE TYPE 'YES' OR 'NO'. "); + } + } + } + + #endregion + + /*********************************************************************** + /* Player Move + /**********************************************************************/ + #region PlayerMove + + /// + /// Possible actions player has taken after ending their move. This + /// replaces the `GOTO` logic that allowed the player to jump out of + /// the game loop and quit. + /// + private enum PlayerAction + { + /// + /// The player ends the game prematurely. + /// + Quit, + /// + /// The player makes a move on the board. + /// + Move, + } + + /// + /// Make the player's move based on their input. + /// + /// Original BASIC: 500-620 + /// + /// Whether the player moved or quit the program. + private PlayerAction PlayerMove() + { + // Loop until a valid move is inputted. + while (true) + { + var move = ReadMove(); + if (move == 1) + { + return PlayerAction.Quit; + } + else if (move == 0) + { + ShowBoard(); + } + else + { + ClearPotentialMoves(); + if (TryCoordToIndex(move, out int moveIndex)) + { + if (Board[moveIndex] == EMPTY) + { + Board[moveIndex] = PLAYER; + return PlayerAction.Move; + } + else + { + Console.WriteLine("THAT SQUARE IS USED, TRY AGAIN."); + } + } + else + { + Console.WriteLine("INCORRECT MOVE, TRY AGAIN."); + } + } + } + } + + /// + /// Read a player move from the terminal. Move can be any integer. + /// + /// Original BASIC: 510-520 + /// + /// the move inputted + private static int ReadMove() + { + Console.Write("YOUR MOVE? "); + return ReadInteger(); + } + + /// + /// Read an integer from the terminal. + /// + /// Original BASIC: 520 + /// + /// Unlike the basic, this code will not accept any string that starts + /// with a number; only full number strings are allowed. + /// + /// the integer inputted + private static int ReadInteger() + { + while (true) + { + var response = Console.ReadLine() ?? " "; + + if (int.TryParse(response, out var move)) + { + return move; + + } + else + { + Console.Write("!NUMBER EXPECTED - RETRY INPUT LINE--? "); + } + } + } + + /// + /// Display the board to the player. Spaces taken by the player are + /// marked with "Y", while machine spaces are marked with "M". + /// + /// Original BASIC: 2550-2740 + /// + private void ShowBoard() + { + var s = new StringBuilder(new string('\n', 9)); + + for (int i = 1; i <= 4; i++) + { + for (int j = 1; j <= 4; j++) + { + s.Append(' ', 3 * (j + 1)); + for (int k = 1; k <= 4; k++) + { + int q = (16 * i) + (4 * j) + k - 21; + s.Append(Board[q] switch + { + EMPTY or POTENTIAL => "( ) ", + PLAYER => "(Y) ", + MACHINE => "(M) ", + _ => throw new Exception($"invalid space value {Board[q]}"), + }); + } + s.Append("\n\n"); + } + s.Append("\n\n"); + } + + Console.WriteLine(s.ToString()); + } + + #endregion + + /*********************************************************************** + /* Machine Move + /**********************************************************************/ + #region MachineMove + + /// + /// Check all rows for a player win. + /// + /// A row indicates a player win if its sum = PLAYER * 4. + /// + /// Original BASIC: 720-780 + /// + /// whether the player won in any row + private bool CheckPlayerWin() + { + for (int row = 0; row < 76; row++) + { + if (RowSums[row] == (PLAYER * 4)) + { + // Found player win! + Console.WriteLine("YOU WIN AS FOLLOWS"); + DisplayRow(row); + return true; + } + } + + // No player win found. + return false; + } + + /// + /// Check all rows for a row that the machine could move to to win + /// immediately. + /// + /// A row indicates a player could win immediately if it has three + /// machine moves already; that is, sum = MACHINE * 3. + /// + /// Original Basic: 790-920 + /// + /// + private bool CheckMachineWin() + { + for (int row = 0; row < 76; row++) + { + if (RowSums[row] == (MACHINE * 3)) + { + // Found a winning row! + for (int space = 0; space < 4; space++) + { + int move = RowsByPlane[row, space]; + if (Board[move] == EMPTY) + { + // Found empty space in winning row; move there. + Board[move] = MACHINE; + Console.WriteLine($"MACHINE MOVES TO {IndexToCoord(move)} , AND WINS AS FOLLOWS"); + DisplayRow(row); + return true; + } + } + } + } + + // No winning row available. + return false; + } + + /// + /// Display the coordinates of a winning row. + /// + /// index into RowsByPlane data + private void DisplayRow(int row) + { + for (int space = 0; space < 4; space++) + { + Console.Write($" {IndexToCoord(RowsByPlane[row, space])} "); + } + Console.WriteLine(); + } + + /// + /// Possible actions machine can take in a move. This helps replace the + /// complex GOTO logic from the original BASIC, which allowed the + /// program to jump from the machine's action to the end of the game. + /// + private enum MachineAction + { + /// + /// Machine did not take any action. + /// + None, + /// + /// Machine made a move. + /// + Move, + /// + /// Machine either won, conceded, or found a draw. + /// + End, + } + + /// + /// Machine decides where to move on the board, and ends the game if + /// appropriate. + /// + /// The machine's AI tries to take the following actions (in order): + /// + /// 1. If the player has a row that will get them the win on their + /// next turn, block that row. + /// 2. If the machine can trap the player (create two different rows + /// with three machine moves each that cannot be blocked by only a + /// single player move, create such a trap. + /// 3. If the player can create a similar trap for the machine on + /// their next move, block the space where that trap would be + /// created. + /// 4. Find a plane in the board that is well-populated by player + /// moves, and take a space in the first such plane. + /// 5. Find the first open corner or center and move there. + /// 6. Find the first open space and move there. + /// + /// If none of these actions are possible, then the board is entirely + /// full, and the game results in a draw. + /// + /// Original BASIC: start at 930 + /// + /// the action the machine took + private MachineAction MachineMove() + { + // The actions the machine attempts to take, in order. + var actions = new Func[] + { + BlockPlayer, + MakePlayerTrap, + BlockMachineTrap, + MoveByPlane, + MoveCornerOrCenter, + MoveAnyOpenSpace, + }; + + foreach (var action in actions) + { + // Try each action, moving to the next if nothing happens. + var actionResult = action(); + if (actionResult != MachineAction.None) + { + // Not in original BASIC: check for draw after each machine + // move. + if (CheckDraw()) + { + return DrawGame(); + } + return actionResult; + } + } + + // If we got here, all spaces are taken. Draw the game. + return DrawGame(); + } + + /// + /// Block a row with three spaces already taken by the player. + /// + /// Original BASIC: 930-1010 + /// + /// + /// Move if the machine blocked, + /// None otherwise + /// + private MachineAction BlockPlayer() + { + for (int row = 0; row < 76; row++) + { + if (RowSums[row] == (PLAYER * 3)) + { + // Found a row to block on! + for (int space = 0; space < 4; space++) + { + if (Board[RowsByPlane[row, space]] == EMPTY) + { + // Take the remaining empty space. + Board[RowsByPlane[row, space]] = MACHINE; + Console.WriteLine($"NICE TRY. MACHINE MOVES TO {IndexToCoord(RowsByPlane[row, space])}"); + return MachineAction.Move; + } + } + } + } + + // Didn't find a row to block on. + return MachineAction.None; + } + + /// + /// Create a trap for the player if possible. A trap can be created if + /// moving to a space on the board results in two different rows having + /// three MACHINE spaces, with the remaining space not shared between + /// the two rows. The player can only block one of these traps, so the + /// machine will win. + /// + /// If a player trap is not possible, but a row is found that is + /// particularly advantageous for the machine to move to, the machine + /// will try and move to a corner-edge in that row. + /// + /// Original BASIC: 1300-1480 + /// + /// + /// Move if a trap was created, + /// End if the machine conceded, + /// None otherwise + /// + private MachineAction MakePlayerTrap() + { + for (int row = 0; row < 76; row++) + { + // Refresh row sum, since new POTENTIALs might have changed it. + var rowSum = RefreshRowSum(row); + + // Machine has moved in this row twice, and player has not moved + // in this row. + if (rowSum >= (MACHINE * 2) && rowSum < (MACHINE * 2) + 1) + { + // Machine has no potential moves yet in this row. + if (rowSum == (MACHINE * 2)) + { + for (int space = 0; space < 4; space++) + { + // Empty space can potentially be used to create a + // trap. + if (Board[RowsByPlane[row, space]] == EMPTY) + { + Board[RowsByPlane[row, space]] = POTENTIAL; + } + } + } + // Machine has already found a potential move in this row, + // so a trap can be created with another row. + else + { + return MakeOrBlockTrap(row); + } + } + } + + // No player traps can be made. + RefreshRowSums(); + + for (int row = 0; row < 76; row++) + { + // A row may be particularly advantageous for the machine to + // move to at this point; this is the case if a row is entirely + // filled with POTENTIAL or has one MACHINE and others + // POTENTIAL. + if (RowSums[row] == (POTENTIAL * 4) || RowSums[row] == MACHINE + (POTENTIAL * 3)) + { + // Try moving to a corner-edge in an advantageous row. + return MoveCornerEdges(row, POTENTIAL); + } + } + + // No spaces found that are particularly advantageous to machine. + ClearPotentialMoves(); + return MachineAction.None; + } + + /// + /// Block a trap that the player could create for the machine on their + /// next turn. + /// + /// If there are no player traps to block, but a row is found that is + /// particularly advantageous for the player to move to, the machine + /// will try and move to a corner-edge in that row. + /// + /// Original BASIC: 1030-1190 + /// + /// + /// Move if a trap was created, + /// End if the machine conceded, + /// None otherwise + /// + private MachineAction BlockMachineTrap() + { + for (int i = 0; i < 76; i++) + { + // Refresh row sum, since new POTENTIALs might have changed it. + var rowSum = RefreshRowSum(i); + + // Player has moved in this row twice, and machine has not moved + // in this row. + if (rowSum >= (PLAYER * 2) && rowSum < (PLAYER * 2) + 1) + { + // Machine has no potential moves yet in this row. + if (rowSum == (PLAYER * 2)) + { + for (int j = 0; j < 4; j++) + { + if (Board[RowsByPlane[i, j]] == EMPTY) + { + Board[RowsByPlane[i, j]] = POTENTIAL; + } + } + } + // Machine has already found a potential move in this row, + // so a trap can be created with another row by the player. + // Move to block. + else + { + return MakeOrBlockTrap(i); + } + } + } + + // No player traps to block found. + RefreshRowSums(); + + for (int row = 0; row < 76; row++) + { + // A row may be particularly advantageous for the player to move + // to at this point, indicated by a row containing all POTENTIAL + // moves or one PLAYER and rest POTENTIAL. + if (RowSums[row] == (POTENTIAL * 4) || RowSums[row] == PLAYER + (POTENTIAL * 3)) + { + // Try moving to a corner-edge in an advantageous row. + return MoveCornerEdges(row, POTENTIAL); + } + } + + // No spaces found that are particularly advantageous to the player. + return MachineAction.None; + } + + /// + /// Either make a trap for the player or block a trap the player could + /// create on their next turn. + /// + /// Unclear how this method could possibly end with a concession; it + /// seems it can only be called if the row contains a potential move. + /// + /// Original BASIC: 2230-2350 + /// + /// the row containing the space to move to + /// + /// Move if the machine moved, + /// End if the machine conceded + /// + private MachineAction MakeOrBlockTrap(int row) + { + for (int space = 0; space < 4; space++) + { + if (Board[RowsByPlane[row, space]] == POTENTIAL) + { + Board[RowsByPlane[row, space]] = MACHINE; + + // Row sum indicates we're blocking a player trap. + if (RowSums[row] < MACHINE) + { + Console.Write("YOU FOX. JUST IN THE NICK OF TIME, "); + } + // Row sum indicates we're completing a machine trap. + else + { + Console.Write("LET'S SEE YOU GET OUT OF THIS: "); + } + + Console.WriteLine($"MACHINE MOVES TO {IndexToCoord(RowsByPlane[row, space])}"); + + return MachineAction.Move; + } + } + + // Unclear how this can be reached. + Console.WriteLine("MACHINE CONCEDES THIS GAME."); + return MachineAction.End; + } + + /// + /// Find a satisfactory plane on the board and move to one if that + /// plane's corner-edges. + /// + /// A plane on the board is satisfactory if it meets the following + /// conditions: + /// 1. Player has made exactly 4 moves on the plane. + /// 2. Machine has made either 0 or one moves on the plane. + /// The machine then attempts to move to a corner-edge in that plane, + /// first finding any potential moves from the previous action it took + /// and moving there, and moving to any open corner-edge if there are + /// no potential moves found. + /// + /// This action by the machine tries to prevent the player from having + /// exclusive control over any plane in the board. + /// + /// Original BASIC: 1830-2020 + /// + /// The BASIC code for this action is tightly bound with base code for + /// MoveCornerEdges. + /// + /// + /// Move if a move in a plane was found, + /// None otherwise + /// + private MachineAction MoveByPlane() + { + // For each plane in the cube... + for (int plane = 1; plane <= 18; plane++) + { + double planeSum = PlaneSum(plane); + + // Check that plane sum satisfies condition. + const double P4 = PLAYER * 4; + const double P4_M1 = (PLAYER * 4) + MACHINE; + if ( + (planeSum >= P4 && planeSum < P4 + 1) || + (planeSum >= P4_M1 && planeSum < P4_M1 + 1) + ) + { + // Try to move to corner edges in each row of plane + // First, check for corner edges marked as POTENTIAL. + for (int row = (4 * plane) - 4; row < (4 * plane); row++) + { + var moveResult = MoveCornerEdges(row, POTENTIAL); + if (moveResult != MachineAction.None) + { + return moveResult; + } + } + + // If no POTENTIAL corner-edge found, look for an EMPTY one. + for (int row = (4 * plane) - 4; row < (4 * plane); row++) + { + var moveResult = MoveCornerEdges(row, EMPTY); + if (moveResult != MachineAction.None) + { + return moveResult; + } + } + } + } + + // No good corner edges found by plane. + ClearPotentialMoves(); + return MachineAction.None; + } + + /// + /// Given a row, move to the first corner-edge of the cube that has the + /// given value. + /// + /// Corner edges are pieces of the cube that have two faces. The AI + /// prefers to move to these spaces before others, presumably + /// because they are powerful moves: a corner edge space is contained + /// in 3 rows on the cube. + /// + /// Original BASIC: 2360-2490 + /// + /// In the original BASIC, this code is pointed to from three different + /// locations by GOTOs (1440/50, or MakePlayerTrap; 1160/70, or + /// BlockMachineTrap; and 1990, or MoveByPlane). Interestingly, line + /// 2440 can only be reached if the code proceeds after a call from + /// 1990. In short, this means that the code flow is incredibly + /// difficult to understand; the block of code at 2360 acts like a + /// generalized subroutine, but contains bits of code that belong + /// to specific pieces of calling code. + /// + /// the row to try to move to + /// + /// what value the space to move to should have in Board + /// + /// + /// Move if a corner-edge piece in the row with the given spaceValue was + /// found, + /// None otherwise + /// + private MachineAction MoveCornerEdges(int row, double spaceValue) + { + // Given a row, we want to find the corner-edge pieces in that row. + // We know that each row is part of a plane, and that the first + // and last rows of the plane are on the plane edge, while the + // other two rows are in the middle. If we know whether a row is an + // edge or middle, we can determine which spaces in that row are + // corner-edges. + // + // Below is a birds-eye view of a plane in the cube, with rows + // oriented horizontally: + // + // row 0: ( ) (1) (2) ( ) + // row 1: (0) ( ) ( ) (3) + // row 2: (0) ( ) ( ) (3) + // row 3: ( ) (1) (2) ( ) + // + // The corner edge pieces have their row indices marked. The pattern + // above shows that: + // + // if row == 0 | 3, corner edge spaces = [1, 2] + // if row == 1 | 2, corner edge spaces = [0, 3] + + // The below condition replaces the following BASIC code (2370): + // + // I-(INT(I/4)*4)>1 + // + // which in C# would be: + // + // + // int a = i - (i / 4) * 4 <= 1) + // ? 1 + // : 2; + // + // In the above, i is the one-indexed row in RowsByPlane. + // + // This condition selects a different a value based on whether the + // given row is on the edge or middle of its plane. + int a = (row % 4) switch + { + 0 or 3 => 1, // row is on edge of plane + 1 or 2 => 2, // row is in middle of plane + _ => throw new Exception($"unreachable ({row % 4})"), + }; + + // Iterate through corner edge pieces of the row. + // + // if a = 1 (row is edge), iterate through [0, 3] + // if a = 2 (row is middle), iterate through [1, 2] + for (int space = a - 1; space <= 4 - a; space += 5 - (2 * a)) + { + if (Board[RowsByPlane[row, space]] == spaceValue) + { + // Found a corner-edge to take! + Board[RowsByPlane[row, space]] = MACHINE; + Console.WriteLine($"MACHINE TAKES {IndexToCoord(RowsByPlane[row, space])}"); + return MachineAction.Move; + } + } + + // No valid corner edge to take. + return MachineAction.None; + } + + /// + /// Find the first open corner or center in the board and move there. + /// + /// Original BASIC: 1200-1290 + /// + /// This is the only place where the Z variable from the BASIC code is + /// used; here it is implied in the for loop. + /// + /// + /// Move if an open corner/center was found and moved to, + /// None otherwise + /// + private MachineAction MoveCornerOrCenter() + { + foreach (int space in CornersAndCenters) + { + if (Board[space] == EMPTY) + { + Board[space] = MACHINE; + Console.WriteLine($"MACHINE MOVES TO {IndexToCoord(space)}"); + return MachineAction.Move; + } + } + + return MachineAction.None; + } + + /// + /// Find the first open space in the board and move there. + /// + /// Original BASIC: 1720-1800 + /// + /// + /// Move if an open space was found and moved to, + /// None otherwise + /// + private MachineAction MoveAnyOpenSpace() + { + for (int row = 0; row < 64; row++) + { + if (Board[row] == EMPTY) + { + Board[row] = MACHINE; + Console.WriteLine($"MACHINE LIKES {IndexToCoord(row)}"); + return MachineAction.Move; + } + } + return MachineAction.None; + } + + /// + /// Draw the game in the event that there are no open spaces. + /// + /// Original BASIC: 1810-1820 + /// + /// End + private MachineAction DrawGame() + { + Console.WriteLine("THIS GAME IS A DRAW."); + return MachineAction.End; + } + + #endregion + + /*********************************************************************** + /* Helpers + /**********************************************************************/ + #region Helpers + + /// + /// Attempt to transform a cube coordinate to an index into Board. + /// + /// A valid cube coordinate is a three-digit number, where each digit + /// of the number X satisfies 1 <= X <= 4. + /// + /// Examples: + /// 111 -> 0 + /// 444 -> 63 + /// 232 -> 35 + /// + /// If the coord provided is not valid, the transformation fails. + /// + /// The conversion from coordinate to index is essentially a conversion + /// between base 4 and base 10. + /// + /// Original BASIC: 525-580 + /// + /// This method fixes a bug in the original BASIC (525-526), which only + /// checked whether the given coord satisfied 111 <= coord <= 444. This + /// allows invalid coordinates such as 199 and 437, whose individual + /// digits are out of range. + /// + /// cube coordinate (e.g. "111", "342") + /// trasnformation output + /// + /// true if the transformation was successful, false otherwise + /// + private static bool TryCoordToIndex(int coord, out int index) + { + // parse individual digits, subtract 1 to get base 4 number + var hundreds = (coord / 100) - 1; + var tens = ((coord % 100) / 10) - 1; + var ones = (coord % 10) - 1; + + // bounds check for each digit + foreach (int digit in new int[] { hundreds, tens, ones }) + { + if (digit < 0 || digit > 3) + { + index = -1; + return false; + } + } + + // conversion from base 4 to base 10 + index = (16 * hundreds) + (4 * tens) + ones; + return true; + } + + /// + /// Transform a Board index into a valid cube coordinate. + /// + /// Examples: + /// 0 -> 111 + /// 63 -> 444 + /// 35 -> 232 + /// + /// The conversion from index to coordinate is essentially a conversion + /// between base 10 and base 4. + /// + /// Original BASIC: 1570-1610 + /// + /// Board index + /// the corresponding cube coordinate + private static int IndexToCoord(int index) + { + // check that index is valid + if (index < 0 || index > 63) + { + // runtime exception; all uses of this method are with + // indices provided by the program, so this should never fail + throw new Exception($"index {index} is out of range"); + } + + // convert to base 4, add 1 to get cube coordinate + var hundreds = (index / 16) + 1; + var tens = ((index % 16) / 4) + 1; + var ones = (index % 4) + 1; + + // concatenate digits + int coord = (hundreds * 100) + (tens * 10) + ones; + return coord; + } + + /// + /// Refresh the values in RowSums to account for any changes. + /// + /// Original BASIC: 1640-1710 + /// + private void RefreshRowSums() + { + for (var row = 0; row < 76; row++) + { + RefreshRowSum(row); + } + } + + /// + /// Refresh a row in RowSums to reflect changes. + /// + /// row in RowSums to refresh + /// row sum after refresh + private double RefreshRowSum(int row) + { + double rowSum = 0; + for (int space = 0; space < 4; space++) + { + rowSum += Board[RowsByPlane[row, space]]; + } + RowSums[row] = rowSum; + return rowSum; + } + + /// + /// Calculate the sum of spaces in one of the 18 cube planes in RowSums. + /// + /// Original BASIC: 1840-1890 + /// + /// the desired plane + /// sum of spaces in plane + private double PlaneSum(int plane) + { + double planeSum = 0; + for (int row = (4 * (plane - 1)); row < (4 * plane); row++) + { + for (int space = 0; space < 4; space++) + { + planeSum += Board[RowsByPlane[row, space]]; + } + } + return planeSum; + } + + /// + /// Check whether the board is in a draw state, that is all spaces are + /// full and neither the player nor the machine has won. + /// + /// The original BASIC contains a bug that if the player moves first, a + /// draw will go undetected. An example series of player inputs + /// resulting in such a draw (assuming player goes first): + /// + /// 114, 414, 144, 444, 122, 221, 112, 121, + /// 424, 332, 324, 421, 231, 232, 244, 311, + /// 333, 423, 331, 134, 241, 243, 143, 413, + /// 142, 212, 314, 341, 432, 412, 431, 442 + /// + /// whether the game is a draw + private bool CheckDraw() + { + for (var i = 0; i < 64; i++) + { + if (Board[i] != PLAYER && Board[i] != MACHINE) + { + return false; + } + } + + RefreshRowSums(); + + for (int row = 0; row < 76; row++) + { + var rowSum = RowSums[row]; + if (rowSum == PLAYER * 4 || rowSum == MACHINE * 4) + { + return false; + } + } + + + return true; + } + + /// + /// Reset POTENTIAL spaces in Board to EMPTY. + /// + /// Original BASIC: 2500-2540 + /// + private void ClearPotentialMoves() + { + for (var i = 0; i < 64; i++) + { + if (Board[i] == POTENTIAL) + { + Board[i] = EMPTY; + } + } + } + + /// + /// Reset all spaces in Board to EMPTY. + /// + /// Original BASIC: 400-420 + /// + private void ClearBoard() + { + for (var i = 0; i < 64; i++) + { + Board[i] = EMPTY; + } + } + + #endregion + } +} diff --git a/88_3-D_Tic-Tac-Toe/csharp/QubicData.cs b/88_3-D_Tic-Tac-Toe/csharp/QubicData.cs new file mode 100644 index 00000000..298ee933 --- /dev/null +++ b/88_3-D_Tic-Tac-Toe/csharp/QubicData.cs @@ -0,0 +1,559 @@ +namespace ThreeDTicTacToe +{ + /// + /// Data in this class was originally given by the following DATA section in + /// the BASIC program: + /// + /// 2030 DATA 1,49,52,4,13,61,64,16,22,39,23,38,26,42,27,43 + /// 2040 DATA 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 + /// 2050 DATA 21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38 + /// 2060 DATA 39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56 + /// 2070 DATA 57,58,59,60,61,62,63,64 + /// 2080 DATA 1,17,33,49,5,21,37,53,9,25,41,57,13,29,45,61 + /// 2090 DATA 2,18,34,50,6,22,38,54,10,26,42,58,14,30,46,62 + /// 2100 DATA 3,19,35,51,7,23,39,55,11,27,43,59,15,31,47,63 + /// 2110 DATA 4,20,36,52,8,24,40,56,12,28,44,60,16,32,48,64 + /// 2120 DATA 1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61 + /// 2130 DATA 2,6,10,14,18,22,26,30,34,38,42,46,50,54,58,62 + /// 2140 DATA 3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,63 + /// 2150 DATA 4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64 + /// 2160 DATA 1,6,11,16,17,22,27,32,33,38,43,48,49,54,59,64 + /// 2170 DATA 13,10,7,4,29,26,23,20,45,42,39,36,61,58,55,52 + /// 2180 DATA 1,21,41,61,2,22,42,62,3,23,43,63,4,24,44,64 + /// 2190 DATA 49,37,25,13,50,38,26,14,51,39,27,15,52,40,28,16 + /// 2200 DATA 1,18,35,52,5,22,39,56,9,26,43,60,13,30,47,64 + /// 2210 DATA 49,34,19,4,53,38,23,8,57,42,27,12,61,46,31,16 + /// 2220 DATA 1,22,43,64,16,27,38,49,4,23,42,61,13,26,39,52 + /// + /// In short, each number is an index into the board. The data in this class + /// is zero-indexed, as opposed to the original data which was one-indexed. + /// + internal static class QubicData + { + /// + /// The corners and centers of the Qubic board. They correspond to the + /// following coordinates: + /// + /// [ + /// 111, 411, 414, 114, 141, 441, 444, 144, + /// 222, 323, 223, 322, 232, 332, 233, 333 + /// ] + /// + public static readonly int[] CornersAndCenters = new int[16] + { + // (X) ( ) ( ) (X) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // (X) ( ) ( ) (X) + + // ( ) ( ) ( ) ( ) + // ( ) (X) (X) ( ) + // ( ) (X) (X) ( ) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // ( ) (X) (X) ( ) + // ( ) (X) (X) ( ) + // ( ) ( ) ( ) ( ) + + // (X) ( ) ( ) (X) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // (X) ( ) ( ) (X) + + 0,48,51,3,12,60,63,15,21,38,22,37,25,41,26,42 + }; + + /// + /// A list of all "winning" rows in the Qubic board; that is, sets of + /// four spaces that, if filled entirely by the player (or machine), + /// would result in a win. + /// + /// Each group of four rows in the list corresponds to a plane in the + /// cube, and each plane is organized so that the first and last rows + /// are on the plane's edges, while the second and third rows are in + /// the middle of the plane. The only exception is the last group of + /// rows, which contains the corners and centers rather than a plane. + /// + /// The order of the rows in this list is key to how the Qubic AI + /// decides its next move. + /// + public static readonly int[,] RowsByPlane = new int[76, 4] + { + // (1) (1) (1) (1) + // (2) (2) (2) (2) + // (3) (3) (3) (3) + // (4) (4) (4) (4) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + { 0, 1, 2, 3, }, + { 4, 5, 6, 7, }, + { 8, 9, 10,11, }, + { 12,13,14,15, }, + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // (1) (1) (1) (1) + // (2) (2) (2) (2) + // (3) (3) (3) (3) + // (4) (4) (4) (4) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + { 16,17,18,19, }, + { 20,21,22,23, }, + { 24,25,26,27, }, + { 28,29,30,31, }, + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // (1) (1) (1) (1) + // (2) (2) (2) (2) + // (3) (3) (3) (3) + // (4) (4) (4) (4) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + { 32,33,34,35, }, + { 36,37,38,39, }, + { 40,41,42,43, }, + { 44,45,46,47, }, + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // (1) (1) (1) (1) + // (2) (2) (2) (2) + // (3) (3) (3) (3) + // (4) (4) (4) (4) + + { 48,49,50,51, }, + { 52,53,54,55, }, + { 56,57,58,59, }, + { 60,61,62,63, }, + + // (1) ( ) ( ) ( ) + // (2) ( ) ( ) ( ) + // (3) ( ) ( ) ( ) + // (4) ( ) ( ) ( ) + + // (1) ( ) ( ) ( ) + // (2) ( ) ( ) ( ) + // (3) ( ) ( ) ( ) + // (4) ( ) ( ) ( ) + + // (1) ( ) ( ) ( ) + // (2) ( ) ( ) ( ) + // (3) ( ) ( ) ( ) + // (4) ( ) ( ) ( ) + + // (1) ( ) ( ) ( ) + // (2) ( ) ( ) ( ) + // (3) ( ) ( ) ( ) + // (4) ( ) ( ) ( ) + + { 0, 16,32,48, }, + { 4, 20,36,52, }, + { 8, 24,40,56, }, + { 12,28,44,60, }, + + // ( ) (1) ( ) ( ) + // ( ) (2) ( ) ( ) + // ( ) (3) ( ) ( ) + // ( ) (4) ( ) ( ) + + // ( ) (1) ( ) ( ) + // ( ) (2) ( ) ( ) + // ( ) (3) ( ) ( ) + // ( ) (4) ( ) ( ) + + // ( ) (1) ( ) ( ) + // ( ) (2) ( ) ( ) + // ( ) (3) ( ) ( ) + // ( ) (4) ( ) ( ) + + // ( ) (1) ( ) ( ) + // ( ) (2) ( ) ( ) + // ( ) (3) ( ) ( ) + // ( ) (4) ( ) ( ) + + { 1, 17,33,49, }, + { 5, 21,37,53, }, + { 9, 25,41,57, }, + { 13,29,45,61, }, + + // ( ) ( ) (1) ( ) + // ( ) ( ) (2) ( ) + // ( ) ( ) (3) ( ) + // ( ) ( ) (4) ( ) + + // ( ) ( ) (1) ( ) + // ( ) ( ) (2) ( ) + // ( ) ( ) (3) ( ) + // ( ) ( ) (4) ( ) + + // ( ) ( ) (1) ( ) + // ( ) ( ) (2) ( ) + // ( ) ( ) (3) ( ) + // ( ) ( ) (4) ( ) + + // ( ) ( ) (1) ( ) + // ( ) ( ) (2) ( ) + // ( ) ( ) (3) ( ) + // ( ) ( ) (4) ( ) + + { 2, 18,34,50, }, + { 6, 22,38,54, }, + { 10,26,42,58, }, + { 14,30,46,62, }, + + // ( ) ( ) ( ) (1) + // ( ) ( ) ( ) (2) + // ( ) ( ) ( ) (3) + // ( ) ( ) ( ) (4) + + // ( ) ( ) ( ) (1) + // ( ) ( ) ( ) (2) + // ( ) ( ) ( ) (3) + // ( ) ( ) ( ) (4) + + // ( ) ( ) ( ) (1) + // ( ) ( ) ( ) (2) + // ( ) ( ) ( ) (3) + // ( ) ( ) ( ) (4) + + // ( ) ( ) ( ) (1) + // ( ) ( ) ( ) (2) + // ( ) ( ) ( ) (3) + // ( ) ( ) ( ) (4) + + { 3, 19,35,51, }, + { 7, 23,39,55, }, + { 11,27,43,59, }, + { 15,31,47,63, }, + + // (1) ( ) ( ) ( ) + // (1) ( ) ( ) ( ) + // (1) ( ) ( ) ( ) + // (1) ( ) ( ) ( ) + + // (2) ( ) ( ) ( ) + // (2) ( ) ( ) ( ) + // (2) ( ) ( ) ( ) + // (2) ( ) ( ) ( ) + + // (3) ( ) ( ) ( ) + // (3) ( ) ( ) ( ) + // (3) ( ) ( ) ( ) + // (3) ( ) ( ) ( ) + + // (4) ( ) ( ) ( ) + // (4) ( ) ( ) ( ) + // (4) ( ) ( ) ( ) + // (4) ( ) ( ) ( ) + + { 0, 4, 8, 12, }, + { 16,20,24,28, }, + { 32,36,40,44, }, + { 48,52,56,60, }, + + // ( ) (1) ( ) ( ) + // ( ) (1) ( ) ( ) + // ( ) (1) ( ) ( ) + // ( ) (1) ( ) ( ) + + // ( ) (2) ( ) ( ) + // ( ) (2) ( ) ( ) + // ( ) (2) ( ) ( ) + // ( ) (2) ( ) ( ) + + // ( ) (3) ( ) ( ) + // ( ) (3) ( ) ( ) + // ( ) (3) ( ) ( ) + // ( ) (3) ( ) ( ) + + // ( ) (4) ( ) ( ) + // ( ) (4) ( ) ( ) + // ( ) (4) ( ) ( ) + // ( ) (4) ( ) ( ) + + { 1, 5, 9, 13, }, + { 17,21,25,29, }, + { 33,37,41,45, }, + { 49,53,57,61, }, + + // ( ) ( ) (1) ( ) + // ( ) ( ) (1) ( ) + // ( ) ( ) (1) ( ) + // ( ) ( ) (1) ( ) + + // ( ) ( ) (2) ( ) + // ( ) ( ) (2) ( ) + // ( ) ( ) (2) ( ) + // ( ) ( ) (2) ( ) + + // ( ) ( ) (3) ( ) + // ( ) ( ) (3) ( ) + // ( ) ( ) (3) ( ) + // ( ) ( ) (3) ( ) + + // ( ) ( ) (4) ( ) + // ( ) ( ) (4) ( ) + // ( ) ( ) (4) ( ) + // ( ) ( ) (4) ( ) + + { 2, 6, 10,14, }, + { 18,22,26,30, }, + { 34,38,42,46, }, + { 50,54,58,62, }, + + // ( ) ( ) ( ) (1) + // ( ) ( ) ( ) (1) + // ( ) ( ) ( ) (1) + // ( ) ( ) ( ) (1) + + // ( ) ( ) ( ) (2) + // ( ) ( ) ( ) (2) + // ( ) ( ) ( ) (2) + // ( ) ( ) ( ) (2) + + // ( ) ( ) ( ) (3) + // ( ) ( ) ( ) (3) + // ( ) ( ) ( ) (3) + // ( ) ( ) ( ) (3) + + // ( ) ( ) ( ) (4) + // ( ) ( ) ( ) (4) + // ( ) ( ) ( ) (4) + // ( ) ( ) ( ) (4) + + { 3, 7, 11,15, }, + { 19,23,27,31, }, + { 35,39,43,47, }, + { 51,55,59,63, }, + + // (1) ( ) ( ) ( ) + // ( ) (1) ( ) ( ) + // ( ) ( ) (1) ( ) + // ( ) ( ) ( ) (1) + + // (2) ( ) ( ) ( ) + // ( ) (2) ( ) ( ) + // ( ) ( ) (2) ( ) + // ( ) ( ) ( ) (2) + + // (3) ( ) ( ) ( ) + // ( ) (3) ( ) ( ) + // ( ) ( ) (3) ( ) + // ( ) ( ) ( ) (3) + + // (4) ( ) ( ) ( ) + // ( ) (4) ( ) ( ) + // ( ) ( ) (4) ( ) + // ( ) ( ) ( ) (4) + + { 0, 5, 10,15, }, + { 16,21,26,31, }, + { 32,37,42,47, }, + { 48,53,58,63, }, + + // ( ) ( ) ( ) (1) + // ( ) ( ) (1) ( ) + // ( ) (1) ( ) ( ) + // (1) ( ) ( ) ( ) + + // ( ) ( ) ( ) (2) + // ( ) ( ) (2) ( ) + // ( ) (2) ( ) ( ) + // (2) ( ) ( ) ( ) + + // ( ) ( ) ( ) (3) + // ( ) ( ) (3) ( ) + // ( ) (3) ( ) ( ) + // (3) ( ) ( ) ( ) + + // ( ) ( ) ( ) (4) + // ( ) ( ) (4) ( ) + // ( ) (4) ( ) ( ) + // (4) ( ) ( ) ( ) + + { 12,9, 6, 3, }, + { 28,25,22,19, }, + { 44,41,38,35, }, + { 60,57,54,51, }, + + // (1) (2) (3) (4) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // (1) (2) (3) (4) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // (1) (2) (3) (4) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // (1) (2) (3) (4) + + { 0, 20,40,60, }, + { 1, 21,41,61, }, + { 2, 22,42,62, }, + { 3, 23,43,63, }, + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // (1) (2) (3) (4) + + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // (1) (2) (3) (4) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // (1) (2) (3) (4) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + // (1) (2) (3) (4) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + + { 48,36,24,12, }, + { 49,37,25,13, }, + { 50,38,26,14, }, + { 51,39,27,15, }, + + // (1) ( ) ( ) ( ) + // (2) ( ) ( ) ( ) + // (3) ( ) ( ) ( ) + // (4) ( ) ( ) ( ) + + // ( ) (1) ( ) ( ) + // ( ) (2) ( ) ( ) + // ( ) (3) ( ) ( ) + // ( ) (4) ( ) ( ) + + // ( ) ( ) (1) ( ) + // ( ) ( ) (2) ( ) + // ( ) ( ) (3) ( ) + // ( ) ( ) (4) ( ) + + // ( ) ( ) ( ) (1) + // ( ) ( ) ( ) (2) + // ( ) ( ) ( ) (3) + // ( ) ( ) ( ) (4) + + { 0, 17,34,51, }, + { 4, 21,38,55, }, + { 8, 25,42,59, }, + { 12,29,46,63, }, + + // ( ) ( ) ( ) (1) + // ( ) ( ) ( ) (2) + // ( ) ( ) ( ) (3) + // ( ) ( ) ( ) (4) + + // ( ) ( ) (1) ( ) + // ( ) ( ) (2) ( ) + // ( ) ( ) (3) ( ) + // ( ) ( ) (4) ( ) + + // ( ) (1) ( ) ( ) + // ( ) (2) ( ) ( ) + // ( ) (3) ( ) ( ) + // ( ) (4) ( ) ( ) + + // (1) ( ) ( ) ( ) + // (2) ( ) ( ) ( ) + // (3) ( ) ( ) ( ) + // (4) ( ) ( ) ( ) + + { 48,33,18,3, }, + { 52,37,22,7, }, + { 56,41,26,11, }, + { 60,45,30,15, }, + + // (1) ( ) ( ) (3) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // (4) ( ) ( ) (2) + + // ( ) ( ) ( ) ( ) + // ( ) (1) (3) ( ) + // ( ) (4) (2) ( ) + // ( ) ( ) ( ) ( ) + + // ( ) ( ) ( ) ( ) + // ( ) (2) (4) ( ) + // ( ) (3) (1) ( ) + // ( ) ( ) ( ) ( ) + + // (2) ( ) ( ) (4) + // ( ) ( ) ( ) ( ) + // ( ) ( ) ( ) ( ) + // (3) ( ) ( ) (1) + + { 0, 21,42,63, }, + { 15,26,37,48, }, + { 3, 22,41,60, }, + { 12,25,38,51, }, + }; + } +} From c85a1ba06eb5b0cca481840841bf06e8416978bd Mon Sep 17 00:00:00 2001 From: Noah Pauls Date: Mon, 17 Jan 2022 19:47:44 -0800 Subject: [PATCH 232/337] updated comments with better details --- 88_3-D_Tic-Tac-Toe/csharp/Qubic.cs | 104 ++++++++++++++++------------- 1 file changed, 59 insertions(+), 45 deletions(-) diff --git a/88_3-D_Tic-Tac-Toe/csharp/Qubic.cs b/88_3-D_Tic-Tac-Toe/csharp/Qubic.cs index 595db661..513651d6 100644 --- a/88_3-D_Tic-Tac-Toe/csharp/Qubic.cs +++ b/88_3-D_Tic-Tac-Toe/csharp/Qubic.cs @@ -568,9 +568,15 @@ namespace ThreeDTicTacToe /// /// If a player trap is not possible, but a row is found that is /// particularly advantageous for the machine to move to, the machine - /// will try and move to a corner-edge in that row. + /// will try and move to a plane edge in that row. /// /// Original BASIC: 1300-1480 + /// + /// Lines 1440/50 of the BASIC call 2360 (MovePlaneEdge). Because it + /// goes to this code only after it has found an open space marked as + /// potential, it cannot reach line 2440 of that code, as that is only + /// reached if an open space failed to be found in the row on which + /// that code was called. /// /// /// Move if a trap was created, @@ -618,11 +624,11 @@ namespace ThreeDTicTacToe // A row may be particularly advantageous for the machine to // move to at this point; this is the case if a row is entirely // filled with POTENTIAL or has one MACHINE and others - // POTENTIAL. + // POTENTIAL. Such rows may help set up trapping opportunities. if (RowSums[row] == (POTENTIAL * 4) || RowSums[row] == MACHINE + (POTENTIAL * 3)) { - // Try moving to a corner-edge in an advantageous row. - return MoveCornerEdges(row, POTENTIAL); + // Try moving to a plane edge in an advantageous row. + return MovePlaneEdge(row, POTENTIAL); } } @@ -637,9 +643,15 @@ namespace ThreeDTicTacToe /// /// If there are no player traps to block, but a row is found that is /// particularly advantageous for the player to move to, the machine - /// will try and move to a corner-edge in that row. + /// will try and move to a plane edge in that row. /// /// Original BASIC: 1030-1190 + /// + /// Lines 1160/1170 of the BASIC call 2360 (MovePlaneEdge). As with + /// MakePlayerTrap, because it goes to this code only after it has + /// found an open space marked as potential, it cannot reach line 2440 + /// of that code, as that is only reached if an open space failed to be + /// found in the row on which that code was called. /// /// /// Move if a trap was created, @@ -685,11 +697,12 @@ namespace ThreeDTicTacToe { // A row may be particularly advantageous for the player to move // to at this point, indicated by a row containing all POTENTIAL - // moves or one PLAYER and rest POTENTIAL. + // moves or one PLAYER and rest POTENTIAL. Such rows may aid in + // in the later creation of traps. if (RowSums[row] == (POTENTIAL * 4) || RowSums[row] == PLAYER + (POTENTIAL * 3)) { - // Try moving to a corner-edge in an advantageous row. - return MoveCornerEdges(row, POTENTIAL); + // Try moving to a plane edge in an advantageous row. + return MovePlaneEdge(row, POTENTIAL); } } @@ -743,24 +756,20 @@ namespace ThreeDTicTacToe /// /// Find a satisfactory plane on the board and move to one if that - /// plane's corner-edges. + /// plane's plane edges. /// /// A plane on the board is satisfactory if it meets the following /// conditions: /// 1. Player has made exactly 4 moves on the plane. /// 2. Machine has made either 0 or one moves on the plane. - /// The machine then attempts to move to a corner-edge in that plane, - /// first finding any potential moves from the previous action it took - /// and moving there, and moving to any open corner-edge if there are - /// no potential moves found. - /// - /// This action by the machine tries to prevent the player from having - /// exclusive control over any plane in the board. + /// Such a plane is one that the player could likely use to form traps. /// /// Original BASIC: 1830-2020 /// - /// The BASIC code for this action is tightly bound with base code for - /// MoveCornerEdges. + /// Line 1990 of the original basic calls 2370 (MovePlaneEdge). Only on + /// this call to MovePlaneEdge can line 2440 of that method be reached, + /// which surves to help this method iterate through the rows of a + /// plane. /// /// /// Move if a move in a plane was found, @@ -781,21 +790,21 @@ namespace ThreeDTicTacToe (planeSum >= P4_M1 && planeSum < P4_M1 + 1) ) { - // Try to move to corner edges in each row of plane - // First, check for corner edges marked as POTENTIAL. + // Try to move to plane edges in each row of plane + // First, check for plane edges marked as POTENTIAL. for (int row = (4 * plane) - 4; row < (4 * plane); row++) { - var moveResult = MoveCornerEdges(row, POTENTIAL); + var moveResult = MovePlaneEdge(row, POTENTIAL); if (moveResult != MachineAction.None) { return moveResult; } } - // If no POTENTIAL corner-edge found, look for an EMPTY one. + // If no POTENTIAL plane edge found, look for an EMPTY one. for (int row = (4 * plane) - 4; row < (4 * plane); row++) { - var moveResult = MoveCornerEdges(row, EMPTY); + var moveResult = MovePlaneEdge(row, EMPTY); if (moveResult != MachineAction.None) { return moveResult; @@ -804,48 +813,53 @@ namespace ThreeDTicTacToe } } - // No good corner edges found by plane. + // No satisfactory planes with open plane edges found. ClearPotentialMoves(); return MachineAction.None; } /// - /// Given a row, move to the first corner-edge of the cube that has the - /// given value. + /// Given a row, move to the first space in that row that: + /// 1. is a plane edge, and + /// 2. has the given value in Board /// - /// Corner edges are pieces of the cube that have two faces. The AI + /// Plane edges are any spaces on a plane with one face exposed. The AI /// prefers to move to these spaces before others, presumably - /// because they are powerful moves: a corner edge space is contained - /// in 3 rows on the cube. + /// because they are powerful moves: a plane edge is contained on 3-4 + /// winning rows of the cube. /// /// Original BASIC: 2360-2490 /// /// In the original BASIC, this code is pointed to from three different - /// locations by GOTOs (1440/50, or MakePlayerTrap; 1160/70, or - /// BlockMachineTrap; and 1990, or MoveByPlane). Interestingly, line - /// 2440 can only be reached if the code proceeds after a call from - /// 1990. In short, this means that the code flow is incredibly - /// difficult to understand; the block of code at 2360 acts like a - /// generalized subroutine, but contains bits of code that belong - /// to specific pieces of calling code. + /// locations by GOTOs: + /// - 1440/50, or MakePlayerTrap; + /// - 1160/70, or BlockMachineTrap; and + /// - 1990, or MoveByPlane. + /// At line 2440, this code jumps back to line 2000, which is in + /// MoveByPlane. This makes it appear as though calling MakePlayerTrap + /// or BlockPlayerTrap in the BASIC could jump into the middle of the + /// MoveByPlane method; were this to happen, not all of MoveByPlane's + /// variables would be defined! However, the program logic prevents + /// this from ever occurring; see each method's description for why + /// this is the case. /// /// the row to try to move to /// /// what value the space to move to should have in Board /// /// - /// Move if a corner-edge piece in the row with the given spaceValue was + /// Move if a plane edge piece in the row with the given spaceValue was /// found, /// None otherwise /// - private MachineAction MoveCornerEdges(int row, double spaceValue) + private MachineAction MovePlaneEdge(int row, double spaceValue) { - // Given a row, we want to find the corner-edge pieces in that row. + // Given a row, we want to find the plane edge pieces in that row. // We know that each row is part of a plane, and that the first // and last rows of the plane are on the plane edge, while the // other two rows are in the middle. If we know whether a row is an // edge or middle, we can determine which spaces in that row are - // corner-edges. + // plane edges. // // Below is a birds-eye view of a plane in the cube, with rows // oriented horizontally: @@ -855,11 +869,11 @@ namespace ThreeDTicTacToe // row 2: (0) ( ) ( ) (3) // row 3: ( ) (1) (2) ( ) // - // The corner edge pieces have their row indices marked. The pattern + // The plane edge pieces have their row indices marked. The pattern // above shows that: // - // if row == 0 | 3, corner edge spaces = [1, 2] - // if row == 1 | 2, corner edge spaces = [0, 3] + // if row == 0 | 3, plane edge spaces = [1, 2] + // if row == 1 | 2, plane edge spaces = [0, 3] // The below condition replaces the following BASIC code (2370): // @@ -883,7 +897,7 @@ namespace ThreeDTicTacToe _ => throw new Exception($"unreachable ({row % 4})"), }; - // Iterate through corner edge pieces of the row. + // Iterate through plane edge pieces of the row. // // if a = 1 (row is edge), iterate through [0, 3] // if a = 2 (row is middle), iterate through [1, 2] @@ -891,7 +905,7 @@ namespace ThreeDTicTacToe { if (Board[RowsByPlane[row, space]] == spaceValue) { - // Found a corner-edge to take! + // Found a plane edge to take! Board[RowsByPlane[row, space]] = MACHINE; Console.WriteLine($"MACHINE TAKES {IndexToCoord(RowsByPlane[row, space])}"); return MachineAction.Move; From 1aa0fa1a244bec481f4b9dd84906e538ae7c355c Mon Sep 17 00:00:00 2001 From: openback Date: Tue, 18 Jan 2022 00:26:34 -0500 Subject: [PATCH 233/337] Add Battle in python --- 09_Battle/python/battle.py | 165 +++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 09_Battle/python/battle.py diff --git a/09_Battle/python/battle.py b/09_Battle/python/battle.py new file mode 100644 index 00000000..8c992458 --- /dev/null +++ b/09_Battle/python/battle.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +from random import randrange +from typing import List, Tuple + +PointType = Tuple[int, int] +VectorType = PointType +SeaType = Tuple[List[int], ...] + +SEA_WIDTH = 6 +DESTROYER_LENGTH = 2 +CRUISER_LENGTH = 3 +AIRCRAFT_CARRIER_LENGTH = 4 + + +def random_vector() -> Tuple[int, int]: + while True: + vector = (randrange(-1, 2), randrange(-1, 2)) + + if vector == (0, 0): + # We can't have a zero vector, so try again + continue + + return vector + + +def add_vector(point: PointType, vector: VectorType) -> PointType: + return (point[0] + vector[0], point[1] + vector[1]) + + +def place_ship(sea: SeaType, size: int, code: int) -> None: + while True: + start = (randrange(1, SEA_WIDTH + 1), randrange(1, SEA_WIDTH + 1)) + vector = random_vector() + + # Get potential ship points + point = start + points = [] + + for _ in range(size): + point = add_vector(point, vector) + points.append(point) + + if not (all([is_within_sea(point, sea) for point in points]) and + all([value_at(point, sea) == 0 for point in points])): + # ship out of bounds or crosses other ship, trying again + continue + + # We found a valid spot, so actually place it now + for point in points: + set_value_at(code, point, sea) + + break + + +def print_encoded_sea(sea: SeaType) -> None: + for x in range(len(sea)): + print(' '.join([str(sea[y][x]) for y in range(len(sea) - 1, -1, -1)])) + + +def is_within_sea(point: PointType, sea: SeaType) -> bool: + return (1 <= point[0] <= len(sea)) and (1 <= point[1] <= len(sea)) + + +def has_ship(sea: SeaType, code: int) -> bool: + return any(code in row for row in sea) + + +def count_sunk(sea: SeaType, codes: Tuple[int, ...]) -> int: + return sum(not has_ship(sea, code) for code in codes) + + +def value_at(point: PointType, sea: SeaType) -> int: + return sea[point[1] - 1][point[0] -1] + + +def set_value_at(value: int, point: PointType, sea: SeaType) -> None: + sea[point[1] - 1][point[0] -1] = value + + +def get_next_target(sea: SeaType) -> PointType: + while True: + try: + guess = input('? ') + point = guess.split(',') + + if len(point) != 2: + raise ValueError() + + point = (int(point[0]), int(point[1])) + + if not is_within_sea(point, sea): + raise ValueError() + + return point + except ValueError: + print(f'INVALID. SPECIFY TWO NUMBERS FROM 1 TO {len(sea)}, SEPARATED BY A COMMA.') + + +def setup_ships(sea: SeaType): + place_ship(sea, DESTROYER_LENGTH, 1) + place_ship(sea, DESTROYER_LENGTH, 2) + place_ship(sea, CRUISER_LENGTH, 3) + place_ship(sea, CRUISER_LENGTH, 4) + place_ship(sea, AIRCRAFT_CARRIER_LENGTH, 5) + place_ship(sea, AIRCRAFT_CARRIER_LENGTH, 6) + + +def main() -> None: + print(' BATTLE') + print('CREATIVE COMPUTING MORRISTOWN, NEW JERSEY') + print() + sea = tuple(([0 for _ in range(SEA_WIDTH)] for _ in range(SEA_WIDTH))) + setup_ships(sea) + print('THE FOLLOWING CODE OF THE BAD GUYS\' FLEET DISPOSITION') + print('HAS BEEN CAPTURED BUT NOT DECODED:') + print() + print_encoded_sea(sea) + print() + print('DE-CODE IT AND USE IT IF YOU CAN') + print('BUT KEEP THE DE-CODING METHOD A SECRET.') + print() + print('START GAME') + splashes = 0 + hits = 0 + + while True: + target = get_next_target(sea) + target_value = value_at(target, sea) + + if target_value < 0: + print(f'YOU ALREADY PUT A HOLE IN SHIP NUMBER {abs(target_value)} AT THAT POINT.') + + if target_value <= 0: + print('SPLASH! TRY AGAIN.') + splashes += 1 + continue + + print(f'A DIRECT HIT ON SHIP NUMBER {target_value}') + hits += 1 + set_value_at(-target_value, target, sea) + + if not has_ship(sea, target_value): + print('AND YOU SUNK IT. HURRAH FOR THE GOOD GUYS.') + print('SO FAR, THE BAD GUYS HAVE LOST') + print(f'{count_sunk(sea, (1, 2))} DESTROYER(S),', + f'{count_sunk(sea, (3, 4))} CRUISER(S),', + f'AND {count_sunk(sea, (5, 6))} AIRCRAFT CARRIER(S).') + + if any(has_ship(sea, code) for code in range(1, SEA_WIDTH + 1)): + print(f'YOUR CURRENT SPLASH/HIT RATIO IS {splashes}/{hits}') + continue + + print('YOU HAVE TOTALLY WIPED OUT THE BAD GUYS\' FLEET ' + f'WITH A FINAL SPLASH/HIT RATIO OF {splashes}/{hits}') + + if not splashes: + print('CONGRATULATIONS -- A DIRECT HIT EVERY TIME.') + + print() + print('****************************') + break + + +if __name__ == "__main__": + main() From d5a032e6423b9e92579d955b0567538deca9791a Mon Sep 17 00:00:00 2001 From: Nezumi Ronin Date: Tue, 18 Jan 2022 10:56:57 -0600 Subject: [PATCH 234/337] Create life.pl --- 55_Life/perl/life.pl | 95 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 55_Life/perl/life.pl diff --git a/55_Life/perl/life.pl b/55_Life/perl/life.pl new file mode 100644 index 00000000..972cb322 --- /dev/null +++ b/55_Life/perl/life.pl @@ -0,0 +1,95 @@ +#!/usr/bin/perl +#use strict; + +print ' 'x 34 . "LIFE\n"; +print ' 'x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; +print "\n"; print "\n"; print "\n"; +print "ENTER YOUR PATTERN; \n"; +$X1=1; $Y1=1; $X2=24; $Y2=70; +@A; +$C=1; + +@B; +Line30: +print "? "; chomp($B[$C] = uc()); +if ($B[$C] eq "DONE") { $B[$C]=""; goto Line80; } +$B[$C]=~ s/\./ /g; +$C=$C+1; +goto Line30; + + +Line80: + +$C=$C-1; $L=0; $G=0; +for ($X=1; $X<=$C-1; $X++) { + if (length($B[$X])>$L) { $L=length($B[$X]); } + } + +$X1=11-$C/2; +$Y1=33-$L/2; +for ($X=1; $X<=$C; $X++) { + for ($Y=1; $Y<=length($B[$X]); $Y++) { + if (substr($B[$X],$Y-1,1) ne " ") { $A[$X1+$X][$Y1+$Y]=1; $P=$P+1; } + } + } +print "\n"; print "\n"; print "\n"; + +Line210: +print "GENERATION: ".$G."\t\tPOPULATION: ".$P; if ($I9) { print "\tINVALID!"; } +print "\n"; +$X3=24; $Y3=70; $X4=1; $Y4=1; $P=0; +$G=$G+1; +for ($X=1; $X<=$X1-1; $X++) { print "\n"; } +for ($X=$X1; $X<=$X2; $X++) { + $Row= " "x 80; + for ($Y=$Y1; $Y<=$Y2; $Y++) { + if ($A[$X][$Y]==2) { $A[$X][$Y]=0; goto Line270; } + if ($A[$X][$Y]==3) { $A[$X][$Y]=1; goto Line261; } + if ($A[$X][$Y]!=1) { goto Line270; } + + Line261: + substr($Row, $Y, 1, "*"); + if ($X<$X3) { $X3=$X; } + if ($X>$X4) { $X4=$X; } + if ($Y<$Y3) { $Y3=$Y; } + if ($Y>$Y4) { $Y4=$Y; } + + Line270: + } + print "$Row\n"; + } + +for ($X=$X2+1; $X<=24; $X++) { print "\n"; } +$X1=$X3; $X2=$X4; $Y1=$Y3; $Y2=$Y4; +if ($X1<3) { $X1=3; $I9=-1; } +if ($X2>22) { $X2=22; $I9=-1; } +if ($Y1<3) { $Y1=3; $I9=-1; } +if ($Y2>68) { $Y2=68; $I9=-1; } +$P=0; + +for ($X=$X1-1; $X<=$X2+1; $X++) { + for ($Y=$Y1-1; $Y<=$Y2+1; $Y++) { + $C=0; + for ($I=$X-1; $I<=$X+1; $I++) { + for ($J=$Y-1; $J<=$Y+1; $J++) { + if ($A[$I][$J]==1 || $A[$I][$J]==2) { $C=$C+1; } + } + } + if ($A[$X][$Y]==0) { goto Line610; } + if ($C<3 || $C>4) { $A[$X][$Y]=2; goto Line600; } + $P=$P+1; + + Line600: + goto Line620; + + Line610: + if ($C==3) { $A[$X][$Y]=3; $P=$P+1; } + + Line620: + } + } +$X1=$X1-1; $Y1=$Y1-1; $X2=$X2+1; $Y2=$Y2+1; +goto Line210; +exit; + + From 7dadd251abb0bba5e4d2ea7e5eded669f8e7e873 Mon Sep 17 00:00:00 2001 From: Stefan Waldmann Date: Wed, 19 Jan 2022 07:20:50 +0100 Subject: [PATCH 235/337] Evaluate invalid state --- 55_Life/java/src/java/Life.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/55_Life/java/src/java/Life.java b/55_Life/java/src/java/Life.java index d3477c66..e3c8ade3 100644 --- a/55_Life/java/src/java/Life.java +++ b/55_Life/java/src/java/Life.java @@ -58,6 +58,9 @@ public class Life { } } else { // cell is dead if (neighbours == 3) { + if (x < 2 || x > 67 || y < 2 || y > 21) { + invalid = true; + } transitions.add(new Transition(y, x, ALIVE)); population++; } From 7a2929f55d4228d1496a30289069edcb1325dbfe Mon Sep 17 00:00:00 2001 From: Jeff Atwood Date: Wed, 19 Jan 2022 18:41:24 -0800 Subject: [PATCH 236/337] Update README.md add notes about difficulty of porting 3d tic tac toe due to extensive use of `GOTO` for complex logic. --- 88_3-D_Tic-Tac-Toe/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/88_3-D_Tic-Tac-Toe/README.md b/88_3-D_Tic-Tac-Toe/README.md index df9cabf4..678bac6b 100644 --- a/88_3-D_Tic-Tac-Toe/README.md +++ b/88_3-D_Tic-Tac-Toe/README.md @@ -6,6 +6,15 @@ Each move is indicated by a 3-digit number (digits not separated by commas), wit This version of 3-D TIC-TAC-TOE is from Dartmouth College. +### Conversion notes + +The AI code for TicTacToe2 depends quite heavily on the non-structured GOTO (I can almost hear Dijkstra now) and translation is quite challenging. This code relies very heavily on GOTOs that bind the code tightly together. Comments explain where that happens in the original. + +There are at least two bugs from the original BASIC: + +1. Code should only allow player to input valid 3D coordinates where every digit is between 1 and 4, but the original code allows any value between 111 and 444 (such as 297, for instance). +2. If the player moves first and the game ends in a draw, the original program will still prompt the player for a move instead of calling for a draw. + --- As published in Basic Computer Games (1978): From dc64d34a3cbd485c03ed8fe7ac6deb85b210e804 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Thu, 20 Jan 2022 10:55:46 +0200 Subject: [PATCH 237/337] Detect Option Strict for VB projects --- 00_Utilities/DotnetUtils/DotnetUtils/Program.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index 560a7207..6e51d4f1 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -232,13 +232,15 @@ void printProjectWarnings(PortInfo info) { nullable, implicitUsing, rootNamespace, - langVersion + langVersion, + optionStrict ) = ( getValue(parent, "TargetFramework", "TargetFrameworks"), getValue(parent, "Nullable"), getValue(parent, "ImplicitUsings"), getValue(parent, "RootNamespace"), - getValue(parent, "LangVersion") + getValue(parent, "LangVersion"), + getValue(parent, "OptionStrict") ); if (framework != "net6.0") { @@ -267,6 +269,9 @@ void printProjectWarnings(PortInfo info) { if (langVersion != "16.9") { warnings.Add($"LangVersion: {langVersion}"); } + if (optionStrict != "On") { + warnings.Add($"OptionStrict: {optionStrict}"); + } } if (warnings.Any()) { From a8165eec0ea922476e67b0f9d5894474c6ec1580 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Thu, 20 Jan 2022 10:56:19 +0200 Subject: [PATCH 238/337] Animal (VB.NET) implementation --- 03_Animal/vbnet/Animal.vbproj | 1 + 03_Animal/vbnet/Branch.vb | 28 +++++ 03_Animal/vbnet/Game.vb | 126 +++++++++++++++++++ 03_Animal/vbnet/Program.vb | 6 + 03_Animal/vbnet/Shared/ConsoleAdapter.vb | 28 +++++ 03_Animal/vbnet/Shared/ConsoleAdapterBase.vb | 9 ++ 03_Animal/vbnet/Shared/Extensions.vb | 21 ++++ 7 files changed, 219 insertions(+) create mode 100644 03_Animal/vbnet/Branch.vb create mode 100644 03_Animal/vbnet/Game.vb create mode 100644 03_Animal/vbnet/Program.vb create mode 100644 03_Animal/vbnet/Shared/ConsoleAdapter.vb create mode 100644 03_Animal/vbnet/Shared/ConsoleAdapterBase.vb create mode 100644 03_Animal/vbnet/Shared/Extensions.vb diff --git a/03_Animal/vbnet/Animal.vbproj b/03_Animal/vbnet/Animal.vbproj index f54e4e3d..f01d7b62 100644 --- a/03_Animal/vbnet/Animal.vbproj +++ b/03_Animal/vbnet/Animal.vbproj @@ -4,5 +4,6 @@ Animal net6.0 16.9 + On diff --git a/03_Animal/vbnet/Branch.vb b/03_Animal/vbnet/Branch.vb new file mode 100644 index 00000000..6734e39d --- /dev/null +++ b/03_Animal/vbnet/Branch.vb @@ -0,0 +1,28 @@ +Public Class Branch + Public Property Text As String + + Public ReadOnly Property IsEnd As Boolean + Get + Return Yes Is Nothing AndAlso No Is Nothing + End Get + End Property + + Public Property Yes As Branch + Public Property No As Branch + + Public Iterator Function DescendantTexts() As IEnumerable(Of String) + If Yes IsNot Nothing Then + Yield Yes.Text + For Each childText In Yes.DescendantTexts + Yield childText + Next + End If + + If No IsNot Nothing Then + Yield No.Text + For Each childText In No.DescendantTexts + Yield childText + Next + End If + End Function +End Class diff --git a/03_Animal/vbnet/Game.vb b/03_Animal/vbnet/Game.vb new file mode 100644 index 00000000..3bc2b2f6 --- /dev/null +++ b/03_Animal/vbnet/Game.vb @@ -0,0 +1,126 @@ +Option Compare Text + +Public Class Game + Private Shared ReadOnly YesNoResponses As New Dictionary(Of String, Boolean)(StringComparer.InvariantCultureIgnoreCase) From { + {"yes", True}, + {"y", True}, + {"true", True}, + {"t", True}, + {"1", True}, + {"no", False}, + {"n", False}, + {"false", False}, + {"f", False}, + {"0", False} + } + + ReadOnly console As ConsoleAdapterBase + ReadOnly root As New Branch With { + .Text = "DOES IT SWIM?", + .Yes = New Branch With {.Text = "FISH"}, + .No = New Branch With {.Text = "BIRD"} + } + + ''' Reduces a string or console input to True, False or Nothing. Case-insensitive. + ''' Optional String to reduce via the same logic. If not passed in, will use console.ReadLine + ''' + ''' Returns True for a "yes" response (yes, y, true, t, 1) and False for a "no" response (no, n, false, f, 0).
+ ''' Returns Nothing if the response doesn't match any of these. + '''
+ Private Function GetYesNo(Optional s As String = Nothing) As Boolean? + s = If(s, console.ReadLine) + Dim ret As Boolean + If YesNoResponses.TryGetValue(s, ret) Then Return ret + Return Nothing + End Function + + Sub New(console As ConsoleAdapterBase) + If console Is Nothing Then Throw New ArgumentNullException(NameOf(console)) + Me.console = console + End Sub + + + Sub BeginLoop() + console.WriteCenteredLine("ANIMAL") + console.WriteCenteredLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + console.Write( +" + + +PLAY 'GUESS THE ANIMAL' + +THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT. + +") + + Do + console.Write("ARE YOU THINKING OF AN ANIMAL? ") + + Dim response = console.ReadLine + If response = "list" Then + console.WriteLine( +" +ANIMALS I ALREADY KNOW ARE:") + root.DescendantTexts.ForEach(Sub(text, index) + If index > 0 AndAlso index Mod 4 = 0 Then console.WriteLine() + console.Write($"{text.MaxLength(15),-15}") + End Sub) + console.WriteLine( +" +") + Continue Do + End If + + Dim ynResponse = GetYesNo(response) + If ynResponse Is Nothing OrElse Not ynResponse Then Continue Do + + Dim currentBranch = root + Do While Not currentBranch.IsEnd + console.Write($"{currentBranch.Text} ") + Do + ynResponse = GetYesNo() + Loop While ynResponse Is Nothing + currentBranch = If( + ynResponse, + currentBranch.Yes, + currentBranch.No + ) + Loop + + 'at end + console.Write($"IS IT A {currentBranch.Text}? ") + ynResponse = GetYesNo() + If ynResponse Then ' No difference between False or Nothing + console.WriteLine("WHY NOT TRY ANOTHER ANIMAL?") + Continue Do + End If + + console.Write("THE ANIMAL YOU WERE THINKING OF WAS A ? ") + Dim newAnimal = console.ReadLine + + console.WriteLine( +$"PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A +{newAnimal} FROM A {currentBranch.Text}") + Dim newQuestion = console.ReadLine + + console.Write( +$"FOR A {newAnimal} THE ANSWER WOULD BE ? ") + Do + ynResponse = GetYesNo() + Loop While ynResponse Is Nothing + + Dim newBranch = New Branch With {.Text = newAnimal} + Dim currentBranchCopy = New Branch With {.Text = currentBranch.Text} + currentBranch.Text = newQuestion + If ynResponse Then + currentBranch.Yes = newBranch + currentBranch.No = currentBranchCopy + Else + currentBranch.No = newBranch + currentBranch.Yes = currentBranchCopy + End If + + ' TODO how do we exit? + Loop + End Sub +End Class diff --git a/03_Animal/vbnet/Program.vb b/03_Animal/vbnet/Program.vb new file mode 100644 index 00000000..adb34932 --- /dev/null +++ b/03_Animal/vbnet/Program.vb @@ -0,0 +1,6 @@ +Module Program + Sub Main() + Dim game As New Game(New ConsoleAdapter) + game.BeginLoop() + End Sub +End Module diff --git a/03_Animal/vbnet/Shared/ConsoleAdapter.vb b/03_Animal/vbnet/Shared/ConsoleAdapter.vb new file mode 100644 index 00000000..132f1968 --- /dev/null +++ b/03_Animal/vbnet/Shared/ConsoleAdapter.vb @@ -0,0 +1,28 @@ +Public Class ConsoleAdapter + Inherits ConsoleAdapterBase + + Public Overrides Sub Write(value As Object) + Console.Write(value) + End Sub + + Public Overrides Sub WriteLine(value As Object) + Console.WriteLine(value) + End Sub + + Public Overrides Sub WriteLine() + Console.WriteLine() + End Sub + + Public Overrides Sub WriteCenteredLine(value As Object) + Dim toWrite = If(value?.ToString, "") + Console.WriteLine($"{Space((Console.WindowWidth - toWrite.Length) \ 2)}{toWrite}") + End Sub + + Public Overrides Function ReadLine() As String + Dim response As String + Do + response = Console.ReadLine + Loop While response Is Nothing + Return response.Trim + End Function +End Class diff --git a/03_Animal/vbnet/Shared/ConsoleAdapterBase.vb b/03_Animal/vbnet/Shared/ConsoleAdapterBase.vb new file mode 100644 index 00000000..4c9166bf --- /dev/null +++ b/03_Animal/vbnet/Shared/ConsoleAdapterBase.vb @@ -0,0 +1,9 @@ +Public MustInherit Class ConsoleAdapterBase + Public MustOverride Sub Write(value As Object) + Public MustOverride Sub WriteLine(value As Object) + Public MustOverride Sub WriteLine() + Public MustOverride Sub WriteCenteredLine(value As Object) + + ''' Implementations should always return a String without leading or trailing whitespace, never Nothng + Public MustOverride Function ReadLine() As String +End Class diff --git a/03_Animal/vbnet/Shared/Extensions.vb b/03_Animal/vbnet/Shared/Extensions.vb new file mode 100644 index 00000000..83d1914b --- /dev/null +++ b/03_Animal/vbnet/Shared/Extensions.vb @@ -0,0 +1,21 @@ +Imports System.Runtime.CompilerServices + +Public Module Extensions + Public Sub ForEach(Of T)(src As IEnumerable(Of T), action As Action(Of T, Integer)) + Dim index As Integer + For Each x In src + action(x, index) + index += 1 + Next + End Sub + + Public Function MaxLength(s As String, value As Integer) As String + If s Is Nothing Then Return Nothing + Return s.Substring(0, Math.Min(s.Length, value)) + End Function + + Public Function ForceEndsWith(s As String, toAppend As String) As String + If Not s.EndsWith(toAppend, StringComparison.OrdinalIgnoreCase) Then s += toAppend + Return s + End Function +End Module From 311776e3a8d6fbe5594499d429e228b84075701d Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Thu, 20 Jan 2022 11:03:38 +0200 Subject: [PATCH 239/337] Create test project --- .../vbnet/Animal.Tests/Animal.Tests.vbproj | 23 +++++++++++++++++ 03_Animal/vbnet/Animal.Tests/UnitTest1.vb | 12 +++++++++ 03_Animal/vbnet/Animal.sln | 25 +++++++++++++------ 03_Animal/vbnet/{ => Animal}/Animal.vbproj | 0 03_Animal/vbnet/{ => Animal}/Branch.vb | 0 03_Animal/vbnet/{ => Animal}/Game.vb | 0 03_Animal/vbnet/{ => Animal}/Program.vb | 0 .../{ => Animal}/Shared/ConsoleAdapter.vb | 0 .../{ => Animal}/Shared/ConsoleAdapterBase.vb | 0 .../vbnet/{ => Animal}/Shared/Extensions.vb | 0 10 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 03_Animal/vbnet/Animal.Tests/Animal.Tests.vbproj create mode 100644 03_Animal/vbnet/Animal.Tests/UnitTest1.vb rename 03_Animal/vbnet/{ => Animal}/Animal.vbproj (100%) rename 03_Animal/vbnet/{ => Animal}/Branch.vb (100%) rename 03_Animal/vbnet/{ => Animal}/Game.vb (100%) rename 03_Animal/vbnet/{ => Animal}/Program.vb (100%) rename 03_Animal/vbnet/{ => Animal}/Shared/ConsoleAdapter.vb (100%) rename 03_Animal/vbnet/{ => Animal}/Shared/ConsoleAdapterBase.vb (100%) rename 03_Animal/vbnet/{ => Animal}/Shared/Extensions.vb (100%) diff --git a/03_Animal/vbnet/Animal.Tests/Animal.Tests.vbproj b/03_Animal/vbnet/Animal.Tests/Animal.Tests.vbproj new file mode 100644 index 00000000..05d00314 --- /dev/null +++ b/03_Animal/vbnet/Animal.Tests/Animal.Tests.vbproj @@ -0,0 +1,23 @@ + + + + Animal.Tests + net6.0 + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + diff --git a/03_Animal/vbnet/Animal.Tests/UnitTest1.vb b/03_Animal/vbnet/Animal.Tests/UnitTest1.vb new file mode 100644 index 00000000..fe32490e --- /dev/null +++ b/03_Animal/vbnet/Animal.Tests/UnitTest1.vb @@ -0,0 +1,12 @@ +Imports System +Imports Xunit + +Namespace Animal.Tests + Public Class UnitTest1 + + Sub TestSub() + + End Sub + End Class +End Namespace + diff --git a/03_Animal/vbnet/Animal.sln b/03_Animal/vbnet/Animal.sln index eaaf1b67..f3b48076 100644 --- a/03_Animal/vbnet/Animal.sln +++ b/03_Animal/vbnet/Animal.sln @@ -1,22 +1,31 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30114.105 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32112.339 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Animal", "Animal.vbproj", "{147D66D5-D817-4024-9447-9F5B9A6D2B7D}" +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Animal", "Animal\Animal.vbproj", "{5517E4CE-BCF9-4D1F-9A17-B620C1B96B0D}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Animal.Tests", "Animal.Tests\Animal.Tests.vbproj", "{3986C6A2-77D4-4F00-B3CF-F5736C623B1E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5517E4CE-BCF9-4D1F-9A17-B620C1B96B0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5517E4CE-BCF9-4D1F-9A17-B620C1B96B0D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5517E4CE-BCF9-4D1F-9A17-B620C1B96B0D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5517E4CE-BCF9-4D1F-9A17-B620C1B96B0D}.Release|Any CPU.Build.0 = Release|Any CPU + {3986C6A2-77D4-4F00-B3CF-F5736C623B1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3986C6A2-77D4-4F00-B3CF-F5736C623B1E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3986C6A2-77D4-4F00-B3CF-F5736C623B1E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3986C6A2-77D4-4F00-B3CF-F5736C623B1E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {147D66D5-D817-4024-9447-9F5B9A6D2B7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {147D66D5-D817-4024-9447-9F5B9A6D2B7D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {147D66D5-D817-4024-9447-9F5B9A6D2B7D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {147D66D5-D817-4024-9447-9F5B9A6D2B7D}.Release|Any CPU.Build.0 = Release|Any CPU + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {88469A47-E30C-4763-A325-074101D16608} EndGlobalSection EndGlobal diff --git a/03_Animal/vbnet/Animal.vbproj b/03_Animal/vbnet/Animal/Animal.vbproj similarity index 100% rename from 03_Animal/vbnet/Animal.vbproj rename to 03_Animal/vbnet/Animal/Animal.vbproj diff --git a/03_Animal/vbnet/Branch.vb b/03_Animal/vbnet/Animal/Branch.vb similarity index 100% rename from 03_Animal/vbnet/Branch.vb rename to 03_Animal/vbnet/Animal/Branch.vb diff --git a/03_Animal/vbnet/Game.vb b/03_Animal/vbnet/Animal/Game.vb similarity index 100% rename from 03_Animal/vbnet/Game.vb rename to 03_Animal/vbnet/Animal/Game.vb diff --git a/03_Animal/vbnet/Program.vb b/03_Animal/vbnet/Animal/Program.vb similarity index 100% rename from 03_Animal/vbnet/Program.vb rename to 03_Animal/vbnet/Animal/Program.vb diff --git a/03_Animal/vbnet/Shared/ConsoleAdapter.vb b/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb similarity index 100% rename from 03_Animal/vbnet/Shared/ConsoleAdapter.vb rename to 03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb diff --git a/03_Animal/vbnet/Shared/ConsoleAdapterBase.vb b/03_Animal/vbnet/Animal/Shared/ConsoleAdapterBase.vb similarity index 100% rename from 03_Animal/vbnet/Shared/ConsoleAdapterBase.vb rename to 03_Animal/vbnet/Animal/Shared/ConsoleAdapterBase.vb diff --git a/03_Animal/vbnet/Shared/Extensions.vb b/03_Animal/vbnet/Animal/Shared/Extensions.vb similarity index 100% rename from 03_Animal/vbnet/Shared/Extensions.vb rename to 03_Animal/vbnet/Animal/Shared/Extensions.vb From ce771b6d3c5e236e69ca3c228a6e6395601fa1a0 Mon Sep 17 00:00:00 2001 From: Claus Volko <49327712+adokhugi@users.noreply.github.com> Date: Thu, 20 Jan 2022 10:38:04 +0100 Subject: [PATCH 240/337] Create aceyducey.kt --- 01_Acey_Ducey/kotlin/aceyducey.kt | 74 +++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 01_Acey_Ducey/kotlin/aceyducey.kt diff --git a/01_Acey_Ducey/kotlin/aceyducey.kt b/01_Acey_Ducey/kotlin/aceyducey.kt new file mode 100644 index 00000000..fe7c32c7 --- /dev/null +++ b/01_Acey_Ducey/kotlin/aceyducey.kt @@ -0,0 +1,74 @@ +import java.util.Random + +fun printCard(a: Int) { + if (a < 11) println(a) + if (a == 11) println("JACK") + if (a == 12) println("QUEEN") + if (a == 13) println("KING") + if (a == 14) println("ACE") +} + +fun main() { + println("ACEY DUCEY CARD GAME") + println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + println() + println() + println("ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER ") + println("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP") + println("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING") + println("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE") + println("A VALUE BETWEEN THE FIRST TWO.") + println("IF YOU DO NOT WANT TO BET, INPUT A 0") + var random = Random() + do { + var q = 100 + var a : Int + var b : Int + var m : Int + println("YOU NOW HAVE " + q + " DOLLARS.") + println() + do { + do { + do { + println("HERE ARE YOUR NEXT TWO CARDS: ") + do { + a = random.nextInt(12) + 2 + b = random.nextInt(12) + 2 + } while (a >= b); + printCard(a) + printCard(b) + println() + println() + print("WHAT IS YOUR BET") + m = readLine()!!.toInt() + if (m == 0) { + println("CHICKEN!!") + println() + } + } while (m == 0); + if (m > q) { + println("SORRY, MY FRIEND, BUT YOU BET TOO MUCH.") + println("YOU HAVE ONLY " + q + " DOLLARS TO BET.") + } + } while (m > q); + var c = random.nextInt(12) + 2 + printCard(c) + println() + if (c > a && c < b) { + println("YOU WIN!!!") + q += m + } + else { + println("SORRY, YOU LOSE") + if (m < q) q -= m + } + } while (m < q); + println() + println() + println("SORRY, FRIEND, BUT YOU BLEW YOUR WAD.") + println() + println() + println("TRY AGAIN (YES OR NO)") + } while (readLine() == "YES"); + println("O.K., HOPE YOU HAD FUN!") +} From 33af445d20d31188fb29b2eb8e8ef7b47aac968c Mon Sep 17 00:00:00 2001 From: Claus Volko <49327712+adokhugi@users.noreply.github.com> Date: Thu, 20 Jan 2022 10:38:20 +0100 Subject: [PATCH 241/337] Delete aceyducey.kt --- 01_Acey_Ducey/aceyducey.kt | 74 -------------------------------------- 1 file changed, 74 deletions(-) delete mode 100644 01_Acey_Ducey/aceyducey.kt diff --git a/01_Acey_Ducey/aceyducey.kt b/01_Acey_Ducey/aceyducey.kt deleted file mode 100644 index ccc5eb0a..00000000 --- a/01_Acey_Ducey/aceyducey.kt +++ /dev/null @@ -1,74 +0,0 @@ -import java.util.Random - -fun printCard(a: Int) { - if (a < 11) println(a) - if (a == 11) println("JACK") - if (a == 12) println("QUEEN") - if (a == 13) println("KING") - if (a == 14) println("ACE") -} - -fun main() { - println("ACEY DUCEY CARD GAME") - println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - println() - println() - println("ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER ") - println("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP") - println("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING") - println("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE") - println("A VALUE BETWEEN THE FIRST TWO.") - println("IF YOU DO NOT WANT TO BET, INPUT A 0") - var random = Random() - do { - var q = 100 - var a : Int - var b : Int - var m : Int - println("YOU NOW HAVE " + q + " DOLLARS.") - println() - do { - do { - do { - println("HERE ARE YOUR NEXT TWO CARDS: ") - do { - a = random.nextInt(12) + 2 - b = random.nextInt(12) + 2 - } while (a >= b); - printCard(a) - printCard(b) - println() - println() - print("WHAT IS YOUR BET") - m = readLine()!!.toInt() - if (m == 0) { - println("CHICKEN!!") - println() - } - } while (m == 0); - if (m > q) { - println("SORRY, MY FRIEND, BUT YOU BET TOO MUCH.") - println("YOU HAVE ONLY " + q + " DOLLARS TO BET.") - } - } while (m > q); - var c = random.nextInt(12) + 2 - printCard(c) - println() - if (c > a && c < b) { - println("YOU WIN!!!") - q += m - } - else { - println("SORRY, YOU LOSE") - if (m < q) q -= m - } - } while (m < q); - println() - println() - println("SORRY, FRIEND, BUT YOU BLEW YOUR WAD.") - println() - println() - println("TRY AGAIN (YES OR NO)") - } while (readLine() == "YES"); - println("O.K., HOPE YOU HAD FUN!") -} From 37eb53b4f1e0d3963c8e1918a6f86273aba2f0f4 Mon Sep 17 00:00:00 2001 From: Nezumi Ronin Date: Thu, 20 Jan 2022 16:02:04 -0600 Subject: [PATCH 242/337] Create yatol.pl YATOL: Yet Another TOdo List Get list of basic files ordered by number or lines. This way you can do the easier ones first. --- 00_Utilities/yatol.pl | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 00_Utilities/yatol.pl diff --git a/00_Utilities/yatol.pl b/00_Utilities/yatol.pl new file mode 100644 index 00000000..71861209 --- /dev/null +++ b/00_Utilities/yatol.pl @@ -0,0 +1,35 @@ +#!/usr/bin/perl +#YATOL: Yet Another TOdo List +use strict; + +#REM: Get list of basic files ordered by number or lines. +#REM: This way you can do the easier ones first. +my @Ret=`find .. -iname '*.bas' -exec wc -l \{\} \\; | sort -h`; + + +my @Langs= qw(PL JS VB PAS RB C# JAVA PY); +my @Dirs= qw(perl javascript vbnet pascal ruby csharp java python); + +print " "x 25 ."LINES\t"; +foreach my $Dir (@Langs) { + print "$Dir\t"; + } +print "\n"; + +foreach my $Lin (@Ret) { + chomp $Lin; + my ($Num, $File)= split (" ", $Lin); + my @Parts= split(/\//, $File); + my $Base= $Parts[1]; + + my $Tab= 25-length($Base); + print "$Base".(" "x$Tab)."$Num\t"; + + foreach my $Dir (@Dirs) { + my $Path= "../$Base/$Dir/"; + my $Ret= `ls $Path | wc -l`; + if ($Ret>1) { print "YES"; } + else { print " ";} + print "\t"; + } + print "\n"; From a8c3604986a9a55df7aefc58567dcbcded820abd Mon Sep 17 00:00:00 2001 From: Nezumi Ronin Date: Thu, 20 Jan 2022 16:07:19 -0600 Subject: [PATCH 243/337] Update yatol.pl --- 00_Utilities/yatol.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/00_Utilities/yatol.pl b/00_Utilities/yatol.pl index 71861209..136c3d67 100644 --- a/00_Utilities/yatol.pl +++ b/00_Utilities/yatol.pl @@ -33,3 +33,4 @@ foreach my $Lin (@Ret) { print "\t"; } print "\n"; + } From 075e10c694b0d28dcd823f917a76213a66136441 Mon Sep 17 00:00:00 2001 From: Alex Gomez Date: Thu, 20 Jan 2022 18:05:52 -0600 Subject: [PATCH 244/337] Execute bit now --- 00_Utilities/yatol.pl | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 00_Utilities/yatol.pl diff --git a/00_Utilities/yatol.pl b/00_Utilities/yatol.pl old mode 100644 new mode 100755 From 9ca24407fe3d1d6a733031997dd826cbab6c008d Mon Sep 17 00:00:00 2001 From: Alex Gomez Date: Thu, 20 Jan 2022 18:10:04 -0600 Subject: [PATCH 245/337] Sorry, I'm learning git --- 00_Utilities/yatol.pl | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/00_Utilities/yatol.pl b/00_Utilities/yatol.pl index 136c3d67..0f4ef111 100755 --- a/00_Utilities/yatol.pl +++ b/00_Utilities/yatol.pl @@ -2,21 +2,24 @@ #YATOL: Yet Another TOdo List use strict; -#REM: Get list of basic files ordered by number or lines. +#REM: Get list of basic files ordered by number of lines. #REM: This way you can do the easier ones first. my @Ret=`find .. -iname '*.bas' -exec wc -l \{\} \\; | sort -h`; my @Langs= qw(PL JS VB PAS RB C# JAVA PY); my @Dirs= qw(perl javascript vbnet pascal ruby csharp java python); +my %Sum; -print " "x 25 ."LINES\t"; +print " "x 25 ."BAS\t"; foreach my $Dir (@Langs) { print "$Dir\t"; } print "\n"; +my $Count; foreach my $Lin (@Ret) { + $Count++; chomp $Lin; my ($Num, $File)= split (" ", $Lin); my @Parts= split(/\//, $File); @@ -28,9 +31,25 @@ foreach my $Lin (@Ret) { foreach my $Dir (@Dirs) { my $Path= "../$Base/$Dir/"; my $Ret= `ls $Path | wc -l`; - if ($Ret>1) { print "YES"; } + if ($Ret>1) { print "YES"; $Sum{$Dir}++; } else { print " ";} print "\t"; } print "\n"; + } + +print "\t\tFILES:\t\t"; +foreach my $Dir (@Dirs) { + print "$Sum{$Dir}\t"; + } +print "\n"; + + +print "\t\tADVANCE:\t"; +foreach my $Dir (@Dirs) { + my $Per= int($Sum{$Dir}/$Count*100)."%"; + print "$Per\t"; + } +print "\n"; + From ed0dcb5add6a4c8ce94e0d85b0e17fbf663c3625 Mon Sep 17 00:00:00 2001 From: openback Date: Thu, 20 Jan 2022 21:05:43 -0500 Subject: [PATCH 246/337] 09_Battle/python - Add multi-line strings and *args --- 09_Battle/python/battle.py | 42 ++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/09_Battle/python/battle.py b/09_Battle/python/battle.py index 8c992458..d9449b77 100644 --- a/09_Battle/python/battle.py +++ b/09_Battle/python/battle.py @@ -40,8 +40,8 @@ def place_ship(sea: SeaType, size: int, code: int) -> None: point = add_vector(point, vector) points.append(point) - if not (all([is_within_sea(point, sea) for point in points]) and - all([value_at(point, sea) == 0 for point in points])): + if (not all([is_within_sea(point, sea) for point in points]) or + any([value_at(point, sea) for point in points])): # ship out of bounds or crosses other ship, trying again continue @@ -65,7 +65,7 @@ def has_ship(sea: SeaType, code: int) -> bool: return any(code in row for row in sea) -def count_sunk(sea: SeaType, codes: Tuple[int, ...]) -> int: +def count_sunk(sea: SeaType, *codes: int) -> int: return sum(not has_ship(sea, code) for code in codes) @@ -106,20 +106,23 @@ def setup_ships(sea: SeaType): def main() -> None: - print(' BATTLE') - print('CREATIVE COMPUTING MORRISTOWN, NEW JERSEY') - print() sea = tuple(([0 for _ in range(SEA_WIDTH)] for _ in range(SEA_WIDTH))) setup_ships(sea) - print('THE FOLLOWING CODE OF THE BAD GUYS\' FLEET DISPOSITION') - print('HAS BEEN CAPTURED BUT NOT DECODED:') - print() + print(f''' + BATTLE +CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + +THE FOLLOWING CODE OF THE BAD GUYS' FLEET DISPOSITION +HAS BEEN CAPTURED BUT NOT DECODED: + +''') print_encoded_sea(sea) - print() - print('DE-CODE IT AND USE IT IF YOU CAN') - print('BUT KEEP THE DE-CODING METHOD A SECRET.') - print() - print('START GAME') + print(''' + +DE-CODE IT AND USE IT IF YOU CAN +BUT KEEP THE DE-CODING METHOD A SECRET. + +START GAME''') splashes = 0 hits = 0 @@ -142,11 +145,11 @@ def main() -> None: if not has_ship(sea, target_value): print('AND YOU SUNK IT. HURRAH FOR THE GOOD GUYS.') print('SO FAR, THE BAD GUYS HAVE LOST') - print(f'{count_sunk(sea, (1, 2))} DESTROYER(S),', - f'{count_sunk(sea, (3, 4))} CRUISER(S),', - f'AND {count_sunk(sea, (5, 6))} AIRCRAFT CARRIER(S).') + print(f'{count_sunk(sea, 1, 2)} DESTROYER(S),', + f'{count_sunk(sea, 3, 4)} CRUISER(S),', + f'AND {count_sunk(sea, 5, 6)} AIRCRAFT CARRIER(S).') - if any(has_ship(sea, code) for code in range(1, SEA_WIDTH + 1)): + if any(has_ship(sea, code) for code in range(1, 7)): print(f'YOUR CURRENT SPLASH/HIT RATIO IS {splashes}/{hits}') continue @@ -156,8 +159,7 @@ def main() -> None: if not splashes: print('CONGRATULATIONS -- A DIRECT HIT EVERY TIME.') - print() - print('****************************') + print("\n****************************") break From 9f9cdc3781a883a8293fbd192b5fdd3daa4f2361 Mon Sep 17 00:00:00 2001 From: openback Date: Thu, 20 Jan 2022 21:06:27 -0500 Subject: [PATCH 247/337] 09_Battle/python - Add OO version --- 09_Battle/python/battle_oo.py | 203 ++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 09_Battle/python/battle_oo.py diff --git a/09_Battle/python/battle_oo.py b/09_Battle/python/battle_oo.py new file mode 100644 index 00000000..dc35efa6 --- /dev/null +++ b/09_Battle/python/battle_oo.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python3 +from dataclasses import dataclass +from random import randrange + + +DESTROYER_LENGTH = 2 +CRUISER_LENGTH = 3 +AIRCRAFT_CARRIER_LENGTH = 4 + + +@dataclass(frozen=True) +class Point: + x: int + y: int + + @classmethod + def random(cls, start: int, stop: int) -> 'Point': + return Point(randrange(start, stop), randrange(start, stop)) + + def __add__(self, vector: 'Vector') -> 'Point': + return Point(self.x + vector.x, self.y + vector.y) + + +@dataclass(frozen=True) +class Vector: + x: int + y: int + + @staticmethod + def random() -> 'Vector': + return Vector(randrange(-1, 2, 2), randrange(-1, 2, 2)) + + def __mul__(self, factor: int) -> 'Vector': + return Vector(self.x * factor, self.y * factor) + + +class Sea: + WIDTH = 6 + + def __init__(self): + self._graph = tuple(([0 for _ in range(self.WIDTH)] for _ in range(self.WIDTH))) + + def _validate_item_indices(self, point: Point) -> None: + if not isinstance(point, Point): + raise ValueError(f'Sea indices must be Points, not {type(point).__name__}') + + if not((1 <= point.x <= self.WIDTH) and (1 <= point.y <= self.WIDTH)): + raise IndexError('Sea index out of range') + + # Allows us to get the value using a point as a key, for example, `sea[Point(3,2)]` + def __getitem__(self, point: Point) -> int: + self._validate_item_indices(point) + + return self._graph[point.y - 1][point.x -1] + + # Allows us to get the value using a point as a key, for example, `sea[Point(3,2)] = 3` + def __setitem__(self, point: Point, value: int) -> None: + self._validate_item_indices(point) + self._graph[point.y - 1][point.x -1] = value + + # Allows us to check if a point exists in the sea for example, `if Point(3,2) in sea:` + def __contains__(self, point: Point) -> bool: + try: + self._validate_item_indices(point) + except IndexError: + return False + + return True + + # Redefines how python will render this object when asked as a str + def __str__(self): + # Display it encoded + return "\n".join([' '.join([str(self._graph[y][x]) + for y in range(self.WIDTH - 1, -1, -1)]) + for x in range(self.WIDTH)]) + + def has_ship(self, ship_code: int) -> bool: + return any(ship_code in row for row in self._graph) + + def count_sunk(self, *ship_codes: int) -> int: + return sum(not self.has_ship(ship_code) for ship_code in ship_codes) + + +class Battle: + def __init__(self) -> None: + self.sea = Sea() + self.place_ship(DESTROYER_LENGTH, 1) + self.place_ship(DESTROYER_LENGTH, 2) + self.place_ship(CRUISER_LENGTH, 3) + self.place_ship(CRUISER_LENGTH, 4) + self.place_ship(AIRCRAFT_CARRIER_LENGTH, 5) + self.place_ship(AIRCRAFT_CARRIER_LENGTH, 6) + self.splashes = 0 + self.hits = 0 + + def _next_target(self) -> Point: + while True: + try: + guess = input('? ') + coordinates = guess.split(',') + + if len(coordinates) != 2: + raise ValueError() + + point = Point(int(coordinates[0]), int(coordinates[1])) + + if point not in self.sea: + raise ValueError() + + return point + except ValueError: + print(f'INVALID. SPECIFY TWO NUMBERS FROM 1 TO {Sea.WIDTH}, SEPARATED BY A COMMA.') + + @property + def splash_hit_ratio(self) -> str: + return f'{self.splashes}/{self.hits}' + + @property + def _is_finished(self) -> bool: + return self.sea.count_sunk(*(i for i in range(1, 7))) == 6 + + def place_ship(self, size: int, ship_code: int) -> None: + while True: + start = Point.random(1, self.sea.WIDTH + 1) + vector = Vector.random() + # Get potential ship points + points = [start + vector * i for i in range(size)] + + if not (all([point in self.sea for point in points]) and + not any([self.sea[point] for point in points])): + # ship out of bounds or crosses other ship, trying again + continue + + # We found a valid spot, so actually place it now + for point in points: + self.sea[point] = ship_code + + break + + + def loop(self): + while True: + target = self._next_target() + target_value = self.sea[target] + + if target_value < 0: + print(f'YOU ALREADY PUT A HOLE IN SHIP NUMBER {abs(target_value)} AT THAT POINT.') + + if target_value <= 0: + print('SPLASH! TRY AGAIN.') + self.splashes += 1 + continue + + print(f'A DIRECT HIT ON SHIP NUMBER {target_value}') + self.hits += 1 + self.sea[target] = -target_value + + if not self.sea.has_ship(target_value): + print('AND YOU SUNK IT. HURRAH FOR THE GOOD GUYS.') + self._display_sunk_report() + + if self._is_finished: + self._display_game_end() + break + + print(f'YOUR CURRENT SPLASH/HIT RATIO IS {self.splash_hit_ratio}') + + def _display_sunk_report(self): + print('SO FAR, THE BAD GUYS HAVE LOST', + f'{self.sea.count_sunk(1, 2)} DESTROYER(S),', + f'{self.sea.count_sunk(3, 4)} CRUISER(S),', + f'AND {self.sea.count_sunk(5, 6)} AIRCRAFT CARRIER(S).') + + def _display_game_end(self): + print('YOU HAVE TOTALLY WIPED OUT THE BAD GUYS\' FLEET ' + f'WITH A FINAL SPLASH/HIT RATIO OF {self.splash_hit_ratio}') + + if not self.splashes: + print('CONGRATULATIONS -- A DIRECT HIT EVERY TIME.') + + print("\n****************************") + + +def main() -> None: + game = Battle() + print(f''' + BATTLE +CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + +THE FOLLOWING CODE OF THE BAD GUYS' FLEET DISPOSITION +HAS BEEN CAPTURED BUT NOT DECODED: + +{game.sea} + +DE-CODE IT AND USE IT IF YOU CAN +BUT KEEP THE DE-CODING METHOD A SECRET. + +START GAME''') + game.loop() + + +if __name__ == "__main__": + main() From e8d753ada84b01229398742925be45e52ac31f77 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Fri, 21 Jan 2022 04:31:55 +0200 Subject: [PATCH 248/337] Added tests project --- .../vbnet/Animal.Tests/Animal.Tests.vbproj | 8 +- 03_Animal/vbnet/Animal.Tests/MockConsole.vb | 65 +++++++++++++++ 03_Animal/vbnet/Animal.Tests/TestContainer.vb | 80 +++++++++++++++++++ 03_Animal/vbnet/Animal.Tests/UnitTest1.vb | 12 --- .../vbnet/Animal/Shared/ConsoleAdapter.vb | 1 + 03_Animal/vbnet/Animal/Shared/Extensions.vb | 29 +++++++ 6 files changed, 181 insertions(+), 14 deletions(-) create mode 100644 03_Animal/vbnet/Animal.Tests/MockConsole.vb create mode 100644 03_Animal/vbnet/Animal.Tests/TestContainer.vb delete mode 100644 03_Animal/vbnet/Animal.Tests/UnitTest1.vb diff --git a/03_Animal/vbnet/Animal.Tests/Animal.Tests.vbproj b/03_Animal/vbnet/Animal.Tests/Animal.Tests.vbproj index 05d00314..62a341e9 100644 --- a/03_Animal/vbnet/Animal.Tests/Animal.Tests.vbproj +++ b/03_Animal/vbnet/Animal.Tests/Animal.Tests.vbproj @@ -3,12 +3,12 @@ Animal.Tests net6.0 - false + On - + runtime; build; native; contentfiles; analyzers; buildtransitive @@ -20,4 +20,8 @@ + + + + diff --git a/03_Animal/vbnet/Animal.Tests/MockConsole.vb b/03_Animal/vbnet/Animal.Tests/MockConsole.vb new file mode 100644 index 00000000..a78dc50f --- /dev/null +++ b/03_Animal/vbnet/Animal.Tests/MockConsole.vb @@ -0,0 +1,65 @@ +Imports System.IO + +Public Class MockConsole + Inherits ConsoleAdapterBase + + Private inputs As Queue(Of String) + Public ReadOnly Lines As New List(Of (line As String, centered As Boolean)) From { + ("", False) + } + + ' TODO it's possible to clear all the lines, and we'd have to check once again in WriteString and WriteCenteredLine if there are any lines + + Sub New(Inputs As IEnumerable(Of String)) + Me.inputs = New Queue(Of String)(Inputs) + End Sub + + Private Sub CheckLinesInitialized() + If Lines.Count = 0 Then Lines.Add(("", False)) + End Sub + + Private Sub WriteString(s As String, Optional centered As Boolean = False) + If s Is Nothing Then Return + CheckLinesInitialized() + s.Split(Environment.NewLine).ForEach(Sub(line, index) + If index = 0 Then + Dim currentLast = Lines(Lines.Count - 1) + ' centered should never come from the current last line + ' if WriteCenteredLine is called, it immediately creates a new line + Lines(Lines.Count - 1) = (currentLast.line + line, centered) + Else + Lines.Add((line, centered)) + End If + End Sub) + End Sub + + Public Overrides Sub Write(value As Object) + WriteString(value?.ToString) + End Sub + + Public Overrides Sub WriteLine(value As Object) + WriteString(value?.ToString) + WriteLine() + End Sub + + Public Overrides Sub WriteLine() + Lines.Add(("", False)) + End Sub + + Public Overrides Sub WriteCenteredLine(value As Object) + If Lines.Count = 0 Then Lines.Add(("", False)) + Dim currentLast = Lines(Lines.Count - 1).line + If currentLast.Length > 0 Then Throw New InvalidOperationException("Can only write centered line if cursor is at start of line.") + WriteString(value?.ToString, True) + WriteLine() + End Sub + + Public Overrides Function ReadLine() As String + ' Indicates the end of a test run, for programs which loop endlessly + If inputs.Count = 0 Then Throw New EndOfStreamException("End of inputs") + + Dim nextInput = inputs.Dequeue.Trim + WriteLine(nextInput) + Return nextInput + End Function +End Class diff --git a/03_Animal/vbnet/Animal.Tests/TestContainer.vb b/03_Animal/vbnet/Animal.Tests/TestContainer.vb new file mode 100644 index 00000000..3aed862a --- /dev/null +++ b/03_Animal/vbnet/Animal.Tests/TestContainer.vb @@ -0,0 +1,80 @@ +Imports Xunit +Imports Animal +Imports System.IO + +Public Class TestContainer + Private Shared Function ResponseVariantExpander(src As IEnumerable(Of String)) As TheoryData(Of String) + Dim theoryData = New TheoryData(Of String) + src. + SelectMany(Function(x) {x, x.Substring(0, 1)}). + SelectMany(Function(x) { + x, + x.ToUpperInvariant, + x.ToLowerInvariant, + x.ToTitleCase, + x.ToReverseCase + }). + Distinct. + ForEach(Sub(x) theoryData.Add(x)) + Return theoryData + End Function + Private Shared YesVariantsThepryData As TheoryData(Of String) = ResponseVariantExpander({"yes", "true", "1"}) + Private Shared Function YesVariants() As TheoryData(Of String) + Return YesVariantsThepryData + End Function + Private Shared NoVariantsThepryData As TheoryData(Of String) = ResponseVariantExpander({"no", "false", "0"}) + Private Shared Function NoVariants() As TheoryData(Of String) + Return NoVariantsThepryData + End Function + + ''' Test LIST variants + + + + + + Sub List(listResponse As String) + Dim console As New MockConsole({listResponse}) + Dim game As New Game(console) + Assert.Throws(Of EndOfStreamException)(Sub() game.BeginLoop()) + Assert.Equal( + { + "ANIMALS I ALREADY KNOW ARE:", + "FISH BIRD " + }, + console.Lines.Slice(-4, -2).Select(Function(x) x.line) + ) + End Sub + + '' Test YES variants + + + Sub YesVariant(yesVariant As String) + Dim console As New MockConsole({yesVariant}) + Dim game As New Game(console) + Assert.Throws(Of EndOfStreamException)(Sub() game.BeginLoop()) + Assert.Equal( + { + $"ARE YOU THINKING OF AN ANIMAL? {yesVariant}", + "DOES IT SWIM? " + }, + console.Lines.Slice(-2, 0).Select(Function(x) x.line) + ) + End Sub + + '' Test NO variants + + + Sub NoVariant(noVariant As String) + Dim console As New MockConsole({"y", noVariant}) + Dim game As New Game(console) + Assert.Throws(Of EndOfStreamException)(Sub() game.BeginLoop()) + Assert.Equal( + { + $"DOES IT SWIM? {noVariant}", + "IS IT A BIRD? " + }, + console.Lines.Slice(-2, 0).Select(Function(x) x.line) + ) + End Sub +End Class diff --git a/03_Animal/vbnet/Animal.Tests/UnitTest1.vb b/03_Animal/vbnet/Animal.Tests/UnitTest1.vb deleted file mode 100644 index fe32490e..00000000 --- a/03_Animal/vbnet/Animal.Tests/UnitTest1.vb +++ /dev/null @@ -1,12 +0,0 @@ -Imports System -Imports Xunit - -Namespace Animal.Tests - Public Class UnitTest1 - - Sub TestSub() - - End Sub - End Class -End Namespace - diff --git a/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb b/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb index 132f1968..f49394e0 100644 --- a/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb +++ b/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb @@ -14,6 +14,7 @@ End Sub Public Overrides Sub WriteCenteredLine(value As Object) + If Console.CursorLeft <> 0 Then Throw New InvalidOperationException("Can only write centered line if cursor is at start of line.") Dim toWrite = If(value?.ToString, "") Console.WriteLine($"{Space((Console.WindowWidth - toWrite.Length) \ 2)}{toWrite}") End Sub diff --git a/03_Animal/vbnet/Animal/Shared/Extensions.vb b/03_Animal/vbnet/Animal/Shared/Extensions.vb index 83d1914b..e10df441 100644 --- a/03_Animal/vbnet/Animal/Shared/Extensions.vb +++ b/03_Animal/vbnet/Animal/Shared/Extensions.vb @@ -1,6 +1,11 @@ Imports System.Runtime.CompilerServices Public Module Extensions + Public Sub ForEach(Of T)(src As IEnumerable(Of T), action As Action(Of T)) + For Each x In src + action(x) + Next + End Sub Public Sub ForEach(Of T)(src As IEnumerable(Of T), action As Action(Of T, Integer)) Dim index As Integer For Each x In src @@ -18,4 +23,28 @@ Public Module Extensions If Not s.EndsWith(toAppend, StringComparison.OrdinalIgnoreCase) Then s += toAppend Return s End Function + + Public Function ToTitleCase(s As String) As String + If s Is Nothing Then Return Nothing + Return Char.ToUpperInvariant(s(0)) + s.Substring(1).ToUpperInvariant + End Function + + ' https://stackoverflow.com/a/3681580/111794 + Public Function ToReverseCase(s As String) As String + If s Is Nothing Then Return Nothing + Return New String(s.Select(Function(c) If( + Not Char.IsLetter(c), + c, + If( + Char.IsUpper(c), Char.ToLowerInvariant(c), Char.ToUpperInvariant(c) + ) + )).ToArray) + End Function + + ' https://stackoverflow.com/a/58132204/111794 + Public Function Slice(Of T)(lst As IList(Of T), start As Integer, [end] As Integer) As T() + start = If(start >= 0, start, lst.Count + start) + [end] = If([end] > 0, [end], lst.Count + [end]) + Return lst.Skip(start).Take([end] - start).ToArray + End Function End Module From 0a4fe29ebe96b9743bb1a3bf00a9c387f511b8c3 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Fri, 21 Jan 2022 04:52:44 +0200 Subject: [PATCH 249/337] Update README and add comments --- 03_Animal/vbnet/Animal/Branch.vb | 1 + 03_Animal/vbnet/Animal/Game.vb | 30 ++++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/03_Animal/vbnet/Animal/Branch.vb b/03_Animal/vbnet/Animal/Branch.vb index 6734e39d..4af369bb 100644 --- a/03_Animal/vbnet/Animal/Branch.vb +++ b/03_Animal/vbnet/Animal/Branch.vb @@ -10,6 +10,7 @@ Public Property Yes As Branch Public Property No As Branch + ' Allows walking all the descendants recursively Public Iterator Function DescendantTexts() As IEnumerable(Of String) If Yes IsNot Nothing Then Yield Yes.Text diff --git a/03_Animal/vbnet/Animal/Game.vb b/03_Animal/vbnet/Animal/Game.vb index 3bc2b2f6..bca72005 100644 --- a/03_Animal/vbnet/Animal/Game.vb +++ b/03_Animal/vbnet/Animal/Game.vb @@ -1,6 +1,8 @@ Option Compare Text Public Class Game + ' This Dictionary holds the corresponding value for each of the variants of "YES" and "NO" we accept + ' Note that the Dictionary is case-insensitive, meaning it maps "YES", "yes" and even "yEs" to True Private Shared ReadOnly YesNoResponses As New Dictionary(Of String, Boolean)(StringComparer.InvariantCultureIgnoreCase) From { {"yes", True}, {"y", True}, @@ -15,6 +17,8 @@ Public Class Game } ReadOnly console As ConsoleAdapterBase + + ' The pre-initialized root branch ReadOnly root As New Branch With { .Text = "DOES IT SWIM?", .Yes = New Branch With {.Text = "FISH"}, @@ -41,6 +45,7 @@ Public Class Game Sub BeginLoop() + ' Print the program heading console.WriteCenteredLine("ANIMAL") console.WriteCenteredLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") console.Write( @@ -58,10 +63,16 @@ THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT. Dim response = console.ReadLine If response = "list" Then + ' List all the stored animals console.WriteLine( " ANIMALS I ALREADY KNOW ARE:") + + ' We're using a ForEach extension method instead of the regular For Each loop to provide the index alongside the text root.DescendantTexts.ForEach(Sub(text, index) + ' We want to move to the next line after every four animals + ' But for the first animal, where the index is 0, 0 Mod 4 will also return 0 + ' So we have to explicitly exclude the first animal If index > 0 AndAlso index Mod 4 = 0 Then console.WriteLine() console.Write($"{text.MaxLength(15),-15}") End Sub) @@ -76,10 +87,14 @@ ANIMALS I ALREADY KNOW ARE:") Dim currentBranch = root Do While Not currentBranch.IsEnd + ' Branches can either be questions, or end branches + ' We have to walk the questions, prompting each time for "yes" or "no" console.Write($"{currentBranch.Text} ") Do ynResponse = GetYesNo() Loop While ynResponse Is Nothing + + ' Depending on the answer, we'll follow either the branch at "Yes" or "No" currentBranch = If( ynResponse, currentBranch.Yes, @@ -87,31 +102,42 @@ ANIMALS I ALREADY KNOW ARE:") ) Loop - 'at end + ' Now we're at an end branch console.Write($"IS IT A {currentBranch.Text}? ") ynResponse = GetYesNo() - If ynResponse Then ' No difference between False or Nothing + If ynResponse Then ' Only if ynResponse = True will we go into this If Then console.WriteLine("WHY NOT TRY ANOTHER ANIMAL?") Continue Do End If + ' Get the new animal console.Write("THE ANIMAL YOU WERE THINKING OF WAS A ? ") Dim newAnimal = console.ReadLine + ' Get the question used to distinguish the new animal from the current end branch console.WriteLine( $"PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A {newAnimal} FROM A {currentBranch.Text}") Dim newQuestion = console.ReadLine + ' Get the answer to that question, for the new animal + ' for the old animal, the answer would be the opposite console.Write( $"FOR A {newAnimal} THE ANSWER WOULD BE ? ") Do ynResponse = GetYesNo() Loop While ynResponse Is Nothing + ' Create the new end branch for the new animal Dim newBranch = New Branch With {.Text = newAnimal} + + ' Copy over the current animal to another new end branch Dim currentBranchCopy = New Branch With {.Text = currentBranch.Text} + + ' Make the current branch into the distinguishing question currentBranch.Text = newQuestion + + ' Set the Yes and No branches of the current branch according to the answer If ynResponse Then currentBranch.Yes = newBranch currentBranch.No = currentBranchCopy From 961c76214540501aba45b4de9e171ffc7b9caa34 Mon Sep 17 00:00:00 2001 From: 0phios Date: Fri, 21 Jan 2022 14:19:16 -0400 Subject: [PATCH 250/337] Update AceyDucey.vb - reduce nested do/loop and if/else statements by utilizing subs and functions. --- 01_Acey_Ducey/vbnet/AceyDucey.vb | 242 +++++++++++++++++++++++++++++++ 01_Acey_Ducey/vbnet/Program.vb | 169 +-------------------- 2 files changed, 248 insertions(+), 163 deletions(-) create mode 100644 01_Acey_Ducey/vbnet/AceyDucey.vb diff --git a/01_Acey_Ducey/vbnet/AceyDucey.vb b/01_Acey_Ducey/vbnet/AceyDucey.vb new file mode 100644 index 00000000..8727e6b2 --- /dev/null +++ b/01_Acey_Ducey/vbnet/AceyDucey.vb @@ -0,0 +1,242 @@ +Public Class AceyDucey + ''' + ''' Create a single instance of the Random class to be used + ''' throughout the program. + ''' + Private ReadOnly Property Rnd As New Random() + + ''' + ''' Define a varaible to store the the player balance.
+ ''' Defaults to 0 + '''
+ ''' + ''' Since is a value type, and no value + ''' has been explicitly set, the default value of the type is used. + ''' + Private _balance As Integer + + Public Sub New() + DisplayIntroduction() + End Sub + + ''' + ''' Play multiple games of Acey Ducey until the player chooses to quit. + ''' + Public Sub Play() + Do + PlayGame() + Loop While TryAgain() 'Loop (play again) based on the Boolean value returned by TryAgain + + Console.WriteLine("O.K., HOPE YOU HAD FUN!") + End Sub + + ''' + ''' Play a game of Acey Ducey, which ends when the player balance reaches 0 + ''' + Private Sub PlayGame() + _balance = 100 'At the start of the game, set the player balance to 100 + + Console.WriteLine() + Console.WriteLine($"YOU NOW HAVE {_balance} DOLLARS.") + + Do + PlayTurn() + Loop While _balance > 0 'Continue playing while the user has a balance + + Console.WriteLine() + Console.WriteLine("SORRY, FRIEND, BUT YOU BLEW YOUR WAD.") + End Sub + + ''' + ''' Play one turn of Acey Ducey + ''' + ''' + ''' A turn consists of displaying to cards, making a wager + ''' and determining the result (win/lose) + ''' + Private Sub PlayTurn() + Console.WriteLine() + Console.WriteLine("HERE ARE YOUR NEXT TWO CARDS: ") + + Dim cards = GetOrderedCards() + + For Each card In cards + DisplayCard(card) + Next + + Dim wager As Integer = GetWager() + Dim finalCard As Integer = GetCard() + + If wager = 0 Then + Console.WriteLine("CHICKEN!!") + Return + End If + + DisplayCard(finalCard) + + Console.WriteLine() + + '''Check if the value of the final card is between the first and second cards. + ''' + '''The use of AndAlso is used to short-circuit the evaluation of the IF condition. + '''Short-circuiting means that both sides of the condition do not need to be + '''evaluated. In this case, if the left criteria returns FALSE, the right criteria + '''is ignored and the evaluation result is returned as FALSE. + ''' + '''This works because AndAlso requires both condition to return TRUE in order to be + '''evaluated as TRUE. If the first condition is FALSE we already know the evaluation result. + If finalCard >= cards.First() AndAlso finalCard <= cards.Last() Then + Console.WriteLine("YOU WIN!!!") + _balance += wager 'Condensed version of _balance = _balance + wager + Else + Console.WriteLine("SORRY, YOU LOSE.") + _balance -= wager 'Condensed version of _balance = _balance - wager + End If + End Sub + + ''' + ''' Get two cards in ascending order + ''' + ''' + ''' The original version generates two cards (A and B) + ''' If A is greater than or equal to B, both cards are regenerated. + '''

+ ''' This version generates the two cards, but only regenerates A + ''' if A is equal to B. The cards are then returned is ascending order, + ''' ensuring that A is less than B (maintaining the original end result) + '''
+ Private Function GetOrderedCards() As Integer() + '''When declaring fixed size arrays in VB.NET you declare the MAX INDEX of the array + '''and NOT the SIZE (number of elements) of the array. + '''As such, card(1) gives you and array with index 0 and index 1, which means + '''the array stores two elements and not one + Dim cards(1) As Integer + + cards(0) = GetCard() + cards(1) = GetCard() + + 'Perform this action as long as the first card is equal to the second card + While cards(0) = cards(1) + cards(0) = GetCard() + End While + + Array.Sort(cards) 'Sort the values in ascending order + + Return cards + End Function + + ''' + ''' Get a random number (card) ranked 2 to 14 + ''' + Private Function GetCard() As Integer + Return Rnd.Next(2, 15) + End Function + + ''' + ''' Display the face value of the card + ''' + Private Sub DisplayCard(card As Integer) + Dim output As String + + Select Case card + Case 2 To 10 + output = card.ToString() + Case 11 + output = "JACK" + Case 12 + output = "QUEEN" + Case 13 + output = "KING" + Case 14 + output = "ACE" + Case Else + Throw New ArgumentOutOfRangeException(NameOf(card), "Value must be between 2 and 14") + End Select + + Console.WriteLine(output) + End Sub + + ''' + ''' Prompt the user to make a bet + ''' + ''' + ''' The function will not return until a valid bet is made.
+ ''' is used to validate that the user input is a valid + '''
+ Private Function GetWager() As Integer + Dim wager As Integer + Do + Console.WriteLine() + Console.Write("WHAT IS YOUR BET? ") + + Dim input As String = Console.ReadLine() + + '''Determine if the user input is an Integer + '''If it is an Integer, store the value in the variable wager + If Not Integer.TryParse(input, wager) Then + Console.WriteLine("SORRY, I DID'T QUITE GET THAT.") + Continue Do 'restart the loop + End If + + 'Prevent the user from betting more than their current balance + If _balance < wager Then + Console.WriteLine("SORRY, MY FRIEND, BUT YOU BET TOO MUCH.") + Console.WriteLine($"YOU HAVE ONLY {_balance} DOLLARS TO BET.") + Continue Do 'restart the loop + End If + + 'Prevent the user from betting negative values + If wager < 0 Then + Console.WriteLine("FUNNY GUY! YOU CANNOT MAKE A NEGATIVE BET.") + Continue Do 'restart the loop + End If + + Exit Do 'If we get to this line, exit the loop as all above validations passed + Loop + + Return wager + End Function + + ''' + ''' Prompt the user to try again + ''' + ''' + ''' This function will not return until a valid reponse is given + ''' + Private Function TryAgain() As Boolean + Dim response As String + Do + Console.Write("TRY AGAIN (YES OR NO) ") + + response = Console.ReadLine() + + If response.Equals("YES", StringComparison.OrdinalIgnoreCase) Then Return True + If response.Equals("NO", StringComparison.OrdinalIgnoreCase) Then Return False + + Console.WriteLine("SORRY, I DID'T QUITE GET THAT.") + Loop + End Function + + ''' + ''' Display the opening title and instructions + ''' + ''' + ''' Refer to + ''' + ''' Interpolated Strings + ''' documentation for the use of $ and { } with strings + ''' + Private Sub DisplayIntroduction() + Console.WriteLine($"{Space((Console.WindowWidth \ 2) - 10)}ACEY DUCEY CARD GAME") + Console.WriteLine($"{Space((Console.WindowWidth \ 2) - 21)}CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + Console.WriteLine("") + Console.WriteLine("") + Console.WriteLine("ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER") + Console.WriteLine("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP") + Console.WriteLine("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING") + Console.WriteLine("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE") + Console.WriteLine("A VALUE BETWEEN THE FIRST TWO.") + Console.WriteLine("IF YOU DO NOT WANT TO BET, INPUT A 0") + Console.WriteLine("") + End Sub +End Class diff --git a/01_Acey_Ducey/vbnet/Program.vb b/01_Acey_Ducey/vbnet/Program.vb index bfa518ca..2f82fd60 100644 --- a/01_Acey_Ducey/vbnet/Program.vb +++ b/01_Acey_Ducey/vbnet/Program.vb @@ -6,173 +6,16 @@ Imports System ''' The structural changes primarily consist of replacing the many GOTOs with ''' Do/Loop constructs to force the continual execution of the program. ''' -''' Because modern Basic allows multi-line If/Then blocks, many GOTO jumps were -''' able to be eliminated and the logic was able to be moved to more relevant areas, -''' For example, the increment/decrement of the player's balance could be in the same -''' area as the notification of win/loss. +''' Some modern improvements were added, primarily the inclusion of a multiple +''' subroutines and functions, which eliminates repeated logic and reduces +''' then need for nested loops. ''' -''' Some modern improvements were added, primarily the inclusion of a function, which -''' eliminated a thrice-repeated block of logic to display the card value. The archaic -''' RND function is greatly simplified with the .NET Framework's Random class. +''' The archaic RND function is greatly simplified with the .NET Framework's Random class. ''' ''' Elementary comments are provided for non-programmers or novices. ''' Module Program - Sub Main(args As String()) - ' These are the variables that will hold values during the program's execution - Dim input As String - Dim rnd As New Random ' You can create a new instance of an object during declaration - Dim currentBalance As Integer = 100 ' You can set a initial value at declaration - Dim currentWager As Integer - Dim cardA, cardB, cardC As Integer ' You can specify multiple variables of the same type in one declaration statement - - ' Display the opening title and instructions - ' Use a preceding $ to insert calculated values within the string using {} - Console.WriteLine($"{Space((Console.WindowWidth \ 2) - 10)}ACEY DUCEY CARD GAME") - Console.WriteLine($"{Space((Console.WindowWidth \ 2) - 21)}CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - Console.WriteLine("") - Console.WriteLine("") - Console.WriteLine("ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER") - Console.WriteLine("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP") - Console.WriteLine("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING") - Console.WriteLine("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE") - Console.WriteLine("A VALUE BETWEEN THE FIRST TWO.") - Console.WriteLine("IF YOU DO NOT WANT TO BET, INPUT A 0") - - Do ' This loop continues as long as the player wants to keep playing - - Do ' This loop continues as long as the player has money to play - - Console.WriteLine("") - Console.WriteLine($"YOU NOW HAVE {currentBalance} DOLLARS.") - Console.WriteLine("") - - Console.WriteLine("HERE ARE YOUR NEXT TWO CARDS:") - - ' We need to ensure that card B is a higher value for our later comparison, - ' so we will loop until we have two cards that meet this criteria - Do - cardA = rnd.Next(2, 14) - cardB = rnd.Next(2, 14) - - Loop While cardA > cardB - - ' We use a function to display the text value of the numeric card value - ' because we do this 3 times and a function reduces repetition of code - Console.WriteLine(DisplayCard(cardA)) - Console.WriteLine(DisplayCard(cardB)) - - Do ' This loop continues until the player provides a valid wager value - Console.WriteLine("") - Console.WriteLine("WHAT IS YOUR BET") - - currentWager = 0 - input = Console.ReadLine - - ' Any input from the console is a string, but we require a number. - ' Test the input to make sure it is a numeric value. - If Integer.TryParse(input, currentWager) Then - ' Test to ensure the player has not wagered more than their balance - If currentWager > currentBalance Then - Console.WriteLine("SORRY, MY FRIEND, BUT YOU BET TOO MUCH.") - Console.WriteLine($"YOU HAVE ONLY {currentBalance} DOLLARS TO BET.") - - Else - ' The player has provided a numeric value that is less/equal to their balance, - ' exit the loop and continue play - Exit Do - - End If ' check player balance - - End If ' check numeric input - - Loop ' wager loop - - ' If the player is wagering, draw the third card, otherwise, mock them. - If currentWager > 0 Then - cardC = rnd.Next(2, 14) - - Console.WriteLine(DisplayCard(cardC)) - - ' The effort we made to have two cards in numeric order earlier makes this check easier, - ' otherwise we would have to have a second check in the opposite direction - If cardC < cardA OrElse cardC >= cardB Then - Console.WriteLine("SORRY, YOU LOSE") - currentBalance -= currentWager ' Shorthand code to decrement a number (currentBalance=currentBalance - currentWager) - - Else - Console.WriteLine("YOU WIN!!!") - currentBalance += currentWager ' Shorthand code to increment a number (currentBalance=currentBalance + currentWager) - - End If - - Else - Console.WriteLine("CHICKEN!!") - Console.WriteLine("") - - End If - - Loop While currentBalance > 0 ' loop as long as the player has money - - ' At this point, the player has no money (currentBalance=0). Inform them of such. - Console.WriteLine("") - Console.WriteLine("SORRY, FRIEND, BUT YOU BLEW YOUR WAD.") - Console.WriteLine("") - Console.WriteLine("") - - ' We will loop to ensure the player provides some answer. - Do - Console.WriteLine("TRY AGAIN (YES OR NO)") - Console.WriteLine("") - - input = Console.ReadLine - - Loop While String.IsNullOrWhiteSpace(input) - - ' We will assume that the player wants to play again only if they answer yes. - ' (yeah and ya are valid as well, because we only check the first letter) - If input.Substring(0, 1).Equals("y", StringComparison.CurrentCultureIgnoreCase) Then ' This allows upper and lower case to be entered. - currentBalance = 100 ' Reset the players balance before restarting - - Else - ' Exit the outer loop which will end the game. - Exit Do - - End If - - Loop ' The full game loop - - Console.WriteLine("O.K., HOPE YOU HAD FUN!") - + Sub Main() + Call New AceyDucey().Play() End Sub - - ' This function is called for each of the 3 cards used in the game. - ' The input and the output are both consistent, making it a good candidate for a function. - Private Function DisplayCard(value As Integer) As String - ' We check the value of the input and run a block of code for whichever - ' evaluation matches - Select Case value - Case 2 To 10 ' Case statements can be ranges of values, also multiple values (Case 2,3,4,5,6,7,8,9,10) - Return value.ToString - - Case 11 - Return "JACK" - - Case 12 - Return "QUEEN" - - Case 13 - Return "KING" - - Case 14 - Return "ACE" - - End Select - - ' Although we have full knowledge of the program and never plan to send an invalid - ' card value, it's important to provide a message for the next developer who won't - Throw New ArgumentOutOfRangeException("Card value must be between 2 and 14") - - End Function - End Module From 057a73cef3ee13b0841a0bdf3b008b93f59a3e0e Mon Sep 17 00:00:00 2001 From: Alex Gomez Date: Fri, 21 Jan 2022 17:40:20 -0600 Subject: [PATCH 251/337] Nice tabs --- 00_Utilities/yatol.pl | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/00_Utilities/yatol.pl b/00_Utilities/yatol.pl index 0f4ef111..89bfbaef 100755 --- a/00_Utilities/yatol.pl +++ b/00_Utilities/yatol.pl @@ -11,9 +11,14 @@ my @Langs= qw(PL JS VB PAS RB C# JAVA PY); my @Dirs= qw(perl javascript vbnet pascal ruby csharp java python); my %Sum; -print " "x 25 ."BAS\t"; +my $Row=25; +my $Tab=7; + +printf("%-$Row\s", "PATH"); +printf("%$Tab\s", "BAS"); + foreach my $Dir (@Langs) { - print "$Dir\t"; + printf("%$Tab\s", $Dir); } print "\n"; @@ -25,31 +30,31 @@ foreach my $Lin (@Ret) { my @Parts= split(/\//, $File); my $Base= $Parts[1]; - my $Tab= 25-length($Base); - print "$Base".(" "x$Tab)."$Num\t"; + printf("%-$Row\s", $Base); + printf("%$Tab\s", "$Num"); foreach my $Dir (@Dirs) { my $Path= "../$Base/$Dir/"; my $Ret= `ls $Path | wc -l`; - if ($Ret>1) { print "YES"; $Sum{$Dir}++; } - else { print " ";} - print "\t"; + if ($Ret>1) { printf("%$Tab\s", "YES"); $Sum{$Dir}++; } + else { printf("%$Tab\s", " ");} } - print "\n"; - + print "\n"; } -print "\t\tFILES:\t\t"; + +printf("%$Row\s", "FILES:"); +printf("%$Tab\s", " "); foreach my $Dir (@Dirs) { - print "$Sum{$Dir}\t"; + printf("%$Tab\s", "$Sum{$Dir}"); } print "\n"; - -print "\t\tADVANCE:\t"; +printf("%$Row\s", "ADVANCE:"); +printf("%$Tab\s", " "); foreach my $Dir (@Dirs) { my $Per= int($Sum{$Dir}/$Count*100)."%"; - print "$Per\t"; + printf("%$Tab\s", "$Per"); } print "\n"; From 41fdd87047eeeb87943c2bf4d64ccdc9e8a106bf Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Sat, 22 Jan 2022 22:27:27 +0200 Subject: [PATCH 252/337] Test for added animal; minor fixes --- .../Animal.Tests/EndOfInputsException.vb | 7 +++ 03_Animal/vbnet/Animal.Tests/MockConsole.vb | 11 ++--- 03_Animal/vbnet/Animal.Tests/TestContainer.vb | 44 +++++++++++++++++-- 03_Animal/vbnet/Animal/Game.vb | 36 ++++++++------- .../vbnet/Animal/Shared/ConsoleAdapter.vb | 11 ++--- .../vbnet/Animal/Shared/ConsoleAdapterBase.vb | 8 +++- 03_Animal/vbnet/README.md | 6 +++ 7 files changed, 88 insertions(+), 35 deletions(-) create mode 100644 03_Animal/vbnet/Animal.Tests/EndOfInputsException.vb diff --git a/03_Animal/vbnet/Animal.Tests/EndOfInputsException.vb b/03_Animal/vbnet/Animal.Tests/EndOfInputsException.vb new file mode 100644 index 00000000..b584e451 --- /dev/null +++ b/03_Animal/vbnet/Animal.Tests/EndOfInputsException.vb @@ -0,0 +1,7 @@ +''' +''' Indicates that there are no more inputs in the MockConsole. +''' We need this while testing, because otherwise the game loop will continue forever, waiting for a nonexistent input. +''' +Public Class EndOfInputsException + Inherits Exception +End Class diff --git a/03_Animal/vbnet/Animal.Tests/MockConsole.vb b/03_Animal/vbnet/Animal.Tests/MockConsole.vb index a78dc50f..7b21dfe2 100644 --- a/03_Animal/vbnet/Animal.Tests/MockConsole.vb +++ b/03_Animal/vbnet/Animal.Tests/MockConsole.vb @@ -37,26 +37,21 @@ Public Class MockConsole WriteString(value?.ToString) End Sub - Public Overrides Sub WriteLine(value As Object) - WriteString(value?.ToString) - WriteLine() - End Sub - Public Overrides Sub WriteLine() Lines.Add(("", False)) End Sub - Public Overrides Sub WriteCenteredLine(value As Object) + Public Overrides Sub WriteCenteredLines(value As Object) If Lines.Count = 0 Then Lines.Add(("", False)) Dim currentLast = Lines(Lines.Count - 1).line - If currentLast.Length > 0 Then Throw New InvalidOperationException("Can only write centered line if cursor is at start of line.") + If currentLast.Length > 0 Then Lines.Add(("", False)) WriteString(value?.ToString, True) WriteLine() End Sub Public Overrides Function ReadLine() As String ' Indicates the end of a test run, for programs which loop endlessly - If inputs.Count = 0 Then Throw New EndOfStreamException("End of inputs") + If inputs.Count = 0 Then Throw New EndOfInputsException Dim nextInput = inputs.Dequeue.Trim WriteLine(nextInput) diff --git a/03_Animal/vbnet/Animal.Tests/TestContainer.vb b/03_Animal/vbnet/Animal.Tests/TestContainer.vb index 3aed862a..f3d0c494 100644 --- a/03_Animal/vbnet/Animal.Tests/TestContainer.vb +++ b/03_Animal/vbnet/Animal.Tests/TestContainer.vb @@ -36,7 +36,7 @@ Public Class TestContainer Sub List(listResponse As String) Dim console As New MockConsole({listResponse}) Dim game As New Game(console) - Assert.Throws(Of EndOfStreamException)(Sub() game.BeginLoop()) + Assert.Throws(Of EndOfInputsException)(Sub() game.BeginLoop()) Assert.Equal( { "ANIMALS I ALREADY KNOW ARE:", @@ -52,7 +52,7 @@ Public Class TestContainer Sub YesVariant(yesVariant As String) Dim console As New MockConsole({yesVariant}) Dim game As New Game(console) - Assert.Throws(Of EndOfStreamException)(Sub() game.BeginLoop()) + Assert.Throws(Of EndOfInputsException)(Sub() game.BeginLoop()) Assert.Equal( { $"ARE YOU THINKING OF AN ANIMAL? {yesVariant}", @@ -68,7 +68,7 @@ Public Class TestContainer Sub NoVariant(noVariant As String) Dim console As New MockConsole({"y", noVariant}) Dim game As New Game(console) - Assert.Throws(Of EndOfStreamException)(Sub() game.BeginLoop()) + Assert.Throws(Of EndOfInputsException)(Sub() game.BeginLoop()) Assert.Equal( { $"DOES IT SWIM? {noVariant}", @@ -77,4 +77,42 @@ Public Class TestContainer console.Lines.Slice(-2, 0).Select(Function(x) x.line) ) End Sub + + ''' Test adding a new animal and using the new animal in the game + + Sub TestAddedAnimal() + Dim console As New MockConsole({ + "y", + "y", + "n", + "whale", + "is it a mammal?", + "y", + "y", + "y", + "y", + "y" + }) + Dim game As New Game(console) + Assert.Throws(Of EndOfInputsException)(Sub() game.BeginLoop()) + Assert.Equal( + { + "ARE YOU THINKING OF AN ANIMAL? y", + "DOES IT SWIM? y", + "IS IT A FISH? n", + "THE ANIMAL YOU WERE THINKING OF WAS A ? whale", + "PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A", + "WHALE FROM A FISH", + "is it a mammal?", + "FOR A WHALE THE ANSWER WOULD BE? y", + "ARE YOU THINKING OF AN ANIMAL? y", + "DOES IT SWIM? y", + "IS IT A MAMMAL? y", + "IS IT A WHALE? y", + "WHY NOT TRY ANOTHER ANIMAL?", + "ARE YOU THINKING OF AN ANIMAL? " + }, + console.Lines.Slice(9, 100).Select(Function(x) x.line) + ) + End Sub End Class diff --git a/03_Animal/vbnet/Animal/Game.vb b/03_Animal/vbnet/Animal/Game.vb index bca72005..2da0bbb1 100644 --- a/03_Animal/vbnet/Animal/Game.vb +++ b/03_Animal/vbnet/Animal/Game.vb @@ -46,8 +46,11 @@ Public Class Game Sub BeginLoop() ' Print the program heading - console.WriteCenteredLine("ANIMAL") - console.WriteCenteredLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + console.WriteCenteredLines( +"ANIMAL +CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + + ' Print the program description console.Write( " @@ -64,9 +67,10 @@ THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT. Dim response = console.ReadLine If response = "list" Then ' List all the stored animals - console.WriteLine( + console.Write( " -ANIMALS I ALREADY KNOW ARE:") +ANIMALS I ALREADY KNOW ARE: +") ' We're using a ForEach extension method instead of the regular For Each loop to provide the index alongside the text root.DescendantTexts.ForEach(Sub(text, index) @@ -76,8 +80,9 @@ ANIMALS I ALREADY KNOW ARE:") If index > 0 AndAlso index Mod 4 = 0 Then console.WriteLine() console.Write($"{text.MaxLength(15),-15}") End Sub) - console.WriteLine( + console.Write( " + ") Continue Do End If @@ -105,25 +110,26 @@ ANIMALS I ALREADY KNOW ARE:") ' Now we're at an end branch console.Write($"IS IT A {currentBranch.Text}? ") ynResponse = GetYesNo() - If ynResponse Then ' Only if ynResponse = True will we go into this If Then + If ynResponse Then ' Only if ynResponse = True will we go into this If Then block + ' The computer guessed the animal; we can go back to the beginning of the game console.WriteLine("WHY NOT TRY ANOTHER ANIMAL?") Continue Do End If - ' Get the new animal + ' Get the new animal from the user console.Write("THE ANIMAL YOU WERE THINKING OF WAS A ? ") - Dim newAnimal = console.ReadLine + Dim newAnimal = console.ReadLine.ToUpperInvariant ' Get the question used to distinguish the new animal from the current end branch - console.WriteLine( -$"PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A -{newAnimal} FROM A {currentBranch.Text}") - Dim newQuestion = console.ReadLine + console.Write( +$"PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A +{newAnimal} FROM A {currentBranch.Text} +") + Dim newQuestion = console.ReadLine.ToUpperInvariant ' Get the answer to that question, for the new animal - ' for the old animal, the answer would be the opposite - console.Write( -$"FOR A {newAnimal} THE ANSWER WOULD BE ? ") + ' for the old animal, the answer will be the opposite + console.Write($"FOR A {newAnimal} THE ANSWER WOULD BE? ") Do ynResponse = GetYesNo() Loop While ynResponse Is Nothing diff --git a/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb b/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb index f49394e0..c5c68f58 100644 --- a/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb +++ b/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb @@ -5,18 +5,15 @@ Console.Write(value) End Sub - Public Overrides Sub WriteLine(value As Object) - Console.WriteLine(value) - End Sub - Public Overrides Sub WriteLine() Console.WriteLine() End Sub - Public Overrides Sub WriteCenteredLine(value As Object) - If Console.CursorLeft <> 0 Then Throw New InvalidOperationException("Can only write centered line if cursor is at start of line.") + Public Overrides Sub WriteCenteredLines(value As Object) + If Console.CursorLeft <> 0 Then WriteLine() Dim toWrite = If(value?.ToString, "") - Console.WriteLine($"{Space((Console.WindowWidth - toWrite.Length) \ 2)}{toWrite}") + Write($"{Space((Console.WindowWidth - toWrite.Length) \ 2)}{toWrite}") + WriteLine() End Sub Public Overrides Function ReadLine() As String diff --git a/03_Animal/vbnet/Animal/Shared/ConsoleAdapterBase.vb b/03_Animal/vbnet/Animal/Shared/ConsoleAdapterBase.vb index 4c9166bf..b08a59ce 100644 --- a/03_Animal/vbnet/Animal/Shared/ConsoleAdapterBase.vb +++ b/03_Animal/vbnet/Animal/Shared/ConsoleAdapterBase.vb @@ -1,9 +1,13 @@ Public MustInherit Class ConsoleAdapterBase Public MustOverride Sub Write(value As Object) - Public MustOverride Sub WriteLine(value As Object) Public MustOverride Sub WriteLine() - Public MustOverride Sub WriteCenteredLine(value As Object) + Public MustOverride Sub WriteCenteredLines(value As Object) ''' Implementations should always return a String without leading or trailing whitespace, never Nothng Public MustOverride Function ReadLine() As String + + Public Sub WriteLine(value As Object) + Write(value) + WriteLine() + End Sub End Class diff --git a/03_Animal/vbnet/README.md b/03_Animal/vbnet/README.md index 98b702c7..9ac8afe5 100644 --- a/03_Animal/vbnet/README.md +++ b/03_Animal/vbnet/README.md @@ -1,3 +1,9 @@ Original BASIC source [downloaded from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Visual Basic .NET](https://en.wikipedia.org/wiki/Visual_Basic_.NET) + +This takes some inspiration from the [C# port of Animal](https://github.com/zspitz/basic-computer-games/tree/main/03_Animal/csharp). + +The `Game` class takes a console abstraction (`ConsoleAdapterBase`), which could also be used for different UIs, such as WinForms or a web page. +This solution also has an xUnit tests project. +Responses can be entered in any capitalization, but animals and the distinguishing question will be converted to uppercase. From 4f032310ad898540202e4fc368a0f353fdf2ddb7 Mon Sep 17 00:00:00 2001 From: Zev Spitz Date: Sun, 23 Jan 2022 00:26:12 +0200 Subject: [PATCH 253/337] Fix WriteCenteredLines --- 03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb b/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb index c5c68f58..b5b98d2f 100644 --- a/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb +++ b/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb @@ -12,8 +12,10 @@ Public Overrides Sub WriteCenteredLines(value As Object) If Console.CursorLeft <> 0 Then WriteLine() Dim toWrite = If(value?.ToString, "") - Write($"{Space((Console.WindowWidth - toWrite.Length) \ 2)}{toWrite}") - WriteLine() + For Each line In toWrite.Split(Environment.NewLine) + Write($"{Space((Console.WindowWidth - line.Length) \ 2)}{line}") + WriteLine() + Next End Sub Public Overrides Function ReadLine() As String From 2198824182d4faee2a58f5a342ef69335220cfb8 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Mon, 24 Jan 2022 00:28:45 +1100 Subject: [PATCH 254/337] Missed two kotlin classes - 01 kotlin/aceyducey.kt - 85 kotlin/Synonym.kt Move repository declaration and plugins in into main build.gradle.kts. All subproject build.gradle files are now much smaller, and identical. --- buildJvm/README.md | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/buildJvm/README.md b/buildJvm/README.md index e2b9da0b..4ecba004 100644 --- a/buildJvm/README.md +++ b/buildJvm/README.md @@ -10,7 +10,7 @@ Build all the games: ./gradlew -q clean assemble installDist distributeBin distributeLib ``` -Then, run a game +Then, run a game: ### Mac or linux: ```shell @@ -56,21 +56,17 @@ local clone to point to your new forked project. ## Adding a new game These are build scripts for all JVM games contributed so far. -New games can be added by: -- Creating a `build_NUMBER_NAME_[java/kotlin]` directory -- Adding a `build.gradle` file to that directory. -All `build.gradle` files under `build_NUMBER_*` should be nearly identical, unless -there is some special requirement. -- Adding a `gradle.properties` file to that directory, defining the source +New games can be added: +- Create a new `build_NUMBER_NAME_[java/kotlin]` directory +- Add a `build.gradle` file to that directory. +All `build.gradle` files under `build_NUMBER_*` are identical. +- Add a `gradle.properties` file to that directory, defining the source directory for the java or kotlin file, and the class that contains the `main` method. +- Add an entry in `settings.gradle` -The `build.gradle` file will normally be identical to this: +The `build.gradle` file **should** be identical to all the other `build.gradle` files +in all the other subprojects: ```groovy - plugins { - id 'application' - // id 'org.jetbrains.kotlin.jvm' // UNCOMMENT for kotlin projects - } - sourceSets { main { java { @@ -78,19 +74,21 @@ The `build.gradle` file will normally be identical to this: } } } - - repositories { - mavenCentral() - } - application { mainClass = gameMain } ``` -And the `gradle.properties` file should look like this: +The `gradle.properties` file should look like this: gameSource=91_Train/java/src gameMain=Train where `gameSource` is the root of the source code directory, and `gameMain` is the main class. + +The `settings.gradle` must be maintained as a list of all subprojects. Add your new +project to the list. + +```groovy +include ":build_91_Train_java" +``` From e6e42dde64af3d9f114ba76c69210800c3db71d4 Mon Sep 17 00:00:00 2001 From: Alex Gomez Date: Mon, 24 Jan 2022 18:19:36 -0600 Subject: [PATCH 255/337] Initial commit --- 00_Utilities/bas2perl.pl | 329 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100755 00_Utilities/bas2perl.pl diff --git a/00_Utilities/bas2perl.pl b/00_Utilities/bas2perl.pl new file mode 100755 index 00000000..2df1b5dc --- /dev/null +++ b/00_Utilities/bas2perl.pl @@ -0,0 +1,329 @@ +#!/usr/bin/perl +use strict; + + +my $Mode= lc($ARGV[0]); #trace #convert +my $File= $ARGV[1]; +my $LN= "Line"; + +my %Vars; +my @Data; +my %Code; +open(FH, $File); +while (my $Line = ) { + chomp $Line; + my $Space= index($Line, " "); + my $Key= substr($Line, 0, $Space); + my $Code= substr($Line, $Space+1); + $Code{$Key}=$Code; + } +close(FH); + + +foreach my $Lin (sort {$a<=>$b} keys %Code) { + if ($Mode eq "trace") { print "==> $Lin $Code{$Lin}\n"; } + my $Ret= &PROCLINE($Code{$Lin}); + if ($Mode eq "trace") { print " $Ret\n"; } + $Code{$Lin}= $Ret; + } + + +if ($Mode eq "convert") { + $Code{'0.1'}= "#!/usr/bin/perl"; + $Code{'0.2'}= "#use strict;"; + $Code{'0.3'}= "# Automatic converted by bas2perl.pl"; + $Code{'0.4'}= ""; + foreach my $Lin (sort {$a<=>$b} keys %Code) { + print "$Code{$Lin}\n"; + } + } + + if (@Data) { &DATAIL(); } + print "\n\n\n"; + + +exit; + + + +#print @Lines; + +sub PROCLINE { + my ($Line)= @_; + #my @Sente= split(/:/, $Line); + #my @Sente= split(/\:(?=([^"]*"[^"]*")*[^"]*$)/g, $Line); + my @Sente= split(/:(?=(?:[^"]*"[^"]*")*[^"]*$)/g, $Line); + + my $Perl; + foreach my $Sen (@Sente) { + #if ($Sen eq "") { next; } # Somehow the regex gives empty items between. + my $Flag=0; + $Sen= &TRIM($Sen); + if ($Sen>0) { $Sen= "GOTO $Sen"; } #The birth of spaguetti code! + if ($Sen=~ /^DATA\b/) { $Sen= &DATA($Sen); $Flag=1; } + if ($Sen=~ /^DIM\b/) { $Sen= &DIM($Sen); $Flag=1; } + if ($Sen=~ /^END\b/) { $Sen= &ENDD($Sen); $Flag=1; } + if ($Sen=~ /^FOR\b/) { $Sen= &FOR($Sen); $Flag=1; } + if ($Sen=~ /^GOTO\b/) { $Sen= &GOTO($Sen); $Flag=1; } + if ($Sen=~ /^GOSUB\b/) { $Sen= &GOSUB($Sen); $Flag=1; } + if ($Sen=~ /^IF\b/) { $Sen= &IF($Sen); $Flag=1; } + if ($Sen=~ /^INPUT\b/) { $Sen= &INPUT($Sen); $Flag=1; } + if ($Sen=~ /^NEXT\b/) { $Sen= &NEXT($Sen); $Flag=1; } + if ($Sen=~ /^ON\b/ && $Sen=~ / GOTO /) { $Sen= &ONGOTO($Sen); $Flag=1; } + if ($Sen=~ /^PRINT\b/) { $Sen= &PRINT($Sen); $Flag=1; } + if ($Sen=~ /^READ\b/) { $Sen= &READ($Sen); $Flag=1; } + if ($Sen=~ /^REM\b/) { $Sen= &REM($Sen); $Flag=1; } + if ($Sen=~ /^RETURN\b/) { $Sen= &RETURN($Sen); $Flag=1; } + if ($Sen=~ /^STOP\b/) { $Sen= &ENDD($Sen); $Flag=1; } + if ($Flag==0) { $Sen= &FORMULA($Sen); } + $Sen.=";"; + $Sen=~ s/\{;$/\{/g; + $Sen=~ s/\};$/\}/g; + $Perl.= "$Sen "; + } + $Perl= &TRIM($Perl); + return $Perl; + } + + + +#################### +# BASIC STATEMENTS # +#################### + +sub DATA { + my ($Str)= @_; + $Str=~ s/DATA //; + push @Data, $Str; + return "# TO DATA SEGMENT"; + } + +sub DIM { + my ($Str)= @_; + $Str=~ s/DIM //; + my @Parts= split(/\,(?![^\(]*\))/, $Str); + my $Out; + foreach my $Par (@Parts) { + $Par=~ s/\$//; + $Par=~ s/\(.*\)//; + $Out.= "my \@$Par; "; + $Vars{$Par}= "array"; + } + chop $Out; + chop $Out; + return $Out; + } + + +sub ENDD { + return "exit"; + } + + +sub FOR { + my ($Str)= @_; + $Str=~ s/= /=/g; + my @Parts= split(" ", $Str); + $Parts[1]= &FORMULA($Parts[1]); + my $Var=substr($Parts[1],0,index($Parts[1],"=")); + $Parts[3]= "$Var<=".&FORMULA($Parts[3]); + if ($Parts[5]<0) { $Parts[3]=~ s//; } + $Parts[5]= $Parts[5] eq "" ? "$Var++" : "$Var+=".&FORMULA($Parts[5]); + $Str= "for ($Parts[1]; $Parts[3]; $Parts[5]) {"; + return $Str; + } + + +sub GOTO { + my ($Str)= @_; + my @Parts= split(" ", $Str); + my $Label= "$LN$Parts[1]"; + $Str= lc($Parts[0])." $Label"; + $Code{($Parts[1]-.2)}=""; + $Code{($Parts[1]-.1)}="$Label:"; + return $Str; + } + + +sub GOSUB { + my ($Str)= @_; + my @Parts= split(" ", $Str); + my $Label= "$LN$Parts[1]"; + $Str= "\&$Label()"; + $Code{($Parts[1]-.2)}=""; + $Code{($Parts[1]-.1)}="sub $Label {"; + return $Str; + } + + +sub IF { + my ($Str)= @_; + $Str=~ s/^IF //g; + my @Parts= split(" THEN ", $Str); + $Parts[0]= &FORMULA($Parts[0], 1); + $Parts[1]= &PROCLINE($Parts[1]); + my $Str= "if ($Parts[0]) { $Parts[1] }"; + return $Str; + } + + +sub INPUT { + my ($Str)= @_; + $Str=~ s/INPUT //; + $Str=~ s/(".*")//g; + my $Ques; + if ($1) { + $Ques= $1; + $Ques=~ s/"//g; + } + + $Str=~ s/\$//g; + $Str=~ s/;//g; + $Str=~ s/\(/\[/g; + $Str=~ s/\)/\]/g; + my $Inp; + if ($Str=~ /,/) { + $Str= "\$$Str"; + $Str=~ s/,/,\$/g; + $Inp= "; ($Str)= split(/,/, \$Inp)"; + $Str= "Inp"; + } + $Str= "print \"$Ques? \"; chomp(\$$Str = uc())"; + return $Str.$Inp; + } + + +sub NEXT { + return "}"; + } + + +sub ONGOTO { + # Base 1, if not match it will be skipped. + my ($Str)= @_; + my @Parts= split(" ", $Str); + my $Var= $Parts[1]; + my @Lines= split(",", $Parts[3]); + my $Count=0; + my $Text; + foreach my $Lin (@Lines) { + $Count++; + my $This= "\telsif (\$$Var==$Count) "; + if ($Count==1) { $This= "if (\$$Var==1) "; } + + my $Goto= &GOTO("GOTO $Lin"); + $This.="{ $Goto; }\n"; + $Text.= $This; + } + return $Text; + } + + +sub PRINT { + my ($Str)= @_; + if ($Str eq "PRINT") { return 'print "\n"' }; + $Str=~ s/^PRINT //; + + my $Enter= 1; + if ($Str=~ /;$/) { $Enter= 0; } + + my $Out; + #my @Parts= split(/;/, $Str); + my @Parts= split(/;(?=(?;[^"]*"[^"]*")*[^"]*$)/g, $Str); + + foreach my $Par (@Parts) { + if ($Par=~ / TAB\((.*?)\);/) { + my $Num= &FORMULA($1); + $Par=~ s/ TAB\(.*\);/' 'x$Num . /; + } + if ($Par=~ /^[A-Z]/) { + $Par= &FIXVAR($Par); + } + $Out.= $Par.". "; + } + chop $Out; + chop $Out; + #$Str=~ s/"$/\\n"/; + #$Str=~ s/;$//; + #$Str=~ s/;/\./g; + #$Str=~ s/"$/\\n"/g; + #$Str=~ s/\.$//g; + if ($Enter) { $Out.= qq|. "\\n"|; } + return "print ".$Out; + } + + +sub READ { + my ($Str)= @_; + $Str=~ s/READ //; + $Str.="= "; + return $Str; + } + + +sub REM { + my ($Str)= @_; + return "#".$Str; + } + + +sub RETURN { + return "return; }"; + } + + +########### +# HELPERS # +########### + +sub TRIM { + my ($Str)= @_; + #$Str=~ s/\s+/ /g; + $Str=~ s/^\s+//; + $Str=~ s/\s+$//; + return $Str; + } + + +sub DATAIL { + print "\n\n\n"; + print "__DATA__\n"; + foreach my $Dat (@Data) { + $Dat=~ s/"//g; + $Dat=~ s/,/\n/g; + print "$Dat\n"; + } + } + + +sub FORMULA { + my ($Str, $Cond)= @_; + $Str=~ s/\$//g; + $Str=~ s/ABS\(/abs\(/; + $Str=~ s/COS\(/cos\(/; + $Str=~ s/LEN\(/length\(/; + $Str=~ s/INT\(/int\(/; + $Str=~ s/MID\$?\(/substr\(/; + $Str=~ s/RND\(/rand\(/; + $Str=~ s/SIN\(/sin\(/; + $Str=~ s/(\b[A-Z][0-9]?\b)/\$$&/g; + if ($Cond==1) { + $Str=~ s/<>/ ne /g; + $Str=~ s/=/ eq /g; + } + return $Str; + } + + +sub FIXVAR { + my ($Str)= @_; + $Str=~ s/\$//g; + $Str=~ s/(\w+)/\$$1/g; + $Str=~ s/\(/\[/g; + $Str=~ s/\)/\]/g; + $Str=~ s/,/\]\[/g; + return $Str; + } + + + From 6738ef25e1bbdf4d4edd49da138e025b67368208 Mon Sep 17 00:00:00 2001 From: Alex Gomez Date: Wed, 26 Jan 2022 18:44:56 -0600 Subject: [PATCH 256/337] Automatic converted with bas2perl.pl --- 69_Pizza/perl/pizza.pl | 113 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100755 69_Pizza/perl/pizza.pl diff --git a/69_Pizza/perl/pizza.pl b/69_Pizza/perl/pizza.pl new file mode 100755 index 00000000..7147ad49 --- /dev/null +++ b/69_Pizza/perl/pizza.pl @@ -0,0 +1,113 @@ +#!/usr/bin/perl +#use strict; +# Automatic converted by bas2perl.pl + +print ' 'x33 . "PIZZA". "\n"; +print ' 'x15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY". "\n"; +print "\n"; print "\n"; print "\n"; +my @S; my @M; +print "PIZZA DELIVERY GAME". "\n"; print "\n"; +print "WHAT IS YOUR FIRST NAME? "; chomp($N = uc()); print "\n"; +print "HI, ". $N. ". IN THIS GAME YOU ARE TO TAKE ORDERS". "\n"; +print "FOR PIZZAS. THEN YOU ARE TO TELL A DELIVERY BOY". "\n"; +print "WHERE TO DELIVER THE ORDERED PIZZAS.". "\n"; print "\n"; print "\n"; +for ($I=1; $I<=16; $I++) { +$S[$I]= ; chomp($S[$I]);; +} +for ($I=1; $I<=4; $I++) { +$M[$I]= ; chomp($M[$I]);; +} +# TO DATA SEGMENT; +# TO DATA SEGMENT; +print "MAP OF THE CITY OF HYATTSVILLE". "\n"; print "\n"; +print " -----1-----2-----3-----4-----". "\n"; +$K=4; +for ($I=1; $I<=4; $I++) { +print "-". "\n"; print "-". "\n"; print "-". "\n"; print "-". "\n"; +print $M[$K]; +$S1=16-4*$I+1; +print " ". $S[$S1]. " ". $S[$S1+1]. " ". $S[$S1+2]. " "; +print $S[$S1+3]. " ". $M[$K]. "\n"; +$K=$K-1; +} +print "-". "\n"; print "-". "\n"; print "-". "\n"; print "-". "\n"; +print " -----1-----2-----3-----4-----". "\n"; print "\n"; +print "THE OUTPUT IS A MAP OF THE HOMES WHERE". "\n"; +print "YOU ARE TO SEND PIZZAS.". "\n"; print "\n"; +print "YOUR JOB IS TO GIVE A TRUCK DRIVER". "\n"; +print "THE LOCATION OR COORDINATES OF THE". "\n"; +print "HOME ORDERING THE PIZZA.". "\n"; print "\n"; + +Line520: +print "DO YOU NEED MORE DIRECTIONS? "; chomp($A = uc()); +if ($A eq "YES") { goto Line590; } +if ($A eq "NO") { goto Line750; } +print "'YES' OR 'NO' PLEASE, NOW THEN,". "\n"; goto Line520; + +Line590: +print "\n"; print "SOMEBODY WILL ASK FOR A PIZZA TO BE". "\n"; +print "DELIVERED. THEN A DELIVERY BOY WILL". "\n"; +print "ASK YOU FOR THE LOCATION.". "\n"; print " EXAMPLE:". "\n"; +print "THIS IS J. PLEASE SEND A PIZZA.". "\n"; +print "DRIVER TO ". $N. ". WHERE DOES J LIVE?". "\n"; +print "YOUR ANSWER WOULD BE 2,3". "\n"; print "\n"; +print "UNDERSTAND? "; chomp($A = uc()); +if ($A eq "YES") { goto Line690; } +print "THIS JOB IS DEFINITELY TOO DIFFICULT FOR YOU. THANKS ANYWAY". "\n"; +goto Line999; + +Line690: +print "GOOD. YOU ARE NOW READY TO START TAKING ORDERS.". "\n"; print "\n"; +print "GOOD LUCK!!". "\n"; print "\n"; + +Line750: +for ($I=1; $I<=5; $I++) { +$S=int(rand(1)*16+1); print "\n"; +print "HELLO ". $N. "'S PIZZA. THIS IS ". $S[$S]. "."; +print " PLEASE SEND A PIZZA.". "\n"; + +Line780: +print " DRIVER TO ". $N. ": WHERE DOES ". $S[$S]. " LIVE"; +print "? "; chomp($Inp_ = uc()); ($A[1],$A[2])= split(/,/, $Inp_); +$T=$A[1]+($A[2]-1)*4; +if ($T eq $S) { goto Line920; } +print "THIS IS ". $S[$T]. ". I DID NOT ORDER A PIZZA.". "\n"; +print "I LIVE AT ". $A[1]. ",". $A[2]. "\n"; +goto Line780; + +Line920: +print "HELLO ". $N. ". THIS IS ". $S[$S]. ", THANKS FOR THE PIZZA.". "\n"; +} +print "\n"; print "DO YOU WANT TO DELIVER MORE PIZZAS? "; chomp($A = uc()); +if ($A eq "YES") { goto Line750; } +print "\n"; print "O.K. ". $N. ", SEE YOU LATER!". "\n"; print "\n"; + +Line999: +exit; + + + +__DATA__ +A +B +C +D +E +F +G +H +I +J +K +L +M +N +O +P +1 +2 +3 +4 + + + From 24a9655b24af86c6d70d9b4db016cc59c33820b6 Mon Sep 17 00:00:00 2001 From: Alex Gomez Date: Wed, 26 Jan 2022 18:48:28 -0600 Subject: [PATCH 257/337] Simple tool to convert BASIC file to Perl code. --- 00_Utilities/bas2perl.pl | 330 +-------------------------------------- 1 file changed, 1 insertion(+), 329 deletions(-) mode change 100755 => 120000 00_Utilities/bas2perl.pl diff --git a/00_Utilities/bas2perl.pl b/00_Utilities/bas2perl.pl deleted file mode 100755 index 2df1b5dc..00000000 --- a/00_Utilities/bas2perl.pl +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/perl -use strict; - - -my $Mode= lc($ARGV[0]); #trace #convert -my $File= $ARGV[1]; -my $LN= "Line"; - -my %Vars; -my @Data; -my %Code; -open(FH, $File); -while (my $Line = ) { - chomp $Line; - my $Space= index($Line, " "); - my $Key= substr($Line, 0, $Space); - my $Code= substr($Line, $Space+1); - $Code{$Key}=$Code; - } -close(FH); - - -foreach my $Lin (sort {$a<=>$b} keys %Code) { - if ($Mode eq "trace") { print "==> $Lin $Code{$Lin}\n"; } - my $Ret= &PROCLINE($Code{$Lin}); - if ($Mode eq "trace") { print " $Ret\n"; } - $Code{$Lin}= $Ret; - } - - -if ($Mode eq "convert") { - $Code{'0.1'}= "#!/usr/bin/perl"; - $Code{'0.2'}= "#use strict;"; - $Code{'0.3'}= "# Automatic converted by bas2perl.pl"; - $Code{'0.4'}= ""; - foreach my $Lin (sort {$a<=>$b} keys %Code) { - print "$Code{$Lin}\n"; - } - } - - if (@Data) { &DATAIL(); } - print "\n\n\n"; - - -exit; - - - -#print @Lines; - -sub PROCLINE { - my ($Line)= @_; - #my @Sente= split(/:/, $Line); - #my @Sente= split(/\:(?=([^"]*"[^"]*")*[^"]*$)/g, $Line); - my @Sente= split(/:(?=(?:[^"]*"[^"]*")*[^"]*$)/g, $Line); - - my $Perl; - foreach my $Sen (@Sente) { - #if ($Sen eq "") { next; } # Somehow the regex gives empty items between. - my $Flag=0; - $Sen= &TRIM($Sen); - if ($Sen>0) { $Sen= "GOTO $Sen"; } #The birth of spaguetti code! - if ($Sen=~ /^DATA\b/) { $Sen= &DATA($Sen); $Flag=1; } - if ($Sen=~ /^DIM\b/) { $Sen= &DIM($Sen); $Flag=1; } - if ($Sen=~ /^END\b/) { $Sen= &ENDD($Sen); $Flag=1; } - if ($Sen=~ /^FOR\b/) { $Sen= &FOR($Sen); $Flag=1; } - if ($Sen=~ /^GOTO\b/) { $Sen= &GOTO($Sen); $Flag=1; } - if ($Sen=~ /^GOSUB\b/) { $Sen= &GOSUB($Sen); $Flag=1; } - if ($Sen=~ /^IF\b/) { $Sen= &IF($Sen); $Flag=1; } - if ($Sen=~ /^INPUT\b/) { $Sen= &INPUT($Sen); $Flag=1; } - if ($Sen=~ /^NEXT\b/) { $Sen= &NEXT($Sen); $Flag=1; } - if ($Sen=~ /^ON\b/ && $Sen=~ / GOTO /) { $Sen= &ONGOTO($Sen); $Flag=1; } - if ($Sen=~ /^PRINT\b/) { $Sen= &PRINT($Sen); $Flag=1; } - if ($Sen=~ /^READ\b/) { $Sen= &READ($Sen); $Flag=1; } - if ($Sen=~ /^REM\b/) { $Sen= &REM($Sen); $Flag=1; } - if ($Sen=~ /^RETURN\b/) { $Sen= &RETURN($Sen); $Flag=1; } - if ($Sen=~ /^STOP\b/) { $Sen= &ENDD($Sen); $Flag=1; } - if ($Flag==0) { $Sen= &FORMULA($Sen); } - $Sen.=";"; - $Sen=~ s/\{;$/\{/g; - $Sen=~ s/\};$/\}/g; - $Perl.= "$Sen "; - } - $Perl= &TRIM($Perl); - return $Perl; - } - - - -#################### -# BASIC STATEMENTS # -#################### - -sub DATA { - my ($Str)= @_; - $Str=~ s/DATA //; - push @Data, $Str; - return "# TO DATA SEGMENT"; - } - -sub DIM { - my ($Str)= @_; - $Str=~ s/DIM //; - my @Parts= split(/\,(?![^\(]*\))/, $Str); - my $Out; - foreach my $Par (@Parts) { - $Par=~ s/\$//; - $Par=~ s/\(.*\)//; - $Out.= "my \@$Par; "; - $Vars{$Par}= "array"; - } - chop $Out; - chop $Out; - return $Out; - } - - -sub ENDD { - return "exit"; - } - - -sub FOR { - my ($Str)= @_; - $Str=~ s/= /=/g; - my @Parts= split(" ", $Str); - $Parts[1]= &FORMULA($Parts[1]); - my $Var=substr($Parts[1],0,index($Parts[1],"=")); - $Parts[3]= "$Var<=".&FORMULA($Parts[3]); - if ($Parts[5]<0) { $Parts[3]=~ s//; } - $Parts[5]= $Parts[5] eq "" ? "$Var++" : "$Var+=".&FORMULA($Parts[5]); - $Str= "for ($Parts[1]; $Parts[3]; $Parts[5]) {"; - return $Str; - } - - -sub GOTO { - my ($Str)= @_; - my @Parts= split(" ", $Str); - my $Label= "$LN$Parts[1]"; - $Str= lc($Parts[0])." $Label"; - $Code{($Parts[1]-.2)}=""; - $Code{($Parts[1]-.1)}="$Label:"; - return $Str; - } - - -sub GOSUB { - my ($Str)= @_; - my @Parts= split(" ", $Str); - my $Label= "$LN$Parts[1]"; - $Str= "\&$Label()"; - $Code{($Parts[1]-.2)}=""; - $Code{($Parts[1]-.1)}="sub $Label {"; - return $Str; - } - - -sub IF { - my ($Str)= @_; - $Str=~ s/^IF //g; - my @Parts= split(" THEN ", $Str); - $Parts[0]= &FORMULA($Parts[0], 1); - $Parts[1]= &PROCLINE($Parts[1]); - my $Str= "if ($Parts[0]) { $Parts[1] }"; - return $Str; - } - - -sub INPUT { - my ($Str)= @_; - $Str=~ s/INPUT //; - $Str=~ s/(".*")//g; - my $Ques; - if ($1) { - $Ques= $1; - $Ques=~ s/"//g; - } - - $Str=~ s/\$//g; - $Str=~ s/;//g; - $Str=~ s/\(/\[/g; - $Str=~ s/\)/\]/g; - my $Inp; - if ($Str=~ /,/) { - $Str= "\$$Str"; - $Str=~ s/,/,\$/g; - $Inp= "; ($Str)= split(/,/, \$Inp)"; - $Str= "Inp"; - } - $Str= "print \"$Ques? \"; chomp(\$$Str = uc())"; - return $Str.$Inp; - } - - -sub NEXT { - return "}"; - } - - -sub ONGOTO { - # Base 1, if not match it will be skipped. - my ($Str)= @_; - my @Parts= split(" ", $Str); - my $Var= $Parts[1]; - my @Lines= split(",", $Parts[3]); - my $Count=0; - my $Text; - foreach my $Lin (@Lines) { - $Count++; - my $This= "\telsif (\$$Var==$Count) "; - if ($Count==1) { $This= "if (\$$Var==1) "; } - - my $Goto= &GOTO("GOTO $Lin"); - $This.="{ $Goto; }\n"; - $Text.= $This; - } - return $Text; - } - - -sub PRINT { - my ($Str)= @_; - if ($Str eq "PRINT") { return 'print "\n"' }; - $Str=~ s/^PRINT //; - - my $Enter= 1; - if ($Str=~ /;$/) { $Enter= 0; } - - my $Out; - #my @Parts= split(/;/, $Str); - my @Parts= split(/;(?=(?;[^"]*"[^"]*")*[^"]*$)/g, $Str); - - foreach my $Par (@Parts) { - if ($Par=~ / TAB\((.*?)\);/) { - my $Num= &FORMULA($1); - $Par=~ s/ TAB\(.*\);/' 'x$Num . /; - } - if ($Par=~ /^[A-Z]/) { - $Par= &FIXVAR($Par); - } - $Out.= $Par.". "; - } - chop $Out; - chop $Out; - #$Str=~ s/"$/\\n"/; - #$Str=~ s/;$//; - #$Str=~ s/;/\./g; - #$Str=~ s/"$/\\n"/g; - #$Str=~ s/\.$//g; - if ($Enter) { $Out.= qq|. "\\n"|; } - return "print ".$Out; - } - - -sub READ { - my ($Str)= @_; - $Str=~ s/READ //; - $Str.="= "; - return $Str; - } - - -sub REM { - my ($Str)= @_; - return "#".$Str; - } - - -sub RETURN { - return "return; }"; - } - - -########### -# HELPERS # -########### - -sub TRIM { - my ($Str)= @_; - #$Str=~ s/\s+/ /g; - $Str=~ s/^\s+//; - $Str=~ s/\s+$//; - return $Str; - } - - -sub DATAIL { - print "\n\n\n"; - print "__DATA__\n"; - foreach my $Dat (@Data) { - $Dat=~ s/"//g; - $Dat=~ s/,/\n/g; - print "$Dat\n"; - } - } - - -sub FORMULA { - my ($Str, $Cond)= @_; - $Str=~ s/\$//g; - $Str=~ s/ABS\(/abs\(/; - $Str=~ s/COS\(/cos\(/; - $Str=~ s/LEN\(/length\(/; - $Str=~ s/INT\(/int\(/; - $Str=~ s/MID\$?\(/substr\(/; - $Str=~ s/RND\(/rand\(/; - $Str=~ s/SIN\(/sin\(/; - $Str=~ s/(\b[A-Z][0-9]?\b)/\$$&/g; - if ($Cond==1) { - $Str=~ s/<>/ ne /g; - $Str=~ s/=/ eq /g; - } - return $Str; - } - - -sub FIXVAR { - my ($Str)= @_; - $Str=~ s/\$//g; - $Str=~ s/(\w+)/\$$1/g; - $Str=~ s/\(/\[/g; - $Str=~ s/\)/\]/g; - $Str=~ s/,/\]\[/g; - return $Str; - } - - - diff --git a/00_Utilities/bas2perl.pl b/00_Utilities/bas2perl.pl new file mode 120000 index 00000000..5f21f3db --- /dev/null +++ b/00_Utilities/bas2perl.pl @@ -0,0 +1 @@ +/home/nezumi/bin/bas2perl.pl \ No newline at end of file From 069c00bc47bd59256b9e7220356f629f0609db8c Mon Sep 17 00:00:00 2001 From: Alex Gomez Date: Thu, 27 Jan 2022 12:25:38 -0600 Subject: [PATCH 258/337] The real file. --- 00_Utilities/bas2perl.pl | 381 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 380 insertions(+), 1 deletion(-) mode change 120000 => 100755 00_Utilities/bas2perl.pl diff --git a/00_Utilities/bas2perl.pl b/00_Utilities/bas2perl.pl deleted file mode 120000 index 5f21f3db..00000000 --- a/00_Utilities/bas2perl.pl +++ /dev/null @@ -1 +0,0 @@ -/home/nezumi/bin/bas2perl.pl \ No newline at end of file diff --git a/00_Utilities/bas2perl.pl b/00_Utilities/bas2perl.pl new file mode 100755 index 00000000..791d1b34 --- /dev/null +++ b/00_Utilities/bas2perl.pl @@ -0,0 +1,380 @@ +#!/usr/bin/perl +use strict; + + +my $Mode= lc($ARGV[0]); #trace #convert +my $File= $ARGV[1]; +my $LN= "Line"; +my $Pedantic= 0; +my $Indent= 0; + +my %Vars; # num | str | anm | ast +my @Data; +my %Code; +open(FH, $File); +while (my $Line = ) { + chomp $Line; + my $Space= index($Line, " "); + my $Key= substr($Line, 0, $Space); + my $Code= substr($Line, $Space+1); + $Code{$Key}=$Code; + } +close(FH); + + +foreach my $Lin (sort {$a<=>$b} keys %Code) { + if ($Mode eq "trace") { print "==> $Lin $Code{$Lin}\n"; } + my $Ret= &PROCLINE($Code{$Lin}); + if ($Mode eq "trace") { print " $Ret\n"; } + $Code{$Lin}= $Ret; + } + + +if ($Mode eq "convert") { + $Code{'0.1'}= "#!/usr/bin/perl"; + $Code{'0.2'}= "#use strict;"; + $Code{'0.3'}= "# Automatic converted by bas2perl.pl"; + $Code{'0.4'}= ""; + foreach my $Lin (sort {$a<=>$b} keys %Code) { + print "$Code{$Lin}\n"; + } + } + + if (@Data) { &DATAIL(); } + print "\n\n\n"; + + +exit; + + +sub PROCLINE { + my ($Line)= @_; + my @Sente= &SMARPLIT($Line, ":", "\""); + + my $Perl; + foreach my $Sen (@Sente) { + my $Flag=0; + if ($Pedantic==0) { + #REM: Resolves some ugly syntaxis... + $Sen=~ s/\bPRINT"/PRINT "/g; # PRINT"Hello" + $Sen=~ s/"([A-Z])\$/"; $1\$/g; # PRINT "Hello "N$ + } + $Sen= &TRIM($Sen); + if ($Sen>0) { $Sen= "GOTO $Sen"; } + if ($Sen=~ /^DATA\b/) { $Sen= &DATA($Sen); $Flag=1; } + if ($Sen=~ /^DIM\b/) { $Sen= &DIM($Sen); $Flag=1; } + if ($Sen=~ /^END\b/) { $Sen= &ENDD($Sen); $Flag=1; } + if ($Sen=~ /^FOR\b/) { $Sen= &FOR($Sen); $Flag=1; } + if ($Sen=~ /^GOTO\b/) { $Sen= &GOTO($Sen); $Flag=1; } + if ($Sen=~ /^GOSUB\b/) { $Sen= &GOSUB($Sen); $Flag=1; } + if ($Sen=~ /^IF\b/) { $Sen= &IF($Sen); $Flag=1; } + if ($Sen=~ /^INPUT\b/) { $Sen= &INPUT($Sen); $Flag=1; } + if ($Sen=~ /^NEXT\b/) { $Sen= &NEXT($Sen); $Flag=1; } + if ($Sen=~ /^ON\b/ && $Sen=~ / GOTO /) { $Sen= &ONGOTO($Sen); $Flag=1; } + if ($Sen=~ /^PRINT\b/) { $Sen= &PRINT($Sen); $Flag=1; } + if ($Sen=~ /^READ\b/) { $Sen= &READ($Sen); $Flag=1; } + if ($Sen=~ /^REM\b/) { $Sen= &REM($Sen); $Flag=1; } + if ($Sen=~ /^RETURN\b/) { $Sen= &RETURN($Sen); $Flag=1; } + if ($Sen=~ /^STOP\b/) { $Sen= &ENDD($Sen); $Flag=1; } + if ($Flag==0) { $Sen= &FORMULA($Sen); } # LET + $Sen.=";"; + $Sen=~ s/\{;$/\{/g; + $Sen=~ s/\};$/\}/g; + $Perl.= "$Sen "; + } + $Perl= &TRIM($Perl); + my $Adj= 0; + if ($Perl=~ /^for\b/) { $Adj--; } + if ($Perl eq "}") { $Adj++; } + $Perl= "\t"x ($Indent+$Adj) . $Perl; + return $Perl; + } + + + +#################### +# BASIC STATEMENTS # +#################### + +sub DATA { + my ($Str)= @_; + $Str=~ s/DATA //; + push @Data, $Str; + return "# TO DATA SEGMENT"; + } + + +sub DIM { + my ($Str)= @_; + $Str=~ s/DIM //; + my @Parts= split(/\,(?![^\(]*\))/, $Str); + my $Out; + foreach my $Par (@Parts) { + my $Type= $Par=~ /\$/ ? "ast" : "anm"; + $Par=~ s/\$//g; + $Par=~ s/\(.*\)//; + $Vars{$Par}= "anm"; + $Out.= "my \@$Par; "; + } + chop $Out; + chop $Out; + return $Out; + } + + +sub ENDD { + return "exit"; + } + + +sub FOR { + my ($Str)= @_; + $Str=~ s/= /=/g; + my @Parts= split(" ", $Str); + $Parts[1]= &FORMULA($Parts[1]); + my $Var=substr($Parts[1],0,index($Parts[1],"=")); + $Parts[3]= "$Var<=".&FORMULA($Parts[3]); + if ($Parts[5]<0) { $Parts[3]=~ s//; } + $Parts[5]= $Parts[5] eq "" ? "$Var++" : "$Var+=".&FORMULA($Parts[5]); + $Str= "for ($Parts[1]; $Parts[3]; $Parts[5]) {"; + $Indent++; + return $Str; + } + + +sub GOTO { + # The birth of spaguetti code! + # Dijkstra would not like this... + my ($Str)= @_; + my @Parts= split(" ", $Str); + my $Label= "$LN$Parts[1]"; + $Str= lc($Parts[0])." $Label"; + $Code{($Parts[1]-.2)}=""; + $Code{($Parts[1]-.1)}="$Label:"; + return $Str; + } + + +sub GOSUB { + my ($Str)= @_; + my @Parts= split(" ", $Str); + my $Label= "$LN$Parts[1]"; + $Str= "\&$Label()"; + $Code{($Parts[1]-.2)}=""; + $Code{($Parts[1]-.1)}="sub $Label {"; + return $Str; + } + + +sub IF { + my ($Str)= @_; + $Str=~ s/^IF //g; + my @Parts= split(" THEN ", $Str); + $Parts[0]= &FORMULA($Parts[0], 1); + $Parts[1]= &PROCLINE($Parts[1]); + my $Str= "if ($Parts[0]) { $Parts[1] }"; + return $Str; + } + + +sub INPUT { + my ($Str)= @_; + $Str=~ s/INPUT //; + $Str=~ s/"(.*)"//g; + + my $Txt= qq|print "$1\? "; |; + + my @Parts= split(/,/, $Str); + my @Multi; + foreach my $Par (@Parts) { + my $Type= "num"; + if ($Par=~ /\$/) { + $Type= "str"; + $Par=~ s/\$//g; + } + if ($Par=~ /\(/) { + if ($Type eq "num") { $Type= "anm"; } + if ($Type eq "str") { $Type= "ast"; } + $Par=~ s/\(/\[/g; + $Par=~ s/\)/\]/g; + } + $Par=~ s/\;//g; + push @Multi, "\$$Par"; + + my $Name= $Par; + $Name=~ s/\[.*\]//; + $Vars{$Name}= $Type; + } + + $Str= join(",", @Multi); + + my $Spl= ""; + if (scalar @Parts>1) { + $Spl= "; ($Str)= split(/,/, \$Inp_)"; + $Str= "\$Inp_"; + } + my $Inp= qq|chomp($Str = uc())$Spl|; + + + if ($Str=~ /,/) { + $Str= "\$$Str"; + $Str=~ s/,/,\$/g; + $Str= "Inp"; + } + return $Txt.$Inp; + } + + +sub NEXT { + $Indent--; + return "}"; + } + + +sub ONGOTO { + # Base 1, if not match it will be skipped. + my ($Str)= @_; + my @Parts= split(" ", $Str); + my $Var= $Parts[1]; + my @Lines= split(",", $Parts[3]); + my $Count=0; + my $Text; + foreach my $Lin (@Lines) { + $Count++; + my $This= "\telsif (\$$Var==$Count) "; + if ($Count==1) { $This= "if (\$$Var==1) "; } + + my $Goto= &GOTO("GOTO $Lin"); + $This.="{ $Goto; }\n"; + $Text.= $This; + } + return $Text; + } + + +sub PRINT { + my ($Str)= @_; + if ($Str eq "PRINT") { return 'print "\n"' }; + $Str=~ s/^PRINT //; + + my $Enter= 1; + if ($Str=~ /;$/) { $Enter= 0; } + + my @Parts= &SMARPLIT($Str, ";", "\""); + + my @Out; + foreach my $Par (@Parts) { + if ($Par=~ /"/) { + push @Out, $Par; + next; + } + + if ($Par=~ /TAB\((.*?)\)/) { + push @Out, "' 'x".&FORMULA($1)." "; + next; + } + + $Par= &FORMULA($Par); + push @Out, $Par; + } + + my $Out= join(". ", @Out); + if ($Enter) { $Out.= qq|. "\\n"|; } + return "print ".$Out; + } + + +sub READ { + my ($Str)= @_; + $Str=~ s/READ //; + $Str= &FORMULA($Str); + $Str.="= ; chomp($Str)"; + return $Str; + } + + +sub REM { + my ($Str)= @_; + return "#".$Str; + } + + +sub RETURN { + return "return; }"; + } + + + +########### +# HELPERS # +########### + +sub TRIM { + my ($Str)= @_; + #$Str=~ s/\s+/ /g; + $Str=~ s/^\s+//; + $Str=~ s/\s+$//; + return $Str; + } + + +sub DATAIL { + print "\n\n\n"; + print "__DATA__\n"; + foreach my $Dat (@Data) { + $Dat=~ s/"//g; + $Dat=~ s/,/\n/g; + print "$Dat\n"; + } + } + + +sub FORMULA { + my ($Str, $Cond)= @_; + $Str=~ s/\$//g; + $Str=~ s/ABS\(/abs\(/g; + $Str=~ s/COS\(/cos\(/g; + $Str=~ s/LEN\(/length\(/g; + $Str=~ s/INT\(/int\(/g; + $Str=~ s/MID\$?\(/substr\(/g; + $Str=~ s/RND\(/rand\(/g; + $Str=~ s/SIN\(/sin\(/g; + $Str=~ s/SQR\(/sqr\(/g; + $Str=~ s/(\b[A-Z][0-9]?\b)/\$$&/g; + + #==> Check for arrays... + foreach my $Key (keys %Vars) { + if ($Vars{$Key}!~ /^a/) { next; } + $Str=~ s/\$$Key\((.*?)\)/\$$Key\[$1\]/g; + } + + if ($Cond==1) { + $Str=~ s/<>/ ne /g; + $Str=~ s/=/ eq /g; + } + return $Str; + } + + +sub SMARPLIT { + my ($Str, $Sep, $Nin)= @_; + my @Parts; + my $Text= ""; + my $Flag= 0; + my $Prev; + foreach my $Char (split('', $Str)) { + if ($Char eq $Nin) { $Flag= !$Flag; } + if ($Char eq $Sep && $Flag==0) { + push @Parts, &TRIM($Text); + $Text= ""; + next; + } + $Prev= $Char; + $Text.= $Char; + } + if ($Text) { push @Parts, &TRIM($Text); } + return @Parts; + } + + + From 5750aca580380505be0039e42cdebc6116010e77 Mon Sep 17 00:00:00 2001 From: Alex Gomez Date: Thu, 27 Jan 2022 17:38:32 -0600 Subject: [PATCH 259/337] Most probable a bad OCR mismatch --- 59_Lunar_LEM_Rocket/lunar.bas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/59_Lunar_LEM_Rocket/lunar.bas b/59_Lunar_LEM_Rocket/lunar.bas index db07b0a5..87cb430f 100644 --- a/59_Lunar_LEM_Rocket/lunar.bas +++ b/59_Lunar_LEM_Rocket/lunar.bas @@ -1,5 +1,5 @@ 10 PRINT TAB(33);"LUNAR" -20 PRINT TAB(l5);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" +20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" 25 PRINT:PRINT:PRINT 30 PRINT "THIS IS A COMPUTER SIMULATION OF AN APOLLO LUNAR" 40 PRINT "LANDING CAPSULE.": PRINT: PRINT From be5552f677db3eab52249759c085e31bd3cd5911 Mon Sep 17 00:00:00 2001 From: Stefan Waldmann Date: Fri, 28 Jan 2022 07:57:44 +0100 Subject: [PATCH 260/337] Add command line arg to stop after each generation --- 55_Life/java/src/java/Life.java | 50 ++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/55_Life/java/src/java/Life.java b/55_Life/java/src/java/Life.java index e3c8ade3..55f55ee8 100644 --- a/55_Life/java/src/java/Life.java +++ b/55_Life/java/src/java/Life.java @@ -2,15 +2,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Scanner; -/** - * Represents a state change for a single cell within the matrix. - * - * @param y the y coordinate (row) of the cell - * @param x the x coordinate (column) of the cell - * @param newState the new state of the cell (either DEAD or ALIVE) - */ -record Transition(int y, int x, byte newState) { } - /** * The Game of Life class.
*
@@ -26,28 +17,47 @@ public class Life { private static final byte DEAD = 0; private static final byte ALIVE = 1; + private static final String NEWLINE = "\n"; private final Scanner consoleReader = new Scanner(System.in); private final byte[][] matrix = new byte[21][67]; private int generation = 0; private int population = 0; + boolean stopAfterGen = false; boolean invalid = false; - private void start() throws Exception { + + public Life(String[] args) { + parse(args); + } + + private void parse(String[] args) { + for (String arg : args) { + if ("-s".equals(arg)) { + stopAfterGen = true; + break; + } + } + } + + private void start() { printGameHeader(); readPattern(); while (true) { printGeneration(); advanceToNextGeneration(); - consoleReader.nextLine(); -// Thread.sleep(1000); + if (stopAfterGen) { + consoleReader.nextLine(); + } } } private void advanceToNextGeneration() { - // store all transitions of cells in a list, i.e. if a dead cell becomes alive, or a living cell dies + // store all cell transitions in a list, i.e. if a dead cell becomes alive, or a living cell dies List transitions = new ArrayList<>(); + // there's still room for optimization: instead of iterating over all cells in the matrix, + // we could consider only the section containing the pattern(s), as in the BASIC version for (int y = 0; y < matrix.length; y++) { for (int x = 0; x < matrix[y].length; x++) { int neighbours = countNeighbours(y, x); @@ -110,7 +120,6 @@ public class Life { private void fillMatrix(List lines, int maxLineLength) { float xMin = 33 - maxLineLength / 2f; float yMin = 11 - lines.size() / 2f; - System.out.println("lines=" + lines.size() + " columns=" + maxLineLength + " yMin=" + yMin + " xMin=" + xMin); for (int y = 0; y < lines.size(); y++) { String line = lines.get(y); for (int x = 1; x <= line.length(); x++) { @@ -129,7 +138,7 @@ public class Life { private void printGameHeader() { printIndented(34, "LIFE"); printIndented(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); - System.out.println("\n\n\n"); + System.out.println(NEWLINE.repeat(3)); } private void printIndented(int spaces, String str) { @@ -158,7 +167,16 @@ public class Life { * @throws Exception if something goes wrong. */ public static void main(String[] args) throws Exception { - new Life().start(); + new Life(args).start(); } } + +/** + * Represents a state change for a single cell within the matrix. + * + * @param y the y coordinate (row) of the cell + * @param x the x coordinate (column) of the cell + * @param newState the new state of the cell (either DEAD or ALIVE) + */ +record Transition(int y, int x, byte newState) { } From 69a62c5c4b6c42fe54285909364570219a477891 Mon Sep 17 00:00:00 2001 From: Stefan Waldmann Date: Fri, 28 Jan 2022 08:01:21 +0100 Subject: [PATCH 261/337] Prompt for ENTER to continue --- 55_Life/java/src/java/Life.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/55_Life/java/src/java/Life.java b/55_Life/java/src/java/Life.java index 55f55ee8..0e202240 100644 --- a/55_Life/java/src/java/Life.java +++ b/55_Life/java/src/java/Life.java @@ -48,6 +48,7 @@ public class Life { printGeneration(); advanceToNextGeneration(); if (stopAfterGen) { + System.out.print("PRESS ENTER TO CONTINUE"); consoleReader.nextLine(); } } @@ -163,7 +164,8 @@ public class Life { /** * Main method that starts the program. * - * @param args the command line arguments. + * @param args the command line arguments: + *
-s: Stop after each generation (press enter to continue)
* @throws Exception if something goes wrong. */ public static void main(String[] args) throws Exception { From 8ba115287ef6939a87333f0f37fb54eb03325bc5 Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Fri, 28 Jan 2022 23:10:25 +0000 Subject: [PATCH 262/337] Improve and modernise javascript for 16 Bug Introduce some named variables Case insensitive inputs Fix delay so that it happens correctly and ensure the page scrolls when it gets too long. --- 16_Bug/javascript/bug.js | 321 +++++++++++++++++++-------------------- 1 file changed, 160 insertions(+), 161 deletions(-) diff --git a/16_Bug/javascript/bug.js b/16_Bug/javascript/bug.js index 2d99d90c..e222e03d 100644 --- a/16_Bug/javascript/bug.js +++ b/16_Bug/javascript/bug.js @@ -10,38 +10,43 @@ function print(str) function input() { - var input_element; - var input_str; - return new Promise(function (resolve) { - input_element = document.createElement("INPUT"); + const input_element = document.createElement("INPUT"); print("? "); input_element.setAttribute("type", "text"); input_element.setAttribute("length", "50"); document.getElementById("output").appendChild(input_element); input_element.focus(); - input_str = undefined; - input_element.addEventListener("keydown", function (event) { - if (event.keyCode == 13) { - input_str = input_element.value; - document.getElementById("output").removeChild(input_element); - print(input_str); - print("\n"); - resolve(input_str); - } - }); + input_element.addEventListener("keydown", + function (event) { + if (event.keyCode === 13) { + const input_str = input_element.value; + document.getElementById("output").removeChild(input_element); + print(input_str); + print("\n"); + resolve(input_str); + } + }); }); } function tab(space) { - var str = ""; + let str = ""; while (space-- > 0) str += " "; return str; } +function waitNSeconds(n) { + return new Promise(resolve => setTimeout(resolve, n*1000)); +} + +function scrollToBottom() { + window.scrollTo(0, document.body.scrollHeight); +} + function draw_head() { print(" HHHHHHH\n"); @@ -52,6 +57,58 @@ function draw_head() print(" HHHHHHH\n"); } +function drawFeelers(feelerCount, character) { + for (let z = 1; z <= 4; z++) { + print(tab(10)); + for (let x = 1; x <= feelerCount; x++) { + print(character + " "); + } + print("\n"); + } +} + +function drawNeck() { + for (let z = 1; z <= 2; z++) + print(" N N\n"); +} + +function drawBody(computerTailCount) { + print(" BBBBBBBBBBBB\n"); + for (let z = 1; z <= 2; z++) + print(" B B\n"); + if (computerTailCount === 1) + print("TTTTTB B\n"); + print(" BBBBBBBBBBBB\n"); +} + +function drawFeet(computerFeetCount) { + for (let z = 1; z <= 2; z++) { + print(tab(5)); + for (let x = 1; x <= computerFeetCount; x++) + print(" L"); + print("\n"); + } +} + +function drawBug(playerFeelerCount, playerHeadCount, playerNeckCount, playerBodyCount, playerTailCount, playerFeetCount, feelerCharacter) { + if (playerFeelerCount !== 0) { + drawFeelers(playerFeelerCount, feelerCharacter); + } + if (playerHeadCount !== 0) + draw_head(); + if (playerNeckCount !== 0) { + drawNeck(); + } + if (playerBodyCount !== 0) { + drawBody(playerTailCount) + } + if (playerFeetCount !== 0) { + drawFeet(playerFeetCount); + } + for (let z = 1; z <= 4; z++) + print("\n"); +} + // Main program async function main() { @@ -60,25 +117,26 @@ async function main() print("\n"); print("\n"); print("\n"); - a = 0; - b = 0; - h = 0; - l = 0; - n = 0; - p = 0; - q = 0; - r = 0; - s = 0; - t = 0; - u = 0; - v = 0; - y = 0; + let playerFeelerCount = 0; + let playerHeadCount = 0; + let playerNeckCount = 0; + let playerBodyCount = 0; + let playerFeetCount = 0; + let playerTailCount = 0; + + let computerFeelerCount = 0; + let computerHeadCount = 0; + let computerNeckCount = 0; + let computerBodyCount = 0; + let computerTailCount = 0; + let computerFeetCount = 0; + print("THE GAME BUG\n"); print("I HOPE YOU ENJOY THIS GAME.\n"); print("\n"); print("DO YOU WANT INSTRUCTIONS"); - str = await input(); - if (str != "NO") { + const instructionsRequired = await input(); + if (instructionsRequired.toUpperCase() !== "NO") { print("THE OBJECT OF BUG IS TO FINISH YOUR BUG BEFORE I FINISH\n"); print("MINE. EACH NUMBER STANDS FOR A PART OF THE BUG BODY.\n"); print("I WILL ROLL THE DIE FOR YOU, TELL YOU WHAT I ROLLED FOR YOU\n"); @@ -98,30 +156,32 @@ async function main() print("\n"); print("\n"); } - while (y == 0) { - z = Math.floor(6 * Math.random() + 1); - c = 1; - print("YOU ROLLED A " + z + "\n"); - switch (z) { + + let gameInProgress = true; + while (gameInProgress) { + let dieRoll = Math.floor(6 * Math.random() + 1); + let partFound = false; + print("YOU ROLLED A " + dieRoll + "\n"); + switch (dieRoll) { case 1: print("1=BODY\n"); - if (b == 0) { + if (playerBodyCount === 0) { print("YOU NOW HAVE A BODY.\n"); - b = 1; - c = 0; + playerBodyCount = 1; + partFound = true; } else { print("YOU DO NOT NEED A BODY.\n"); } break; case 2: print("2=NECK\n"); - if (n == 0) { - if (b == 0) { + if (playerNeckCount === 0) { + if (playerBodyCount === 0) { print("YOU DO NOT HAVE A BODY.\n"); } else { print("YOU NOW HAVE A NECK.\n"); - n = 1; - c = 0; + playerNeckCount = 1; + partFound = true; } } else { print("YOU DO NOT NEED A NECK.\n"); @@ -129,219 +189,158 @@ async function main() break; case 3: print("3=HEAD\n"); - if (n == 0) { + if (playerNeckCount === 0) { print("YOU DO NOT HAVE A NECK.\n"); - } else if (h == 0) { + } else if (playerHeadCount === 0) { print("YOU NEEDED A HEAD.\n"); - h = 1; - c = 0; + playerHeadCount = 1; + partFound = true; } else { print("YOU HAVE A HEAD.\n"); } break; case 4: print("4=FEELERS\n"); - if (h == 0) { + if (playerHeadCount === 0) { print("YOU DO NOT HAVE A HEAD.\n"); - } else if (a == 2) { + } else if (playerFeelerCount === 2) { print("YOU HAVE TWO FEELERS ALREADY.\n"); } else { print("I NOW GIVE YOU A FEELER.\n"); - a++; - c = 0; + playerFeelerCount ++; + partFound = true; } break; case 5: print("5=TAIL\n"); - if (b == 0) { + if (playerBodyCount === 0) { print("YOU DO NOT HAVE A BODY.\n"); - } else if (t == 1) { + } else if (playerTailCount === 1) { print("YOU ALREADY HAVE A TAIL.\n"); } else { print("I NOW GIVE YOU A TAIL.\n"); - t++; - c = 0; + playerTailCount++; + partFound = true; } break; case 6: print("6=LEG\n"); - if (l == 6) { + if (playerFeetCount === 6) { print("YOU HAVE 6 FEET ALREADY.\n"); - } else if (b == 0) { + } else if (playerBodyCount === 0) { print("YOU DO NOT HAVE A BODY.\n"); } else { - l++; - c = 0; - print("YOU NOW HAVE " + l + " LEGS.\n"); + playerFeetCount++; + partFound = true; + print("YOU NOW HAVE " + playerFeetCount + " LEGS.\n"); } break; } - x = Math.floor(6 * Math.random() + 1) ; + dieRoll = Math.floor(6 * Math.random() + 1) ; print("\n"); - date = new Date().valueOf; - while (date - new Date().valueOf < 1000000) ; - print("I ROLLED A " + x + "\n"); - switch (x) { + scrollToBottom(); + await waitNSeconds(1); + + print("I ROLLED A " + dieRoll + "\n"); + switch (dieRoll) { case 1: print("1=BODY\n"); - if (p == 1) { + if (computerBodyCount === 1) { print("I DO NOT NEED A BODY.\n"); } else { print("I NOW HAVE A BODY.\n"); - c = 0; - p = 1; + partFound = true; + computerBodyCount = 1; } break; case 2: print("2=NECK\n"); - if (q == 1) { + if (computerNeckCount === 1) { print("I DO NOT NEED A NECK.\n"); - } else if (p == 0) { + } else if (computerBodyCount === 0) { print("I DO NOT HAVE A BODY.\n"); } else { print("I NOW HAVE A NECK.\n"); - q = 1; - c = 0; + computerNeckCount = 1; + partFound = true; } break; case 3: print("3=HEAD\n"); - if (q == 0) { + if (computerNeckCount === 0) { print("I DO NOT HAVE A NECK.\n"); - } else if (r == 1) { + } else if (computerHeadCount === 1) { print("I DO NOT NEED A HEAD.\n"); } else { print("I NEEDED A HEAD.\n"); - r = 1; - c = 0; + computerHeadCount = 1; + partFound = true; } break; case 4: print("4=FEELERS\n"); - if (r == 0) { + if (computerHeadCount === 0) { print("I DO NOT HAVE A HEAD.\n"); - } else if (s == 2) { + } else if (computerFeelerCount === 2) { print("I HAVE 2 FEELERS ALREADY.\n"); } else { print("I GET A FEELER.\n"); - s++; - c = 0; + computerFeelerCount++; + partFound = true; } break; case 5: print("5=TAIL\n"); - if (p == 0) { + if (computerBodyCount === 0) { print("I DO NOT HAVE A BODY.\n"); - } else if (u == 1) { + } else if (computerTailCount === 1) { print("I DO NOT NEED A TAIL.\n"); } else { print("I NOW HAVE A TAIL.\n"); - u = 1; - c = 0; + computerTailCount = 1; + partFound = true; } break; case 6: print("6=LEGS\n"); - if (v == 6) { + if (computerFeetCount === 6) { print("I HAVE 6 FEET.\n"); - } else if (p == 0) { + } else if (computerBodyCount === 0) { print("I DO NOT HAVE A BODY.\n"); } else { - v++; - c = 0; - print("I NOW HAVE " + v + " LEGS.\n"); + computerFeetCount++; + partFound = true; + print("I NOW HAVE " + computerFeetCount + " LEGS.\n"); } break; } - if (a == 2 && t == 1 && l == 6) { + if (playerFeelerCount === 2 && playerTailCount === 1 && playerFeetCount === 6) { print("YOUR BUG IS FINISHED.\n"); - y++; + gameInProgress = false; } - if (s == 2 && p == 1 && v == 6) { + if (computerFeelerCount === 2 && computerBodyCount === 1 && computerFeetCount === 6) { print("MY BUG IS FINISHED.\n"); - y += 2; + gameInProgress = false; } - if (c == 1) + if (!partFound) continue; print("DO YOU WANT THE PICTURES"); - str = await input(); - if (str == "NO") + const showPictures = await input(); + if (showPictures.toUpperCase() === "NO") continue; print("*****YOUR BUG*****\n"); print("\n"); print("\n"); - if (a != 0) { - for (z = 1; z <= 4; z++) { - print(tab(10)); - for (x = 1; x <= a; x++) { - print("A "); - } - print("\n"); - } - } - if (h != 0) - draw_head(); - if (n != 0) { - for (z = 1; z <= 2; z++) - print(" N N\n"); - } - if (b != 0) { - print(" BBBBBBBBBBBB\n"); - for (z = 1; z <= 2; z++) - print(" B B\n"); - if (t == 1) - print("TTTTTB B\n"); - print(" BBBBBBBBBBBB\n"); - } - if (l != 0) { - for (z = 1; z <= 2; z++) { - print(tab(5)); - for (x = 1; x <= l; x++) - print(" L"); - print("\n"); - } - } - for (z = 1; z <= 4; z++) - print("\n"); + drawBug(playerFeelerCount, playerHeadCount, playerNeckCount, playerBodyCount, playerTailCount, playerFeetCount, "A"); print("*****MY BUG*****\n"); print("\n"); print("\n"); - print("\n"); - if (s != 0) { - for (z = 1; z <= 4; z++) { - print(tab(10)); - for (x = 1; x <= s; x++) { - print("F "); - } - print("\n"); - } - } - if (r != 0) - draw_head(); - if (q != 0) { - for (z = 1; z <= 2; z++) - print(" N N\n"); - } - if (p != 0) { - print(" BBBBBBBBBBBB\n"); - for (z = 1; z <= 2; z++) - print(" B B\n"); - if (u == 1) - print("TTTTTB B\n"); - print(" BBBBBBBBBBBB\n"); - } - if (v != 0) { - for (z = 1; z <= 2; z++) { - print(tab(5)); - for (x = 1; x <= v; x++) - print(" L"); - print("\n"); - } - } - for (z = 1; z <= 4; z++) + drawBug(computerFeelerCount, computerHeadCount, computerNeckCount, computerBodyCount, computerTailCount, computerFeetCount, "F"); + for (let z = 1; z <= 4; z++) print("\n"); } print("I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!\n"); + scrollToBottom(); } main(); From 302e1a0e0b688e6b029cef2e6a7f81681cd6ecfe Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sat, 29 Jan 2022 22:36:29 +1100 Subject: [PATCH 263/337] Testing added! Now some full behaviour tests on both Animal JVM implementations. Still todo: Move the ConsoleTest library into its own module, add a gradle dependency on it. --- 03_Animal/java/{ => src}/Animal.java | 6 +-- 03_Animal/java/test/AnimalJavaTest.kt | 54 +++++++++++++++++++++++++++ 03_Animal/java/test/ConsoleTest.kt | 35 +++++++++++++++++ 03_Animal/kotlin/{ => src}/Animal.kt | 0 03_Animal/kotlin/test/AnimalKtTest.kt | 54 +++++++++++++++++++++++++++ 03_Animal/kotlin/test/ConsoleTest.kt | 35 +++++++++++++++++ 6 files changed, 181 insertions(+), 3 deletions(-) rename 03_Animal/java/{ => src}/Animal.java (98%) create mode 100644 03_Animal/java/test/AnimalJavaTest.kt create mode 100644 03_Animal/java/test/ConsoleTest.kt rename 03_Animal/kotlin/{ => src}/Animal.kt (100%) create mode 100644 03_Animal/kotlin/test/AnimalKtTest.kt create mode 100644 03_Animal/kotlin/test/ConsoleTest.kt diff --git a/03_Animal/java/Animal.java b/03_Animal/java/src/Animal.java similarity index 98% rename from 03_Animal/java/Animal.java rename to 03_Animal/java/src/Animal.java index 681425c1..c4222c5f 100644 --- a/03_Animal/java/Animal.java +++ b/03_Animal/java/src/Animal.java @@ -74,11 +74,11 @@ public class Animal { private static void askForInformationAndSave(Scanner scan, AnimalNode current, QuestionNode previous, boolean previousToCurrentDecisionChoice) { //Failed to get it right and ran out of questions //Let's ask the user for the new information - System.out.print("THE ANIMAL YOU WERE THINKING OF WAS A "); + System.out.print("THE ANIMAL YOU WERE THINKING OF WAS A ? "); String animal = scan.nextLine(); - System.out.printf("PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A %s FROM A %s ", animal, current.getAnimal()); + System.out.printf("PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A %s FROM A %s ? ", animal, current.getAnimal()); String newQuestion = scan.nextLine(); - System.out.printf("FOR A %s THE ANSWER WOULD BE ", animal); + System.out.printf("FOR A %s THE ANSWER WOULD BE ? ", animal); boolean newAnswer = readYesOrNo(scan); //Add it to our question store addNewAnimal(current, previous, animal, newQuestion, newAnswer, previousToCurrentDecisionChoice); diff --git a/03_Animal/java/test/AnimalJavaTest.kt b/03_Animal/java/test/AnimalJavaTest.kt new file mode 100644 index 00000000..06513481 --- /dev/null +++ b/03_Animal/java/test/AnimalJavaTest.kt @@ -0,0 +1,54 @@ +import org.junit.Test + +class AnimalJavaTest : ConsoleTest() { + + @Test + fun `given a standard setup, find the fish`() { + assertConversation( + """ + $title + ARE YOU THINKING OF AN ANIMAL ? {YES} + DOES IT SWIM ? {YES} + IS IT A FISH ? {YES} + WHY NOT TRY ANOTHER ANIMAL? + ARE YOU THINKING OF AN ANIMAL ? {QUIT} + """ + ) { + Animal.main(emptyArray()) + } + } + + @Test + fun `given a standard setup, create a cow, and verify`() { + assertConversation( + """ + $title + ARE YOU THINKING OF AN ANIMAL ? {YES} + DOES IT SWIM ? {NO} + IS IT A BIRD ? {NO} + THE ANIMAL YOU WERE THINKING OF WAS A ? {COW} + PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A + COW FROM A BIRD + ? {DOES IT EAT GRASS} + FOR A COW THE ANSWER WOULD BE ? {YES} + ARE YOU THINKING OF AN ANIMAL ? {YES} + DOES IT SWIM ? {NO} + DOES IT EAT GRASS ? {YES} + IS IT A COW ? {YES} + WHY NOT TRY ANOTHER ANIMAL? + ARE YOU THINKING OF AN ANIMAL ? {QUIT} + """ + ) { + Animal.main(emptyArray()) + } + } + + private val title = """ + ANIMAL + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + PLAY 'GUESS THE ANIMAL' + THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT. + """ +} + diff --git a/03_Animal/java/test/ConsoleTest.kt b/03_Animal/java/test/ConsoleTest.kt new file mode 100644 index 00000000..3eebdcbb --- /dev/null +++ b/03_Animal/java/test/ConsoleTest.kt @@ -0,0 +1,35 @@ +import com.google.common.truth.Truth +import org.junit.Rule +import org.junit.contrib.java.lang.system.SystemOutRule +import org.junit.contrib.java.lang.system.TextFromStandardInputStream + +abstract class ConsoleTest { + @get:Rule + val inputRule = TextFromStandardInputStream.emptyStandardInputStream() + + @get:Rule + val systemOutRule = SystemOutRule().enableLog() + + val regexInputCommand = "\\{(.*)}".toRegex() + + fun assertConversation(conversation: String, runMain: () -> Unit) { + + inputRule.provideLines(*regexInputCommand + .findAll(conversation) + .map { it.groupValues[1] } + .toList().toTypedArray()) + + runMain() + + Truth.assertThat( + systemOutRule.log.trimWhiteSpace() + ) + .isEqualTo( + regexInputCommand + .replace(conversation, "").trimWhiteSpace() + ) + } + + private fun String.trimWhiteSpace() = + replace("[\\s]+".toRegex(), " ") +} \ No newline at end of file diff --git a/03_Animal/kotlin/Animal.kt b/03_Animal/kotlin/src/Animal.kt similarity index 100% rename from 03_Animal/kotlin/Animal.kt rename to 03_Animal/kotlin/src/Animal.kt diff --git a/03_Animal/kotlin/test/AnimalKtTest.kt b/03_Animal/kotlin/test/AnimalKtTest.kt new file mode 100644 index 00000000..38fae815 --- /dev/null +++ b/03_Animal/kotlin/test/AnimalKtTest.kt @@ -0,0 +1,54 @@ +import org.junit.Test + +class AnimalKtTest : ConsoleTest() { + + @Test + fun `given a standard setup, find the fish`() { + assertConversation( + """ + $title + ARE YOU THINKING OF AN ANIMAL? {YES} + DOES IT SWIM? {YES} + IS IT A FISH? {YES} + WHY NOT TRY ANOTHER ANIMAL? + ARE YOU THINKING OF AN ANIMAL? {QUIT} + """ + ) { + main() + } + } + + @Test + fun `given a standard setup, create a cow, and verify`() { + assertConversation( + """ + $title + ARE YOU THINKING OF AN ANIMAL? {YES} + DOES IT SWIM? {NO} + IS IT A BIRD? {NO} + THE ANIMAL YOU WERE THINKING OF WAS A? {COW} + PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A + COW FROM A BIRD + ? {DOES IT EAT GRASS} + FOR A COW THE ANSWER WOULD BE? {YES} + ARE YOU THINKING OF AN ANIMAL? {YES} + DOES IT SWIM? {NO} + DOES IT EAT GRASS? {YES} + IS IT A COW? {YES} + WHY NOT TRY ANOTHER ANIMAL? + ARE YOU THINKING OF AN ANIMAL? {QUIT} + """ + ) { + main() + } + } + + private val title = """ + ANIMAL + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + PLAY 'GUESS THE ANIMAL' + THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT. + """ +} + diff --git a/03_Animal/kotlin/test/ConsoleTest.kt b/03_Animal/kotlin/test/ConsoleTest.kt new file mode 100644 index 00000000..3eebdcbb --- /dev/null +++ b/03_Animal/kotlin/test/ConsoleTest.kt @@ -0,0 +1,35 @@ +import com.google.common.truth.Truth +import org.junit.Rule +import org.junit.contrib.java.lang.system.SystemOutRule +import org.junit.contrib.java.lang.system.TextFromStandardInputStream + +abstract class ConsoleTest { + @get:Rule + val inputRule = TextFromStandardInputStream.emptyStandardInputStream() + + @get:Rule + val systemOutRule = SystemOutRule().enableLog() + + val regexInputCommand = "\\{(.*)}".toRegex() + + fun assertConversation(conversation: String, runMain: () -> Unit) { + + inputRule.provideLines(*regexInputCommand + .findAll(conversation) + .map { it.groupValues[1] } + .toList().toTypedArray()) + + runMain() + + Truth.assertThat( + systemOutRule.log.trimWhiteSpace() + ) + .isEqualTo( + regexInputCommand + .replace(conversation, "").trimWhiteSpace() + ) + } + + private fun String.trimWhiteSpace() = + replace("[\\s]+".toRegex(), " ") +} \ No newline at end of file From 417d7d0117c87125074a53e54442b6597c360d13 Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Sat, 29 Jan 2022 10:41:23 +0000 Subject: [PATCH 264/337] 96 Word: Remove warnings --- 96_Word/javascript/word.js | 82 +++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/96_Word/javascript/word.js b/96_Word/javascript/word.js index 4df5d3fd..20131805 100644 --- a/96_Word/javascript/word.js +++ b/96_Word/javascript/word.js @@ -10,25 +10,22 @@ function print(str) function input() { - var input_element; - var input_str; return new Promise(function (resolve) { - input_element = document.createElement("INPUT"); + const input_element = document.createElement("INPUT"); print("? "); input_element.setAttribute("type", "text"); input_element.setAttribute("length", "50"); document.getElementById("output").appendChild(input_element); input_element.focus(); - input_str = undefined; input_element.addEventListener("keydown", function (event) { - if (event.keyCode == 13) { - input_str = input_element.value; - document.getElementById("output").removeChild(input_element); - print(input_str); - print("\n"); - resolve(input_str); + if (event.keyCode === 13) { + const input_str = input_element.value; + document.getElementById("output").removeChild(input_element); + print(input_str); + print("\n"); + resolve(input_str); } }); }); @@ -36,21 +33,21 @@ function input() function tab(space) { - var str = ""; + let str = ""; while (space-- > 0) str += " "; return str; } -var words = ["DINKY", "SMOKE", "WATER", "GLASS", "TRAIN", +const words = ["DINKY", "SMOKE", "WATER", "GLASS", "TRAIN", "MIGHT", "FIRST", "CANDY", "CHAMP", "WOULD", "CLUMP", "DOPEY"]; -var s = []; -var a = []; -var l = []; -var d = []; -var p = []; +const s = []; +const a = []; +const l = []; +const d = []; +const p = []; // Main control section async function main() @@ -68,47 +65,48 @@ async function main() print("\n"); print("\n"); print("YOU ARE STARTING A NEW GAME...\n"); - n = words.length; - ss = words[Math.floor(Math.random() * n)]; - g = 0; + let n = words.length; + let ss = words[Math.floor(Math.random() * n)]; + let g = 0; s[0] = ss.length; - for (i = 1; i <= ss.length; i++) + for (let i = 1; i <= ss.length; i++) s[i] = ss.charCodeAt(i - 1); - for (i = 1; i <= 5; i++) + for (let i = 1; i <= 5; i++) a[i] = 45; - for (j = 1; j <= 5; j++) + for (let j = 1; j <= 5; j++) p[j] = 0; + let ls = undefined; while (1) { print("GUESS A FIVE LETTER WORD"); ls = await input(); g++; - if (ss == ls) + if (ss === ls) break; - for (i = 1; i <= 7; i++) + for (let i = 1; i <= 7; i++) p[i] = 0; l[0] = ls.length; - for (i = 1; i <= ls.length; i++) { + for (let i = 1; i <= ls.length; i++) { l[i] = ls.charCodeAt(i - 1); } - if (l[1] == 63) { + if (l[1] === 63) { print("THE SECRET WORD IS " + ss + "\n"); print("\n"); break; } - if (l[0] != 5) { + if (l[0] !== 5) { print("YOU MUST GUESS A 5 LETTER WORD. START AGAIN.\n"); print("\n"); g--; continue; } - m = 0; - q = 1; - for (i = 1; i <= 5; i++) { - for (j = 1; j <= 5; j++) { - if (s[i] == l[j]) { + let m = 0; + let q = 1; + for (let i = 1; i <= 5; i++) { + for (let j = 1; j <= 5; j++) { + if (s[i] === l[j]) { p[q] = l[j]; q++; - if (i == j) + if (i === j) a[j] = l[j]; m++; } @@ -116,15 +114,15 @@ async function main() } a[0] = 5; p[0] = m; - as = ""; - for (i = 1; i <= a[0]; i++) + let as = ""; + for (let i = 1; i <= a[0]; i++) as += String.fromCharCode(a[i]); - ps = ""; - for (i = 1; i <= p[0]; i++) + let ps = ""; + for (let i = 1; i <= p[0]; i++) ps += String.fromCharCode(p[i]); print("THERE WERE " + m + " MATCHES AND THE COMMON LETTERS WERE... " + ps + "\n"); print("FROM THE EXACT LETTER MATCHES, YOU KNOW............ " + as + "\n"); - if (as == ss) { + if (as === ss) { ls = as; break; } @@ -134,15 +132,15 @@ async function main() print("\n"); } } - if (ss == ls) { + if (ss === ls) { print("YOU HAVE GUESSED THE WORD. IT TOOK " + g + " GUESSES!\n"); print("\n"); } else { continue; } print("WANT TO PLAY AGAIN"); - qs = await input(); - if (qs != "YES") + let qs = await input(); + if (qs !== "YES") break; } } From ff61ec7d07015eb633500b06510d6777d420f2e1 Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Sat, 29 Jan 2022 10:44:26 +0000 Subject: [PATCH 265/337] 96 Word: Make game case-insensitive --- 96_Word/javascript/word.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/96_Word/javascript/word.js b/96_Word/javascript/word.js index 20131805..8e5d4551 100644 --- a/96_Word/javascript/word.js +++ b/96_Word/javascript/word.js @@ -78,7 +78,7 @@ async function main() let ls = undefined; while (1) { print("GUESS A FIVE LETTER WORD"); - ls = await input(); + ls = (await input()).toUpperCase(); g++; if (ss === ls) break; @@ -139,7 +139,7 @@ async function main() continue; } print("WANT TO PLAY AGAIN"); - let qs = await input(); + let qs = (await input()).toUpperCase(); if (qs !== "YES") break; } From 41b10c4d8a9dfad42776eae6fc67341d21ce11ef Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Sat, 29 Jan 2022 11:41:24 +0000 Subject: [PATCH 266/337] 96 Word: Name the variables --- 96_Word/javascript/word.js | 105 ++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/96_Word/javascript/word.js b/96_Word/javascript/word.js index 8e5d4551..0d0ebe33 100644 --- a/96_Word/javascript/word.js +++ b/96_Word/javascript/word.js @@ -43,11 +43,10 @@ const words = ["DINKY", "SMOKE", "WATER", "GLASS", "TRAIN", "MIGHT", "FIRST", "CANDY", "CHAMP", "WOULD", "CLUMP", "DOPEY"]; -const s = []; -const a = []; -const l = []; -const d = []; -const p = []; +const secretWordDetails = []; +const knownLettersDetails = []; +const guessDetails = []; +const lettersInCommonDetails = []; // Main control section async function main() @@ -65,82 +64,90 @@ async function main() print("\n"); print("\n"); print("YOU ARE STARTING A NEW GAME...\n"); - let n = words.length; - let ss = words[Math.floor(Math.random() * n)]; - let g = 0; - s[0] = ss.length; - for (let i = 1; i <= ss.length; i++) - s[i] = ss.charCodeAt(i - 1); + + const n = words.length; + const secretWord = words[Math.floor(Math.random() * n)]; + + let guessCount = 0; + secretWordDetails[0] = secretWord.length; + for (let i = 1; i <= secretWord.length; i++) + secretWordDetails[i] = secretWord.charCodeAt(i - 1); for (let i = 1; i <= 5; i++) - a[i] = 45; + knownLettersDetails[i] = "-".charCodeAt(0); for (let j = 1; j <= 5; j++) - p[j] = 0; - let ls = undefined; + lettersInCommonDetails[j] = 0; + + let guess = undefined; while (1) { print("GUESS A FIVE LETTER WORD"); - ls = (await input()).toUpperCase(); - g++; - if (ss === ls) + guess = (await input()).toUpperCase(); + guessCount++; + if (secretWord === guess) break; for (let i = 1; i <= 7; i++) - p[i] = 0; - l[0] = ls.length; - for (let i = 1; i <= ls.length; i++) { - l[i] = ls.charCodeAt(i - 1); + lettersInCommonDetails[i] = 0; + + // store detail about the guess + guessDetails[0] = guess.length; + for (let i = 1; i <= guess.length; i++) { + guessDetails[i] = guess.charCodeAt(i - 1); } - if (l[1] === 63) { - print("THE SECRET WORD IS " + ss + "\n"); + + if (guessDetails[1] === 63) { + print("THE SECRET WORD IS " + secretWord + "\n"); print("\n"); break; } - if (l[0] !== 5) { + if (guessDetails[0] !== 5) { print("YOU MUST GUESS A 5 LETTER WORD. START AGAIN.\n"); print("\n"); - g--; + guessCount--; continue; } - let m = 0; - let q = 1; + let lettersInCommonCount = 0; + let nextCorrectLetterIndex = 1; for (let i = 1; i <= 5; i++) { for (let j = 1; j <= 5; j++) { - if (s[i] === l[j]) { - p[q] = l[j]; - q++; + if (secretWordDetails[i] === guessDetails[j]) { + lettersInCommonDetails[nextCorrectLetterIndex] = guessDetails[j]; + nextCorrectLetterIndex++; if (i === j) - a[j] = l[j]; - m++; + knownLettersDetails[j] = guessDetails[j]; + lettersInCommonCount++; } } } - a[0] = 5; - p[0] = m; - let as = ""; - for (let i = 1; i <= a[0]; i++) - as += String.fromCharCode(a[i]); - let ps = ""; - for (let i = 1; i <= p[0]; i++) - ps += String.fromCharCode(p[i]); - print("THERE WERE " + m + " MATCHES AND THE COMMON LETTERS WERE... " + ps + "\n"); - print("FROM THE EXACT LETTER MATCHES, YOU KNOW............ " + as + "\n"); - if (as === ss) { - ls = as; + knownLettersDetails[0] = 5; + lettersInCommonDetails[0] = lettersInCommonCount; + + let lettersInCommonText = ""; + for (let i = 1; i <= lettersInCommonDetails[0]; i++) + lettersInCommonText += String.fromCharCode(lettersInCommonDetails[i]); + print("THERE WERE " + lettersInCommonCount + " MATCHES AND THE COMMON LETTERS WERE... " + lettersInCommonText + "\n"); + + let knownLettersText = ""; + for (let i = 1; i <= knownLettersDetails[0]; i++) + knownLettersText += String.fromCharCode(knownLettersDetails[i]); + print("FROM THE EXACT LETTER MATCHES, YOU KNOW............ " + knownLettersText + "\n"); + if (knownLettersText === secretWord) { + guess = knownLettersText; break; } - if (m <= 1) { + if (lettersInCommonCount <= 1) { print("\n"); print("IF YOU GIVE UP, TYPE '?' FOR YOUR NEXT GUESS.\n"); print("\n"); } } - if (ss === ls) { - print("YOU HAVE GUESSED THE WORD. IT TOOK " + g + " GUESSES!\n"); + if (secretWord === guess) { + print("YOU HAVE GUESSED THE WORD. IT TOOK " + guessCount + " GUESSES!\n"); print("\n"); } else { continue; } print("WANT TO PLAY AGAIN"); - let qs = (await input()).toUpperCase(); - if (qs !== "YES") + const playAgainResponse = (await input()).toUpperCase(); + if (playAgainResponse !== "YES") break; } } From f756389037a8abd02c37bde4d2479325741c48e6 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sat, 29 Jan 2022 23:48:53 +1100 Subject: [PATCH 267/337] Createa a build_00_utilities project containing testing helpers, including the ConsoleTest abstract class. --- .../jvmTestUtils/kotlin}/test/ConsoleTest.kt | 2 ++ 03_Animal/java/test/AnimalJavaTest.kt | 1 + 03_Animal/kotlin/test/AnimalKtTest.kt | 1 + 03_Animal/kotlin/test/ConsoleTest.kt | 35 ------------------- 4 files changed, 4 insertions(+), 35 deletions(-) rename {03_Animal/java => 00_Utilities/jvmTestUtils/kotlin}/test/ConsoleTest.kt (96%) delete mode 100644 03_Animal/kotlin/test/ConsoleTest.kt diff --git a/03_Animal/java/test/ConsoleTest.kt b/00_Utilities/jvmTestUtils/kotlin/test/ConsoleTest.kt similarity index 96% rename from 03_Animal/java/test/ConsoleTest.kt rename to 00_Utilities/jvmTestUtils/kotlin/test/ConsoleTest.kt index 3eebdcbb..d58af170 100644 --- a/03_Animal/java/test/ConsoleTest.kt +++ b/00_Utilities/jvmTestUtils/kotlin/test/ConsoleTest.kt @@ -1,3 +1,5 @@ +package com.pcholt.console.testutils + import com.google.common.truth.Truth import org.junit.Rule import org.junit.contrib.java.lang.system.SystemOutRule diff --git a/03_Animal/java/test/AnimalJavaTest.kt b/03_Animal/java/test/AnimalJavaTest.kt index 06513481..013655a3 100644 --- a/03_Animal/java/test/AnimalJavaTest.kt +++ b/03_Animal/java/test/AnimalJavaTest.kt @@ -1,3 +1,4 @@ +import com.pcholt.console.testutils.ConsoleTest import org.junit.Test class AnimalJavaTest : ConsoleTest() { diff --git a/03_Animal/kotlin/test/AnimalKtTest.kt b/03_Animal/kotlin/test/AnimalKtTest.kt index 38fae815..e93857ea 100644 --- a/03_Animal/kotlin/test/AnimalKtTest.kt +++ b/03_Animal/kotlin/test/AnimalKtTest.kt @@ -1,3 +1,4 @@ +import com.pcholt.console.testutils.ConsoleTest import org.junit.Test class AnimalKtTest : ConsoleTest() { diff --git a/03_Animal/kotlin/test/ConsoleTest.kt b/03_Animal/kotlin/test/ConsoleTest.kt deleted file mode 100644 index 3eebdcbb..00000000 --- a/03_Animal/kotlin/test/ConsoleTest.kt +++ /dev/null @@ -1,35 +0,0 @@ -import com.google.common.truth.Truth -import org.junit.Rule -import org.junit.contrib.java.lang.system.SystemOutRule -import org.junit.contrib.java.lang.system.TextFromStandardInputStream - -abstract class ConsoleTest { - @get:Rule - val inputRule = TextFromStandardInputStream.emptyStandardInputStream() - - @get:Rule - val systemOutRule = SystemOutRule().enableLog() - - val regexInputCommand = "\\{(.*)}".toRegex() - - fun assertConversation(conversation: String, runMain: () -> Unit) { - - inputRule.provideLines(*regexInputCommand - .findAll(conversation) - .map { it.groupValues[1] } - .toList().toTypedArray()) - - runMain() - - Truth.assertThat( - systemOutRule.log.trimWhiteSpace() - ) - .isEqualTo( - regexInputCommand - .replace(conversation, "").trimWhiteSpace() - ) - } - - private fun String.trimWhiteSpace() = - replace("[\\s]+".toRegex(), " ") -} \ No newline at end of file From 7674913388397e09c1cf15ef39726beb550e2733 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 30 Jan 2022 00:11:59 +1100 Subject: [PATCH 268/337] Description added to README --- buildJvm/README.md | 95 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 10 deletions(-) diff --git a/buildJvm/README.md b/buildJvm/README.md index 4ecba004..3db4014a 100644 --- a/buildJvm/README.md +++ b/buildJvm/README.md @@ -67,16 +67,16 @@ directory for the java or kotlin file, and the class that contains the `main` me The `build.gradle` file **should** be identical to all the other `build.gradle` files in all the other subprojects: ```groovy - sourceSets { - main { - java { - srcDirs "../../$gameSource" - } - } - } - application { - mainClass = gameMain - } + sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } + } + application { + mainClass = gameMain + } ``` The `gradle.properties` file should look like this: @@ -92,3 +92,78 @@ project to the list. ```groovy include ":build_91_Train_java" ``` + +### Adding a game with tests + +You can add tests for JVM games with a `build.gradle` looking a little different. +Use the build files from `03_Animal` as a template to add tests: + +```groovy +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } + test { + java { + srcDirs "../../$gameTest" + } + } +} + +application { + mainClass = gameMain +} + +dependencies { + testImplementation(project(":build_00_utilities").sourceSets.test.output) +} +``` + +The gradle.properties needs an additional directory name for the tests, as `gameTest` : +``` +gameSource=03_Animal/java/src +gameTest=03_Animal/java/test +gameMain=Animal +``` + +Each project should have its own test, and shouldn't share test source directories +with other projects, even if they are for the same game. + +Tests are constructed by subclassing `ConsoleTest`. This allows you to use the +`assertConversation` function to check for correct interactive conversations. +```kotlin +import com.pcholt.console.testutils.ConsoleTest +import org.junit.Test + +class AnimalJavaTest : ConsoleTest() { + @Test + fun `should have a simple conversation`() { + assertConversation( + """ + WHAT'S YOUR NAME? {PAUL} + YOUR NAME IS PAUL? {YES} + THANKS FOR PLAYING + """ + ) { + // The game's Main method + main() + } + } +} +``` + +Curly brackets are the expected user input. +Note - this is actually just a way of defining the expected input as "PAUL" and "YES" +and not that the input happens at the exact prompt position. Thus this is equivalent: +```kotlin +""" +{PAUL} {YES} WHAT'S YOUR NAME? +YOUR NAME IS PAUL? +THANKS FOR PLAYING +""" +``` + +Amounts of whitespace are not counted, but whitespace is significant: You will get a failure if +your game emits `"NAME?"` when it expects `"NAME ?"`. From cefe471fdf79fd95589285bb92e4e8fcd0e286db Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 30 Jan 2022 00:21:25 +1100 Subject: [PATCH 269/337] Description added to README --- buildJvm/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/buildJvm/README.md b/buildJvm/README.md index 3db4014a..c08811b9 100644 --- a/buildJvm/README.md +++ b/buildJvm/README.md @@ -167,3 +167,9 @@ THANKS FOR PLAYING Amounts of whitespace are not counted, but whitespace is significant: You will get a failure if your game emits `"NAME?"` when it expects `"NAME ?"`. + +Run all the tests from within the buildJvm project directory: +```bash +cd buildJvm +./gradlew test +``` From 6f7e311b5197ae61a4ff883802a812bad5a1c599 Mon Sep 17 00:00:00 2001 From: Stefan Waldmann Date: Sat, 29 Jan 2022 16:30:42 +0100 Subject: [PATCH 270/337] Add Javadoc --- 55_Life/java/src/java/Life.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/55_Life/java/src/java/Life.java b/55_Life/java/src/java/Life.java index 0e202240..2f5c184a 100644 --- a/55_Life/java/src/java/Life.java +++ b/55_Life/java/src/java/Life.java @@ -27,7 +27,11 @@ public class Life { boolean stopAfterGen = false; boolean invalid = false; - + /** + * Constructor. + * + * @param args the command line arguments + */ public Life(String[] args) { parse(args); } @@ -41,7 +45,10 @@ public class Life { } } - private void start() { + /** + * Starts the game. + */ + public void start() { printGameHeader(); readPattern(); while (true) { From 1f3855e98c7a463613ae016b23cd4da085c55ecc Mon Sep 17 00:00:00 2001 From: Stefan Waldmann Date: Sat, 29 Jan 2022 16:56:53 +0100 Subject: [PATCH 271/337] Edit README.md --- 55_Life/java/README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/55_Life/java/README.md b/55_Life/java/README.md index 51edd8d4..27b6941b 100644 --- a/55_Life/java/README.md +++ b/55_Life/java/README.md @@ -1,3 +1,18 @@ +# Game of Life - Java version + Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Oracle Java](https://openjdk.java.net/) + +## Requirements + +* Requires Java 17 (or later) + +## Notes + +The Java version of Game of Life tries to mimics the behaviour of the BASIC version. +However, the Java code does not have much in common with the original. + +**Differences in behaviour:** +* Input supports the ```.``` character, but it's optional. +* Evaluation of ```DONE``` input string is case insensitive. From a7b9ab89c67f97c9414c948f98cd8fe5d536af18 Mon Sep 17 00:00:00 2001 From: Stefan Waldmann Date: Sat, 29 Jan 2022 17:05:10 +0100 Subject: [PATCH 272/337] Edit README.md --- 55_Life/java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/55_Life/java/README.md b/55_Life/java/README.md index 27b6941b..19a5ff38 100644 --- a/55_Life/java/README.md +++ b/55_Life/java/README.md @@ -16,3 +16,4 @@ However, the Java code does not have much in common with the original. **Differences in behaviour:** * Input supports the ```.``` character, but it's optional. * Evaluation of ```DONE``` input string is case insensitive. +* Run with the ```-s``` command line argument to halt the program after each generation, and continue when ```ENTER``` is pressed. \ No newline at end of file From c552019cd8332daa8c4b86b0071977382a185ce1 Mon Sep 17 00:00:00 2001 From: roygilliam <58305899+roygilliam@users.noreply.github.com> Date: Sat, 29 Jan 2022 11:15:11 -0500 Subject: [PATCH 273/337] Initial conversion to C# --- 85_Synonym/csharp/Synonym.cs | 149 +++++++++++++++++++++++++++++++ 85_Synonym/csharp/Synonym.csproj | 3 +- 2 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 85_Synonym/csharp/Synonym.cs diff --git a/85_Synonym/csharp/Synonym.cs b/85_Synonym/csharp/Synonym.cs new file mode 100644 index 00000000..9d58da71 --- /dev/null +++ b/85_Synonym/csharp/Synonym.cs @@ -0,0 +1,149 @@ +using System.Text; + +namespace Synonym +{ + class Synonym + { + Random rand = new Random(); + + // Initialize list of corrent responses + private string[] Affirmations = { "Right", "Correct", "Fine", "Good!", "Check" }; + + // Initialize list of words and their synonyms + private string[][] Words = + { + new string[] {"first", "start", "beginning", "onset", "initial"}, + new string[] {"similar", "alike", "same", "like", "resembling"}, + new string[] {"model", "pattern", "prototype", "standard", "criterion"}, + new string[] {"small", "insignificant", "little", "tiny", "minute"}, + new string[] {"stop", "halt", "stay", "arrest", "check", "standstill"}, + new string[] {"house", "dwelling", "residence", "domicile", "lodging", "habitation"}, + new string[] {"pit", "hole", "hollow", "well", "gulf", "chasm", "abyss"}, + new string[] {"push", "shove", "thrust", "prod", "poke", "butt", "press"}, + new string[] {"red", "rouge", "scarlet", "crimson", "flame", "ruby"}, + new string[] {"pain", "suffering", "hurt", "misery", "distress", "ache", "discomfort"} + }; + + private void DisplayIntro() + { + Console.WriteLine(""); + Console.WriteLine("SYNONYM".PadLeft(23)); + Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Console.WriteLine(""); + Console.WriteLine("A synonym of a word means another word in the English"); + Console.WriteLine("language which has the same or very nearly the same meaning."); + Console.WriteLine("I choose a word -- you type a synonym."); + Console.WriteLine("If you can't think of a synonym, type the word 'help'"); + Console.WriteLine("and I will tell you a synonym."); + Console.WriteLine(""); + } + + private void DisplayOutro() + { + Console.WriteLine("Synonym drill completed."); + } + + private void RandomizeTheList() + { + // Randomize the list of Words to pick from + int[] Order = new int[Words.Length]; + foreach (int i in Order) + { + Order[i] = rand.Next(); + } + Array.Sort(Order, Words); + } + + private string GetAnAffirmation() + { + return Affirmations[rand.Next(Affirmations.Length)]; + } + + private bool CheckTheResponse(string WordName, int WordIndex, string LineInput, string[] WordList) + { + if (LineInput.Equals("help")) + { + // Choose a random correct synonym response that doesn't equal the current word given + int HelpIndex = rand.Next(WordList.Length); + while (HelpIndex == WordIndex) + { + HelpIndex = rand.Next(0, WordList.Length); + } + Console.WriteLine("**** A synonym of {0} is {1}.", WordName, WordList[HelpIndex]); + + return false; + } + else + { + // Check to see if the response is one of the listed synonyms and not the current word prompt + if (WordList.Contains(LineInput) && LineInput != WordName) + { + // Randomly display one of the five correct answer exclamations + Console.WriteLine(GetAnAffirmation()); + + return true; + } + else + { + // Incorrect response. Try again. + Console.WriteLine(" Try again.".PadLeft(5)); + + return false; + } + } + } + + private string PromptForSynonym(string WordName) + { + Console.Write(" What is a synonym of {0}? ", WordName); + string LineInput = Console.ReadLine().Trim().ToLower(); + + return LineInput; + } + + private void AskForSynonyms() + { + Random rand = new Random(); + + // Loop through the now randomized list of Words and display a random word from each to prompt for a synonym + foreach (string[] WordList in Words) + { + int WordIndex = rand.Next(WordList.Length); // random word position in the current list of words + string WordName = WordList[WordIndex]; // what is that actual word + bool Success = false; + + while (!Success) + { + // Ask for the synonym of the current word + string LineInput = PromptForSynonym(WordName); + + // Check the response + Success = CheckTheResponse(WordName, WordIndex, LineInput, WordList); + + // Add extra line space for formatting + Console.WriteLine(""); + } + } + } + + public void PlayTheGame() + { + RandomizeTheList(); + + DisplayIntro(); + + AskForSynonyms(); + + DisplayOutro(); + } + } + class Program + { + static void Main(string[] args) + { + + new Synonym().PlayTheGame(); + + } + } +} \ No newline at end of file diff --git a/85_Synonym/csharp/Synonym.csproj b/85_Synonym/csharp/Synonym.csproj index d3fe4757..1fd332a6 100644 --- a/85_Synonym/csharp/Synonym.csproj +++ b/85_Synonym/csharp/Synonym.csproj @@ -1,9 +1,10 @@ - + Exe net6.0 10 enable enable + Synonym.Program From 4c49492449b78c7449c815b06fe41457dcbe8fcd Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Sat, 29 Jan 2022 17:07:45 +0000 Subject: [PATCH 274/337] 96 Word: Simplify use of arrays; add some comments --- 96_Word/javascript/word.js | 91 ++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/96_Word/javascript/word.js b/96_Word/javascript/word.js index 0d0ebe33..3d7e3a5a 100644 --- a/96_Word/javascript/word.js +++ b/96_Word/javascript/word.js @@ -39,14 +39,11 @@ function tab(space) return str; } -const words = ["DINKY", "SMOKE", "WATER", "GLASS", "TRAIN", +// These are the words that the game knows about> If you want a bigger challenge you could add more words to the array +const WORDS = ["DINKY", "SMOKE", "WATER", "GLASS", "TRAIN", "MIGHT", "FIRST", "CANDY", "CHAMP", "WOULD", "CLUMP", "DOPEY"]; - -const secretWordDetails = []; -const knownLettersDetails = []; -const guessDetails = []; -const lettersInCommonDetails = []; +const WORD_COUNT = WORDS.length; // Main control section async function main() @@ -60,91 +57,87 @@ async function main() print("CLUES TO HELP YOU GET IT. GOOD LUCK!!\n"); print("\n"); print("\n"); - while (1) { + outer: while (1) { print("\n"); print("\n"); print("YOU ARE STARTING A NEW GAME...\n"); - const n = words.length; - const secretWord = words[Math.floor(Math.random() * n)]; + const secretWord = WORDS[Math.floor(Math.random() * WORD_COUNT)]; let guessCount = 0; - secretWordDetails[0] = secretWord.length; - for (let i = 1; i <= secretWord.length; i++) - secretWordDetails[i] = secretWord.charCodeAt(i - 1); - for (let i = 1; i <= 5; i++) - knownLettersDetails[i] = "-".charCodeAt(0); - for (let j = 1; j <= 5; j++) - lettersInCommonDetails[j] = 0; + // This array holds the letters which have been found in the correct position across all guesses + // For instance if the word is "PLAIN" and the guesses so far are + // "SHALL" ("A" correct) and "CLIMB" ("L" correct) then it will hold "-LA--" + const knownLetters = []; + for (let i = 0; i < 5; i++) + knownLetters[i] = "-"; let guess = undefined; while (1) { print("GUESS A FIVE LETTER WORD"); guess = (await input()).toUpperCase(); guessCount++; - if (secretWord === guess) + if (secretWord === guess) { + // The player has guessed correctly break; - for (let i = 1; i <= 7; i++) - lettersInCommonDetails[i] = 0; - - // store detail about the guess - guessDetails[0] = guess.length; - for (let i = 1; i <= guess.length; i++) { - guessDetails[i] = guess.charCodeAt(i - 1); } - if (guessDetails[1] === 63) { + if (guess.charAt(0) === "?") { + // Player has given up print("THE SECRET WORD IS " + secretWord + "\n"); print("\n"); - break; + // Start a new game by going to the start of the outer while loop + continue outer; } - if (guessDetails[0] !== 5) { + + if (guess.length !== 5) { print("YOU MUST GUESS A 5 LETTER WORD. START AGAIN.\n"); print("\n"); guessCount--; continue; } + + // Two things happen in this double loop: + // 1. Letters which are in both the guessed and secret words are put in the lettersInCommon array + // 2. Letters which are in the correct position in the guessed word are added to the knownLetters array let lettersInCommonCount = 0; - let nextCorrectLetterIndex = 1; - for (let i = 1; i <= 5; i++) { - for (let j = 1; j <= 5; j++) { - if (secretWordDetails[i] === guessDetails[j]) { - lettersInCommonDetails[nextCorrectLetterIndex] = guessDetails[j]; - nextCorrectLetterIndex++; - if (i === j) - knownLettersDetails[j] = guessDetails[j]; + const lettersInCommon = []; + for (let i = 0; i < 5; i++) {// loop round characters in secret word + let secretWordCharacter = secretWord.charAt(i); + for (let j = 0; j < 5; j++) {// loop round characters in guessed word + let guessedWordCharacter = guess.charAt(j); + if (secretWordCharacter === guessedWordCharacter) { + lettersInCommon[lettersInCommonCount] = guessedWordCharacter; + if (i === j) { + // Letter is in the exact position so add to the known letters array + knownLetters[j] = guessedWordCharacter; + } lettersInCommonCount++; } } } - knownLettersDetails[0] = 5; - lettersInCommonDetails[0] = lettersInCommonCount; - let lettersInCommonText = ""; - for (let i = 1; i <= lettersInCommonDetails[0]; i++) - lettersInCommonText += String.fromCharCode(lettersInCommonDetails[i]); + const lettersInCommonText = lettersInCommon.join(""); print("THERE WERE " + lettersInCommonCount + " MATCHES AND THE COMMON LETTERS WERE... " + lettersInCommonText + "\n"); - let knownLettersText = ""; - for (let i = 1; i <= knownLettersDetails[0]; i++) - knownLettersText += String.fromCharCode(knownLettersDetails[i]); + const knownLettersText = knownLetters.join(""); print("FROM THE EXACT LETTER MATCHES, YOU KNOW............ " + knownLettersText + "\n"); + if (knownLettersText === secretWord) { guess = knownLettersText; break; } + if (lettersInCommonCount <= 1) { print("\n"); print("IF YOU GIVE UP, TYPE '?' FOR YOUR NEXT GUESS.\n"); print("\n"); } } - if (secretWord === guess) { - print("YOU HAVE GUESSED THE WORD. IT TOOK " + guessCount + " GUESSES!\n"); - print("\n"); - } else { - continue; - } + + print("YOU HAVE GUESSED THE WORD. IT TOOK " + guessCount + " GUESSES!\n"); + print("\n"); + print("WANT TO PLAY AGAIN"); const playAgainResponse = (await input()).toUpperCase(); if (playAgainResponse !== "YES") From 3583421ea5e13deabe4208347c56c60eabb0cd26 Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Sun, 30 Jan 2022 00:03:52 +0000 Subject: [PATCH 275/337] 95 Workday - remove warnings using const and let --- 95_Weekday/javascript/weekday.js | 92 +++++++++++++++----------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index 276e1817..caf45990 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -10,33 +10,29 @@ function print(str) function input() { - var input_element; - var input_str; - return new Promise(function (resolve) { - input_element = document.createElement("INPUT"); + const input_element = document.createElement("INPUT"); print("? "); input_element.setAttribute("type", "text"); input_element.setAttribute("length", "50"); document.getElementById("output").appendChild(input_element); input_element.focus(); - input_str = undefined; input_element.addEventListener("keydown", function (event) { - if (event.keyCode == 13) { - input_str = input_element.value; - document.getElementById("output").removeChild(input_element); - print(input_str); - print("\n"); - resolve(input_str); - } + if (event.keyCode === 13) { + const input_str = input_element.value; + document.getElementById("output").removeChild(input_element); + print(input_str); + print("\n"); + resolve(input_str); + } }); }); } function tab(space) { - var str = ""; + let str = ""; while (space-- > 0) str += " "; return str; @@ -50,19 +46,19 @@ function fnb(arg) { return Math.floor(arg / 7); } -var t = [, 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; +const t = [, 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; -var k5; -var k6; -var k7; +let k5; +let k6; +let k7; function time_spent(f, a8) { - k1 = Math.floor(f * a8); - i5 = Math.floor(k1 / 365); + let k1 = Math.floor(f * a8); + const i5 = Math.floor(k1 / 365); k1 -= i5 * 365; - i6 = Math.floor(k1 / 30); - i7 = k1 - (i6 * 30); + const i6 = Math.floor(k1 / 30); + const i7 = k1 - (i6 * 30); k5 -= i5; k6 -= i6; k7 -= i7; @@ -89,47 +85,47 @@ async function main() print("GIVES FACTS ABOUT A DATE OF INTEREST TO YOU.\n"); print("\n"); print("ENTER TODAY'S DATE IN THE FORM: 3,24,1979 "); - str = await input(); - m1 = parseInt(str); - d1 = parseInt(str.substr(str.indexOf(",") + 1)); - y1 = parseInt(str.substr(str.lastIndexOf(",") + 1)); + let str = await input(); + const m1 = parseInt(str); + const d1 = parseInt(str.substr(str.indexOf(",") + 1)); + const y1 = parseInt(str.substr(str.lastIndexOf(",") + 1)); // This program determines the day of the week // for a date after 1582 print("ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST)"); str = await input(); - m = parseInt(str); - d = parseInt(str.substr(str.indexOf(",") + 1)); - y = parseInt(str.substr(str.lastIndexOf(",") + 1)); + const m = parseInt(str); + const d = parseInt(str.substr(str.indexOf(",") + 1)); + const y = parseInt(str.substr(str.lastIndexOf(",") + 1)); print("\n"); - i1 = Math.floor((y - 1500) / 100); + const i1 = Math.floor((y - 1500) / 100); // Test for date before current calendar. if (y - 1582 < 0) { print("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII.\n"); } else { - a = i1 * 5 + (i1 + 3) / 4; - i2 = Math.floor(a - fnb(a) * 7); - y2 = Math.floor(y / 100); - y3 = Math.floor(y - y2 * 100); + let a = i1 * 5 + (i1 + 3) / 4; + const i2 = Math.floor(a - fnb(a) * 7); + const y2 = Math.floor(y / 100); + const y3 = Math.floor(y - y2 * 100); a = y3 / 4 + y3 + d + t[m] + i2; - b = Math.floor(a - fnb(a) * 7) + 1; + let b = Math.floor(a - fnb(a) * 7) + 1; if (m <= 2) { - if (y3 != 0) { + if (y3 !== 0) { t1 = Math.floor(y - fna(y) * 4); } else { a = i1 - 1; t1 = Math.floor(a - fna(a) * 4); } - if (t1 == 0) { - if (b == 0) + if (t1 === 0) { + if (b === 0) b = 6; b--; } } - if (b == 0) + if (b === 0) b = 7; if ((y1 * 12 + m1) * 31 + d1 < (y * 12 + m) * 31 + d) { print(m + "/" + d + "/" + y + " WILL BE A "); - } else if ((y1 * 12 + m1) * 31 + d1 == (y * 12 + m) * 31 + d) { + } else if ((y1 * 12 + m1) * 31 + d1 === (y * 12 + m) * 31 + d) { print(m + "/" + d + "/" + y + " IS A "); } else { print(m + "/" + d + "/" + y + " WAS A "); @@ -141,7 +137,7 @@ async function main() case 4: print("WEDNESDAY.\n"); break; case 5: print("THURSDAY.\n"); break; case 6: - if (d == 13) { + if (d === 13) { print("FRIDAY THE THIRTEENTH---BEWARE!\n"); } else { print("FRIDAY.\n"); @@ -149,11 +145,11 @@ async function main() break; case 7: print("SATURDAY.\n"); break; } - if ((y1 * 12 + m1) * 31 + d1 != (y * 12 + m) * 31 + d) { - i5 = y1 - y; + if ((y1 * 12 + m1) * 31 + d1 !== (y * 12 + m) * 31 + d) { + let i5 = y1 - y; print("\n"); - i6 = m1 - m; - i7 = d1 - d; + let i6 = m1 - m; + let i7 = d1 - d; if (i7 < 0) { i6--; i7 += 30; @@ -163,17 +159,17 @@ async function main() i6 += 12; } if (i5 >= 0) { - if (i7 == 0 && i6 == 0) + if (i7 === 0 && i6 === 0) print("***HAPPY BIRTHDAY***\n"); print(" \tYEARS\tMONTHS\tDAYS\n"); print(" \t-----\t------\t----\n"); print("YOUR AGE (IF BIRTHDATE) \t" + i5 + "\t" + i6 + "\t" + i7 + "\n"); - a8 = (i5 * 365) + (i6 * 30) + i7 + Math.floor(i6 / 2); + const a8 = (i5 * 365) + (i6 * 30) + i7 + Math.floor(i6 / 2); k5 = i5; k6 = i6; k7 = i7; // Calculate retirement date. - e = y + 65; + const e = y + 65; // Calculate time spent in the following functions. print("YOU HAVE SLEPT \t\t\t"); time_spent(0.35, a8); @@ -187,7 +183,7 @@ async function main() print("YOU HAVE WORKED/PLAYED \t\t"); } time_spent(0.23, a8); - if (k6 == 12) { + if (k6 === 12) { k5++; k6 = 0; } From 63f78550cdf0d0c73e7b97059be8def4b6d2486f Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Sun, 30 Jan 2022 09:59:11 +0000 Subject: [PATCH 276/337] 95 Workday - introduce some comments, and methods; improve some variable names; spotted a bug --- 95_Weekday/javascript/weekday.js | 160 ++++++++++++++++++++----------- 1 file changed, 103 insertions(+), 57 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index caf45990..dd1d82d5 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -46,7 +46,33 @@ function fnb(arg) { return Math.floor(arg / 7); } -const t = [, 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; +// in a non-leap year the day of the week for the first of each month moves by the following amounts. +const MONTHLY_DAY_OF_WEEK_OFFSETS = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; + +/** + * Reads a date, and extracts the date information. + * This expects date parts to be comma separated, using US date ordering, + * i.e. Month,Day,Year. + * @returns {Promise<[number,number,number]>} [year, month, dayOfMonth] + */ +async function readDateElements() { + let dateString = await input(); + const month = parseInt(dateString); + const dayOfMonth = parseInt(dateString.substr(dateString.indexOf(",") + 1)); + const year = parseInt(dateString.substr(dateString.lastIndexOf(",") + 1)); + return [year, month, dayOfMonth]; +} + +/** + * Returns a US formatted date, i.e. Month/Day/Year. + * @param year + * @param month + * @param dayOfMonth + * @returns {string} + */ +function getFormattedDate(year, month, dayOfMonth) { + return month + "/" + dayOfMonth + "/" + year; +} let k5; let k6; @@ -73,6 +99,46 @@ function time_spent(f, a8) print(i5 + "\t" + i6 + "\t" + i7 + "\n"); } +function getDayOfWeek(dobYear, dobMonth, dobDayOfMonth) { + const i1 = Math.floor((dobYear - 1500) / 100); + let a = i1 * 5 + (i1 + 3) / 4; + const i2 = Math.floor(a - fnb(a) * 7); + const y2 = Math.floor(dobYear / 100); + const y3 = Math.floor(dobYear - y2 * 100); + a = y3 / 4 + y3 + dobDayOfMonth + MONTHLY_DAY_OF_WEEK_OFFSETS[dobMonth-1] + i2; + let dayOfWeek = Math.floor(a - fnb(a) * 7) + 1; + if (dobMonth <= 2) { + if (y3 !== 0) { + t1 = Math.floor(dobYear - fna(dobYear) * 4); + } else { + a = i1 - 1; + t1 = Math.floor(a - fna(a) * 4); + } + if (t1 === 0) { + if (dayOfWeek === 0) { + dayOfWeek = 6; + } + dayOfWeek--; + } + } + if (dayOfWeek === 0) { + dayOfWeek = 7; + } + return dayOfWeek; +} + +/** + * The following performs a special hash on the day parts which guarantees + * that different days will return different numbers, and the numbers returned are in ordered. + * @param todayYear + * @param todayMonth + * @param todayDayOfMonth + * @returns {*} + */ +function getNormalisedDay(todayYear, todayMonth, todayDayOfMonth) { + return (todayYear * 12 + todayMonth) * 31 + todayDayOfMonth; +} + // Main control section async function main() { @@ -85,59 +151,38 @@ async function main() print("GIVES FACTS ABOUT A DATE OF INTEREST TO YOU.\n"); print("\n"); print("ENTER TODAY'S DATE IN THE FORM: 3,24,1979 "); - let str = await input(); - const m1 = parseInt(str); - const d1 = parseInt(str.substr(str.indexOf(",") + 1)); - const y1 = parseInt(str.substr(str.lastIndexOf(",") + 1)); + const [todayYear, todayMonth, todayDayOfMonth] = await readDateElements(); // This program determines the day of the week // for a date after 1582 print("ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST)"); - str = await input(); - const m = parseInt(str); - const d = parseInt(str.substr(str.indexOf(",") + 1)); - const y = parseInt(str.substr(str.lastIndexOf(",") + 1)); + const [dobYear, dobMonth, dobDayOfMonth] = await readDateElements(); print("\n"); - const i1 = Math.floor((y - 1500) / 100); // Test for date before current calendar. - if (y - 1582 < 0) { + // Note: this test is unreliable - the Gregorian calendar was introduced on Friday 15 October 1582 + // and the weekday algorithm fails for dates prior to that + if (dobYear - 1582 < 0) { print("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII.\n"); } else { - let a = i1 * 5 + (i1 + 3) / 4; - const i2 = Math.floor(a - fnb(a) * 7); - const y2 = Math.floor(y / 100); - const y3 = Math.floor(y - y2 * 100); - a = y3 / 4 + y3 + d + t[m] + i2; - let b = Math.floor(a - fnb(a) * 7) + 1; - if (m <= 2) { - if (y3 !== 0) { - t1 = Math.floor(y - fna(y) * 4); - } else { - a = i1 - 1; - t1 = Math.floor(a - fna(a) * 4); - } - if (t1 === 0) { - if (b === 0) - b = 6; - b--; - } - } - if (b === 0) - b = 7; - if ((y1 * 12 + m1) * 31 + d1 < (y * 12 + m) * 31 + d) { - print(m + "/" + d + "/" + y + " WILL BE A "); - } else if ((y1 * 12 + m1) * 31 + d1 === (y * 12 + m) * 31 + d) { - print(m + "/" + d + "/" + y + " IS A "); + const dayOfWeek = getDayOfWeek(dobYear, dobMonth, dobDayOfMonth); + + const normalisedToday = getNormalisedDay(todayYear, todayMonth, todayDayOfMonth); + const normalisedDob = getNormalisedDay(dobYear, dobMonth, dobDayOfMonth); + + if (normalisedToday < normalisedDob) { + print(getFormattedDate(dobYear, dobMonth, dobDayOfMonth) + " WILL BE A "); + } else if (normalisedToday === normalisedDob) { + print(getFormattedDate(dobYear, dobMonth, dobDayOfMonth) + " IS A "); } else { - print(m + "/" + d + "/" + y + " WAS A "); + print(getFormattedDate(dobYear, dobMonth, dobDayOfMonth) + " WAS A "); } - switch (b) { + switch (dayOfWeek) { case 1: print("SUNDAY.\n"); break; case 2: print("MONDAY.\n"); break; case 3: print("TUESDAY.\n"); break; case 4: print("WEDNESDAY.\n"); break; case 5: print("THURSDAY.\n"); break; case 6: - if (d === 13) { + if (dobDayOfMonth === 13) { print("FRIDAY THE THIRTEENTH---BEWARE!\n"); } else { print("FRIDAY.\n"); @@ -145,31 +190,32 @@ async function main() break; case 7: print("SATURDAY.\n"); break; } - if ((y1 * 12 + m1) * 31 + d1 !== (y * 12 + m) * 31 + d) { - let i5 = y1 - y; + if (normalisedToday !== normalisedDob) { + let yearsBetweenDates = todayYear - dobYear; print("\n"); - let i6 = m1 - m; - let i7 = d1 - d; - if (i7 < 0) { - i6--; - i7 += 30; + let monthsBetweenDates = todayMonth - dobMonth; + let daysBetweenDates = todayDayOfMonth - dobDayOfMonth; + if (daysBetweenDates < 0) { + monthsBetweenDates--; + daysBetweenDates += 30; } - if (i6 < 0) { - i5--; - i6 += 12; + if (monthsBetweenDates < 0) { + yearsBetweenDates--; + monthsBetweenDates += 12; } - if (i5 >= 0) { - if (i7 === 0 && i6 === 0) + if (yearsBetweenDates >= 0) { + if (daysBetweenDates === 0 && monthsBetweenDates === 0) { print("***HAPPY BIRTHDAY***\n"); + } print(" \tYEARS\tMONTHS\tDAYS\n"); print(" \t-----\t------\t----\n"); - print("YOUR AGE (IF BIRTHDATE) \t" + i5 + "\t" + i6 + "\t" + i7 + "\n"); - const a8 = (i5 * 365) + (i6 * 30) + i7 + Math.floor(i6 / 2); - k5 = i5; - k6 = i6; - k7 = i7; + print("YOUR AGE (IF BIRTHDATE) \t" + yearsBetweenDates + "\t" + monthsBetweenDates + "\t" + daysBetweenDates + "\n"); + const a8 = (yearsBetweenDates * 365) + (monthsBetweenDates * 30) + daysBetweenDates + Math.floor(monthsBetweenDates / 2); + k5 = yearsBetweenDates; + k6 = monthsBetweenDates; + k7 = daysBetweenDates; // Calculate retirement date. - const e = y + 65; + const e = dobYear + 65; // Calculate time spent in the following functions. print("YOU HAVE SLEPT \t\t\t"); time_spent(0.35, a8); From a28a0adafa97cf9a21186f1702c70bd22a33d92a Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Sun, 30 Jan 2022 12:13:00 +0000 Subject: [PATCH 277/337] 95 Workday - break time spent calculation and printining into multiple parts --- 95_Weekday/javascript/weekday.js | 103 ++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 36 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index dd1d82d5..2451f19b 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -74,29 +74,50 @@ function getFormattedDate(year, month, dayOfMonth) { return month + "/" + dayOfMonth + "/" + year; } -let k5; -let k6; -let k7; - -function time_spent(f, a8) +/** + * Calculate years, months and days as factor of days. + * This is a naive calculation which assumes all months are 30 days. + * @param factor + * @param dayCount + * @returns {{years: number, months: number, days: number}} + */ +function time_spent(factor, dayCount) { - let k1 = Math.floor(f * a8); - const i5 = Math.floor(k1 / 365); - k1 -= i5 * 365; - const i6 = Math.floor(k1 / 30); - const i7 = k1 - (i6 * 30); - k5 -= i5; - k6 -= i6; - k7 -= i7; - if (k7 < 0) { - k7 += 30; - k6--; + let totalDays = Math.floor(factor * dayCount); + const years = Math.floor(totalDays / 365); + totalDays -= years * 365; + const months = Math.floor(totalDays / 30); + const days = totalDays - (months * 30); + return {years, months, days} +} + +/** + * Print the supplied time + * @param years + * @param months + * @param days + */ +function printTimeSpent({years, months, days}) { + print(years + "\t" + months + "\t" + days + "\n"); +} + +/** + * Adjust unaccounted time by remove years, months and days supplied. + * @param {{years:number, months:number, days:number}} unaccountedTime + * @param {{years:number, months:number, days:number}} timeToRemove + */ +function adjustUnaccountedTime(unaccountedTime, timeToRemove) { + unaccountedTime.years -= timeToRemove.years; + unaccountedTime.months -= timeToRemove.months; + unaccountedTime.days -= timeToRemove.days; + if (unaccountedTime.days < 0) { + unaccountedTime.days += 30; + unaccountedTime.months--; } - if (k6 <= 0) { - k6 += 12; - k5--; + if (unaccountedTime.months <= 0) { + unaccountedTime.months += 12; + unaccountedTime.years--; } - print(i5 + "\t" + i6 + "\t" + i7 + "\n"); } function getDayOfWeek(dobYear, dobMonth, dobDayOfMonth) { @@ -210,32 +231,42 @@ async function main() print(" \tYEARS\tMONTHS\tDAYS\n"); print(" \t-----\t------\t----\n"); print("YOUR AGE (IF BIRTHDATE) \t" + yearsBetweenDates + "\t" + monthsBetweenDates + "\t" + daysBetweenDates + "\n"); - const a8 = (yearsBetweenDates * 365) + (monthsBetweenDates * 30) + daysBetweenDates + Math.floor(monthsBetweenDates / 2); - k5 = yearsBetweenDates; - k6 = monthsBetweenDates; - k7 = daysBetweenDates; - // Calculate retirement date. - const e = dobYear + 65; + const approximateDaysBetween = (yearsBetweenDates * 365) + (monthsBetweenDates * 30) + daysBetweenDates + Math.floor(monthsBetweenDates / 2); + // Create an object containing time unaccounted for + const unaccountedTime = {years: yearsBetweenDates, months: monthsBetweenDates, days: daysBetweenDates}; + // Calculate time spent in the following functions. print("YOU HAVE SLEPT \t\t\t"); - time_spent(0.35, a8); + const sleepTimeSpent = time_spent(0.35, approximateDaysBetween); + printTimeSpent(sleepTimeSpent); + + adjustUnaccountedTime(unaccountedTime, sleepTimeSpent); print("YOU HAVE EATEN \t\t\t"); - time_spent(0.17, a8); - if (k5 <= 3) { + const eatenTimeSpent = time_spent(0.17, approximateDaysBetween); + printTimeSpent(eatenTimeSpent); + + adjustUnaccountedTime(unaccountedTime, eatenTimeSpent); + if (unaccountedTime.years <= 3) { print("YOU HAVE PLAYED \t\t\t"); - } else if (k5 <= 9) { + } else if (unaccountedTime.years <= 9) { print("YOU HAVE PLAYED/STUDIED \t\t"); } else { print("YOU HAVE WORKED/PLAYED \t\t"); } - time_spent(0.23, a8); - if (k6 === 12) { - k5++; - k6 = 0; + const workPlayTimeSpent = time_spent(0.23, approximateDaysBetween); + printTimeSpent(workPlayTimeSpent); + + adjustUnaccountedTime(unaccountedTime, workPlayTimeSpent); + if (unaccountedTime.months === 12) { + unaccountedTime.years++; + unaccountedTime.months = 0; } - print("YOU HAVE RELAXED \t\t" + k5 + "\t" + k6 + "\t" + k7 + "\n"); + print("YOU HAVE RELAXED \t\t"); + printTimeSpent(unaccountedTime) + + const retirementYear = dobYear + 65; print("\n"); - print(tab(16) + "*** YOU MAY RETIRE IN " + e + " ***\n"); + print(tab(16) + "*** YOU MAY RETIRE IN " + retirementYear + " ***\n"); print("\n"); } } From 7cea1454bf0492832f8e9db4a1999e5a952e552b Mon Sep 17 00:00:00 2001 From: roygilliam <58305899+roygilliam@users.noreply.github.com> Date: Sun, 30 Jan 2022 12:44:24 -0500 Subject: [PATCH 278/337] Initial C# version of Weekday --- 95_Weekday/csharp/Program.cs | 203 +++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 95_Weekday/csharp/Program.cs diff --git a/95_Weekday/csharp/Program.cs b/95_Weekday/csharp/Program.cs new file mode 100644 index 00000000..d2e531bc --- /dev/null +++ b/95_Weekday/csharp/Program.cs @@ -0,0 +1,203 @@ +using System.Text; + +namespace Weekday +{ + class Weekday + { + private void DisplayIntro() + { + Console.WriteLine(""); + Console.WriteLine("SYNONYM".PadLeft(23)); + Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Console.WriteLine(""); + Console.WriteLine("Weekday is a computer demonstration that"); + Console.WriteLine("gives facts about a date of interest to you."); + Console.WriteLine(""); + } + + private bool ValidateDate(string InputDate, out DateTime ReturnDate) + { + // The expectation is that the input is in the format D,M,Y + // but any valid date format (other than with commas) will work + string DateString = InputDate.Replace(",", "/"); + + return (DateTime.TryParse(DateString, out ReturnDate)); + } + + private DateTime PromptForADate(string Prompt) + { + bool Success = false; + string LineInput = String.Empty; + DateTime TodaysDate = DateTime.MinValue; + + // Get the date for input and validate it + while (!Success) + { + Console.Write(Prompt); + LineInput = Console.ReadLine().Trim().ToLower(); + + Success = ValidateDate(LineInput, out TodaysDate); + + if (!Success) + { + Console.WriteLine("*** Invalid date. Please try again."); + Console.WriteLine(""); + } + } + + return TodaysDate; + } + + private void CalculateDateDiff(DateTime TodaysDate, DateTime BirthDate, Double Factor, out int AgeInYears, out int AgeInMonths, out int AgeInDays) + { + // leveraged Stack Overflow answer: https://stackoverflow.com/a/3055445 + + // Convert to number of days since Birth Date, multiple by factor then store as new FactorDate + TimeSpan TimeDiff = TodaysDate.Subtract(BirthDate); + Double NumberOfDays = TimeDiff.Days * Factor; + DateTime FactorDate = BirthDate.AddDays(NumberOfDays); + + // Compute difference between FactorDate (which is TodaysDate * Factor) and BirthDate + AgeInMonths = FactorDate.Month - BirthDate.Month; + AgeInYears = FactorDate.Year - BirthDate.Year; + + if (FactorDate.Day < BirthDate.Day) + { + AgeInMonths--; + } + + if (AgeInMonths < 0) + { + AgeInYears--; + AgeInMonths += 12; + } + + AgeInDays = (FactorDate - BirthDate.AddMonths((AgeInYears * 12) + AgeInMonths)).Days; + + } + + private void WriteColumnOutput(string Message, int Years, int Months, int Days) + { + + Console.WriteLine("{0,-25} {1,-10:N0} {2,-10:N0} {3,-10:N0}", Message, Years, Months, Days); + + } + + private void DisplayOutput(DateTime TodaysDate, DateTime BirthDate) + { + Console.WriteLine(""); + + // Not allowed to play if the current year is before 1582 + if (TodaysDate.Year < 1582) + { + Console.WriteLine("Not prepared to give day of week prior to MDLXXXII."); + return; + } + + // Share which day of the week the BirthDate was on + Console.Write(" {0} ", BirthDate.ToString("d")); + + string DateVerb = ""; + if (BirthDate.CompareTo(TodaysDate) < 0) + { + DateVerb = "was a "; + } + else if (BirthDate.CompareTo(TodaysDate) == 0) + { + DateVerb = "is a "; + } + else + { + DateVerb = "will be a "; + } + Console.Write("{0}", DateVerb); + + // Special warning if their birth date was on a Friday the 13th! + if (BirthDate.DayOfWeek.ToString().Equals("Friday") && BirthDate.Day == 13) + { + Console.WriteLine("{0} the Thirteenth---BEWARE", BirthDate.DayOfWeek.ToString()); + } + else + { + Console.WriteLine("{0}", BirthDate.DayOfWeek.ToString()); + } + + // If today's date is the same month & day as the birth date then wish them a happy birthday! + if (BirthDate.Month == TodaysDate.Month && BirthDate.Day == TodaysDate.Day) + { + Console.WriteLine(""); + Console.Write("***Happy Birthday***"); + } + + Console.WriteLine(""); + + // Only show the date calculations if BirthDate is before TodaysDate + if (DateVerb.Trim().Equals("was a")) + { + + Console.WriteLine("{0,-24} {1,-10} {2,-10} {3,-10}", " ", "Years", "Months", "Days"); + + int TheYears = 0, TheMonths = 0, TheDays = 0; + int FlexYears = 0, FlexMonths = 0, FlexDays = 0; + + CalculateDateDiff(TodaysDate, BirthDate, 1, out TheYears, out TheMonths, out TheDays); + WriteColumnOutput("Your age if birthdate", TheYears, TheMonths, TheDays); + + FlexYears = TheYears; + FlexMonths = TheMonths; + FlexDays = TheDays; + CalculateDateDiff(TodaysDate, BirthDate, .35, out FlexYears, out FlexMonths, out FlexDays); + WriteColumnOutput("You have slept", FlexYears, FlexMonths, FlexDays); + + FlexYears = TheYears; + FlexMonths = TheMonths; + FlexDays = TheDays; + CalculateDateDiff(TodaysDate, BirthDate, .17, out FlexYears, out FlexMonths, out FlexDays); + WriteColumnOutput("You have eaten", FlexYears, FlexMonths, FlexDays); + + FlexYears = TheYears; + FlexMonths = TheMonths; + FlexDays = TheDays; + CalculateDateDiff(TodaysDate, BirthDate, .23, out FlexYears, out FlexMonths, out FlexDays); + string FlexPhrase = "You have played"; + if (TheYears > 3) + FlexPhrase = "You have played/studied"; + if (TheYears > 9) + FlexPhrase = "You have worked/played"; + WriteColumnOutput(FlexPhrase, FlexYears, FlexMonths, FlexDays); + + FlexYears = TheYears; + FlexMonths = TheMonths; + FlexDays = TheDays; + CalculateDateDiff(TodaysDate, BirthDate, .25, out FlexYears, out FlexMonths, out FlexDays); + WriteColumnOutput("You have relaxed", FlexYears, FlexMonths, FlexDays); + + Console.WriteLine(""); + Console.WriteLine("* You may retire in {0} *".PadLeft(38), BirthDate.Year + 65); + } + } + + public void PlayTheGame() + { + DateTime TodaysDate = DateTime.MinValue; + DateTime BirthDate = DateTime.MinValue; + + DisplayIntro(); + + TodaysDate = PromptForADate("Enter today's date in the form: 3,24,1978 ? "); + BirthDate = PromptForADate("Enter day of birth (or other day of interest)? "); + + DisplayOutput(TodaysDate, BirthDate); + + } + } + class Program + { + static void Main(string[] args) + { + + new Weekday().PlayTheGame(); + + } + } +} \ No newline at end of file From cd3545199222ea77478ad53f31e6dd26ced418df Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Mon, 31 Jan 2022 00:14:03 +0000 Subject: [PATCH 279/337] 95 Workday - tidy up time calculation to make it more readable --- 95_Weekday/javascript/weekday.js | 145 +++++++++++++++---------------- 1 file changed, 72 insertions(+), 73 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index 2451f19b..f7e28758 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -3,51 +3,40 @@ // Converted from BASIC to Javascript by Oscar Toledo G. (nanochess) // -function print(str) -{ +function print(str) { document.getElementById("output").appendChild(document.createTextNode(str)); } -function input() -{ +function input() { return new Promise(function (resolve) { - const input_element = document.createElement("INPUT"); - - print("? "); - input_element.setAttribute("type", "text"); - input_element.setAttribute("length", "50"); - document.getElementById("output").appendChild(input_element); - input_element.focus(); - input_element.addEventListener("keydown", function (event) { - if (event.keyCode === 13) { - const input_str = input_element.value; - document.getElementById("output").removeChild(input_element); - print(input_str); - print("\n"); - resolve(input_str); - } - }); - }); + const input_element = document.createElement("INPUT"); + + print("? "); + input_element.setAttribute("type", "text"); + input_element.setAttribute("length", "50"); + document.getElementById("output").appendChild(input_element); + input_element.focus(); + input_element.addEventListener("keydown", function (event) { + if (event.keyCode === 13) { + const input_str = input_element.value; + document.getElementById("output").removeChild(input_element); + print(input_str); + print("\n"); + resolve(input_str); + } + }); + }); } -function tab(space) -{ +function tab(space) { let str = ""; while (space-- > 0) str += " "; return str; } -function fna(arg) { - return Math.floor(arg / 4); -} - -function fnb(arg) { - return Math.floor(arg / 7); -} - // in a non-leap year the day of the week for the first of each month moves by the following amounts. -const MONTHLY_DAY_OF_WEEK_OFFSETS = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; +const COMMON_YEAR_MONTH_OFFSET = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; /** * Reads a date, and extracts the date information. @@ -67,11 +56,11 @@ async function readDateElements() { * Returns a US formatted date, i.e. Month/Day/Year. * @param year * @param month - * @param dayOfMonth + * @param day * @returns {string} */ -function getFormattedDate(year, month, dayOfMonth) { - return month + "/" + dayOfMonth + "/" + year; +function getFormattedDate(year, month, day) { + return month + "/" + day + "/" + year; } /** @@ -81,8 +70,7 @@ function getFormattedDate(year, month, dayOfMonth) { * @param dayCount * @returns {{years: number, months: number, days: number}} */ -function time_spent(factor, dayCount) -{ +function time_spent(factor, dayCount) { let totalDays = Math.floor(factor * dayCount); const years = Math.floor(totalDays / 365); totalDays -= years * 365; @@ -120,30 +108,30 @@ function adjustUnaccountedTime(unaccountedTime, timeToRemove) { } } -function getDayOfWeek(dobYear, dobMonth, dobDayOfMonth) { - const i1 = Math.floor((dobYear - 1500) / 100); - let a = i1 * 5 + (i1 + 3) / 4; - const i2 = Math.floor(a - fnb(a) * 7); - const y2 = Math.floor(dobYear / 100); - const y3 = Math.floor(dobYear - y2 * 100); - a = y3 / 4 + y3 + dobDayOfMonth + MONTHLY_DAY_OF_WEEK_OFFSETS[dobMonth-1] + i2; - let dayOfWeek = Math.floor(a - fnb(a) * 7) + 1; - if (dobMonth <= 2) { - if (y3 !== 0) { - t1 = Math.floor(dobYear - fna(dobYear) * 4); - } else { - a = i1 - 1; - t1 = Math.floor(a - fna(a) * 4); - } - if (t1 === 0) { - if (dayOfWeek === 0) { - dayOfWeek = 6; - } - dayOfWeek--; - } +function isLeapYear(year) { + if ((year % 4) !== 0) { + return false; + } else if ((year % 100) !== 0) { + return true; + } else if ((year % 400) !== 0) { + return false; } - if (dayOfWeek === 0) { - dayOfWeek = 7; + return true; +} + +function getDayOfWeek(year, month, day) { + const centuriesSince1500 = Math.floor((year - 1500) / 100); + let centuryOffset = centuriesSince1500 * 5 + (centuriesSince1500 + 3) / 4; + centuryOffset = Math.floor(centuryOffset % 7); + // January 1st moves forward by approximately 1.25 days per year + const yearInCentury = year % 100; + const yearInCenturyOffsets = yearInCentury / 4 + yearInCentury; + + const a = yearInCenturyOffsets + day + COMMON_YEAR_MONTH_OFFSET[month-1] + centuryOffset; + + let dayOfWeek = Math.floor(a % 7) + 1; + if (month <= 2 && isLeapYear(year)) { + dayOfWeek--; } return dayOfWeek; } @@ -151,18 +139,17 @@ function getDayOfWeek(dobYear, dobMonth, dobDayOfMonth) { /** * The following performs a special hash on the day parts which guarantees * that different days will return different numbers, and the numbers returned are in ordered. - * @param todayYear - * @param todayMonth - * @param todayDayOfMonth + * @param year + * @param month + * @param day * @returns {*} */ -function getNormalisedDay(todayYear, todayMonth, todayDayOfMonth) { - return (todayYear * 12 + todayMonth) * 31 + todayDayOfMonth; +function getNormalisedDay(year, month, day) { + return (year * 12 + month) * 31 + day; } // Main control section -async function main() -{ +async function main() { print(tab(32) + "WEEKDAY\n"); print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"); print("\n"); @@ -197,11 +184,21 @@ async function main() print(getFormattedDate(dobYear, dobMonth, dobDayOfMonth) + " WAS A "); } switch (dayOfWeek) { - case 1: print("SUNDAY.\n"); break; - case 2: print("MONDAY.\n"); break; - case 3: print("TUESDAY.\n"); break; - case 4: print("WEDNESDAY.\n"); break; - case 5: print("THURSDAY.\n"); break; + case 1: + print("SUNDAY.\n"); + break; + case 2: + print("MONDAY.\n"); + break; + case 3: + print("TUESDAY.\n"); + break; + case 4: + print("WEDNESDAY.\n"); + break; + case 5: + print("THURSDAY.\n"); + break; case 6: if (dobDayOfMonth === 13) { print("FRIDAY THE THIRTEENTH---BEWARE!\n"); @@ -209,7 +206,9 @@ async function main() print("FRIDAY.\n"); } break; - case 7: print("SATURDAY.\n"); break; + case 7: + print("SATURDAY.\n"); + break; } if (normalisedToday !== normalisedDob) { let yearsBetweenDates = todayYear - dobYear; From 84615c1a753af6cbd75b73a51b3d9d860978d49d Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Mon, 31 Jan 2022 16:52:55 +0000 Subject: [PATCH 280/337] 95 Workday - tidy-up time calculation to make it more readable --- 95_Weekday/javascript/weekday.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index f7e28758..5adb74f4 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -119,6 +119,18 @@ function isLeapYear(year) { return true; } +/** + * Determine the day of the week. + * This calculation returns a number between 1 and 7 where Sunday=1, Monday=2, ..., Saturday=7. + * First it calculates a known date near the start of the century (defined as a year ending "00"). + * January 1st in "00" years is always one of: Saturday (years divisible by 400), Friday, Wednesday, or Monday. + * This is a combination of years being 52 weeks and either 1 (non-leap years) or 2 (leap years) days, + * and years ending "00" only being leap years if they are also divisible by 400. + * @param year + * @param month + * @param day + * @returns {number} Value between 1 and 7 representing Sunday to Saturday. + */ function getDayOfWeek(year, month, day) { const centuriesSince1500 = Math.floor((year - 1500) / 100); let centuryOffset = centuriesSince1500 * 5 + (centuriesSince1500 + 3) / 4; @@ -127,12 +139,14 @@ function getDayOfWeek(year, month, day) { const yearInCentury = year % 100; const yearInCenturyOffsets = yearInCentury / 4 + yearInCentury; - const a = yearInCenturyOffsets + day + COMMON_YEAR_MONTH_OFFSET[month-1] + centuryOffset; - - let dayOfWeek = Math.floor(a % 7) + 1; + let dayOfWeek = centuryOffset + yearInCenturyOffsets + day + COMMON_YEAR_MONTH_OFFSET[month-1]; + dayOfWeek = Math.floor(dayOfWeek % 7) + 1; if (month <= 2 && isLeapYear(year)) { dayOfWeek--; } + if (dayOfWeek === 0) { + dayOfWeek = 7; + } return dayOfWeek; } From 1f84184b92a27c7aef56d46c240fda4bfcefccbd Mon Sep 17 00:00:00 2001 From: Tom Wyant Date: Mon, 31 Jan 2022 15:28:40 -0500 Subject: [PATCH 281/337] Port 95_Weekday to Perl. --- 95_Weekday/perl/README.md | 17 +++ 95_Weekday/perl/weekday.pl | 249 +++++++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+) create mode 100755 95_Weekday/perl/weekday.pl diff --git a/95_Weekday/perl/README.md b/95_Weekday/perl/README.md index e69c8b81..ac8ee399 100644 --- a/95_Weekday/perl/README.md +++ b/95_Weekday/perl/README.md @@ -1,3 +1,20 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Perl](https://www.perl.org/) + +I have replaced the manual date logic with Perl built-ins to the extent +possible. Unfortunately the kind of date math involved in the "time +spent doing ..." functionality is not well-defined, so I have been +forced to retain the original logic here. Sigh. + +You can use any punctuation character you please in the date +input. So something like 2/29/2020 is perfectly acceptable. + +It would also have been nice to produce a localized version that +supports day/month/year or year-month-day input, but that didn't happen. + +Also nice would have been language-specific output -- especially if it +could have accommodated regional differences in which day of the week or +month is unlucky. + +Tom Wyant diff --git a/95_Weekday/perl/weekday.pl b/95_Weekday/perl/weekday.pl new file mode 100755 index 00000000..e1820af6 --- /dev/null +++ b/95_Weekday/perl/weekday.pl @@ -0,0 +1,249 @@ +#!/usr/bin/env perl + +use 5.010; # To get 'state' and 'say' + +use strict; # Require explicit declaration of variables +use warnings; # Enable optional compiler warnings + +use English; # Use more friendly names for Perl's magic variables +use Term::ReadLine; # Prompt and return user input +use Time::Local qw{ timelocal }; # date-time to epoch +# FIXME timelocal() is too smart for its own good in the interpretation +# of years, and caused a bunch of Y2020 problems in Perl code that used +# it. I believe that this script avoids these problems (which only occur +# if the year is less than 1000), but it is probably safer in general to +# use timelocal_modern() or timelocal_posix(). These are also exported +# by Time::Local, but only by versions 1.28 and 1.30 respectively. This +# means that they only come (by default) with Perl 5.30 and 5.34 +# respectively. Now, Time::Local is a dual-life module, meaning it can +# be upgraded from the version packaged with older Perls. But I did not +# want to assume that it HAD been upgraded. Caveat coder. +use Time::Piece; # O-O epoch to date-time, plus formatting + +our $VERSION = '0.000_01'; + +print <<'EOD'; + + WEEKDAY + Creative Computing Morristown, New Jersey + + + +WEEKDAY is a computer demonstration that +gives facts about a date of interest to you. + +EOD + +my $now = localtime; +my $default_date = join ',', map { $now->$_() } qw{ mon mday year }; + +my $today = get_date( + "Enter today's date in the form month,day,year (default: $default_date): ", + "Please enter month,day,year or return for default\n", + $default_date, +); + +my $birthday = get_date( + 'Ender day of birth (or other day of interest): ', + "Please enter month,day,year\n", +); + +say ''; +printf "%d/%d/%d %s a %s\n", $birthday->mon, $birthday->mday, + $birthday->year, tense( $today, $birthday), + ( $birthday->mday == 13 && $birthday->wday == 6 ) ? + $birthday->fullday . ' the thirteenth --- Beware!' : + $birthday->fullday . '.'; + +if ( $birthday->epoch <= $today->epoch ) { + + say '*** Happy Birthday! ***' + if $birthday->mon == $today->mon && + $birthday->mday == $today->mday; + + print <<'EOD'; + Years Months Days + ----- ------ ---- +EOD + + my @delta = map { $today->$_() - $birthday->$_() } qw{ year mon mday }; + if ( $delta[2] < 0 ) { + $delta[2] += 30; + $delta[1] -= 1; + } + if ( $delta[1] < 0 ) { + $delta[1] += 12; + $delta[0] -= 1; + } + my @residue = @delta; + + my $delta_days = 365 * $delta[0] + 30 * $delta[1] + $delta[2]; + + display_ymd( 'Your age (if birthdate)', compute_ymd( $delta_days ) ); + display_ymd( 'You have slept', compute_ymd( $delta_days, 0.35, + \@residue ) ); + display_ymd( 'You have eaten', compute_ymd( $delta_days, 0.17, + \@residue ) ); + display_ymd( + $residue[0] > 9 ? 'You have worked/played' : + $residue[0] > 3 ? 'You have played/studied' : + 'You have played', + compute_ymd( $delta_days, 0.23, + \@residue ) ); + display_ymd( 'You have relaxed', \@residue ); + + say ''; + say "\t\t*** You may retire in @{[ $birthday->year + 65 ]} ***"; +} + +say ''; + +sub compute_ymd { + my ( $delta_days, $fract, $residue ) = @ARG; + my $days = defined $fract ? int ( $delta_days * $fract ) : $delta_days; + my $years = int( $days / 365 ); + $days -= $years * 365; + my $months = int( $days / 30 ); + $days -= $months * 30; + + if ( $residue ) { + $residue->[2] -= $days; + if ( $residue->[2] < 0 ) { + $residue->[2] += 30; + $residue->[1] -= 1; + } + $residue->[1] -= $months; + if ( $residue->[1] < 0 ) { + $residue->[1] += 12; + $residue->[0] -= 1; + } + $residue->[0] -= $years; + } + + return [ $years, $months, $days ]; +} + +sub display_ymd { + my ( $label, $ymd ) = @ARG; + printf "%-24s%4d%6d%8d\n", $label, @{ $ymd }; + return; +} + +sub get_date { + my ( $prompt, $warning, $default ) = @ARG; + my ( $month, $day, $year ) = split qr< [[:punct:]] >smx, get_input( + $prompt, + sub { + return 0 unless m/ \A (?: [0-9]+ [[:punct:]] ){2} ( [0-9]+ ) \z /smx; + return 1 if $1 >= 1582; + warn "Not prepared to give day of week prior to MDLXXXII.\n"; + return 0; + }, + $warning, + $default, + ); + return localtime timelocal( 0, 0, 0, $day, $month - 1, $year ); +} + +sub tense { + my ( $today, $birthday ) = @ARG; + my $cmp = $birthday->epoch <=> $today->epoch + or return 'is'; + return $cmp < 0 ? 'was' : 'will be'; +} + +# Get input from the user. The arguments are: +# * The prompt +# * A reference to validation code. This code receives the response in +# $ARG and returns true for a valid response. +# * A warning to print if the response is not valid. This must end in a +# return. +# * A default to return if the user simply presses . +# The first valid response is returned. An end-of-file terminates the +# script. +sub get_input { + my ( $prompt, $validate, $warning, $default ) = @ARG; + + # If no validator is passed, default to one that always returns + # true. + $validate ||= sub { 1 }; + + # Create the readline object. The 'state' causes the variable to be + # initialized only once, no matter how many times this subroutine is + # called. The do { ... } is a compound statement used because we + # need to tweak the created object before we store it. + state $term = do { + my $obj = Term::ReadLine->new( 'reverse' ); + $obj->ornaments( 0 ); + $obj; + }; + + while ( 1 ) { # Iterate indefinitely + + # Read the input into the topic variable, localized to prevent + # Spooky Action at a Distance. We exit on undef, which signals + # end-of-file. + exit unless defined( local $ARG = $term->readline( $prompt ) ); + + # Return the default if it exists AND we got an empty line + return $default if defined( $default ) && $ARG eq ''; + + # Return the input if it is valid. + return $ARG if $validate->(); + + # Issue the warning, and go around the merry-go-round again. + warn $warning; + } +} + +__END__ + +=head1 TITLE + +weekday - Play the game 'Weekday' from Basic Computer Games + +=head1 SYNOPSIS + + weekday.pl + +=head1 DETAILS + +This Perl script is a port of weekday.bas, which is the 95th entry in +Basic Computer Games. + +I have replaced the manual date logic with Perl built-ins to the extent +possible. Unfortunately the kind of date math involved in the "time +spent doing ..." functionality is not well-defined, so I have been +forced to retain the original logic here. Sigh. + +You can use any punctuation character you please in the date +input. So something like 2/29/2020 is perfectly acceptable. + +It would also have been nice to produce a localized version that +supports day/month/year or year-month-day input, but that didn't happen. + +Also nice would have been language-specific output -- especially if it +could have accommodated regional differences in which day of the week or +month is unlucky. + +=head1 PORTED BY + +Thomas R. Wyant, III F + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2022 by Thomas R. Wyant, III + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl 5.10.0. For more details, see the Artistic +License 1.0 at +L, and/or the +Gnu GPL at L. + +This program is distributed in the hope that it will be useful, but +without any warranty; without even the implied warranty of +merchantability or fitness for a particular purpose. + +=cut + +# ex: set expandtab tabstop=4 textwidth=72 : From 8a694ee30f76ac264e2527f1153f35521e9cc5e3 Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Tue, 1 Feb 2022 00:08:34 +0000 Subject: [PATCH 282/337] 95 Weekday - introduce classes for durations and dates --- 95_Weekday/javascript/weekday.js | 271 ++++++++++++++++++++----------- 1 file changed, 175 insertions(+), 96 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index 5adb74f4..6feeda2e 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -35,32 +35,66 @@ function tab(space) { return str; } -// in a non-leap year the day of the week for the first of each month moves by the following amounts. +class DateStruct { + year; + month; + day; + + /** + * Build a DateStruct + * @param {number} year + * @param {number} month + * @param {number} day + */ + constructor(year, month, day) { + this.year = year; + this.month = month; + this.day = day; + } +} + +class Duration { + years; + months; + days; + + /** + * Build a Duration + * @param {number} years + * @param {number} months + * @param {number} days + */ + constructor(years, months, days) { + this.years = years; + this.months = months; + this.days = days; + } +} + +// In a common (non-leap) year the day of the week for the first of each month moves by the following amounts. const COMMON_YEAR_MONTH_OFFSET = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; /** * Reads a date, and extracts the date information. * This expects date parts to be comma separated, using US date ordering, * i.e. Month,Day,Year. - * @returns {Promise<[number,number,number]>} [year, month, dayOfMonth] + * @returns {Promise<{year: number, month: number, day: number}>} */ async function readDateElements() { let dateString = await input(); const month = parseInt(dateString); - const dayOfMonth = parseInt(dateString.substr(dateString.indexOf(",") + 1)); + const day = parseInt(dateString.substr(dateString.indexOf(",") + 1)); const year = parseInt(dateString.substr(dateString.lastIndexOf(",") + 1)); - return [year, month, dayOfMonth]; + return {year, month, day}; } /** * Returns a US formatted date, i.e. Month/Day/Year. - * @param year - * @param month - * @param day + * @param {DateStruct} date * @returns {string} */ -function getFormattedDate(year, month, day) { - return month + "/" + day + "/" + year; +function getFormattedDate(date) { + return date.month + "/" + date.day + "/" + date.year; } /** @@ -68,7 +102,7 @@ function getFormattedDate(year, month, day) { * This is a naive calculation which assumes all months are 30 days. * @param factor * @param dayCount - * @returns {{years: number, months: number, days: number}} + * @returns {Duration} */ function time_spent(factor, dayCount) { let totalDays = Math.floor(factor * dayCount); @@ -76,23 +110,21 @@ function time_spent(factor, dayCount) { totalDays -= years * 365; const months = Math.floor(totalDays / 30); const days = totalDays - (months * 30); - return {years, months, days} + return new Duration(years, months, days); } /** - * Print the supplied time - * @param years - * @param months - * @param days + * Print the supplied duration. + * @param {Duration} duration */ -function printTimeSpent({years, months, days}) { - print(years + "\t" + months + "\t" + days + "\n"); +function printTimeSpent(duration) { + print(duration.years + "\t" + duration.months + "\t" + duration.days + "\n"); } /** * Adjust unaccounted time by remove years, months and days supplied. - * @param {{years:number, months:number, days:number}} unaccountedTime - * @param {{years:number, months:number, days:number}} timeToRemove + * @param {Duration} unaccountedTime + * @param {Duration} timeToRemove */ function adjustUnaccountedTime(unaccountedTime, timeToRemove) { unaccountedTime.years -= timeToRemove.years; @@ -108,6 +140,11 @@ function adjustUnaccountedTime(unaccountedTime, timeToRemove) { } } +/** + * Determine if the given year is a leap year. + * @param year + * @returns {boolean} + */ function isLeapYear(year) { if ((year % 4) !== 0) { return false; @@ -122,26 +159,25 @@ function isLeapYear(year) { /** * Determine the day of the week. * This calculation returns a number between 1 and 7 where Sunday=1, Monday=2, ..., Saturday=7. - * First it calculates a known date near the start of the century (defined as a year ending "00"). - * January 1st in "00" years is always one of: Saturday (years divisible by 400), Friday, Wednesday, or Monday. - * This is a combination of years being 52 weeks and either 1 (non-leap years) or 2 (leap years) days, - * and years ending "00" only being leap years if they are also divisible by 400. - * @param year - * @param month - * @param day + * @param {DateStruct} date * @returns {number} Value between 1 and 7 representing Sunday to Saturday. */ -function getDayOfWeek(year, month, day) { - const centuriesSince1500 = Math.floor((year - 1500) / 100); +function getDayOfWeek(date) { + // Calculate an offset based on the century part of the year. + const centuriesSince1500 = Math.floor((date.year - 1500) / 100); let centuryOffset = centuriesSince1500 * 5 + (centuriesSince1500 + 3) / 4; centuryOffset = Math.floor(centuryOffset % 7); + + // Calculate an offset based on the shortened two digit year. // January 1st moves forward by approximately 1.25 days per year - const yearInCentury = year % 100; + const yearInCentury = date.year % 100; const yearInCenturyOffsets = yearInCentury / 4 + yearInCentury; - let dayOfWeek = centuryOffset + yearInCenturyOffsets + day + COMMON_YEAR_MONTH_OFFSET[month-1]; + // combine offsets with day and month + let dayOfWeek = centuryOffset + yearInCenturyOffsets + date.day + COMMON_YEAR_MONTH_OFFSET[date.month-1]; + dayOfWeek = Math.floor(dayOfWeek % 7) + 1; - if (month <= 2 && isLeapYear(year)) { + if (date.month <= 2 && isLeapYear(date.year)) { dayOfWeek--; } if (dayOfWeek === 0) { @@ -151,15 +187,95 @@ function getDayOfWeek(year, month, day) { } /** - * The following performs a special hash on the day parts which guarantees - * that different days will return different numbers, and the numbers returned are in ordered. - * @param year - * @param month - * @param day - * @returns {*} + * Obtain text for the day of the week. + * @param {DateStruct} date + * @returns {string} */ -function getNormalisedDay(year, month, day) { - return (year * 12 + month) * 31 + day; +function getDayOfWeekText(date) { + const dayOfWeek = getDayOfWeek(date); + let dayOfWeekText = ""; + switch (dayOfWeek) { + case 1: + dayOfWeekText = "SUNDAY."; + break; + case 2: + dayOfWeekText = "MONDAY."; + break; + case 3: + dayOfWeekText = "TUESDAY."; + break; + case 4: + dayOfWeekText = "WEDNESDAY."; + break; + case 5: + dayOfWeekText = "THURSDAY."; + break; + case 6: + if (date.day === 13) { + dayOfWeekText = "FRIDAY THE THIRTEENTH---BEWARE!"; + } else { + dayOfWeekText = "FRIDAY."; + } + break; + case 7: + dayOfWeekText = "SATURDAY."; + break; + } + return dayOfWeekText; +} + +/** + * The following performs a hash on the day parts which guarantees that + * 1. different days will return different numbers + * 2. the numbers returned are ordered. + * @param {DateStruct} date + * @returns {number} + */ +function getNormalisedDay(date) { + return (date.year * 12 + date.month) * 31 + date.day; +} + +/** + * Determine approximate difference between two dates. + * This is a naive calculation which assumes all months are 30 days. + * @param {DateStruct} date1 + * @param {DateStruct} date2 + * @returns {Duration} + */ +function difference(date1, date2) { + let years = date1.year - date2.year; + let months = date1.month - date2.month; + let days = date1.day - date2.day; + if (days < 0) { + months--; + days += 30; + } + if (months < 0) { + years--; + months += 12; + } + return new Duration(years, months, days); +} + +/** + * Determine if the supplied date could be a Gregorian date. + * Be aware the Gregorian calendar was not introduced in all places at once, + * see https://en.wikipedia.org/wiki/Gregorian_calendar + * @param {DateStruct} date + * @returns {boolean} true if date could be Gregorian; otherwise false. + */ +function isGregorianDate(date) { + let result = false; + if (date.year > 1582) { + result = true; + } else if (date.year === 1582) { + if (date.month > 10) { + result = true; + } else if (date.month === 10 && date.day >= 15) { + result = true; + } + } + return result; } // Main control section @@ -173,80 +289,43 @@ async function main() { print("GIVES FACTS ABOUT A DATE OF INTEREST TO YOU.\n"); print("\n"); print("ENTER TODAY'S DATE IN THE FORM: 3,24,1979 "); - const [todayYear, todayMonth, todayDayOfMonth] = await readDateElements(); + const today = await readDateElements(); // This program determines the day of the week // for a date after 1582 print("ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST)"); - const [dobYear, dobMonth, dobDayOfMonth] = await readDateElements(); + const dateOfBirth = await readDateElements(); print("\n"); // Test for date before current calendar. - // Note: this test is unreliable - the Gregorian calendar was introduced on Friday 15 October 1582 - // and the weekday algorithm fails for dates prior to that - if (dobYear - 1582 < 0) { - print("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII.\n"); + if (!isGregorianDate(dateOfBirth)) { + print("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO X.XV.MDLXXXII.\n"); } else { - const dayOfWeek = getDayOfWeek(dobYear, dobMonth, dobDayOfMonth); - - const normalisedToday = getNormalisedDay(todayYear, todayMonth, todayDayOfMonth); - const normalisedDob = getNormalisedDay(dobYear, dobMonth, dobDayOfMonth); + const normalisedToday = getNormalisedDay(today); + const normalisedDob = getNormalisedDay(dateOfBirth); + const dateOfBirthText = getFormattedDate(dateOfBirth); + let dayOfWeekText = getDayOfWeekText(dateOfBirth); if (normalisedToday < normalisedDob) { - print(getFormattedDate(dobYear, dobMonth, dobDayOfMonth) + " WILL BE A "); + print(dateOfBirthText + " WILL BE A " + dayOfWeekText + "\n"); } else if (normalisedToday === normalisedDob) { - print(getFormattedDate(dobYear, dobMonth, dobDayOfMonth) + " IS A "); + print(dateOfBirthText + " IS A " + dayOfWeekText + "\n"); } else { - print(getFormattedDate(dobYear, dobMonth, dobDayOfMonth) + " WAS A "); - } - switch (dayOfWeek) { - case 1: - print("SUNDAY.\n"); - break; - case 2: - print("MONDAY.\n"); - break; - case 3: - print("TUESDAY.\n"); - break; - case 4: - print("WEDNESDAY.\n"); - break; - case 5: - print("THURSDAY.\n"); - break; - case 6: - if (dobDayOfMonth === 13) { - print("FRIDAY THE THIRTEENTH---BEWARE!\n"); - } else { - print("FRIDAY.\n"); - } - break; - case 7: - print("SATURDAY.\n"); - break; + print(dateOfBirthText + " WAS A " + dayOfWeekText + "\n"); } + if (normalisedToday !== normalisedDob) { - let yearsBetweenDates = todayYear - dobYear; print("\n"); - let monthsBetweenDates = todayMonth - dobMonth; - let daysBetweenDates = todayDayOfMonth - dobDayOfMonth; - if (daysBetweenDates < 0) { - monthsBetweenDates--; - daysBetweenDates += 30; - } - if (monthsBetweenDates < 0) { - yearsBetweenDates--; - monthsBetweenDates += 12; - } - if (yearsBetweenDates >= 0) { - if (daysBetweenDates === 0 && monthsBetweenDates === 0) { + let differenceBetweenDates = difference(today, dateOfBirth); + if (differenceBetweenDates.years >= 0) { + if (differenceBetweenDates.days === 0 && differenceBetweenDates.months === 0) { print("***HAPPY BIRTHDAY***\n"); } print(" \tYEARS\tMONTHS\tDAYS\n"); print(" \t-----\t------\t----\n"); - print("YOUR AGE (IF BIRTHDATE) \t" + yearsBetweenDates + "\t" + monthsBetweenDates + "\t" + daysBetweenDates + "\n"); - const approximateDaysBetween = (yearsBetweenDates * 365) + (monthsBetweenDates * 30) + daysBetweenDates + Math.floor(monthsBetweenDates / 2); + print("YOUR AGE (IF BIRTHDATE) \t"); + printTimeSpent(differenceBetweenDates); + const approximateDaysBetween = (differenceBetweenDates.years * 365) + (differenceBetweenDates.months * 30) + differenceBetweenDates.days + Math.floor(differenceBetweenDates.months / 2); // Create an object containing time unaccounted for - const unaccountedTime = {years: yearsBetweenDates, months: monthsBetweenDates, days: daysBetweenDates}; + const unaccountedTime = {...differenceBetweenDates}; // Calculate time spent in the following functions. print("YOU HAVE SLEPT \t\t\t"); @@ -277,7 +356,7 @@ async function main() { print("YOU HAVE RELAXED \t\t"); printTimeSpent(unaccountedTime) - const retirementYear = dobYear + 65; + const retirementYear = dateOfBirth.year + 65; print("\n"); print(tab(16) + "*** YOU MAY RETIRE IN " + retirementYear + " ***\n"); print("\n"); From 8e9ed09ce3b00426712f4a6e7c9f804d40dc4a7f Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Tue, 1 Feb 2022 00:10:47 +0000 Subject: [PATCH 283/337] 95 Weekday - introduce classes for durations and dates --- 95_Weekday/javascript/weekday.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index 6feeda2e..ec2386d0 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -78,14 +78,14 @@ const COMMON_YEAR_MONTH_OFFSET = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; * Reads a date, and extracts the date information. * This expects date parts to be comma separated, using US date ordering, * i.e. Month,Day,Year. - * @returns {Promise<{year: number, month: number, day: number}>} + * @returns {Promise} */ async function readDateElements() { let dateString = await input(); const month = parseInt(dateString); const day = parseInt(dateString.substr(dateString.indexOf(",") + 1)); const year = parseInt(dateString.substr(dateString.lastIndexOf(",") + 1)); - return {year, month, day}; + return new DateStruct(year, month, day); } /** From d976d8297412d55f999c2e65c97f61f243052f0e Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Wed, 2 Feb 2022 14:30:04 +0000 Subject: [PATCH 284/337] Create build.yml --- .github/workflows/build.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..d371424b --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,17 @@ +name: Java CI + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + - name: Build with Maven + run: mvn --batch-mode --update-snapshots verify From 6311b6a7854854f7033bf741d6ab3dcf64a4ffb3 Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Wed, 2 Feb 2022 14:33:25 +0000 Subject: [PATCH 285/337] Revert "Create build.yml" This reverts commit d976d8297412d55f999c2e65c97f61f243052f0e. --- .github/workflows/build.yml | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index d371424b..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Java CI - -on: [push] - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn --batch-mode --update-snapshots verify From 0434ac8fd404eea517ed314e7e43907202fde91d Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Wed, 2 Feb 2022 23:11:27 +0000 Subject: [PATCH 286/337] 95 Weekday - move date functions into DateStruct --- 95_Weekday/javascript/weekday.js | 62 ++++++++++++++++---------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index ec2386d0..2e1129a0 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -51,6 +51,34 @@ class DateStruct { this.month = month; this.day = day; } + + /** + * Determine if the date could be a Gregorian date. + * Be aware the Gregorian calendar was not introduced in all places at once, + * see https://en.wikipedia.org/wiki/Gregorian_calendar + * @returns {boolean} true if date could be Gregorian; otherwise false. + */ + isGregorianDate() { + let result = false; + if (this.year > 1582) { + result = true; + } else if (this.year === 1582) { + if (this.month > 10) { + result = true; + } else if (this.month === 10 && this.day >= 15) { + result = true; + } + } + return result; + } + + /** + * Returns a US formatted date, i.e. Month/Day/Year. + * @returns {string} + */ + getFormattedDate() { + return this.month + "/" + this.day + "/" + this.year; + } } class Duration { @@ -88,15 +116,6 @@ async function readDateElements() { return new DateStruct(year, month, day); } -/** - * Returns a US formatted date, i.e. Month/Day/Year. - * @param {DateStruct} date - * @returns {string} - */ -function getFormattedDate(date) { - return date.month + "/" + date.day + "/" + date.year; -} - /** * Calculate years, months and days as factor of days. * This is a naive calculation which assumes all months are 30 days. @@ -257,27 +276,6 @@ function difference(date1, date2) { return new Duration(years, months, days); } -/** - * Determine if the supplied date could be a Gregorian date. - * Be aware the Gregorian calendar was not introduced in all places at once, - * see https://en.wikipedia.org/wiki/Gregorian_calendar - * @param {DateStruct} date - * @returns {boolean} true if date could be Gregorian; otherwise false. - */ -function isGregorianDate(date) { - let result = false; - if (date.year > 1582) { - result = true; - } else if (date.year === 1582) { - if (date.month > 10) { - result = true; - } else if (date.month === 10 && date.day >= 15) { - result = true; - } - } - return result; -} - // Main control section async function main() { print(tab(32) + "WEEKDAY\n"); @@ -296,13 +294,13 @@ async function main() { const dateOfBirth = await readDateElements(); print("\n"); // Test for date before current calendar. - if (!isGregorianDate(dateOfBirth)) { + if (!dateOfBirth.isGregorianDate()) { print("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO X.XV.MDLXXXII.\n"); } else { const normalisedToday = getNormalisedDay(today); const normalisedDob = getNormalisedDay(dateOfBirth); - const dateOfBirthText = getFormattedDate(dateOfBirth); + const dateOfBirthText = dateOfBirth.getFormattedDate(); let dayOfWeekText = getDayOfWeekText(dateOfBirth); if (normalisedToday < normalisedDob) { print(dateOfBirthText + " WILL BE A " + dayOfWeekText + "\n"); From 5f4e40e733f32c29129ce37f96a72e8a5a8123ca Mon Sep 17 00:00:00 2001 From: Aldrin Misquitta Date: Thu, 3 Feb 2022 15:57:20 +0000 Subject: [PATCH 287/337] Port of 83 Stockmarket to Java --- 83_Stock_Market/java/StockMarket.java | 426 ++++++++++++++++++++++++++ 1 file changed, 426 insertions(+) create mode 100644 83_Stock_Market/java/StockMarket.java diff --git a/83_Stock_Market/java/StockMarket.java b/83_Stock_Market/java/StockMarket.java new file mode 100644 index 00000000..142f6fb6 --- /dev/null +++ b/83_Stock_Market/java/StockMarket.java @@ -0,0 +1,426 @@ +import java.util.ArrayList; +import java.util.InputMismatchException; +import java.util.List; +import java.util.Random; +import java.util.Scanner; + +/** + * Stock Market Simulation + * + * Some of the original program's variables' documentation and their equivalent in this program: + * A-MRKT TRND SLP; marketTrendSlope + * B5-BRKRGE FEE; brokerageFee + * C-TTL CSH ASSTS; cashAssets + * C5-TTL CSH ASSTS (TEMP); tmpCashAssets + * C(I)-CHNG IN STK VAL; changeStockValue + * D-TTL ASSTS; assets + * E1,E2-LRG CHNG MISC; largeChange1, largeChange2 + * I1,I2-STCKS W LRG CHNG; randomStockIndex1, randomStockIndex2 + * N1,N2-LRG CHNG DAY CNTS; largeChangeNumberDays1, largeChangeNumberDays2 + * P5-TTL DAYS PRCHSS; totalDaysPurchases + * P(I)-PRTFL CNTNTS; portfolioContents + * Q9-NEW CYCL?; newCycle + * S4-SGN OF A; slopeSign + * S5-TTL DYS SLS; totalDaysSales + * S(I)-VALUE/SHR; stockValue + * T-TTL STCK ASSTS; totalStockAssets + * T5-TTL VAL OF TRNSCTNS; totalValueOfTransactions + * W3-LRG CHNG; bigChange + * X1-SMLL CHNG(<$1); smallChange + * Z4,Z5,Z6-NYSE AVE.; tmpNyseAverage, nyseAverage, nyseAverageChange + * Z(I)-TRNSCT transactionQuantity + * + * new price = old price + (trend x old price) + (small random price + * change) + (possible large price change) + * + * Converted from BASIC to Java by Aldrin Misquitta (@aldrinm) + */ +public class StockMarket { + + private static final Random random = new Random(); + + public static void main(String[] args) { + + Scanner scan = new Scanner(System.in); + + printIntro(); + printGameHelp(scan); + + final List stocks = initStocks(); + + double marketTrendSlope = Math.floor((random.nextFloat() / 10) * 100 + 0.5)/100f; + double totalValueOfTransactions; + int largeChangeNumberDays1 = 0; + int largeChangeNumberDays2 = 0; + + //DAYS FOR FIRST TREND SLOPE (A) + var t8 = randomNumber(1, 6); + + //RANDOMIZE SIGN OF FIRST TREND SLOPE (A) + if (random.nextFloat() <= 0.5) { + marketTrendSlope = -marketTrendSlope; + } + + // INITIALIZE CASH ASSETS:C + double cashAssets = 10000; + boolean largeChange1 = false; + boolean largeChange2 = false; + double tmpNyseAverage; + double nyseAverage = 0; + boolean inProgress = true; + var firstRound = true; + + while (inProgress) { + + /* Original documentation: + RANDOMLY PRODUCE NEW STOCK VALUES BASED ON PREVIOUS DAY'S VALUES + N1,N2 ARE RANDOM NUMBERS OF DAYS WHICH RESPECTIVELY + DETERMINE WHEN STOCK I1 WILL INCREASE 10 PTS. AND STOCK + I2 WILL DECREASE 10 PTS. + IF N1 DAYS HAVE PASSED, PICK AN I1, SET E1, DETERMINE NEW N1 + */ + int randomStockIndex1 = 0; + int randomStockIndex2 = 0; + + if (largeChangeNumberDays1 <= 0) { + randomStockIndex1 = randomNumber(0, stocks.size()); + largeChangeNumberDays1 = randomNumber(1, 6); + largeChange1 = true; + } + if (largeChangeNumberDays2 <= 0) { + randomStockIndex2 = randomNumber(0, stocks.size()); + largeChangeNumberDays2 = randomNumber(1, 6); + largeChange2 = true; + } + adjustAllStockValues(stocks, largeChange1, largeChange2, marketTrendSlope, stocks.get(randomStockIndex1), stocks.get(randomStockIndex2)); + + //reset largeChange flags + largeChange1 = false; + largeChange2 = false; + largeChangeNumberDays1--; + largeChangeNumberDays2--; + + //AFTER T8 DAYS RANDOMLY CHANGE TREND SIGN AND SLOPE + t8 = t8 - 1; + if (t8 < 1) { + marketTrendSlope = newMarketTrendSlope(); + t8 = randomNumber(1, 6); + } + + //PRINT PORTFOLIO + printPortfolio(firstRound, stocks); + + tmpNyseAverage = nyseAverage; + nyseAverage = 0; + double totalStockAssets = 0; + for (Stock stock : stocks) { + nyseAverage = nyseAverage + stock.getStockValue(); + totalStockAssets = totalStockAssets + stock.getStockValue() * stock.getPortfolioContents(); + } + nyseAverage = Math.floor(100 * (nyseAverage / 5) + .5) / 100f; + double nyseAverageChange = Math.floor((nyseAverage - tmpNyseAverage) * 100 + .5) / 100f; + + // TOTAL ASSETS:D + double assets = totalStockAssets + cashAssets; + if (firstRound) { + System.out.printf("\n\nNEW YORK STOCK EXCHANGE AVERAGE: %.2f", nyseAverage); + } else { + System.out.printf("\n\nNEW YORK STOCK EXCHANGE AVERAGE: %.2f NET CHANGE %.2f", nyseAverage, nyseAverageChange); + } + + totalStockAssets = Math.floor(100 * totalStockAssets + 0.5) / 100d; + System.out.printf("\n\nTOTAL STOCK ASSETS ARE $ %.2f", totalStockAssets); + cashAssets = Math.floor(100 * cashAssets + 0.5) / 100d; + System.out.printf("\nTOTAL CASH ASSETS ARE $ %.2f", cashAssets); + assets = Math.floor(100 * assets + .5) / 100d; + System.out.printf("\nTOTAL ASSETS ARE $ %.2f\n", assets); + + if (!firstRound) { + System.out.print("\nDO YOU WISH TO CONTINUE (YES-TYPE 1, NO-TYPE 0)? "); + var newCycle = readANumber(scan); + if (newCycle < 1) { + System.out.println("HOPE YOU HAD FUN!!"); + inProgress = false; + } + } + + if (inProgress) { + boolean validTransaction = false; + // TOTAL DAY'S PURCHASES IN $:P5 + double totalDaysPurchases = 0; + // TOTAL DAY'S SALES IN $:S5 + double totalDaysSales = 0; + double tmpCashAssets; + while (!validTransaction) { + //INPUT TRANSACTIONS + readStockTransactions(stocks, scan); + totalDaysPurchases = 0; + totalDaysSales = 0; + + validTransaction = true; + for (Stock stock : stocks) { + stock.setTransactionQuantity(Math.floor(stock.getTransactionQuantity() + 0.5)); + if (stock.getTransactionQuantity() > 0) { + totalDaysPurchases = totalDaysPurchases + stock.getTransactionQuantity() * stock.getStockValue(); + } else { + totalDaysSales = totalDaysSales - stock.getTransactionQuantity() * stock.getStockValue(); + if (-stock.getTransactionQuantity() > stock.getPortfolioContents()) { + System.out.println("YOU HAVE OVERSOLD A STOCK; TRY AGAIN."); + validTransaction = false; + break; + } + } + } + + //TOTAL VALUE OF TRANSACTIONS:T5 + totalValueOfTransactions = totalDaysPurchases + totalDaysSales; + // BROKERAGE FEE:B5 + var brokerageFee = Math.floor(0.01 * totalValueOfTransactions * 100 + .5) / 100d; + // CASH ASSETS=OLD CASH ASSETS-TOTAL PURCHASES + //-BROKERAGE FEES+TOTAL SALES:C5 + tmpCashAssets = cashAssets - totalDaysPurchases - brokerageFee + totalDaysSales; + if (tmpCashAssets < 0) { + System.out.printf("\nYOU HAVE USED $%.2f MORE THAN YOU HAVE.", -tmpCashAssets); + validTransaction = false; + } else { + cashAssets = tmpCashAssets; + } + } + + // CALCULATE NEW PORTFOLIO + for (Stock stock : stocks) { + stock.setPortfolioContents(stock.getPortfolioContents() + stock.getTransactionQuantity()); + } + + firstRound = false; + } + + } + } + + /** + * Random int between lowerBound(inclusive) and upperBound(exclusive) + */ + private static int randomNumber(int lowerBound, int upperBound) { + return random.nextInt((upperBound - lowerBound)) + lowerBound; + } + + private static double newMarketTrendSlope() { + return randomlyChangeTrendSignAndSlopeAndDuration(); + } + + private static void printPortfolio(boolean firstRound, List stocks) { + //BELL RINGING-DIFFERENT ON MANY COMPUTERS + if (firstRound) { + System.out.printf("%n%-30s\t%12s\t%12s", "STOCK", "INITIALS", "PRICE/SHARE"); + for (Stock stock : stocks) { + System.out.printf("%n%-30s\t%12s\t%12.2f ------ %12.2f", stock.getStockName(), stock.getStockCode(), + stock.getStockValue(), stock.getChangeStockValue()); + } + System.out.println(""); + } else { + System.out.println("\n********** END OF DAY'S TRADING **********\n\n"); + System.out.printf("%n%-12s\t%-12s\t%-12s\t%-12s\t%-20s", "STOCK", "PRICE/SHARE", + "HOLDINGS", "VALUE", "NET PRICE CHANGE"); + for (Stock stock : stocks) { + System.out.printf("%n%-12s\t%-12.2f\t%-12.0f\t%-12.2f\t%-20.2f", + stock.getStockCode(), stock.getStockValue(), stock.getPortfolioContents(), + stock.getStockValue() * stock.getPortfolioContents(), stock.getChangeStockValue()); + } + } + } + + private static void readStockTransactions(List stocks, Scanner scan) { + System.out.println("\n\nWHAT IS YOUR TRANSACTION IN"); + for (Stock stock : stocks) { + System.out.printf("%s? ", stock.getStockCode()); + + stock.setTransactionQuantity(readANumber(scan)); + } + } + + private static int readANumber(Scanner scan) { + int choice = 0; + + boolean validInput = false; + while (!validInput) { + try { + choice = scan.nextInt(); + validInput = true; + } catch (InputMismatchException ex) { + System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE"); + } finally { + scan.nextLine(); + } + } + + return choice; + } + + private static void adjustAllStockValues(List stocks, boolean largeChange1, + boolean largeChange2, + double marketTrendSlope, + Stock stockForLargeChange1, Stock stockForLargeChange2 + ) { + //LOOP THROUGH ALL STOCKS + for (Stock stock : stocks) { + double smallChange = random.nextFloat(); + + if (smallChange <= 0.25) { + smallChange = 0.25; + } else if (smallChange <= 0.5) { + smallChange = 0.5; + } else if (smallChange <= 0.75) { + smallChange = 0.75; + } else { + smallChange = 0; + } + + //BIG CHANGE CONSTANT:W3 (SET TO ZERO INITIALLY) + var bigChange = 0; + if (largeChange1) { + if (stock.getStockCode().equals(stockForLargeChange1.getStockCode())) { + //ADD 10 PTS. TO THIS STOCK; RESET E1 + bigChange = 10; + } + } + + if (largeChange2) { + if (stock.getStockCode().equals(stockForLargeChange2.getStockCode())) { + //SUBTRACT 10 PTS. FROM THIS STOCK; RESET E2 + bigChange = bigChange - 10; + } + } + + stock.setChangeStockValue(Math.floor(marketTrendSlope * stock.stockValue) + smallChange + + Math.floor(3 - 6 * random.nextFloat() + .5) + bigChange); + stock.setChangeStockValue(Math.floor(100 * stock.getChangeStockValue() + .5) / 100d); + stock.stockValue += stock.getChangeStockValue(); + + if (stock.stockValue > 0) { + stock.stockValue = Math.floor(100 * stock.stockValue + 0.5) / 100d; + } else { + stock.setChangeStockValue(0); + stock.stockValue = 0; + } + } + } + + private static double randomlyChangeTrendSignAndSlopeAndDuration() { + // RANDOMLY CHANGE TREND SIGN AND SLOPE (A), AND DURATION + var newTrend = Math.floor((random.nextFloat() / 10) * 100 + .5) / 100d; + var slopeSign = random.nextFloat(); + if (slopeSign > 0.5) { + newTrend = -newTrend; + } + return newTrend; + } + + private static List initStocks() { + List stocks = new ArrayList<>(); + stocks.add(new Stock(100, "INT. BALLISTIC MISSILES", "IBM")); + stocks.add(new Stock(85, "RED CROSS OF AMERICA", "RCA")); + stocks.add(new Stock(150, "LICHTENSTEIN, BUMRAP & JOKE", "LBJ")); + stocks.add(new Stock(140, "AMERICAN BANKRUPT CO.", "ABC")); + stocks.add(new Stock(110, "CENSURED BOOKS STORE", "CBS")); + return stocks; + } + + private static void printGameHelp(Scanner scan) { + System.out.print("DO YOU WANT THE INSTRUCTIONS (YES-TYPE 1, NO-TYPE 0) ? "); + int choice = scan.nextInt(); + if (choice >= 1) { + System.out.println(""); + System.out.println("THIS PROGRAM PLAYS THE STOCK MARKET. YOU WILL BE GIVEN"); + System.out.println("$10,000 AND MAY BUY OR SELL STOCKS. THE STOCK PRICES WILL"); + System.out.println("BE GENERATED RANDOMLY AND THEREFORE THIS MODEL DOES NOT"); + System.out.println("REPRESENT EXACTLY WHAT HAPPENS ON THE EXCHANGE. A TABLE"); + System.out.println("OF AVAILABLE STOCKS, THEIR PRICES, AND THE NUMBER OF SHARES"); + System.out.println("IN YOUR PORTFOLIO WILL BE PRINTED. FOLLOWING THIS, THE"); + System.out.println("INITIALS OF EACH STOCK WILL BE PRINTED WITH A QUESTION"); + System.out.println("MARK. HERE YOU INDICATE A TRANSACTION. TO BUY A STOCK"); + System.out.println("TYPE +NNN, TO SELL A STOCK TYPE -NNN, WHERE NNN IS THE"); + System.out.println("NUMBER OF SHARES. A BROKERAGE FEE OF 1% WILL BE CHARGED"); + System.out.println("ON ALL TRANSACTIONS. NOTE THAT IF A STOCK'S VALUE DROPS"); + System.out.println("TO ZERO IT MAY REBOUND TO A POSITIVE VALUE AGAIN. YOU"); + System.out.println("HAVE $10,000 TO INVEST. USE INTEGERS FOR ALL YOUR INPUTS."); + System.out.println("(NOTE: TO GET A 'FEEL' FOR THE MARKET RUN FOR AT LEAST"); + System.out.println("10 DAYS)"); + System.out.println("-----GOOD LUCK!-----"); + } + System.out.println("\n\n"); + } + + private static void printIntro() { + System.out.println(" STOCK MARKET"); + System.out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println("\n\n"); + } + + /** + * Stock class also storing the stock information and other related information for simplicity + */ + private static class Stock { + + private final String stockName; + private final String stockCode; + private double stockValue; + private double portfolioContents = 0; + private double transactionQuantity = 0; + private double changeStockValue = 0; + + public Stock(double stockValue, String stockName, String stockCode) { + this.stockValue = stockValue; + this.stockName = stockName; + this.stockCode = stockCode; + } + + public String getStockName() { + return stockName; + } + + public String getStockCode() { + return stockCode; + } + + public double getStockValue() { + return stockValue; + } + + public double getPortfolioContents() { + return portfolioContents; + } + + public void setPortfolioContents(double portfolioContents) { + this.portfolioContents = portfolioContents; + } + + public double getTransactionQuantity() { + return transactionQuantity; + } + + public void setTransactionQuantity(double transactionQuantity) { + this.transactionQuantity = transactionQuantity; + } + + public double getChangeStockValue() { + return changeStockValue; + } + + public void setChangeStockValue(double changeStockValue) { + this.changeStockValue = changeStockValue; + } + + @Override + public String toString() { + return "Stock{" + + "stockValue=" + stockValue + + ", stockCode='" + stockCode + '\'' + + ", portfolioContents=" + portfolioContents + + ", transactionQuantity=" + transactionQuantity + + ", changeStockValue=" + changeStockValue + + '}'; + } + } + +} \ No newline at end of file From 285e658bbcb4b2436e5f0178b09302aacfb884bd Mon Sep 17 00:00:00 2001 From: Aldrin Misquitta Date: Thu, 3 Feb 2022 16:48:34 +0000 Subject: [PATCH 288/337] Document a bonus option to view the game data as a tree! --- 03_Animal/java/src/Animal.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/03_Animal/java/src/Animal.java b/03_Animal/java/src/Animal.java index c4222c5f..1e489559 100644 --- a/03_Animal/java/src/Animal.java +++ b/03_Animal/java/src/Animal.java @@ -10,6 +10,8 @@ import java.util.stream.Collectors; * Converted from BASIC to Java by Aldrin Misquitta (@aldrinm) * The original BASIC program uses an array to maintain the questions and answers and to decide which question to * ask next. Updated this Java implementation to use a tree instead of the earlier faulty one based on a list (thanks @patimen). + * + * Bonus option: TREE --> prints the game decision data as a tree to visualize/debug the state of the game */ public class Animal { From c5ef9f42a2d727ae63517e63aa1a11574fa56731 Mon Sep 17 00:00:00 2001 From: Tom Wyant Date: Thu, 3 Feb 2022 14:44:49 -0500 Subject: [PATCH 289/337] Port 60_Mastermind to Perl. --- 60_Mastermind/perl/README.md | 4 + 60_Mastermind/perl/mastermind.pl | 419 +++++++++++++++++++++++++++++++ 2 files changed, 423 insertions(+) create mode 100755 60_Mastermind/perl/mastermind.pl diff --git a/60_Mastermind/perl/README.md b/60_Mastermind/perl/README.md index e69c8b81..67786f32 100644 --- a/60_Mastermind/perl/README.md +++ b/60_Mastermind/perl/README.md @@ -1,3 +1,7 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Perl](https://www.perl.org/) + +This is pretty much a re-implementation of the BASIC, taking advantage +of Perl's array functionality and working directly with the alphabetic +color codes. diff --git a/60_Mastermind/perl/mastermind.pl b/60_Mastermind/perl/mastermind.pl new file mode 100755 index 00000000..d27e2e47 --- /dev/null +++ b/60_Mastermind/perl/mastermind.pl @@ -0,0 +1,419 @@ +#!/usr/bin/env perl + +use 5.010; # To get 'state' and 'say' + +use strict; # Require explicit declaration of variables +use warnings; # Enable optional compiler warnings + +use English; # Use more friendly names for Perl's magic variables +use List::Util qw{ min sum }; # Convenient list utilities +use Term::ReadLine; # Prompt and return user input + +our $VERSION = '0.000_01'; + +use constant MAX_GUESSES => 10; + +print <<'EOD'; + MASTERMIND + Creative Computing Morristown, New Jersey + + +EOD + +=begin comment + + MASTERMIND II + STEVE NORTH + CREATIVE COMPUTING + PO BOX 789-M MORRISTOWN NEW JERSEY 07960 + +=end comment + +=cut + +# NOTE that mixed-case 'my' variables are 'global' in the sense that +# they are used in subroutines, but not passed to them. + +say ''; + +my $number_of_colors = get_input( + 'Number of colors [1-8]: ', + sub { m/ \A [1-8] \z /smx }, + "No more than 8, please!\n", +); + +say ''; + +my $Number_of_Positions = get_input( + 'Number of positions: ', + sub { m/ \A [0-9]+ \z /smx && $ARG }, + "A positive number, please\n", +); + +say ''; + +my $number_of_rounds = get_input( + 'Number of rounds: ', + sub { m/ \A [0-9]+ \z /smx && $ARG }, + "A positive number, please\n", +); + +my $P = $number_of_colors ** $Number_of_Positions; +say 'Total possibilities = ', $P; + +my @colors = ( qw{ + Black White Red Green Orange Yellow Purple Tan +})[ 0 .. $number_of_colors - 1 ]; +my @Color_Codes = map { uc substr $ARG, 0, 1 } @colors; + +print <<'EOD'; + + +Color Letter +===== ====== +EOD + +foreach my $inx ( 0 .. $#colors ) { + printf "%-13s%s\n", $colors[$inx], $Color_Codes[$inx]; +} + +say ''; + +my $computer_score = 0; # Computer score +my $human_score = 0; # Human score + +foreach my $round_number ( 1 .. $number_of_rounds ) { + + print <<"EOD"; + +Round number $round_number ---- + +Guess my combination. + +EOD + + $human_score += human_guesses( $Number_of_Positions ); + + print_score( $computer_score, $human_score ); + + $computer_score += computer_guesses(); + + print_score( $computer_score, $human_score ); + +} + +# Make a $pattern into a hash with one key for each possible color. The +# value for each color is the number of times it appears in the pattern. +sub hashify_pattern { + my $pattern = uc $ARG[0]; + my %p = map { $ARG => 0 } @Color_Codes; + $p{$ARG}++ for split qr//, $pattern; + return \%p; +} + +# Given a $pattern, a $guess at that pattern, and $black and $white +# scores, return a true value if the $black and $white scores of the +# $guess are those supplied as arguments; otherwise return a false +# value. This is used by computer_guesses() to eliminate possibilities. +sub analyze_black_white { + my ( $pattern, $guess, $black, $white ) = @ARG; + my $info = analyze_guess( $pattern, $guess ); + return $info->{black} == $black && $info->{white} == $white; +} + +# Given a $pattern and a $guess at that pattern, return a reference to a +# hash with the following keys: +# {guess} is the guess; +# {black} is the black score of the guess +# {white} is the white score of the guess +sub analyze_guess { + my ( $pattern, $guess ) = @ARG; + my $pattern_hash = hashify_pattern( $pattern ); + my $guess_hash = hashify_pattern( $guess ); + my $white = sum( + map { min( $pattern_hash->{$ARG}, $guess_hash->{$ARG} ) } @Color_Codes, + ); + my $black = 0; + foreach my $inx ( 0 .. length( $pattern ) - 1 ) { + if ( substr( $pattern, $inx, 1 ) eq substr( $guess, $inx, 1 ) ) + { + $black++; + --$white; + } + } + return +{ + guess => $guess, + black => $black, + white => $white, + } +} + +# Used by the computer to guess the human's choice. The return is the +# number of guesses the computer took. The return is the maximum plus +# one if the computer failed to guess. +sub computer_guesses { + + print <<'EOD'; + +Now I guess. Think of a combination. +EOD + get_input( + 'Hit when ready:', + ); + + # Generate all possible permutations. + my @possible; + foreach my $permutation ( 0 .. @Color_Codes ** $Number_of_Positions - 1 ) { + my $guess; + for ( 1 .. $Number_of_Positions ) { + my $inx = $permutation % @Color_Codes; + $guess .= $Color_Codes[ $inx ]; + $permutation = int( $permutation / @Color_Codes ); + } + push @possible, $guess; + } + + # Guess ... + foreach my $guess_num ( 1 .. MAX_GUESSES ) { + + # Guess a possible permutation at random, removing it from the + # list. + my $guess = splice @possible, int rand @possible, 1; + say 'My guess is: ', $guess; + + # Find out its black/white score. + my ( $black, $white ) = split qr< , >smx, get_input( + 'Blacks, Whites: ', + sub { m/ \A [0-9]+ , [0-9]+ \z /smx }, + "Please enter two unsigned integers\n", + ); + + # If it's all black, the computer wins. + if ( $black == $Number_of_Positions ) { + say "I got it in $guess_num moves!"; + return $guess_num; + } + + # Eliminate all possible permutations that give the black/white + # score that our guess got. If there are any left, take another + # guess. + next if @possible = grep { analyze_black_white( $ARG, $guess, $black, + $white ) } @possible; + + # There were no permutations left. Complain. + print <<'EOD'; +You have given me inconsistent information. +Try again, and this time please be more careful. +EOD + + goto &computer_guesses; # Tail-call ourselves to try again. + } + + print <<'EOD'; +I used up all my moves! +I guess my CPU is just having an off day. +EOD + + return MAX_GUESSES + 1; +} + +# Used to generate a pattern and process the human's guesses. The return +# is the number of guesses the human took. The return is the maximum +# plus one if the human failed to guess. +sub human_guesses { + + my @saved_moves; # Saved moves + my $pattern = uc join '', + map { $Color_Codes[ rand @Color_Codes ] } 1 .. $Number_of_Positions; + + foreach my $guess_num ( 1 .. MAX_GUESSES ) { + + my $guess = uc get_input( + "Move # $guess_num guess: ", + sub { + + # If the user entered 'quit', bail out. + if ( m/ \A quit \z /smxi ) { + die "Quitter! My combination was $pattern\n\nGood bye\n"; + } + + # If the user entered 'board', display the board so far. + # We return success to prevent the warning message, but + # we also clear $ARG. The caller's caller sees this and + # re-queries. + if ( m/ \A board \z /smxi ) { + print <<'EOD'; + +Board +Move Guess Black White +EOD + my $number = 1; + foreach my $item ( @saved_moves ) { + printf "%4d %-13s %3d %3d\n", $number++, + @{ $item }{ qw{ guess black white } }; + } + return undef; # Validation failure, but suppress warning. + } + + # End of special-case code. Below here we are dealing + # with guess input. + + # The length of the input must equal the number of + # positions. + if ( $Number_of_Positions != length ) { + warn "Bad number of positions\n"; + return 0; + } + + # The input may contain only valid color codes. + state $invalid_color = do { # Evaluated only once + local $LIST_SEPARATOR = ''; + qr< [^@Color_Codes] >smxi; + }; + if ( m/ ( $invalid_color ) /smxi ) { + warn "'$1' is unrecognized.\n"; + return 0; + } + + # We're good. + return 1; + }, + "Please enter 'board', 'quit', or any $Number_of_Positions of @{[ + join ', ', map { qq<'$ARG'> } @Color_Codes ]}.\n", + ); + + my $rslt = analyze_guess( $pattern, $guess ); + + push @saved_moves, $rslt; + + if ( $rslt->{black} == $Number_of_Positions ) { + say "You guessed it in $guess_num moves."; + return $guess_num; + } + + say "You have $rslt->{black} blacks and $rslt->{white} whites."; + + } + + print <<"EOD"; +You ran out of moves. That's all you get. + +The actual combination was: $pattern +EOD + + return MAX_GUESSES + 1; +} + +# Print the $computer and $human score +sub print_score { + my ( $computer, $human ) = @ARG; + print <<"EOD"; +Score: + Computer: $computer + Human: $human +EOD + return; +} + +# Get input from the user. The arguments are: +# * The prompt +# * A reference to validation code. This code receives the response in +# $ARG and returns true for a valid response. +# * A warning to print if the response is not valid. This must end in a +# return. It is suppressed if the validation code returned undef. +# The first valid response is returned. An end-of-file terminates the +# script. +sub get_input { + my ( $prompt, $validate, $warning ) = @ARG; + + # If no validator is passed, default to one that always returns + # true. + $validate ||= sub { 1 }; + + # Create the readline object. The 'state' causes the variable to be + # initialized only once, no matter how many times this subroutine is + # called. The do { ... } is a compound statement used because we + # need to tweak the created object before we store it. + state $term = do { + my $obj = Term::ReadLine->new( 'reverse' ); + $obj->ornaments( 0 ); + $obj; + }; + + while ( 1 ) { # Iterate indefinitely + + # Read the input into the topic variable, localized to prevent + # Spooky Action at a Distance. We exit on undef, which signals + # end-of-file. + exit unless defined( local $ARG = $term->readline( $prompt ) ); + + # Return the input if it is valid. + return $ARG if my $rslt = $validate->(); + + # Issue the warning, and go around the merry-go-round again. + warn $warning if defined $rslt; + } +} + +# NOTE the following is unused, but left in place in case someone wants +# to add a 'Do you want instructions?' +# +# Get a yes-or-no answer. The argument is the prompt, which will have +# '? [y/n]: ' appended. The donkey work is done by get_input(), which is +# requested to validate the response as beginning with 'y' or 'n', +# case-insensitive. The return is a true value for 'y' and a false value +# for 'n'. +sub get_yes_no { + my ( $prompt ) = @ARG; + state $map_answer = { + n => 0, + y => 1, + }; + my $resp = lc get_input( + "$prompt? [y/n]: ", + sub { m/ \A [yn] /smxi }, + "Please respond 'y' or 'n'\n", + ); + return $map_answer->{ substr $resp, 0, 1 }; +} + +__END__ + +=head1 TITLE + +mastermind - Play the game 'Mastermind' from Basic Computer Games + +=head1 SYNOPSIS + + mastermind.pl + +=head1 DETAILS + +This Perl script is a port of mastermind, which is the 60th +entry in Basic Computer Games. + +This is pretty much a re-implementation of the BASIC, taking advantage +of Perl's array functionality and working directly with the alphabetic +color codes. + +=head1 PORTED BY + +Thomas R. Wyant, III F + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2022 by Thomas R. Wyant, III + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl 5.10.0. For more details, see the Artistic +License 1.0 at +L, and/or the +Gnu GPL at L. + +This program is distributed in the hope that it will be useful, but +without any warranty; without even the implied warranty of +merchantability or fitness for a particular purpose. + +=cut + +# ex: set expandtab tabstop=4 textwidth=72 : From 277ab470192122617b4f49f371e9ff7ca5b6a96a Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Thu, 3 Feb 2022 23:44:23 +0000 Subject: [PATCH 290/337] 95 Weekday - move functions into classes --- 95_Weekday/javascript/weekday.js | 175 ++++++++++++++++++------------- 1 file changed, 105 insertions(+), 70 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index 2e1129a0..653b3de3 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -36,9 +36,9 @@ function tab(space) { } class DateStruct { - year; - month; - day; + #year; + #month; + #day; /** * Build a DateStruct @@ -47,9 +47,25 @@ class DateStruct { * @param {number} day */ constructor(year, month, day) { - this.year = year; - this.month = month; - this.day = day; + this.#year = year; + this.#month = month; + this.#day = day; + } + + get year() { + return this.#year; + } + + get month() { + return this.#month; + } + + get day() { + return this.#day; + } + + clone = () => { + return new DateStruct(this.#year, this.#month, this.#day) } /** @@ -58,14 +74,14 @@ class DateStruct { * see https://en.wikipedia.org/wiki/Gregorian_calendar * @returns {boolean} true if date could be Gregorian; otherwise false. */ - isGregorianDate() { + isGregorianDate = function () { let result = false; - if (this.year > 1582) { + if (this.#year > 1582) { result = true; - } else if (this.year === 1582) { - if (this.month > 10) { + } else if (this.#year === 1582) { + if (this.#month > 10) { result = true; - } else if (this.month === 10 && this.day >= 15) { + } else if (this.#month === 10 && this.#day >= 15) { result = true; } } @@ -76,15 +92,15 @@ class DateStruct { * Returns a US formatted date, i.e. Month/Day/Year. * @returns {string} */ - getFormattedDate() { - return this.month + "/" + this.day + "/" + this.year; + toString = function () { + return this.#month + "/" + this.#day + "/" + this.#year; } } class Duration { - years; - months; - days; + #years; + #months; + #days; /** * Build a Duration @@ -93,9 +109,70 @@ class Duration { * @param {number} days */ constructor(years, months, days) { - this.years = years; - this.months = months; - this.days = days; + this.#years = years; + this.#months = months; + this.#days = days; + } + + get years() { + return this.#years; + } + + get months() { + return this.#months; + } + + get days() { + return this.#days; + } + + clone = () => { + return new Duration(this.#years, this.#months, this.#days) + } + + /** + * Adjust Duration by removing years, months and days from supplied Duration. + * This is a naive calculation which assumes all months are 30 days. + * @param {Duration} timeToRemove + */ + remove = (timeToRemove) => { + this.#years -= timeToRemove.years; + this.#months -= timeToRemove.months; + this.#days -= timeToRemove.days; + if (this.#days < 0) { + this.#days += 30; + this.#months--; + } + if (this.#months < 0) { + this.#months += 12; + this.#years--; + } + } + + toString = () => { + return this.#years + "/" + this.#months + "/" + this.#days; + } + + /** + * Determine approximate Duration between two dates. + * This is a naive calculation which assumes all months are 30 days. + * @param {DateStruct} date1 + * @param {DateStruct} date2 + * @returns {Duration} + */ + static between(date1, date2) { + let years = date1.year - date2.year; + let months = date1.month - date2.month; + let days = date1.day - date2.day; + if (days < 0) { + months--; + days += 30; + } + if (months < 0) { + years--; + months += 12; + } + return new Duration(years, months, days); } } @@ -140,25 +217,6 @@ function printTimeSpent(duration) { print(duration.years + "\t" + duration.months + "\t" + duration.days + "\n"); } -/** - * Adjust unaccounted time by remove years, months and days supplied. - * @param {Duration} unaccountedTime - * @param {Duration} timeToRemove - */ -function adjustUnaccountedTime(unaccountedTime, timeToRemove) { - unaccountedTime.years -= timeToRemove.years; - unaccountedTime.months -= timeToRemove.months; - unaccountedTime.days -= timeToRemove.days; - if (unaccountedTime.days < 0) { - unaccountedTime.days += 30; - unaccountedTime.months--; - } - if (unaccountedTime.months <= 0) { - unaccountedTime.months += 12; - unaccountedTime.years--; - } -} - /** * Determine if the given year is a leap year. * @param year @@ -193,7 +251,7 @@ function getDayOfWeek(date) { const yearInCenturyOffsets = yearInCentury / 4 + yearInCentury; // combine offsets with day and month - let dayOfWeek = centuryOffset + yearInCenturyOffsets + date.day + COMMON_YEAR_MONTH_OFFSET[date.month-1]; + let dayOfWeek = centuryOffset + yearInCenturyOffsets + date.day + COMMON_YEAR_MONTH_OFFSET[date.month - 1]; dayOfWeek = Math.floor(dayOfWeek % 7) + 1; if (date.month <= 2 && isLeapYear(date.year)) { @@ -254,28 +312,6 @@ function getNormalisedDay(date) { return (date.year * 12 + date.month) * 31 + date.day; } -/** - * Determine approximate difference between two dates. - * This is a naive calculation which assumes all months are 30 days. - * @param {DateStruct} date1 - * @param {DateStruct} date2 - * @returns {Duration} - */ -function difference(date1, date2) { - let years = date1.year - date2.year; - let months = date1.month - date2.month; - let days = date1.day - date2.day; - if (days < 0) { - months--; - days += 30; - } - if (months < 0) { - years--; - months += 12; - } - return new Duration(years, months, days); -} - // Main control section async function main() { print(tab(32) + "WEEKDAY\n"); @@ -300,19 +336,18 @@ async function main() { const normalisedToday = getNormalisedDay(today); const normalisedDob = getNormalisedDay(dateOfBirth); - const dateOfBirthText = dateOfBirth.getFormattedDate(); let dayOfWeekText = getDayOfWeekText(dateOfBirth); if (normalisedToday < normalisedDob) { - print(dateOfBirthText + " WILL BE A " + dayOfWeekText + "\n"); + print(dateOfBirth + " WILL BE A " + dayOfWeekText + "\n"); } else if (normalisedToday === normalisedDob) { - print(dateOfBirthText + " IS A " + dayOfWeekText + "\n"); + print(dateOfBirth + " IS A " + dayOfWeekText + "\n"); } else { - print(dateOfBirthText + " WAS A " + dayOfWeekText + "\n"); + print(dateOfBirth + " WAS A " + dayOfWeekText + "\n"); } if (normalisedToday !== normalisedDob) { print("\n"); - let differenceBetweenDates = difference(today, dateOfBirth); + let differenceBetweenDates = Duration.between(today, dateOfBirth); if (differenceBetweenDates.years >= 0) { if (differenceBetweenDates.days === 0 && differenceBetweenDates.months === 0) { print("***HAPPY BIRTHDAY***\n"); @@ -323,19 +358,19 @@ async function main() { printTimeSpent(differenceBetweenDates); const approximateDaysBetween = (differenceBetweenDates.years * 365) + (differenceBetweenDates.months * 30) + differenceBetweenDates.days + Math.floor(differenceBetweenDates.months / 2); // Create an object containing time unaccounted for - const unaccountedTime = {...differenceBetweenDates}; + const unaccountedTime = differenceBetweenDates.clone(); // Calculate time spent in the following functions. print("YOU HAVE SLEPT \t\t\t"); const sleepTimeSpent = time_spent(0.35, approximateDaysBetween); printTimeSpent(sleepTimeSpent); - adjustUnaccountedTime(unaccountedTime, sleepTimeSpent); + unaccountedTime.remove(sleepTimeSpent); print("YOU HAVE EATEN \t\t\t"); const eatenTimeSpent = time_spent(0.17, approximateDaysBetween); printTimeSpent(eatenTimeSpent); - adjustUnaccountedTime(unaccountedTime, eatenTimeSpent); + unaccountedTime.remove(eatenTimeSpent); if (unaccountedTime.years <= 3) { print("YOU HAVE PLAYED \t\t\t"); } else if (unaccountedTime.years <= 9) { @@ -346,7 +381,7 @@ async function main() { const workPlayTimeSpent = time_spent(0.23, approximateDaysBetween); printTimeSpent(workPlayTimeSpent); - adjustUnaccountedTime(unaccountedTime, workPlayTimeSpent); + unaccountedTime.remove(workPlayTimeSpent); if (unaccountedTime.months === 12) { unaccountedTime.years++; unaccountedTime.months = 0; From 239e511b66e4a8e2b1f3e48667c7692a14a35403 Mon Sep 17 00:00:00 2001 From: "stephan.com" Date: Fri, 4 Feb 2022 22:54:12 -0800 Subject: [PATCH 291/337] 58_Love: ruby --- 58_Love/ruby/love.rb | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 58_Love/ruby/love.rb diff --git a/58_Love/ruby/love.rb b/58_Love/ruby/love.rb new file mode 100644 index 00000000..3717a14b --- /dev/null +++ b/58_Love/ruby/love.rb @@ -0,0 +1,43 @@ +data = [60, 1, 12, 26, 9, 12, 3, 8, 24, 17, 8, 4, 6, 23, 21, 6, 4, 6, 22, 12, 5, 6, 5, + 4, 6, 21, 11, 8, 6, 4, 4, 6, 21, 10, 10, 5, 4, 4, 6, 21, 9, 11, 5, 4, 4, 6, 21, + 8, 11, 6, 4, 4, 6, 21, 7, 11, 7, 4, 4, 6, 21, 6, 11, 8, 4, 4, 6, 19, 1, 1, 5, + 11, 9, 4, 4, 6, 19, 1, 1, 5, 10, 10, 4, 4, 6, 18, 2, 1, 6, 8, 11, 4, 4, 6, 17, + 3, 1, 7, 5, 13, 4, 4, 6, 15, 5, 2, 23, 5, 1, 29, 5, 17, 8, 1, 29, 9, 9, 12, 1, + 13, 5, 40, 1, 1, 13, 5, 40, 1, 4, 6, 13, 3, 10, 6, 12, 5, 1, 5, 6, 11, 3, 11, + 6, 14, 3, 1, 5, 6, 11, 3, 11, 6, 15, 2, 1, 6, 6, 9, 3, 12, 6, 16, 1, 1, 6, 6, + 9, 3, 12, 6, 7, 1, 10, 7, 6, 7, 3, 13, 6, 6, 2, 10, 7, 6, 7, 3, 13, 14, 10, 8, + 6, 5, 3, 14, 6, 6, 2, 10, 8, 6, 5, 3, 14, 6, 7, 1, 10, 9, 6, 3, 3, 15, 6, 16, 1, + 1, 9, 6, 3, 3, 15, 6, 15, 2, 1, 10, 6, 1, 3, 16, 6, 14, 3, 1, 10, 10, 16, 6, 12, + 5, 1, 11, 8, 13, 27, 1, 11, 8, 13, 27, 1, 60] + +puts 'LOVE'.center(60) +puts 'stephan.com'.center(60) +puts "\n\n" + +puts <<~EOLOVE + A TRIBUTE TO THE GREAT AMERICAN ARTIST, ROBERT INDIANA. + HIS GREATEST WORK WILL BE REPRODUCED WITH A MESSAGE OF + YOUR CHOICE UP TO 60 CHARACTERS. IF YOU CAN'T THINK OF + A MESSAGE, SIMPLY TYPE THE WORD 'LOVE'\n +EOLOVE + +message = gets.strip +message = 'love' if message.empty? +l = message.length + +until data.empty? + puts + col = 0 + p = true + while col < 60 + run = data.shift + + if p + run.times { |i| print message[(col + i) % l] } + else + print ' ' * run + end + p = !p + col += run + end +end From a599e47e3d16be1f8e4c4d8da0a6c00e42b7e468 Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Sun, 6 Feb 2022 00:10:37 +0000 Subject: [PATCH 292/337] 95 Weekday - reduce use of lambdas; add a single method for tidying up values --- 95_Weekday/javascript/weekday.js | 85 +++++++++++++++++++------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index 653b3de3..71e29617 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -3,10 +3,18 @@ // Converted from BASIC to Javascript by Oscar Toledo G. (nanochess) // +/** + * Print given string to the end of the "output" element. + * @param str + */ function print(str) { document.getElementById("output").appendChild(document.createTextNode(str)); } +/** + * Obtain user input + * @returns {Promise} + */ function input() { return new Promise(function (resolve) { const input_element = document.createElement("INPUT"); @@ -28,13 +36,26 @@ function input() { }); } -function tab(space) { +/** + * Create a string consisting of the given number of spaces + * @param spaceCount + * @returns {string} + */ +function tab(spaceCount) { let str = ""; - while (space-- > 0) + while (spaceCount-- > 0) str += " "; return str; } +const MONTHS_PER_YEAR = 12; +const DAYS_PER_COMMON_YEAR = 365; +const DAYS_PER_IDEAL_MONTH = 30; +const MAXIMUM_DAYS_PER_MONTH = 31; + +/** + * Date representation. + */ class DateStruct { #year; #month; @@ -64,17 +85,13 @@ class DateStruct { return this.#day; } - clone = () => { - return new DateStruct(this.#year, this.#month, this.#day) - } - /** * Determine if the date could be a Gregorian date. * Be aware the Gregorian calendar was not introduced in all places at once, * see https://en.wikipedia.org/wiki/Gregorian_calendar * @returns {boolean} true if date could be Gregorian; otherwise false. */ - isGregorianDate = function () { + isGregorianDate() { let result = false; if (this.#year > 1582) { result = true; @@ -92,11 +109,15 @@ class DateStruct { * Returns a US formatted date, i.e. Month/Day/Year. * @returns {string} */ - toString = function () { + toString() { return this.#month + "/" + this.#day + "/" + this.#year; } } +/** + * Duration representation. + * Note: this class only handles positive durations well + */ class Duration { #years; #months; @@ -112,6 +133,7 @@ class Duration { this.#years = years; this.#months = months; this.#days = days; + this.#fixRanges(); } get years() { @@ -126,8 +148,8 @@ class Duration { return this.#days; } - clone = () => { - return new Duration(this.#years, this.#months, this.#days) + clone() { + return new Duration(this.#years, this.#months, this.#days); } /** @@ -135,21 +157,28 @@ class Duration { * This is a naive calculation which assumes all months are 30 days. * @param {Duration} timeToRemove */ - remove = (timeToRemove) => { + remove(timeToRemove) { this.#years -= timeToRemove.years; this.#months -= timeToRemove.months; this.#days -= timeToRemove.days; + this.#fixRanges(); + } + + /** + * Move days and months into expected range. + */ + #fixRanges() { if (this.#days < 0) { - this.#days += 30; + this.#days += DAYS_PER_IDEAL_MONTH; this.#months--; } if (this.#months < 0) { - this.#months += 12; + this.#months += MONTHS_PER_YEAR; this.#years--; } } - toString = () => { + toString() { return this.#years + "/" + this.#months + "/" + this.#days; } @@ -164,14 +193,6 @@ class Duration { let years = date1.year - date2.year; let months = date1.month - date2.month; let days = date1.day - date2.day; - if (days < 0) { - months--; - days += 30; - } - if (months < 0) { - years--; - months += 12; - } return new Duration(years, months, days); } } @@ -202,10 +223,10 @@ async function readDateElements() { */ function time_spent(factor, dayCount) { let totalDays = Math.floor(factor * dayCount); - const years = Math.floor(totalDays / 365); - totalDays -= years * 365; - const months = Math.floor(totalDays / 30); - const days = totalDays - (months * 30); + const years = Math.floor(totalDays / DAYS_PER_COMMON_YEAR); + totalDays -= years * DAYS_PER_COMMON_YEAR; + const months = Math.floor(totalDays / DAYS_PER_IDEAL_MONTH); + const days = totalDays - (months * DAYS_PER_IDEAL_MONTH); return new Duration(years, months, days); } @@ -309,7 +330,7 @@ function getDayOfWeekText(date) { * @returns {number} */ function getNormalisedDay(date) { - return (date.year * 12 + date.month) * 31 + date.day; + return (date.year * MONTHS_PER_YEAR + date.month) * MAXIMUM_DAYS_PER_MONTH + date.day; } // Main control section @@ -356,7 +377,7 @@ async function main() { print(" \t-----\t------\t----\n"); print("YOUR AGE (IF BIRTHDATE) \t"); printTimeSpent(differenceBetweenDates); - const approximateDaysBetween = (differenceBetweenDates.years * 365) + (differenceBetweenDates.months * 30) + differenceBetweenDates.days + Math.floor(differenceBetweenDates.months / 2); + const approximateDaysBetween = (differenceBetweenDates.years * DAYS_PER_COMMON_YEAR) + (differenceBetweenDates.months * DAYS_PER_IDEAL_MONTH) + differenceBetweenDates.days + Math.floor(differenceBetweenDates.months / 2); // Create an object containing time unaccounted for const unaccountedTime = differenceBetweenDates.clone(); @@ -372,7 +393,7 @@ async function main() { unaccountedTime.remove(eatenTimeSpent); if (unaccountedTime.years <= 3) { - print("YOU HAVE PLAYED \t\t\t"); + print("YOU HAVE PLAYED \t\t"); } else if (unaccountedTime.years <= 9) { print("YOU HAVE PLAYED/STUDIED \t\t"); } else { @@ -382,12 +403,8 @@ async function main() { printTimeSpent(workPlayTimeSpent); unaccountedTime.remove(workPlayTimeSpent); - if (unaccountedTime.months === 12) { - unaccountedTime.years++; - unaccountedTime.months = 0; - } print("YOU HAVE RELAXED \t\t"); - printTimeSpent(unaccountedTime) + printTimeSpent(unaccountedTime); const retirementYear = dateOfBirth.year + 65; print("\n"); From 97186e7d83c2dde1785ae98369eb19f1d894dd39 Mon Sep 17 00:00:00 2001 From: Paul Sobolik Date: Sun, 6 Feb 2022 10:25:54 -0500 Subject: [PATCH 293/337] Bowling in csharp --- 14_Bowling/csharp/Bowling.cs | 195 +++++++++++++++++++++++++++++++ 14_Bowling/csharp/FrameResult.cs | 23 ++++ 14_Bowling/csharp/GameResults.cs | 23 ++++ 14_Bowling/csharp/Pins.cs | 56 +++++++++ 14_Bowling/csharp/Program.cs | 16 +++ 14_Bowling/csharp/Utility.cs | 54 +++++++++ 6 files changed, 367 insertions(+) create mode 100644 14_Bowling/csharp/Bowling.cs create mode 100644 14_Bowling/csharp/FrameResult.cs create mode 100644 14_Bowling/csharp/GameResults.cs create mode 100644 14_Bowling/csharp/Pins.cs create mode 100644 14_Bowling/csharp/Program.cs create mode 100644 14_Bowling/csharp/Utility.cs diff --git a/14_Bowling/csharp/Bowling.cs b/14_Bowling/csharp/Bowling.cs new file mode 100644 index 00000000..ed5b9998 --- /dev/null +++ b/14_Bowling/csharp/Bowling.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + public class Bowling + { + private readonly Pins pins = new Pins(); + + private int players; + + public void Play() + { + ShowBanner(); + MaybeShowInstructions(); + Setup(); + GameLoop(); + } + + private static void ShowBanner() + { + Utility.PrintString(34, "BOWL"); + Utility.PrintString(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Utility.PrintString(); + Utility.PrintString(); + Utility.PrintString(); + Utility.PrintString("WELCOME TO THE ALLEY"); + Utility.PrintString("BRING YOUR FRIENDS"); + Utility.PrintString("OKAY LET'S FIRST GET ACQUAINTED"); + Utility.PrintString(); + } + private static void MaybeShowInstructions() + { + Utility.PrintString("THE INSTRUCTIONS (Y/N)"); + if (Utility.InputString() == "N") return; + Utility.PrintString("THE GAME OF BOWLING TAKES MIND AND SKILL.DURING THE GAME"); + Utility.PrintString("THE COMPUTER WILL KEEP SCORE.YOU MAY COMPETE WITH"); + Utility.PrintString("OTHER PLAYERS[UP TO FOUR].YOU WILL BE PLAYING TEN FRAMES"); + Utility.PrintString("ON THE PIN DIAGRAM 'O' MEANS THE PIN IS DOWN...'+' MEANS THE"); + Utility.PrintString("PIN IS STANDING.AFTER THE GAME THE COMPUTER WILL SHOW YOUR"); + Utility.PrintString("SCORES ."); + } + private void Setup() + { + Utility.PrintString("FIRST OF ALL...HOW MANY ARE PLAYING", false); + var input = Utility.InputInt(); + players = input < 1 ? 1 : input; + Utility.PrintString(); + Utility.PrintString("VERY GOOD..."); + } + private void GameLoop() + { + var gameResults = new GameResults[players]; + var done = false; + while (!done) + { + ResetGameResults(gameResults); + for (int frame = 0; frame < GameResults.FramesPerGame; ++frame) + { + for (int player = 0; player < players; ++player) + { + pins.Reset(); + int pinsDownThisFrame = pins.GetPinsDown(); + + int ball = 1; + while (ball == 1 || ball == 2) // One or two rolls + { + Utility.PrintString("TYPE ROLL TO GET THE BALL GOING."); + _ = Utility.InputString(); + + int pinsDownAfterRoll = pins.Roll(); + ShowPins(player, frame, ball); + + if (pinsDownAfterRoll == pinsDownThisFrame) + { + Utility.PrintString("GUTTER!!"); + } + + if (ball == 1) + { + // Store current pin count + gameResults[player].Results[frame].PinsBall1 = pinsDownAfterRoll; + + // Special handling for strike + if (pinsDownAfterRoll == Pins.TotalPinCount) + { + Utility.PrintString("STRIKE!!!!!\a\a\a\a"); + // No second roll + ball = 0; + gameResults[player].Results[frame].PinsBall2 = pinsDownAfterRoll; + gameResults[player].Results[frame].Score = FrameResult.Points.Strike; + } + else + { + ball = 2; // Roll again + Utility.PrintString("ROLL YOUR SECOND BALL"); + } + } + else if (ball == 2) + { + // Store current pin count + gameResults[player].Results[frame].PinsBall2 = pinsDownAfterRoll; + ball = 0; + + // Determine the score for the frame + if (pinsDownAfterRoll == Pins.TotalPinCount) + { + Utility.PrintString("SPARE!!!!"); + gameResults[player].Results[frame].Score = FrameResult.Points.Spare; + } + else + { + Utility.PrintString("ERROR!!!"); + gameResults[player].Results[frame].Score = FrameResult.Points.Error; + } + } + Utility.PrintString(); + } + } + } + ShowGameResults(gameResults); + Utility.PrintString("DO YOU WANT ANOTHER GAME"); + var a = Utility.InputString(); + done = a.Length == 0 || a[0] != 'Y'; + } + } + private void ShowPins(int player, int frame, int ball) + { + Utility.PrintString($"FRAME: {frame + 1} PLAYER: {player + 1} BALL: {ball}"); + var breakPins = new bool[] { true, false, false, false, true, false, false, true, false, true }; + var indent = 0; + for (int pin = 0; pin < Pins.TotalPinCount; ++pin) + { + if (breakPins[pin]) + { + Utility.PrintString(); // End row + Utility.PrintString(indent++, false); // Indent next row + } + var s = pins[pin] == Pins.State.Down ? "+ " : "o "; + Utility.PrintString(s, false); + } + Utility.PrintString(); + Utility.PrintString(); + } + private void ResetGameResults(GameResults[] gameResults) + { + for (int playerIndex = 0; playerIndex < gameResults.Length; ++playerIndex) + { + var frameResults = gameResults[playerIndex]; + if (frameResults == null) + { + gameResults[playerIndex] = new GameResults(); + } + else + { + for (int frameIndex = 0; frameIndex < frameResults.Results.Length; ++frameIndex) + { + gameResults[playerIndex].Results[frameIndex].Reset(); + } + } + } + } + private void ShowGameResults(GameResults[] gameResults) + { + Utility.PrintString("FRAMES"); + for (int i = 0; i < GameResults.FramesPerGame; ++i) + { + Utility.PrintString(Utility.PadInt(i, 3), false); + } + Utility.PrintString(); + for (var player = 0; player < gameResults.Length; ++player) + { + for (var frame = 0; frame < gameResults[player].Results.Length; ++frame) + { + Utility.PrintString(Utility.PadInt(gameResults[player].Results[frame].PinsBall1, 3), false); + } + Utility.PrintString(); + for (var frame = 0; frame < gameResults[player].Results.Length; ++frame) + { + Utility.PrintString(Utility.PadInt(gameResults[player].Results[frame].PinsBall2, 3), false); + } + Utility.PrintString(); + for (var frame = 0; frame < gameResults[player].Results.Length; ++frame) + { + Utility.PrintString(Utility.PadInt((int)gameResults[player].Results[frame].Score, 3), false); + } + Utility.PrintString(); + Utility.PrintString(); + } + } + } +} diff --git a/14_Bowling/csharp/FrameResult.cs b/14_Bowling/csharp/FrameResult.cs new file mode 100644 index 00000000..c28b5c0f --- /dev/null +++ b/14_Bowling/csharp/FrameResult.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + public class FrameResult + { + public enum Points { None, Error, Spare, Strike }; + + public int PinsBall1 { get; set; } + public int PinsBall2 { get; set; } + public Points Score { get; set; } + + public void Reset() + { + PinsBall1 = PinsBall2 = 0; + Score = Points.None; + } + } +} diff --git a/14_Bowling/csharp/GameResults.cs b/14_Bowling/csharp/GameResults.cs new file mode 100644 index 00000000..10f1e735 --- /dev/null +++ b/14_Bowling/csharp/GameResults.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + public class GameResults + { + public static readonly int FramesPerGame = 10; + public FrameResult[] Results { get; set; } + + public GameResults() + { + Results = new FrameResult[FramesPerGame]; + for (int i = 0; i < FramesPerGame; ++i) + { + Results[i] = new FrameResult(); + } + } + } +} diff --git a/14_Bowling/csharp/Pins.cs b/14_Bowling/csharp/Pins.cs new file mode 100644 index 00000000..5321b530 --- /dev/null +++ b/14_Bowling/csharp/Pins.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + public class Pins + { + public enum State { Up, Down }; + public static readonly int TotalPinCount = 10; + private readonly Random random = new(); + + private State[] PinSet { get; set; } + + public Pins() + { + PinSet = new State[TotalPinCount]; + } + public State this[int i] + { + get { return PinSet[i]; } + set { PinSet[i] = value; } + } + public int Roll() + { + // REM ARK BALL GENERATOR USING MOD '15' SYSTEM + for (int i = 0; i < 20; ++i) + { + var x = random.Next(100) + 1; + int j; + for (j = 1; j <= 10; ++j) + { + if (x < 15 * j) + break; + } + var pindex = 15 * j - x; + if (pindex > 0 && pindex <= TotalPinCount) + PinSet[--pindex] = State.Down; + } + return GetPinsDown(); + } + public void Reset() + { + for (int i = 0; i < PinSet.Length; ++i) + { + PinSet[i] = State.Up; + } + } + public int GetPinsDown() + { + return PinSet.Count(p => p == State.Down); + } + } +} diff --git a/14_Bowling/csharp/Program.cs b/14_Bowling/csharp/Program.cs new file mode 100644 index 00000000..85e058b7 --- /dev/null +++ b/14_Bowling/csharp/Program.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + public static class Program + { + public static void Main() + { + new Bowling().Play(); + } + } +} diff --git a/14_Bowling/csharp/Utility.cs b/14_Bowling/csharp/Utility.cs new file mode 100644 index 00000000..fb935057 --- /dev/null +++ b/14_Bowling/csharp/Utility.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + internal class Utility + { + public static string PadInt(int value, int width) + { + return value.ToString().PadLeft(width); + } + public static int InputInt() + { + while (true) + { + if (int.TryParse(InputString(), out int i)) + return i; + else + PrintString("!NUMBER EXPECTED - RETRY INPUT LINE"); + } + } + public static string InputString() + { + PrintString("? ", false); + var input = Console.ReadLine(); + return input == null ? string.Empty : input.ToUpper(); + } + public static void PrintInt(int value, bool newLine = false) + { + PrintString($"{value} ", newLine); + } + public static void PrintString(bool newLine = true) + { + PrintString(0, string.Empty); + } + public static void PrintString(int tab, bool newLine = true) + { + PrintString(tab, string.Empty, newLine); + } + public static void PrintString(string value, bool newLine = true) + { + PrintString(0, value, newLine); + } + public static void PrintString(int tab, string value, bool newLine = true) + { + Console.Write(new String(' ', tab)); + Console.Write(value); + if (newLine) Console.WriteLine(); + } + } +} From 2e9c8ab1505070effd712adaa3d17de70837dade Mon Sep 17 00:00:00 2001 From: Paul Sobolik Date: Sun, 6 Feb 2022 10:25:54 -0500 Subject: [PATCH 294/337] Bowling in csharp --- 14_Bowling/csharp/Bowling.cs | 198 +++++++++++++++++++++++++++++++ 14_Bowling/csharp/FrameResult.cs | 23 ++++ 14_Bowling/csharp/GameResults.cs | 23 ++++ 14_Bowling/csharp/Pins.cs | 56 +++++++++ 14_Bowling/csharp/Program.cs | 16 +++ 14_Bowling/csharp/Utility.cs | 54 +++++++++ 6 files changed, 370 insertions(+) create mode 100644 14_Bowling/csharp/Bowling.cs create mode 100644 14_Bowling/csharp/FrameResult.cs create mode 100644 14_Bowling/csharp/GameResults.cs create mode 100644 14_Bowling/csharp/Pins.cs create mode 100644 14_Bowling/csharp/Program.cs create mode 100644 14_Bowling/csharp/Utility.cs diff --git a/14_Bowling/csharp/Bowling.cs b/14_Bowling/csharp/Bowling.cs new file mode 100644 index 00000000..66fef5e9 --- /dev/null +++ b/14_Bowling/csharp/Bowling.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + public class Bowling + { + private readonly Pins pins = new(); + + private int players; + + public void Play() + { + ShowBanner(); + MaybeShowInstructions(); + Setup(); + GameLoop(); + } + + private static void ShowBanner() + { + Utility.PrintString(34, "BOWL"); + Utility.PrintString(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Utility.PrintString(); + Utility.PrintString(); + Utility.PrintString(); + Utility.PrintString("WELCOME TO THE ALLEY"); + Utility.PrintString("BRING YOUR FRIENDS"); + Utility.PrintString("OKAY LET'S FIRST GET ACQUAINTED"); + Utility.PrintString(); + } + private static void MaybeShowInstructions() + { + Utility.PrintString("THE INSTRUCTIONS (Y/N)"); + if (Utility.InputString() == "N") return; + Utility.PrintString("THE GAME OF BOWLING TAKES MIND AND SKILL.DURING THE GAME"); + Utility.PrintString("THE COMPUTER WILL KEEP SCORE.YOU MAY COMPETE WITH"); + Utility.PrintString("OTHER PLAYERS[UP TO FOUR].YOU WILL BE PLAYING TEN FRAMES"); + Utility.PrintString("ON THE PIN DIAGRAM 'O' MEANS THE PIN IS DOWN...'+' MEANS THE"); + Utility.PrintString("PIN IS STANDING.AFTER THE GAME THE COMPUTER WILL SHOW YOUR"); + Utility.PrintString("SCORES ."); + } + private void Setup() + { + Utility.PrintString("FIRST OF ALL...HOW MANY ARE PLAYING", false); + var input = Utility.InputInt(); + players = input < 1 ? 1 : input; + Utility.PrintString(); + Utility.PrintString("VERY GOOD..."); + } + private void GameLoop() + { + GameResults[] gameResults = InitGameResults(); + var done = false; + while (!done) + { + ResetGameResults(gameResults); + for (int frame = 0; frame < GameResults.FramesPerGame; ++frame) + { + for (int player = 0; player < players; ++player) + { + pins.Reset(); + int pinsDownThisFrame = pins.GetPinsDown(); + + int ball = 1; + while (ball == 1 || ball == 2) // One or two rolls + { + Utility.PrintString("TYPE ROLL TO GET THE BALL GOING."); + _ = Utility.InputString(); + + int pinsDownAfterRoll = pins.Roll(); + ShowPins(player, frame, ball); + + if (pinsDownAfterRoll == pinsDownThisFrame) + { + Utility.PrintString("GUTTER!!"); + } + + if (ball == 1) + { + // Store current pin count + gameResults[player].Results[frame].PinsBall1 = pinsDownAfterRoll; + + // Special handling for strike + if (pinsDownAfterRoll == Pins.TotalPinCount) + { + Utility.PrintString("STRIKE!!!!!\a\a\a\a"); + // No second roll + ball = 0; + gameResults[player].Results[frame].PinsBall2 = pinsDownAfterRoll; + gameResults[player].Results[frame].Score = FrameResult.Points.Strike; + } + else + { + ball = 2; // Roll again + Utility.PrintString("ROLL YOUR SECOND BALL"); + } + } + else if (ball == 2) + { + // Store current pin count + gameResults[player].Results[frame].PinsBall2 = pinsDownAfterRoll; + ball = 0; + + // Determine the score for the frame + if (pinsDownAfterRoll == Pins.TotalPinCount) + { + Utility.PrintString("SPARE!!!!"); + gameResults[player].Results[frame].Score = FrameResult.Points.Spare; + } + else + { + Utility.PrintString("ERROR!!!"); + gameResults[player].Results[frame].Score = FrameResult.Points.Error; + } + } + Utility.PrintString(); + } + } + } + ShowGameResults(gameResults); + Utility.PrintString("DO YOU WANT ANOTHER GAME"); + var a = Utility.InputString(); + done = a.Length == 0 || a[0] != 'Y'; + } + } + + private GameResults[] InitGameResults() + { + var gameResults = new GameResults[players]; + for (int i = 0; i < gameResults.Length; i++) + { + gameResults[i] = new GameResults(); + } + return gameResults; + } + + private void ShowPins(int player, int frame, int ball) + { + Utility.PrintString($"FRAME: {frame + 1} PLAYER: {player + 1} BALL: {ball}"); + var breakPins = new bool[] { true, false, false, false, true, false, false, true, false, true }; + var indent = 0; + for (int pin = 0; pin < Pins.TotalPinCount; ++pin) + { + if (breakPins[pin]) + { + Utility.PrintString(); // End row + Utility.PrintString(indent++, false); // Indent next row + } + var s = pins[pin] == Pins.State.Down ? "+ " : "o "; + Utility.PrintString(s, false); + } + Utility.PrintString(); + Utility.PrintString(); + } + private void ResetGameResults(GameResults[] gameResults) + { + foreach (var gameResult in gameResults) + { + foreach (var frameResult in gameResult.Results) + { + frameResult.Reset(); + } + } + } + private void ShowGameResults(GameResults[] gameResults) + { + Utility.PrintString("FRAMES"); + for (int i = 0; i < GameResults.FramesPerGame; ++i) + { + Utility.PrintString(Utility.PadInt(i, 3), false); + } + Utility.PrintString(); + foreach (var gameResult in gameResults) + { + foreach (var frameResult in gameResult.Results) + { + Utility.PrintString(Utility.PadInt(frameResult.PinsBall1, 3), false); + } + Utility.PrintString(); + foreach (var frameResult in gameResult.Results) + { + Utility.PrintString(Utility.PadInt(frameResult.PinsBall2, 3), false); + } + Utility.PrintString(); + foreach (var frameResult in gameResult.Results) + { + Utility.PrintString(Utility.PadInt((int)frameResult.Score, 3), false); + } + Utility.PrintString(); + Utility.PrintString(); + } + } + } +} diff --git a/14_Bowling/csharp/FrameResult.cs b/14_Bowling/csharp/FrameResult.cs new file mode 100644 index 00000000..c28b5c0f --- /dev/null +++ b/14_Bowling/csharp/FrameResult.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + public class FrameResult + { + public enum Points { None, Error, Spare, Strike }; + + public int PinsBall1 { get; set; } + public int PinsBall2 { get; set; } + public Points Score { get; set; } + + public void Reset() + { + PinsBall1 = PinsBall2 = 0; + Score = Points.None; + } + } +} diff --git a/14_Bowling/csharp/GameResults.cs b/14_Bowling/csharp/GameResults.cs new file mode 100644 index 00000000..10f1e735 --- /dev/null +++ b/14_Bowling/csharp/GameResults.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + public class GameResults + { + public static readonly int FramesPerGame = 10; + public FrameResult[] Results { get; set; } + + public GameResults() + { + Results = new FrameResult[FramesPerGame]; + for (int i = 0; i < FramesPerGame; ++i) + { + Results[i] = new FrameResult(); + } + } + } +} diff --git a/14_Bowling/csharp/Pins.cs b/14_Bowling/csharp/Pins.cs new file mode 100644 index 00000000..5321b530 --- /dev/null +++ b/14_Bowling/csharp/Pins.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + public class Pins + { + public enum State { Up, Down }; + public static readonly int TotalPinCount = 10; + private readonly Random random = new(); + + private State[] PinSet { get; set; } + + public Pins() + { + PinSet = new State[TotalPinCount]; + } + public State this[int i] + { + get { return PinSet[i]; } + set { PinSet[i] = value; } + } + public int Roll() + { + // REM ARK BALL GENERATOR USING MOD '15' SYSTEM + for (int i = 0; i < 20; ++i) + { + var x = random.Next(100) + 1; + int j; + for (j = 1; j <= 10; ++j) + { + if (x < 15 * j) + break; + } + var pindex = 15 * j - x; + if (pindex > 0 && pindex <= TotalPinCount) + PinSet[--pindex] = State.Down; + } + return GetPinsDown(); + } + public void Reset() + { + for (int i = 0; i < PinSet.Length; ++i) + { + PinSet[i] = State.Up; + } + } + public int GetPinsDown() + { + return PinSet.Count(p => p == State.Down); + } + } +} diff --git a/14_Bowling/csharp/Program.cs b/14_Bowling/csharp/Program.cs new file mode 100644 index 00000000..85e058b7 --- /dev/null +++ b/14_Bowling/csharp/Program.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + public static class Program + { + public static void Main() + { + new Bowling().Play(); + } + } +} diff --git a/14_Bowling/csharp/Utility.cs b/14_Bowling/csharp/Utility.cs new file mode 100644 index 00000000..09687232 --- /dev/null +++ b/14_Bowling/csharp/Utility.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bowling +{ + internal static class Utility + { + public static string PadInt(int value, int width) + { + return value.ToString().PadLeft(width); + } + public static int InputInt() + { + while (true) + { + if (int.TryParse(InputString(), out int i)) + return i; + else + PrintString("!NUMBER EXPECTED - RETRY INPUT LINE"); + } + } + public static string InputString() + { + PrintString("? ", false); + var input = Console.ReadLine(); + return input == null ? string.Empty : input.ToUpper(); + } + public static void PrintInt(int value, bool newLine = false) + { + PrintString($"{value} ", newLine); + } + public static void PrintString(bool newLine = true) + { + PrintString(0, string.Empty); + } + public static void PrintString(int tab, bool newLine = true) + { + PrintString(tab, string.Empty, newLine); + } + public static void PrintString(string value, bool newLine = true) + { + PrintString(0, value, newLine); + } + public static void PrintString(int tab, string value, bool newLine = true) + { + Console.Write(new String(' ', tab)); + Console.Write(value); + if (newLine) Console.WriteLine(); + } + } +} From 9517d86f29534d0c6158910644246ab1c3c6590f Mon Sep 17 00:00:00 2001 From: Paul Sobolik Date: Sun, 6 Feb 2022 16:30:50 -0500 Subject: [PATCH 295/337] Bunny in csharp --- 19_Bunny/csharp/BasicData.cs | 25 +++++++++++ 19_Bunny/csharp/Bunny.cs | 87 ++++++++++++++++++++++++++++++++++++ 19_Bunny/csharp/Program.cs | 16 +++++++ 3 files changed, 128 insertions(+) create mode 100644 19_Bunny/csharp/BasicData.cs create mode 100644 19_Bunny/csharp/Bunny.cs create mode 100644 19_Bunny/csharp/Program.cs diff --git a/19_Bunny/csharp/BasicData.cs b/19_Bunny/csharp/BasicData.cs new file mode 100644 index 00000000..76647a56 --- /dev/null +++ b/19_Bunny/csharp/BasicData.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bunny +{ + internal class BasicData + { + private readonly int[] data; + + private int index; + + public BasicData(int[] data) + { + this.data = data; + index = 0; + } + public int Read() + { + return data[index++]; + } + } +} diff --git a/19_Bunny/csharp/Bunny.cs b/19_Bunny/csharp/Bunny.cs new file mode 100644 index 00000000..76e5e7e4 --- /dev/null +++ b/19_Bunny/csharp/Bunny.cs @@ -0,0 +1,87 @@ +namespace Bunny +{ + internal class Bunny + { + private const int asciiBase = 64; + private readonly int[] bunnyData = { + 2,21,14,14,25, + 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 + }; + + public void Run() + { + PrintString(33, "BUNNY"); + PrintString(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + PrintLines(3); + + // Set up a BASIC-ish data object + BasicData data = new (bunnyData); + + // Get the first five data values into an array. + // These are the characters we are going to print. + // Unlike the original program, we are only converting + // them to ASCII once. + var a = new char[5]; + for (var i = 0; i < 5; ++i) + { + a[i] = (char)(asciiBase + data.Read()); + } + PrintLines(6); + + PrintLines(1); + var col = 0; + while (true) + { + var x = data.Read(); + if (x < 0) // Start a new line + { + PrintLines(1); + col = 0; + continue; + } + if (x > 128) break; // End processing + col += PrintSpaces(x - col); // Move to TAB position x (sort of) + var y = data.Read(); // Read the next value + for (var i = x; i <= y; ++i) + { + // var j = i - 5 * (i / 5); // BASIC didn't have a modulus operator + Console.Write(a[i % 5]); + // Console.Write(a[col % 5]); // This works, too + ++col; + } + } + PrintLines(6); + } + private static void PrintLines(int count) + { + for (var i = 0; i < count; ++i) + Console.WriteLine(); + } + private static int PrintSpaces(int count) + { + for (var i = 0; i < count; ++i) + Console.Write(' '); + return count; + } + public static void PrintString(int tab, string value, bool newLine = true) + { + PrintSpaces(tab); + Console.Write(value); + if (newLine) Console.WriteLine(); + } + + } +} diff --git a/19_Bunny/csharp/Program.cs b/19_Bunny/csharp/Program.cs new file mode 100644 index 00000000..25604a51 --- /dev/null +++ b/19_Bunny/csharp/Program.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bunny +{ + public static class Program + { + public static void Main() + { + new Bunny().Run(); + } + } +} From 463351287e69aa6507a26f867617f4771acb029d Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Sun, 6 Feb 2022 21:53:50 +0000 Subject: [PATCH 296/337] 95 Weekday - move methods into appropriate? scopes or classes --- 95_Weekday/javascript/weekday.js | 290 +++++++++++++++---------------- 1 file changed, 143 insertions(+), 147 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index 71e29617..69b385d8 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -50,8 +50,10 @@ function tab(spaceCount) { const MONTHS_PER_YEAR = 12; const DAYS_PER_COMMON_YEAR = 365; -const DAYS_PER_IDEAL_MONTH = 30; +const DAYS_PER_IDEALISED_MONTH = 30; const MAXIMUM_DAYS_PER_MONTH = 31; +// In a common (non-leap) year the day of the week for the first of each month moves by the following amounts. +const COMMON_YEAR_MONTH_OFFSET = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; /** * Date representation. @@ -105,6 +107,60 @@ class DateStruct { return result; } + /** + * The following performs a hash on the day parts which guarantees that + * 1. different days will return different numbers + * 2. the numbers returned are ordered. + * @returns {number} + */ + getNormalisedDay() { + return (this.year * MONTHS_PER_YEAR + this.month) * MAXIMUM_DAYS_PER_MONTH + this.day; + } + + /** + * Determine the day of the week. + * This calculation returns a number between 1 and 7 where Sunday=1, Monday=2, ..., Saturday=7. + * @returns {number} Value between 1 and 7 representing Sunday to Saturday. + */ + getDayOfWeek() { + // Calculate an offset based on the century part of the year. + const centuriesSince1500 = Math.floor((this.year - 1500) / 100); + let centuryOffset = centuriesSince1500 * 5 + (centuriesSince1500 + 3) / 4; + centuryOffset = Math.floor(centuryOffset % 7); + + // Calculate an offset based on the shortened two digit year. + // January 1st moves forward by approximately 1.25 days per year + const yearInCentury = this.year % 100; + const yearInCenturyOffsets = yearInCentury / 4 + yearInCentury; + + // combine offsets with day and month + let dayOfWeek = centuryOffset + yearInCenturyOffsets + this.day + COMMON_YEAR_MONTH_OFFSET[this.month - 1]; + + dayOfWeek = Math.floor(dayOfWeek % 7) + 1; + if (this.month <= 2 && this.isLeapYear()) { + dayOfWeek--; + } + if (dayOfWeek === 0) { + dayOfWeek = 7; + } + return dayOfWeek; + } + + /** + * Determine if the given year is a leap year. + * @returns {boolean} + */ + isLeapYear() { + if ((this.year % 4) !== 0) { + return false; + } else if ((this.year % 100) !== 0) { + return true; + } else if ((this.year % 400) !== 0) { + return false; + } + return true; + } + /** * Returns a US formatted date, i.e. Month/Day/Year. * @returns {string} @@ -169,7 +225,7 @@ class Duration { */ #fixRanges() { if (this.#days < 0) { - this.#days += DAYS_PER_IDEAL_MONTH; + this.#days += DAYS_PER_IDEALISED_MONTH; this.#months--; } if (this.#months < 0) { @@ -178,10 +234,6 @@ class Duration { } } - toString() { - return this.#years + "/" + this.#months + "/" + this.#days; - } - /** * Determine approximate Duration between two dates. * This is a naive calculation which assumes all months are 30 days. @@ -195,146 +247,90 @@ class Duration { let days = date1.day - date2.day; return new Duration(years, months, days); } -} -// In a common (non-leap) year the day of the week for the first of each month moves by the following amounts. -const COMMON_YEAR_MONTH_OFFSET = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; - -/** - * Reads a date, and extracts the date information. - * This expects date parts to be comma separated, using US date ordering, - * i.e. Month,Day,Year. - * @returns {Promise} - */ -async function readDateElements() { - let dateString = await input(); - const month = parseInt(dateString); - const day = parseInt(dateString.substr(dateString.indexOf(",") + 1)); - const year = parseInt(dateString.substr(dateString.lastIndexOf(",") + 1)); - return new DateStruct(year, month, day); -} - -/** - * Calculate years, months and days as factor of days. - * This is a naive calculation which assumes all months are 30 days. - * @param factor - * @param dayCount - * @returns {Duration} - */ -function time_spent(factor, dayCount) { - let totalDays = Math.floor(factor * dayCount); - const years = Math.floor(totalDays / DAYS_PER_COMMON_YEAR); - totalDays -= years * DAYS_PER_COMMON_YEAR; - const months = Math.floor(totalDays / DAYS_PER_IDEAL_MONTH); - const days = totalDays - (months * DAYS_PER_IDEAL_MONTH); - return new Duration(years, months, days); -} - -/** - * Print the supplied duration. - * @param {Duration} duration - */ -function printTimeSpent(duration) { - print(duration.years + "\t" + duration.months + "\t" + duration.days + "\n"); -} - -/** - * Determine if the given year is a leap year. - * @param year - * @returns {boolean} - */ -function isLeapYear(year) { - if ((year % 4) !== 0) { - return false; - } else if ((year % 100) !== 0) { - return true; - } else if ((year % 400) !== 0) { - return false; + /** + * Calculate years, months and days as factor of days. + * This is a naive calculation which assumes all months are 30 days. + * @param dayCount Total day to convert to a duration + * @param factor Factor to apply when calculating the duration + * @returns {Duration} + */ + static fromDays(dayCount, factor) { + let totalDays = Math.floor(factor * dayCount); + const years = Math.floor(totalDays / DAYS_PER_COMMON_YEAR); + totalDays -= years * DAYS_PER_COMMON_YEAR; + const months = Math.floor(totalDays / DAYS_PER_IDEALISED_MONTH); + const days = totalDays - (months * DAYS_PER_IDEALISED_MONTH); + return new Duration(years, months, days); } - return true; -} -/** - * Determine the day of the week. - * This calculation returns a number between 1 and 7 where Sunday=1, Monday=2, ..., Saturday=7. - * @param {DateStruct} date - * @returns {number} Value between 1 and 7 representing Sunday to Saturday. - */ -function getDayOfWeek(date) { - // Calculate an offset based on the century part of the year. - const centuriesSince1500 = Math.floor((date.year - 1500) / 100); - let centuryOffset = centuriesSince1500 * 5 + (centuriesSince1500 + 3) / 4; - centuryOffset = Math.floor(centuryOffset % 7); - - // Calculate an offset based on the shortened two digit year. - // January 1st moves forward by approximately 1.25 days per year - const yearInCentury = date.year % 100; - const yearInCenturyOffsets = yearInCentury / 4 + yearInCentury; - - // combine offsets with day and month - let dayOfWeek = centuryOffset + yearInCenturyOffsets + date.day + COMMON_YEAR_MONTH_OFFSET[date.month - 1]; - - dayOfWeek = Math.floor(dayOfWeek % 7) + 1; - if (date.month <= 2 && isLeapYear(date.year)) { - dayOfWeek--; + toString() { + return this.#years + "/" + this.#months + "/" + this.#days; } - if (dayOfWeek === 0) { - dayOfWeek = 7; - } - return dayOfWeek; -} - -/** - * Obtain text for the day of the week. - * @param {DateStruct} date - * @returns {string} - */ -function getDayOfWeekText(date) { - const dayOfWeek = getDayOfWeek(date); - let dayOfWeekText = ""; - switch (dayOfWeek) { - case 1: - dayOfWeekText = "SUNDAY."; - break; - case 2: - dayOfWeekText = "MONDAY."; - break; - case 3: - dayOfWeekText = "TUESDAY."; - break; - case 4: - dayOfWeekText = "WEDNESDAY."; - break; - case 5: - dayOfWeekText = "THURSDAY."; - break; - case 6: - if (date.day === 13) { - dayOfWeekText = "FRIDAY THE THIRTEENTH---BEWARE!"; - } else { - dayOfWeekText = "FRIDAY."; - } - break; - case 7: - dayOfWeekText = "SATURDAY."; - break; - } - return dayOfWeekText; -} - -/** - * The following performs a hash on the day parts which guarantees that - * 1. different days will return different numbers - * 2. the numbers returned are ordered. - * @param {DateStruct} date - * @returns {number} - */ -function getNormalisedDay(date) { - return (date.year * MONTHS_PER_YEAR + date.month) * MAXIMUM_DAYS_PER_MONTH + date.day; } // Main control section async function main() { + /** + * Reads a date, and extracts the date information. + * This expects date parts to be comma separated, using US date ordering, + * i.e. Month,Day,Year. + * @returns {Promise} + */ + async function inputDate() { + let dateString = await input(); + const month = parseInt(dateString); + const day = parseInt(dateString.substr(dateString.indexOf(",") + 1)); + const year = parseInt(dateString.substr(dateString.lastIndexOf(",") + 1)); + return new DateStruct(year, month, day); + } + + /** + * Print the supplied duration. + * @param {Duration} duration + */ + function printTimeSpent(duration) { + print(duration.years + "\t" + duration.months + "\t" + duration.days + "\n"); + } + + /** + * Obtain text for the day of the week. + * @param {DateStruct} date + * @returns {string} + */ + function getDayOfWeekText(date) { + const dayOfWeek = date.getDayOfWeek(); + let dayOfWeekText = ""; + switch (dayOfWeek) { + case 1: + dayOfWeekText = "SUNDAY."; + break; + case 2: + dayOfWeekText = "MONDAY."; + break; + case 3: + dayOfWeekText = "TUESDAY."; + break; + case 4: + dayOfWeekText = "WEDNESDAY."; + break; + case 5: + dayOfWeekText = "THURSDAY."; + break; + case 6: + if (date.day === 13) { + dayOfWeekText = "FRIDAY THE THIRTEENTH---BEWARE!"; + } else { + dayOfWeekText = "FRIDAY."; + } + break; + case 7: + dayOfWeekText = "SATURDAY."; + break; + } + return dayOfWeekText; + } + print(tab(32) + "WEEKDAY\n"); print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"); print("\n"); @@ -344,18 +340,18 @@ async function main() { print("GIVES FACTS ABOUT A DATE OF INTEREST TO YOU.\n"); print("\n"); print("ENTER TODAY'S DATE IN THE FORM: 3,24,1979 "); - const today = await readDateElements(); + const today = await inputDate(); // This program determines the day of the week // for a date after 1582 print("ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST)"); - const dateOfBirth = await readDateElements(); + const dateOfBirth = await inputDate(); print("\n"); // Test for date before current calendar. if (!dateOfBirth.isGregorianDate()) { print("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO X.XV.MDLXXXII.\n"); } else { - const normalisedToday = getNormalisedDay(today); - const normalisedDob = getNormalisedDay(dateOfBirth); + const normalisedToday = today.getNormalisedDay(); + const normalisedDob = dateOfBirth.getNormalisedDay(); let dayOfWeekText = getDayOfWeekText(dateOfBirth); if (normalisedToday < normalisedDob) { @@ -377,29 +373,29 @@ async function main() { print(" \t-----\t------\t----\n"); print("YOUR AGE (IF BIRTHDATE) \t"); printTimeSpent(differenceBetweenDates); - const approximateDaysBetween = (differenceBetweenDates.years * DAYS_PER_COMMON_YEAR) + (differenceBetweenDates.months * DAYS_PER_IDEAL_MONTH) + differenceBetweenDates.days + Math.floor(differenceBetweenDates.months / 2); + const approximateDaysBetween = (differenceBetweenDates.years * DAYS_PER_COMMON_YEAR) + (differenceBetweenDates.months * DAYS_PER_IDEALISED_MONTH) + differenceBetweenDates.days + Math.floor(differenceBetweenDates.months / 2); // Create an object containing time unaccounted for const unaccountedTime = differenceBetweenDates.clone(); // Calculate time spent in the following functions. print("YOU HAVE SLEPT \t\t\t"); - const sleepTimeSpent = time_spent(0.35, approximateDaysBetween); + const sleepTimeSpent = Duration.fromDays(approximateDaysBetween, 0.35); printTimeSpent(sleepTimeSpent); unaccountedTime.remove(sleepTimeSpent); print("YOU HAVE EATEN \t\t\t"); - const eatenTimeSpent = time_spent(0.17, approximateDaysBetween); + const eatenTimeSpent = Duration.fromDays(approximateDaysBetween, 0.17); printTimeSpent(eatenTimeSpent); unaccountedTime.remove(eatenTimeSpent); if (unaccountedTime.years <= 3) { print("YOU HAVE PLAYED \t\t"); } else if (unaccountedTime.years <= 9) { - print("YOU HAVE PLAYED/STUDIED \t\t"); + print("YOU HAVE PLAYED/STUDIED \t"); } else { print("YOU HAVE WORKED/PLAYED \t\t"); } - const workPlayTimeSpent = time_spent(0.23, approximateDaysBetween); + const workPlayTimeSpent = Duration.fromDays(approximateDaysBetween, 0.23); printTimeSpent(workPlayTimeSpent); unaccountedTime.remove(workPlayTimeSpent); From b981f2b9de9f65127b22144d156a61aa5502c6cc Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Sun, 6 Feb 2022 22:38:56 +0000 Subject: [PATCH 297/337] 95 Weekday - move methods into appropriate? scopes or classes --- 95_Weekday/javascript/weekday.js | 82 ++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index 69b385d8..223e17fe 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -52,8 +52,6 @@ const MONTHS_PER_YEAR = 12; const DAYS_PER_COMMON_YEAR = 365; const DAYS_PER_IDEALISED_MONTH = 30; const MAXIMUM_DAYS_PER_MONTH = 31; -// In a common (non-leap) year the day of the week for the first of each month moves by the following amounts. -const COMMON_YEAR_MONTH_OFFSET = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; /** * Date representation. @@ -123,6 +121,9 @@ class DateStruct { * @returns {number} Value between 1 and 7 representing Sunday to Saturday. */ getDayOfWeek() { + // In a common (non-leap) year the day of the week for the first of each month moves by the following amounts. + const COMMON_YEAR_MONTH_OFFSET = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; + // Calculate an offset based on the century part of the year. const centuriesSince1500 = Math.floor((this.year - 1500) / 100); let centuryOffset = centuriesSince1500 * 5 + (centuriesSince1500 + 3) / 4; @@ -234,6 +235,29 @@ class Duration { } } + /** + * Computes an approximation of the days covered by the duration. + * The calculation assumes all years are 365 days, months are 30 days each, + * and adds on an extra bit the more months that have passed. + * @returns {number} + */ + getApproximateDays() { + return ( + (this.#years * DAYS_PER_COMMON_YEAR) + + (this.#months * DAYS_PER_IDEALISED_MONTH) + + this.#days + + Math.floor(this.#months / 2) + ); + } + + /** + * Returns a formatted duration with tab separated values, i.e. Years\tMonths\tDays. + * @returns {string} + */ + toString() { + return this.#years + "\t" + this.#months + "\t" + this.#days; + } + /** * Determine approximate Duration between two dates. * This is a naive calculation which assumes all months are 30 days. @@ -263,10 +287,6 @@ class Duration { const days = totalDays - (months * DAYS_PER_IDEALISED_MONTH); return new Duration(years, months, days); } - - toString() { - return this.#years + "/" + this.#months + "/" + this.#days; - } } // Main control section @@ -285,14 +305,6 @@ async function main() { return new DateStruct(year, month, day); } - /** - * Print the supplied duration. - * @param {Duration} duration - */ - function printTimeSpent(duration) { - print(duration.years + "\t" + duration.months + "\t" + duration.days + "\n"); - } - /** * Obtain text for the day of the week. * @param {DateStruct} date @@ -371,36 +383,34 @@ async function main() { } print(" \tYEARS\tMONTHS\tDAYS\n"); print(" \t-----\t------\t----\n"); - print("YOUR AGE (IF BIRTHDATE) \t"); - printTimeSpent(differenceBetweenDates); - const approximateDaysBetween = (differenceBetweenDates.years * DAYS_PER_COMMON_YEAR) + (differenceBetweenDates.months * DAYS_PER_IDEALISED_MONTH) + differenceBetweenDates.days + Math.floor(differenceBetweenDates.months / 2); - // Create an object containing time unaccounted for + print("YOUR AGE (IF BIRTHDATE) \t" + differenceBetweenDates + "\n"); + + const approximateDaysBetween = differenceBetweenDates.getApproximateDays(); const unaccountedTime = differenceBetweenDates.clone(); - // Calculate time spent in the following functions. - print("YOU HAVE SLEPT \t\t\t"); + // 35% sleeping const sleepTimeSpent = Duration.fromDays(approximateDaysBetween, 0.35); - printTimeSpent(sleepTimeSpent); - + print("YOU HAVE SLEPT \t\t\t" + sleepTimeSpent + "\n"); unaccountedTime.remove(sleepTimeSpent); - print("YOU HAVE EATEN \t\t\t"); + + // 17% eating const eatenTimeSpent = Duration.fromDays(approximateDaysBetween, 0.17); - printTimeSpent(eatenTimeSpent); - + print("YOU HAVE EATEN \t\t\t" + eatenTimeSpent + "\n"); unaccountedTime.remove(eatenTimeSpent); - if (unaccountedTime.years <= 3) { - print("YOU HAVE PLAYED \t\t"); - } else if (unaccountedTime.years <= 9) { - print("YOU HAVE PLAYED/STUDIED \t"); - } else { - print("YOU HAVE WORKED/PLAYED \t\t"); - } - const workPlayTimeSpent = Duration.fromDays(approximateDaysBetween, 0.23); - printTimeSpent(workPlayTimeSpent); + // 23% working, studying or playing + const workPlayTimeSpent = Duration.fromDays(approximateDaysBetween, 0.23); + if (unaccountedTime.years <= 3) { + print("YOU HAVE PLAYED \t\t" + workPlayTimeSpent + "\n"); + } else if (unaccountedTime.years <= 9) { + print("YOU HAVE PLAYED/STUDIED \t" + workPlayTimeSpent + "\n"); + } else { + print("YOU HAVE WORKED/PLAYED \t\t" + workPlayTimeSpent + "\n"); + } unaccountedTime.remove(workPlayTimeSpent); - print("YOU HAVE RELAXED \t\t"); - printTimeSpent(unaccountedTime); + + // Remaining time spent relaxing + print("YOU HAVE RELAXED \t\t" + unaccountedTime + "\n"); const retirementYear = dateOfBirth.year + 65; print("\n"); From 9a76fa76fbf8ac9af76cbf291acf417e043a6b91 Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Sun, 6 Feb 2022 22:40:07 +0000 Subject: [PATCH 298/337] 95 Weekday - move methods into appropriate? scopes or classes --- 95_Weekday/javascript/weekday.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index 223e17fe..6070c71c 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -52,6 +52,8 @@ const MONTHS_PER_YEAR = 12; const DAYS_PER_COMMON_YEAR = 365; const DAYS_PER_IDEALISED_MONTH = 30; const MAXIMUM_DAYS_PER_MONTH = 31; +// In a common (non-leap) year the day of the week for the first of each month moves by the following amounts. +const COMMON_YEAR_MONTH_OFFSET = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; /** * Date representation. @@ -121,9 +123,6 @@ class DateStruct { * @returns {number} Value between 1 and 7 representing Sunday to Saturday. */ getDayOfWeek() { - // In a common (non-leap) year the day of the week for the first of each month moves by the following amounts. - const COMMON_YEAR_MONTH_OFFSET = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; - // Calculate an offset based on the century part of the year. const centuriesSince1500 = Math.floor((this.year - 1500) / 100); let centuryOffset = centuriesSince1500 * 5 + (centuriesSince1500 + 3) / 4; From ea190fda3314ee28e3fa19ac015c7a989ad77231 Mon Sep 17 00:00:00 2001 From: roygilliam <58305899+roygilliam@users.noreply.github.com> Date: Sun, 6 Feb 2022 19:30:59 -0500 Subject: [PATCH 299/337] Initial conversion to C# --- 81_Splat/csharp/Program.cs | 330 +++++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 81_Splat/csharp/Program.cs diff --git a/81_Splat/csharp/Program.cs b/81_Splat/csharp/Program.cs new file mode 100644 index 00000000..a128ef0f --- /dev/null +++ b/81_Splat/csharp/Program.cs @@ -0,0 +1,330 @@ +using System.Collections; +using System.Text; + +namespace Splat +{ + class Splat + { + private ArrayList DistanceLog = new ArrayList(); + + private string[][] AccelerationData = + { + new string[] {"Fine. You're on Mercury. Acceleration={0} ft/sec/sec", "12.2"}, + new string[] {"All right. You're on Venus. Acceleration={0} ft/sec/sec", "28.3"}, + new string[] {"Then you're on Earth. Acceleration={0} ft/sec/sec", "32.16"}, + new string[] {"Fine. You're on the Moon. Acceleration={0} ft/sec/sec", "5.15"}, + new string[] {"All right. You're on Mars. Acceleration={0} ft/sec/sec", "12.5"}, + new string[] {"Then you're on Jupiter. Acceleration={0} ft/sec/sec", "85.2"}, + new string[] {"Fine. You're on Saturn. Acceleration={0} ft/sec/sec", "37.6"}, + new string[] {"All right. You're on Uranus. Acceleration={0} ft/sec/sec", "33.8"}, + new string[] {"Then you're on Neptune. Acceleration={0} ft/sec/sec", "39.6"}, + new string[] {"Fine. You're on the Sun. Acceleration={0} ft/sec/sec", "896"} + }; + + private void DisplayIntro() + { + Console.WriteLine(""); + Console.WriteLine("SPLAT".PadLeft(23)); + Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Console.WriteLine(""); + Console.WriteLine("Welcome to 'Splat' -- the game that simulates a parachute"); + Console.WriteLine("jump. Try to open your chute at the last possible"); + Console.WriteLine("moment without going splat."); + Console.WriteLine(""); + } + + private bool PromptYesNo(string Prompt) + { + bool Success = false; + + while (!Success) + { + Console.Write(Prompt); + string LineInput = Console.ReadLine().Trim().ToLower(); + + if (LineInput.Equals("yes")) + return true; + else if (LineInput.Equals("no")) + return false; + else + Console.WriteLine("Yes or No"); + } + + return false; + } + + private void WriteRandomBadResult() + { + string[] BadResults = {"Requiescat in pace.","May the Angel of Heaven lead you into paradise.", + "Rest in peace.","Son-of-a-gun.","#$%&&%!$","A kick in the pants is a boost if you're headed right.", + "Hmmm. Should have picked a shorter time.","Mutter. Mutter. Mutter.","Pushing up daisies.", + "Easy come, easy go."}; + + Random rand = new Random(); + + Console.WriteLine(BadResults[rand.Next(BadResults.Length)]); + } + + private void WriteColumnOutput(double Column1, double Column2) + { + + Console.WriteLine("{0,-11:N3} {1,-17:N2}", Column1, Column2); + + } + + private void WriteColumnOutput(double Column1, string Column2) + { + + Console.WriteLine("{0,-11:N3} {1,-17}", Column1, Column2); + + } + + private void WriteColumnOutput(string Column1, string Column2) + { + + Console.WriteLine("{0,-11} {1,-17}", Column1, Column2); + + } + + private void WriteSuccessfulResults(double Distance) + { + // Add new result + DistanceLog.Add(Distance); + + // Sort by distance + DistanceLog.Sort(); + + int ArrayLength = DistanceLog.Count; + + // If 1st, 2nd, or 3rd jump then write a special message + if (ArrayLength <= 3) + { + Console.Write("Amazing!!! Not bad for your "); + if (ArrayLength == 1) + Console.Write("1st "); + else if (ArrayLength == 2) + Console.Write("2nd "); + else + Console.Write("3rd "); + Console.WriteLine("successful jump!!!"); + } + // Otherwise write a message based on where this jump falls in the list + else + { + int JumpPosition = DistanceLog.IndexOf(Distance); + + + if (ArrayLength - JumpPosition <= .1 * ArrayLength) + { + Console.WriteLine("Wow! That's some jumping. Of the {0} successful jumps", ArrayLength); + Console.WriteLine("before yours, only {0} opened their chutes lower than", (ArrayLength - JumpPosition)); + Console.WriteLine("you did."); + } + else if (ArrayLength - JumpPosition <= .25 * ArrayLength) + { + Console.WriteLine("Pretty good! {0} successful jumps preceded yours and only", ArrayLength - 1); + Console.WriteLine("{0} of them got lower than you did before their chutes", (ArrayLength - 1 - JumpPosition)); + Console.WriteLine("opened."); + } + else if (ArrayLength - JumpPosition <= .5 * ArrayLength) + { + Console.WriteLine("Not bad. There have been {0} successful jumps before yours.", ArrayLength - 1); + Console.WriteLine("You were beaten out by {0} of them.", (ArrayLength - 1 - JumpPosition)); + } + else if (ArrayLength - JumpPosition <= .75 * ArrayLength) + { + Console.WriteLine("Conservative aren't you? You ranked only {0} in the", (ArrayLength - JumpPosition)); + Console.WriteLine("{0} successful jumps before yours.", ArrayLength - 1); + } + else if (ArrayLength - JumpPosition <= .9 * ArrayLength) + { + Console.WriteLine("Humph! Don't you have any sporting blood? There were"); + Console.WriteLine("{0} successful jumps before yours and you came in {1} jumps", ArrayLength - 1, JumpPosition); + Console.WriteLine("better than the worst. Shape up!!!"); + } + else + { + Console.WriteLine("Hey! You pulled the rip cord much too soon. {0} successful", ArrayLength - 1); + Console.WriteLine("jumps before yours and you came in number {0}! Get with it!", (ArrayLength - JumpPosition)); + } + } + + } + + private void PlayOneRound() + { + bool InputSuccess = false; + Random rand = new Random(); + double Velocity = 0; + double TerminalVelocity = 0; + double Acceleration = 0; + double AccelerationInput = 0; + double Altitude = ((9001 * rand.NextDouble()) + 1000); + double SecondsTimer = 0; + double Distance = 0; + bool TerminalVelocityReached = false; + + Console.WriteLine(""); + + // Determine the terminal velocity (user or system) + if (PromptYesNo("Select your own terminal velocity (yes or no)? ")) + { + // Prompt user to enter the terminal velocity of their choice + while (!InputSuccess) + { + Console.Write("What terminal velocity (mi/hr)? "); + string Input = Console.ReadLine().Trim(); + InputSuccess = double.TryParse(Input, out TerminalVelocity); + if (!InputSuccess) + Console.WriteLine("*** Please enter a valid number ***"); + } + } + else + { + TerminalVelocity = rand.NextDouble() * 1000; + Console.WriteLine("OK. Terminal Velocity = {0:N0} mi/hr", (TerminalVelocity)); + } + + // Convert Terminal Velocity to ft/sec + TerminalVelocity = TerminalVelocity * 5280 / 3600; + + // Not sure what this calculation is + Velocity = TerminalVelocity + ((TerminalVelocity * rand.NextDouble()) / 20) - ((TerminalVelocity * rand.NextDouble()) / 20); + + // Determine acceleration due to gravity (user or system) + if (PromptYesNo("Want to select acceleration due to gravity (yes or no)? ")) + { + // Prompt user to enter the acceleration of their choice + InputSuccess = false; + while (!InputSuccess) + { + Console.Write("What acceleration (ft/sec/sec)? "); + string Input = Console.ReadLine().Trim(); + InputSuccess = double.TryParse(Input, out AccelerationInput); + if (!InputSuccess) + Console.WriteLine("*** Please enter a valid number ***"); + } + } + else + { + // Choose a random acceleration entry from the data array + int Index = rand.Next(0, AccelerationData.Length); + Double.TryParse(AccelerationData[Index][1], out AccelerationInput); + + // Display the corresponding planet this acceleration exists on and the value + Console.WriteLine(AccelerationData[Index][0], AccelerationInput.ToString()); + } + + Acceleration = AccelerationInput + ((AccelerationInput * rand.NextDouble()) / 20) - ((AccelerationInput * rand.NextDouble()) / 20); + + Console.WriteLine(""); + Console.WriteLine(" Altitude = {0:N0} ft", Altitude); + Console.WriteLine(" Term. Velocity = {0:N3} ft/sec +/-5%", TerminalVelocity); + Console.WriteLine(" Acceleration = {0:N2} ft/sec/sec +/-5%", AccelerationInput); + Console.WriteLine("Set the timer for your freefall."); + + // Prompt for how many seconds the fall should be before opening the chute + InputSuccess = false; + while (!InputSuccess) + { + Console.Write("How many seconds? "); + string Input = Console.ReadLine().Trim(); + InputSuccess = double.TryParse(Input, out SecondsTimer); + if (!InputSuccess) + Console.WriteLine("*** Please enter a valid number ***"); + } + + // Begin the drop! + Console.WriteLine("Here we go."); + Console.WriteLine(""); + + WriteColumnOutput("Time (sec)", "Dist to Fall (ft)"); + WriteColumnOutput("==========", "================="); + + // Loop through the number of seconds stepping by 8 intervals + for (double i = 0; i < SecondsTimer; i+=(SecondsTimer/8)) + { + if (i > (Velocity / Acceleration)) + { + // Terminal Velocity achieved. Only print out the warning once. + if (TerminalVelocityReached == false) + Console.WriteLine("Terminal velocity reached at T plus {0:N4} seconds.", (Velocity / Acceleration)); + + TerminalVelocityReached = true; + } + + // Calculate distance dependent upon whether terminal velocity has been reached + if (TerminalVelocityReached) + { + Distance = Altitude - ((Math.Pow(Velocity,2) / (2 * Acceleration)) + (Velocity * (i - (Velocity / Acceleration)))); + } + else + { + Distance = Altitude - ((Acceleration / 2) * Math.Pow(i,2)); + } + + // Was the ground hit? If so, then SPLAT! + if (Distance <= 0) + { + if (TerminalVelocityReached) + { + WriteColumnOutput((Velocity / Acceleration) + ((Altitude - (Math.Pow(Velocity,2) / (2 * Acceleration))) / Velocity).ToString(), "SPLAT"); + } + else + { + WriteColumnOutput(Math.Sqrt(2 * Altitude / Acceleration), "SPLAT"); + } + + WriteRandomBadResult(); + + Console.WriteLine("I'll give you another chance."); + break; + } + else + { + WriteColumnOutput(i, Distance); + } + } + + // If the number of seconds of drop ended and we are still above ground then success! + if (Distance > 0) + { + // We made it! Chutes open! + Console.WriteLine("Chute Open"); + + // Store succesful jump and write out a fun message + WriteSuccessfulResults(Distance); + } + + } + + public void PlayTheGame() + { + bool ContinuePlay = false; + + DisplayIntro(); + + do + { + PlayOneRound(); + + ContinuePlay = PromptYesNo("Do you want to play again? "); + if (!ContinuePlay) + ContinuePlay = PromptYesNo("Please? "); + } + while (ContinuePlay); + + Console.WriteLine("SSSSSSSSSS."); + + } + } + class Program + { + static void Main(string[] args) + { + + new Splat().PlayTheGame(); + + } + } +} \ No newline at end of file From 00235289d0cc4a88b93c0885b065d1dee9e0cc63 Mon Sep 17 00:00:00 2001 From: "stephan.com" Date: Sun, 6 Feb 2022 22:22:29 -0800 Subject: [PATCH 300/337] 94_war: ruby --- 94_War/ruby/war.rb | 118 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 94_War/ruby/war.rb diff --git a/94_War/ruby/war.rb b/94_War/ruby/war.rb new file mode 100644 index 00000000..cf7e8a59 --- /dev/null +++ b/94_War/ruby/war.rb @@ -0,0 +1,118 @@ +#!/usr/bin/env ruby +# reinterpreted from BASIC by stephan.com +class War + class Card + class CardError < StandardError; end + + SUITS = %i[spades hearts clubs diamonds].freeze + PIPS = %i[ace deuce trey four five six seven eight nine ten jack king queen].freeze + CARDS = SUITS.product(PIPS).freeze + VALUES = PIPS.zip(1..13).to_h.freeze + + attr_reader :value + + def initialize(suit, pip) + @suit = suit + @pip = pip + raise CardError, 'invalid suit' unless SUITS.include? @suit + raise CardError, 'invalid pip' unless PIPS.include? @pip + + @value = VALUES[pip] + end + + def <=>(other) + @value <=> other.value + end + + def >(other) + @value > other.value + end + + def <(other) + @value < other.value + end + + def to_s + "the #{@pip} of #{@suit}" + end + + def self.shuffle + CARDS.map { |suit, pip| new(suit, pip) }.shuffle + end + end + + def initialize + @your_score = 0 + @computer_score = 0 + @your_deck = Card.shuffle + @computer_deck = Card.shuffle + end + + def play + intro + + loop do + puts "\nYou: #{@your_score} Computer: #{@computer_score}" + round @your_deck.shift, @computer_deck.shift + break if empty? + + puts 'Do you want to continue?' + break unless yesno + end + + outro + end + + private + + def round(your_card, computer_card) + puts "You: #{your_card} vs Computer: #{computer_card}" + return puts 'Tie. No score change.' if your_card == computer_card + + if computer_card > your_card + puts "Computer wins with #{computer_card}" + @computer_score += 1 + else + puts "You win with #{your_card}" + @your_score += 1 + end + end + + def yesno + loop do + wants = gets.strip + return true if wants.downcase == 'yes' + return false if wants.downcase == 'no' + + puts 'Yes or no, please.' + end + end + + def intro + puts 'War'.center(80) + puts 'stephan.com'.center(80) + puts + puts 'This is the card game of war.' + puts 'Do you want directions' + directions if yesno + end + + def directions + puts 'The computer gives you and it a \'card\'. The higher card' + puts '(numerically) wins. The game ends when you choose not to' + puts 'continue or when you have finished the pack.' + puts + end + + def outro + puts "We've run out of cards" if empty? + puts "Final score:\nYou: #{@your_score}\nComputer: #{@computer_score}" + puts 'Thanks for playing!' + end + + def empty? + @your_deck.empty? || @computer_deck.empty? + end +end + +War.new.play From 5f3aadd2b38c72bf9dd761b2809108f73ac32a01 Mon Sep 17 00:00:00 2001 From: Steve Bosman Date: Mon, 7 Feb 2022 21:24:07 +0000 Subject: [PATCH 301/337] 94 War - allow case insensitive input --- 94_War/javascript/war.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/94_War/javascript/war.js b/94_War/javascript/war.js index ededa1ed..ca11d063 100644 --- a/94_War/javascript/war.js +++ b/94_War/javascript/war.js @@ -39,11 +39,11 @@ function input() { async function askYesOrNo(question) { while (1) { print(question); - const str = await input(); - if (str == "YES") { + const str = (await input()).toUpperCase(); + if (str === "YES") { return true; } - else if (str == "NO") { + else if (str === "NO") { return false; } else { From b36966b235cc3364c0932cc5d7f6c9c9bba25e27 Mon Sep 17 00:00:00 2001 From: "stephan.com" Date: Mon, 7 Feb 2022 17:13:30 -0800 Subject: [PATCH 302/337] 06-Banner: ruby --- 06_Banner/ruby/banner.rb | 92 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100755 06_Banner/ruby/banner.rb diff --git a/06_Banner/ruby/banner.rb b/06_Banner/ruby/banner.rb new file mode 100755 index 00000000..53136dbd --- /dev/null +++ b/06_Banner/ruby/banner.rb @@ -0,0 +1,92 @@ +#!/usr/bin/env ruby + +# Banner +# reinterpreted from BASIC by stephan.com + +# this implementation diverges from the original in some notable +# ways, but maintains the same font definition as before as well +# as the same somewhat bizarre way of interpreting it. It would +# be more efficient to redesign the font to allow `"%09b" % row` +# and then some substitutions. + +FONT = { + ' ' => [0, 0, 0, 0, 0, 0, 0].freeze, + '!' => [1, 1, 1, 384, 1, 1, 1].freeze, + '*' => [69, 41, 17, 512, 17, 41, 69].freeze, + '.' => [1, 1, 129, 449, 129, 1, 1].freeze, + '0' => [57, 69, 131, 258, 131, 69, 57].freeze, + '1' => [0, 0, 261, 259, 512, 257, 257].freeze, + '2' => [261, 387, 322, 290, 274, 267, 261].freeze, + '3' => [66, 130, 258, 274, 266, 150, 100].freeze, + '4' => [33, 49, 41, 37, 35, 512, 33].freeze, + '5' => [160, 274, 274, 274, 274, 274, 226].freeze, + '6' => [194, 291, 293, 297, 305, 289, 193].freeze, + '7' => [258, 130, 66, 34, 18, 10, 8].freeze, + '8' => [69, 171, 274, 274, 274, 171, 69].freeze, + '9' => [263, 138, 74, 42, 26, 10, 7].freeze, + '=' => [41, 41, 41, 41, 41, 41, 41].freeze, + '?' => [5, 3, 2, 354, 18, 11, 5].freeze, + 'a' => [505, 37, 35, 34, 35, 37, 505].freeze, + 'b' => [512, 274, 274, 274, 274, 274, 239].freeze, + 'c' => [125, 131, 258, 258, 258, 131, 69].freeze, + 'd' => [512, 258, 258, 258, 258, 131, 125].freeze, + 'e' => [512, 274, 274, 274, 274, 258, 258].freeze, + 'f' => [512, 18, 18, 18, 18, 2, 2].freeze, + 'g' => [125, 131, 258, 258, 290, 163, 101].freeze, + 'h' => [512, 17, 17, 17, 17, 17, 512].freeze, + 'i' => [258, 258, 258, 512, 258, 258, 258].freeze, + 'j' => [65, 129, 257, 257, 257, 129, 128].freeze, + 'k' => [512, 17, 17, 41, 69, 131, 258].freeze, + 'l' => [512, 257, 257, 257, 257, 257, 257].freeze, + 'm' => [512, 7, 13, 25, 13, 7, 512].freeze, + 'n' => [512, 7, 9, 17, 33, 193, 512].freeze, + 'o' => [125, 131, 258, 258, 258, 131, 125].freeze, + 'p' => [512, 18, 18, 18, 18, 18, 15].freeze, + 'q' => [125, 131, 258, 258, 322, 131, 381].freeze, + 'r' => [512, 18, 18, 50, 82, 146, 271].freeze, + 's' => [69, 139, 274, 274, 274, 163, 69].freeze, + 't' => [2, 2, 2, 512, 2, 2, 2].freeze, + 'u' => [128, 129, 257, 257, 257, 129, 128].freeze, + 'v' => [64, 65, 129, 257, 129, 65, 64].freeze, + 'w' => [256, 257, 129, 65, 129, 257, 256].freeze, + 'x' => [388, 69, 41, 17, 41, 69, 388].freeze, + 'y' => [8, 9, 17, 481, 17, 9, 8].freeze, + 'z' => [386, 322, 290, 274, 266, 262, 260].freeze +}.freeze + +puts 'horizontal' +x = gets.strip.to_i +puts 'vertical' +y = gets.strip.to_i +puts 'centered' +centered = gets.strip.downcase.chars.first == 'y' +puts 'character ("all" for character being printed)' +fill = gets.strip.downcase +puts 'statement' +statement = gets.strip.downcase + +all = (fill.downcase == 'all') +lenxs = all ? 1 : fill.length +start = 1 +start += (63 - 4.5 * y) / lenxs if centered + +statement.each_char do |char| + next puts "\n" * 7 * x if char == ' ' + + xs = all ? char : fill + FONT[char].each do |su| + print ' ' * start + 8.downto(0) do |k| + if (1 << k) < su + print xs * y + su -= (1 << k) + else + print ' ' * (y * lenxs) + end + end + puts + end + + (2 * x).times { puts } +end +75.times { puts } From f0c869037a83ab8fce6ee253ca4fbbf3d2eda67b Mon Sep 17 00:00:00 2001 From: "stephan.com" Date: Tue, 8 Feb 2022 17:13:08 -0800 Subject: [PATCH 303/337] remove extra folder there appear to be two Russian Roulette folders in the repo, one with spaces and the other with dashes. The one with spaces contains nothing but a perl implementation, which is identical to the one in `76_Russian_Roulette/perl/russianroulette.pl` --- 76 Russian Roulette/perl/russianroulette.pl | 39 --------------------- 1 file changed, 39 deletions(-) delete mode 100644 76 Russian Roulette/perl/russianroulette.pl diff --git a/76 Russian Roulette/perl/russianroulette.pl b/76 Russian Roulette/perl/russianroulette.pl deleted file mode 100644 index 0fa0cff7..00000000 --- a/76 Russian Roulette/perl/russianroulette.pl +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/perl -#use strict; -# Automatic converted by bas2perl.pl - -print ' 'x28 . "RUSSIAN ROULETTE\n"; -print ' 'x15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; -print "\n"; print "\n"; print "\n"; -print "THIS IS A GAME OF >>>>>>>>>>RUSSIAN ROULETTE.\n"; -Line10: -print "\n"; print "HERE IS A REVOLVER.\n"; -Line20: -print "TYPE '1' TO SPIN CHAMBER AND PULL TRIGGER.\n"; -print "TYPE '2' TO GIVE UP.\n"; -print "GO"; -$N=0; -Line30: -print "? "; chomp($I = ); -if ($I ne 2) { goto Line35; } -print " CHICKEN!!!!!\n"; -goto Line72; -Line35: -$N=$N+1; -if (rand(1)>.833333) { goto Line70; } -if ($N>10) { goto Line80; } -print "- CLICK -\n"; -print "\n"; goto Line30; -Line70: -print " BANG!!!!! YOU'RE DEAD!\n"; -print "CONDOLENCES WILL BE SENT TO YOUR RELATIVES.\n"; -Line72: -print "\n"; print "\n"; print "\n"; -print "...NEXT VICTIM...\n"; goto Line20; -Line80: -print "YOU WIN!!!!!\n"; -print "LET SOMEONE ELSE BLOW HIS BRAINS OUT.\n"; -goto Line10; -exit; - - From ba9ca01206467088129dbf4e968ae3124f425584 Mon Sep 17 00:00:00 2001 From: "stephan.com" Date: Tue, 8 Feb 2022 17:41:28 -0800 Subject: [PATCH 304/337] 52-Kinema: ruby --- 52_Kinema/ruby/kinema.rb | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 52_Kinema/ruby/kinema.rb diff --git a/52_Kinema/ruby/kinema.rb b/52_Kinema/ruby/kinema.rb new file mode 100644 index 00000000..27ed2aa2 --- /dev/null +++ b/52_Kinema/ruby/kinema.rb @@ -0,0 +1,45 @@ +#!/usr/bin/env ruby + +# Kinema +# reinterpreted from BASIC by stephan.com + +EPSILON = 0.15 + +def close?(guess, answer) + (guess-answer).abs < answer * EPSILON +end + +def ask(text, answer) + puts text + guess = gets.strip.to_f + if close?(guess, answer) + puts 'Close enough' + @score += 1 + else + puts 'Not even close....' + end + + puts "Correct answer is #{answer}" +end + +puts 'Kinema'.center(80) +puts 'Adapted by stephan.com'.center(80) +puts; puts; puts; + +loop do + puts; puts + @score = 0 + v = 5 + rand(35) + + puts "A ball is thrown upwards at #{v} meters per second" + + ask 'How high will it go? (in meters)', 0.05 * v * v + ask 'How long until it returns? (in seconds)', v/5.0 + + t = 1 + rand(2*v)/10.0 + ask "What will its velocity be after #{t} seconds?", v - 10 * t + puts + print "#{@score} right out of 3." + print " not bad" if @score > 1 + puts +end From 72864de3a8d95c4d71017c6685fa19a9afe0b502 Mon Sep 17 00:00:00 2001 From: "stephan.com" Date: Tue, 8 Feb 2022 21:38:40 -0800 Subject: [PATCH 305/337] 54-Letter: ruby --- 54_Letter/ruby/letter.rb | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 54_Letter/ruby/letter.rb diff --git a/54_Letter/ruby/letter.rb b/54_Letter/ruby/letter.rb new file mode 100644 index 00000000..c4c7a00c --- /dev/null +++ b/54_Letter/ruby/letter.rb @@ -0,0 +1,45 @@ +#!/usr/bin/env ruby + +# Kinema +# reinterpreted from BASIC by stephan.com + +puts 'Letter'.center(80) +puts 'Adapted by stephan.com'.center(80) +puts "\n\n\n" + +puts "Letter guessing game\n\n" + +puts "I'll think of a letter of the alphabet, A to Z." +puts "Try to guess my letter and I'll give you clues" +puts "as to how close you're getting to my letter." + +def win(turns) + puts "\nyou got it in #{turns} guesses!!" + return puts "but it shouldn't take more than 5 guesses!" if turns > 5 + + puts "good job !!!!!\a\a\a" +end + +def play + letter = ('A'..'Z').to_a.sample + guess = nil + turn = 0 + + puts "\nO.K., I have a letter. Start guessing." + + until guess == letter + puts "\nWhat is your guess?" + + guess = gets.strip.chars.first.upcase + turn += 1 + + puts 'Too low. Try a higher letter.' if guess < letter + puts 'Too high. Try a lower letter.' if guess > letter + end + win(turn) +end + +loop do + play + puts "\nlet's play again....." +end From b59eba353407c14e84874021d39fb707612cdac8 Mon Sep 17 00:00:00 2001 From: ribtips Date: Fri, 11 Feb 2022 12:12:02 -0500 Subject: [PATCH 306/337] modified the AI logic to make it a bit more difficult --- 89_Tic-Tac-Toe/perl/tictactoe2.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/89_Tic-Tac-Toe/perl/tictactoe2.pl b/89_Tic-Tac-Toe/perl/tictactoe2.pl index 0cbf4c10..4bc7cc0b 100644 --- a/89_Tic-Tac-Toe/perl/tictactoe2.pl +++ b/89_Tic-Tac-Toe/perl/tictactoe2.pl @@ -110,7 +110,7 @@ sub check_for_corners { @precedence=(1,9,7,3,5,2,4,6,8); } else { - @precedence=(5,1,9,7,3,2,4,6,8); + @precedence=(5,2,4,6,8,1,9,7,3); } foreach my $move (@precedence) { my $validity=&check_occupation($move); @@ -166,7 +166,7 @@ sub check_occupation { sub print_board { foreach my $num (1..9) { - my $char = &which_char($board{$num}); + my $char = &which_char($board{$num}); if ($num == 4 || $num == 7) { print "\n---+---+---\n";} print "$char"; if ($num % 3 > 0) { print "!" } From c542abf3df580708286a3f3270ec39ffd6b2c931 Mon Sep 17 00:00:00 2001 From: Paul Sobolik Date: Fri, 11 Feb 2022 19:58:03 -0500 Subject: [PATCH 307/337] Node app to find unimplemented games by language --- 00_Utilities/find-unimplemented.js | 73 ++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 00_Utilities/find-unimplemented.js diff --git a/00_Utilities/find-unimplemented.js b/00_Utilities/find-unimplemented.js new file mode 100644 index 00000000..41641f52 --- /dev/null +++ b/00_Utilities/find-unimplemented.js @@ -0,0 +1,73 @@ +/** + * Program to show unimplemented games by language, optionally filtered by + * language + * + * Usage: node find-unimplemented.js [[[lang1] lang2] ...] + * + * Adapted from find-missing-implementtion.js + */ + +const fs = require("fs"); +const glob = require("glob"); + +// relative path to the repository root +const ROOT_PATH = "../."; + +let languages = [ + { name: "csharp", extension: "cs" }, + { name: "java", extension: "java" }, + { name: "javascript", extension: "html" }, + { name: "pascal", extension: "pas" }, + { name: "perl", extension: "pl" }, + { name: "python", extension: "py" }, + { name: "ruby", extension: "rb" }, + { name: "vbnet", extension: "vb" }, +]; + +const getFilesRecursive = async (path, extension) => { + return new Promise((resolve, reject) => { + glob(`${path}/**/*.${extension}`, (err, matches) => { + if (err) { + reject(err); + } + resolve(matches); + }); + }); +}; + +const getPuzzleFolders = () => { + return fs + .readdirSync(ROOT_PATH, { withFileTypes: true }) + .filter((dirEntry) => dirEntry.isDirectory()) + .filter( + (dirEntry) => + ![".git", "node_modules", "00_Utilities", "buildJvm"].includes(dirEntry.name) + ) + .map((dirEntry) => dirEntry.name); +}; + +(async () => { + const result = {}; + if (process.argv.length > 2) { + languages = languages.filter((language) => process.argv.slice(2).includes(language.name)); + } + for (const { name: language } of languages) { + result[language] = []; + } + + const puzzleFolders = getPuzzleFolders(); + for (const puzzleFolder of puzzleFolders) { + for (const { name: language, extension } of languages) { + const files = await getFilesRecursive( + `${ROOT_PATH}/${puzzleFolder}/${language}`, extension + ); + if (files.length === 0) { + result[language].push(puzzleFolder); + } + } + } + console.log('Unimplementation by language:') + console.dir(result); +})(); + +return; From b5be39ebee5a380764c07223713ab8fe46b4ade3 Mon Sep 17 00:00:00 2001 From: roygilliam <58305899+roygilliam@users.noreply.github.com> Date: Sun, 13 Feb 2022 16:46:49 -0500 Subject: [PATCH 308/337] Initial C# conversion --- 79_Slalom/csharp/program.cs | 433 ++++++++++++++++++++++++++++++++++++ 1 file changed, 433 insertions(+) create mode 100644 79_Slalom/csharp/program.cs diff --git a/79_Slalom/csharp/program.cs b/79_Slalom/csharp/program.cs new file mode 100644 index 00000000..2d3b07d9 --- /dev/null +++ b/79_Slalom/csharp/program.cs @@ -0,0 +1,433 @@ +using System.Text; + +namespace Slalom +{ + class Slalom + { + private int[] GateMaxSpeed = { 14,18,26,29,18,25,28,32,29,20,29,29,25,21,26,29,20,21,20, + 18,26,25,33,31,22 }; + + private int GoldMedals = 0; + private int SilverMedals = 0; + private int BronzeMedals = 0; + private void DisplayIntro() + { + Console.WriteLine(""); + Console.WriteLine("SLALOM".PadLeft(23)); + Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Console.WriteLine(""); + } + + private void DisplayInstructions() + { + Console.WriteLine(); + Console.WriteLine("*** Slalom: This is the 1976 Winter Olympic Giant Slalom. You are"); + Console.WriteLine(" the American team's only hope of a gold medal."); + Console.WriteLine(); + Console.WriteLine(" 0 -- Type this if you want to see how long you've taken."); + Console.WriteLine(" 1 -- Type this if you want to speed up a lot."); + Console.WriteLine(" 2 -- Type this if you want to speed up a little."); + Console.WriteLine(" 3 -- Type this if you want to speed up a teensy."); + Console.WriteLine(" 4 -- Type this if you want to keep going the same speed."); + Console.WriteLine(" 5 -- Type this if you want to check a teensy."); + Console.WriteLine(" 6 -- Type this if you want to check a litte."); + Console.WriteLine(" 7 -- Type this if you want to check a lot."); + Console.WriteLine(" 8 -- Type this if you want to cheat and try to skip a gate."); + Console.WriteLine(); + Console.WriteLine(" The place to use these options is when the computer asks:"); + Console.WriteLine(); + Console.WriteLine("Option?"); + Console.WriteLine(); + Console.WriteLine(" Good Luck!"); + Console.WriteLine(); + } + + private bool PromptYesNo(string Prompt) + { + bool Success = false; + + while (!Success) + { + Console.Write(Prompt); + string LineInput = Console.ReadLine().Trim().ToLower(); + + if (LineInput.Equals("yes")) + return true; + else if (LineInput.Equals("no")) + return false; + else + Console.WriteLine("Please type 'YES' or 'NO'"); + } + + return false; + } + + private int PromptForGates() + { + bool Success = false; + int NumberOfGates = 0; + + while (!Success) + { + Console.Write("How many gates does this course have (1 to 25) "); + string LineInput = Console.ReadLine().Trim().ToLower(); + + if (int.TryParse(LineInput, out NumberOfGates)) + { + if (NumberOfGates >= 1 && NumberOfGates <= 25) + { + Success = true; + } + else if (NumberOfGates < 1) + { + Console.WriteLine("Try again,"); + } + else // greater than 25 + { + Console.WriteLine("25 is the limit."); + NumberOfGates = 25; + Success = true; + } + } + else + { + Console.WriteLine("Try again,"); + } + } + + return NumberOfGates; + } + + private int PromptForRate() + { + bool Success = false; + int Rating = 0; + + while (!Success) + { + Console.Write("Rate yourself as a skier, (1=worst, 3=best) "); + string LineInput = Console.ReadLine().Trim().ToLower(); + + if (int.TryParse(LineInput, out Rating)) + { + if (Rating >= 1 && Rating <= 3) + { + Success = true; + } + else + { + Console.WriteLine("The bounds are 1-3"); + } + } + else + { + Console.WriteLine("The bounds are 1-3"); + } + } + + return Rating; + } + + private int PromptForOption() + { + bool Success = false; + int Option = 0; + + while (!Success) + { + Console.Write("Option? "); + string LineInput = Console.ReadLine().Trim().ToLower(); + + if (int.TryParse(LineInput, out Option)) + { + if (Option >= 0 && Option <= 8) + { + Success = true; + } + else if (Option > 8) + { + Console.WriteLine("What?"); + } + } + else + { + Console.WriteLine("What?"); + } + } + + return Option; + } + + private string PromptForCommand() + { + bool Success = false; + string Result = ""; + + Console.WriteLine(); + Console.WriteLine("Type \"INS\" for intructions"); + Console.WriteLine("Type \"MAX\" for approximate maximum speeds"); + Console.WriteLine("Type \"RUN\" for the beginning of the race"); + + while (!Success) + { + + Console.Write("Command--? "); + string LineInput = Console.ReadLine().Trim().ToLower(); + + if (LineInput.Equals("ins") || LineInput.Equals("max") || LineInput.Equals("run")) + { + Result = LineInput; + Success = true; + } + else + { + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("\"{0}\" is an illegal command--retry", LineInput); + } + } + + return Result; + } + + private bool ExceedGateSpeed(double MaxGateSpeed, double MPH, double Time) + { + Random rand = new Random(); + + Console.WriteLine("{0:N0} M.P.H.", MPH); + if (MPH > MaxGateSpeed) + { + Console.Write("You went over the maximum speed "); + if (rand.NextDouble() < ((MPH - (double)MaxGateSpeed) * 0.1) + 0.2) + { + Console.WriteLine("and made it!"); + } + else + { + if (rand.NextDouble() < 0.5) + { + Console.WriteLine("snagged a flag!"); + } + else + { + Console.WriteLine("wiped out!"); + } + + Console.WriteLine("You took {0:N2} seconds", rand.NextDouble() + Time); + + return false; + } + } + else if (MPH > (MaxGateSpeed - 1)) + { + Console.WriteLine("Close one!"); + } + + return true; + } + private void DoARun(int NumberOfGates, int Rating) + { + Random rand = new Random(); + double MPH = 0; + double Time = 0; + int Option = 0; + double MaxGateSpeed = 0; // Q + double PreviousMPH = 0; + double Medals = 0; + + Console.WriteLine("The starter counts down...5...4...3...2...1...GO!"); + + MPH = rand.NextDouble() * (18-9)+9; + + Console.WriteLine(); + Console.WriteLine("You're off!"); + + for (int GateNumber = 1; GateNumber <= NumberOfGates; GateNumber++) + { + MaxGateSpeed = GateMaxSpeed[GateNumber-1]; + + Console.WriteLine(); + Console.WriteLine("Here comes Gate # {0}:", GateNumber); + Console.WriteLine("{0:N0} M.P.H.", MPH); + + PreviousMPH = MPH; + + Option = PromptForOption(); + while (Option == 0) + { + Console.WriteLine("You've taken {0:N2} seconds.", Time); + Option = PromptForOption(); + } + + switch (Option) + { + case 1: + MPH = MPH + (rand.NextDouble() * (10-5)+5); + if (ExceedGateSpeed(MaxGateSpeed, MPH, Time)) + break; + else + return; + case 2: + MPH = MPH + (rand.NextDouble() * (5-3)+3); + if (ExceedGateSpeed(MaxGateSpeed, MPH, Time)) + break; + else + return; + case 3: + MPH = MPH + (rand.NextDouble() * (4-1)+1); + if (ExceedGateSpeed(MaxGateSpeed, MPH, Time)) + break; + else + return; + case 4: + if (ExceedGateSpeed(MaxGateSpeed, MPH, Time)) + break; + else + return; + case 5: + MPH = MPH - (rand.NextDouble() * (4-1)+1); + if (ExceedGateSpeed(MaxGateSpeed, MPH, Time)) + break; + else + return; + case 6: + MPH = MPH - (rand.NextDouble() * (5-3)+3); + if (ExceedGateSpeed(MaxGateSpeed, MPH, Time)) + break; + else + return; + case 7: + MPH = MPH - (rand.NextDouble() * (10-5)+5); + if (ExceedGateSpeed(MaxGateSpeed, MPH, Time)) + break; + else + return; + case 8: // Cheat! + Console.WriteLine("***Cheat"); + if (rand.NextDouble() < 0.7) + { + Console.WriteLine("An official caught you!"); + Console.WriteLine("You took {0:N2} seconds.", Time); + + return; + } + else + { + Console.WriteLine("You made it!"); + Time = Time + 1.5; + } + break; + } + + if (MPH < 7) + { + Console.WriteLine("Let's be realistic, OK? Let's go back and try again..."); + MPH = PreviousMPH; + } + else + { + Time = Time + (MaxGateSpeed - MPH + 1); + if (MPH > MaxGateSpeed) + { + Time = Time + 0.5; + + } + } + } + + Console.WriteLine(); + Console.WriteLine("You took {0:N2} seconds.", Time); + + Medals = Time; + Medals = Medals / NumberOfGates; + + if (Medals < (1.5 - (Rating * 0.1))) + { + Console.WriteLine("You won a gold medal!"); + GoldMedals++; + } + else if (Medals < (2.9 - (Rating * 0.1))) + { + Console.WriteLine("You won a silver medal!"); + SilverMedals++; + } + else if (Medals < (4.4 - (Rating * 0.01))) + { + Console.WriteLine("You won a bronze medal!"); + BronzeMedals++; + } + } + + private void PlayOneRound() + { + int NumberOfGates = 0; + string Command = "first"; + bool KeepPlaying = false; + int Rating = 0; + + Console.WriteLine(""); + + NumberOfGates = PromptForGates(); + + while (!Command.Equals("")) + { + Command = PromptForCommand(); + + // Display instructions + if (Command.Equals("ins")) + { + DisplayInstructions(); + } + else if (Command.Equals("max")) + { + Console.WriteLine("Gate Max"); + Console.WriteLine(" # M.P.H."); + Console.WriteLine("----------"); + for (int i = 0; i < NumberOfGates; i++) + { + Console.WriteLine(" {0} {1}", i+1, GateMaxSpeed[i]); + } + } + else // do a run! + { + Rating = PromptForRate(); + + do + { + DoARun(NumberOfGates, Rating); + + KeepPlaying = PromptYesNo("Do you want to race again? "); + } + while (KeepPlaying); + + Console.WriteLine("Thanks for the race"); + + if (GoldMedals > 0) + Console.WriteLine("Gold Medals: {0}", GoldMedals); + if (SilverMedals > 0) + Console.WriteLine("Silver Medals: {0}", SilverMedals); + if (BronzeMedals > 0) + Console.WriteLine("Bronze Medals: {0}", BronzeMedals); + + return; + } + } + } + + public void PlayTheGame() + { + DisplayIntro(); + + PlayOneRound(); + } + } + class Program + { + static void Main(string[] args) + { + + new Slalom().PlayTheGame(); + + } + } +} \ No newline at end of file From 7ab91a0e9b23214a8fda4c4745610d8543d78da6 Mon Sep 17 00:00:00 2001 From: mur4ik18 Date: Mon, 14 Feb 2022 19:22:51 +0200 Subject: [PATCH 309/337] :rocket: 41_guess add rust --- 41_Guess/rust/Cargo.toml | 9 ++++ 41_Guess/rust/README.md | 3 ++ 41_Guess/rust/src/main.rs | 86 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 41_Guess/rust/Cargo.toml create mode 100644 41_Guess/rust/README.md create mode 100644 41_Guess/rust/src/main.rs diff --git a/41_Guess/rust/Cargo.toml b/41_Guess/rust/Cargo.toml new file mode 100644 index 00000000..66ea57a5 --- /dev/null +++ b/41_Guess/rust/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guess" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.4" \ No newline at end of file diff --git a/41_Guess/rust/README.md b/41_Guess/rust/README.md new file mode 100644 index 00000000..a2d10996 --- /dev/null +++ b/41_Guess/rust/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Python](https://www.rust-lang.org/) diff --git a/41_Guess/rust/src/main.rs b/41_Guess/rust/src/main.rs new file mode 100644 index 00000000..442e348b --- /dev/null +++ b/41_Guess/rust/src/main.rs @@ -0,0 +1,86 @@ +use rand::Rng; +use std::io; +use std::cmp::Ordering; +// Rust haven't log2 in the standard library so I added fn log_2 +const fn num_bits() -> usize { std::mem::size_of::() * 8 } + +fn main() { + + let mut rng = rand::thread_rng(); + let mut still_guessing = true; + let limit = set_limit(); + let limit_goal = 1+(log_2(limit.try_into().unwrap())/log_2(2)) ; + loop{ + + let mut won = false; + let mut guess_count = 1; + let my_guess = rng.gen_range(1..limit); + + println!("I'm thinking of a number between 1 and {}",limit); + println!("Now you try to guess what it is."); + + while still_guessing { + let inp = get_input() + .trim() + .parse::().unwrap(); + println!("\n\n\n"); + if inp < my_guess { + println!("Too low. Try a bigger answer"); + guess_count+=1; + } + else if inp > my_guess { + println!("Too high. Try a smaller answer"); + guess_count+=1; + } + else { + println!("That's it! You got it in {} tries", guess_count); + won = true; + still_guessing = false; + } + } + if won { + match guess_count.cmp(&limit_goal) { + Ordering::Less => println!("Very good."), + Ordering::Equal => println!("Good."), + Ordering::Greater => println!("You should have been able to get it in only {}", limit_goal), + } + + println!("\n\n\n"); + still_guessing = true; + } else { + println!("\n\n\n"); + } + } +} + +fn log_2(x:i32) -> u32 { + assert!(x > 0); + num_bits::() as u32 - x.leading_zeros() - 1 +} + +fn set_limit() -> i64 { + + println!(" Guess"); + println!("\n\n\n"); + println!("This is a number guessing game. I'll think"); + println!("of a number between 1 and any limit you want.\n"); + println!("Then you have to guess what it is\n"); + println!("What limit do you want?"); + + let inp = get_input().trim().parse::().unwrap(); + + if inp >= 2 { + inp + } + else { + set_limit() + } +} + +fn get_input() -> String { + let mut input = String::new(); + io::stdin() + .read_line(&mut input) + .expect("Your input is not correct"); + input +} From 971e75d066a70fe610eb349ccb99652bba54827d Mon Sep 17 00:00:00 2001 From: Alex Kotov <79057640+mur4ik18@users.noreply.github.com> Date: Mon, 14 Feb 2022 19:24:34 +0200 Subject: [PATCH 310/337] Update README.md --- 41_Guess/rust/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/41_Guess/rust/README.md b/41_Guess/rust/README.md index a2d10996..fc6468b9 100644 --- a/41_Guess/rust/README.md +++ b/41_Guess/rust/README.md @@ -1,3 +1,3 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) -Conversion to [Python](https://www.rust-lang.org/) +Conversion to [Rust](https://www.rust-lang.org/) From b79200166eb927898efdf5723dd6205d218e8807 Mon Sep 17 00:00:00 2001 From: Alex Kotov <79057640+mur4ik18@users.noreply.github.com> Date: Mon, 14 Feb 2022 19:27:44 +0200 Subject: [PATCH 311/337] Update main.rs --- 41_Guess/rust/src/main.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/41_Guess/rust/src/main.rs b/41_Guess/rust/src/main.rs index 442e348b..da175038 100644 --- a/41_Guess/rust/src/main.rs +++ b/41_Guess/rust/src/main.rs @@ -1,3 +1,26 @@ +//####################################################### +// +// Guess +// +// From: Basic Computer Games (1978) +// +// "In program Guess, the computer chooses a random +// integer between 0 and any limit and any limit you +// set. You must then try to guess the number the +// computer has choosen using the clues provideed by +// the computer. +// You should be able to guess the number in one less +// than the number of digits needed to represent the +// number in binary notation - i.e. in base 2. This ought +// to give you a clue as to the optimum search technique. +// Guess converted from the original program in FOCAL +// which appeared in the book "Computers in the Classroom" +// by Walt Koetke of Lexington High School, Lexington, +// Massaschusetts. +// +//####################################################### + + use rand::Rng; use std::io; use std::cmp::Ordering; From a54369c677d7b5b6af05f7860f734a7b5e218ad3 Mon Sep 17 00:00:00 2001 From: Peter Eastwood Date: Mon, 14 Feb 2022 19:29:37 +0000 Subject: [PATCH 312/337] 54_Letter - added csharp --- 54_Letter/csharp/Game.cs | 137 ++++++++++++++++++++++++++++++++++ 54_Letter/csharp/GameState.cs | 37 +++++++++ 54_Letter/csharp/Program.cs | 3 + 3 files changed, 177 insertions(+) create mode 100644 54_Letter/csharp/Game.cs create mode 100644 54_Letter/csharp/GameState.cs create mode 100644 54_Letter/csharp/Program.cs diff --git a/54_Letter/csharp/Game.cs b/54_Letter/csharp/Game.cs new file mode 100644 index 00000000..e7d525c9 --- /dev/null +++ b/54_Letter/csharp/Game.cs @@ -0,0 +1,137 @@ +namespace Letter +{ + internal static class Game + { + /// + /// Maximum number of guesses. + /// Note the program doesn't enforce this - it just displays a message if this is exceeded. + /// + private const int MaximumGuesses = 5; + + /// + /// Main game loop. + /// + public static void Play() + { + DisplayIntroductionText(); + + // Keep playing forever, or until the user quits. + while (true) + { + PlayRound(); + } + } + + /// + /// Play a single round. + /// + internal static void PlayRound() + { + var gameState = new GameState(); + DisplayRoundIntroduction(); + + char letterInput = '\0'; // Set the initial character to something that's not A-Z. + while (letterInput != gameState.Letter) + { + letterInput = GetCharacterFromKeyboard(); + gameState.GuessesSoFar++; + DisplayGuessResult(gameState.Letter, letterInput); + } + DisplaySuccessMessage(gameState); + } + + /// + /// Display an introduction when the game loads. + /// + internal static void DisplayIntroductionText() + { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine("LETTER"); + Console.WriteLine("Creative Computing, Morristown, New Jersey."); + Console.WriteLine(""); + + Console.ForegroundColor = ConsoleColor.DarkGreen; + Console.WriteLine("Letter Guessing Game"); + Console.WriteLine("I'll think of a letter of the alphabet, A to Z."); + Console.WriteLine("Try to guess my letter and I'll give you clues"); + Console.WriteLine("as to how close you're getting to my letter."); + Console.WriteLine(""); + + Console.ResetColor(); + } + + /// + /// Display introductionary text for each round. + /// + internal static void DisplayRoundIntroduction() + { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine("O.K., I have a letter. Start guessing."); + + Console.ResetColor(); + } + + /// + /// Display text depending whether the guess is lower or higher. + /// + internal static void DisplayGuessResult(char letterToGuess, char letterInput) + { + Console.BackgroundColor = ConsoleColor.White; + Console.ForegroundColor = ConsoleColor.Black; + Console.Write(" " + letterInput + " "); + + Console.ResetColor(); + Console.ForegroundColor = ConsoleColor.Gray; + Console.Write(" "); + if (letterInput != letterToGuess) + { + if (letterInput > letterToGuess) + { + Console.WriteLine("Too high. Try a lower letter"); + } + else + { + Console.WriteLine("Too low. Try a higher letter"); + } + } + Console.ResetColor(); + } + + /// + /// Display success, and the number of guesses. + /// + internal static void DisplaySuccessMessage(GameState gameState) + { + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine($"You got it in {gameState.GuessesSoFar} guesses!!"); + if (gameState.GuessesSoFar > MaximumGuesses) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"But it shouldn't take more than {MaximumGuesses} guesses!"); + } + else + { + Console.WriteLine("Good job !!!!!"); + } + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine(""); + Console.WriteLine("Let's play again....."); + + Console.ResetColor(); + } + + /// + /// Get valid input from the keyboard: must be an alpha character. Converts to upper case if necessary. + /// + internal static char GetCharacterFromKeyboard() + { + char letterInput; + do + { + var keyPressed = Console.ReadKey(true); + letterInput = Char.ToUpper(keyPressed.KeyChar); // Convert to upper case immediately. + } while (!Char.IsLetter(letterInput)); // If the input is not a letter, wait for another letter to be pressed. + return letterInput; + } + } +} diff --git a/54_Letter/csharp/GameState.cs b/54_Letter/csharp/GameState.cs new file mode 100644 index 00000000..02aa38b1 --- /dev/null +++ b/54_Letter/csharp/GameState.cs @@ -0,0 +1,37 @@ +namespace Letter +{ + /// + /// Holds the current state. + /// + internal class GameState + { + /// + /// Initialise the game state with a random letter. + /// + public GameState() + { + Letter = GetRandomLetter(); + GuessesSoFar = 0; + } + + /// + /// The letter that the user is guessing. + /// + public char Letter { get; set; } + + /// + /// The number of guesses the user has had so far. + /// + public int GuessesSoFar { get; set; } + + /// + /// Get a random character (A-Z) for the user to guess. + /// + internal static char GetRandomLetter() + { + var random = new Random(); + var randomNumber = random.Next(0, 26); + return (char)('A' + randomNumber); + } + } +} diff --git a/54_Letter/csharp/Program.cs b/54_Letter/csharp/Program.cs new file mode 100644 index 00000000..9a1c29db --- /dev/null +++ b/54_Letter/csharp/Program.cs @@ -0,0 +1,3 @@ +using Letter; + +Game.Play(); \ No newline at end of file From 605a80767280c46767687253c78b5f8f7fca1999 Mon Sep 17 00:00:00 2001 From: mur4ik18 Date: Tue, 15 Feb 2022 23:04:10 +0200 Subject: [PATCH 313/337] :memo: updated .gitignore for rust --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index fea38bce..d6fb1f7f 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,7 @@ Pipfile .DS_Store .vs/ +/target/ +Cargo.lock +**/*.rs.bk +/target From a97e36e4e31701214556853700f978bda33a6e13 Mon Sep 17 00:00:00 2001 From: mur4ik18 Date: Tue, 15 Feb 2022 23:17:17 +0200 Subject: [PATCH 314/337] :rocket: Ace game in rust started --- .gitignore | 2 +- 01_Acey_Ducey/rust/Cargo.toml | 9 +++++++++ 01_Acey_Ducey/rust/src/main.rs | 28 ++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 01_Acey_Ducey/rust/Cargo.toml create mode 100644 01_Acey_Ducey/rust/src/main.rs diff --git a/.gitignore b/.gitignore index d6fb1f7f..2675262f 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,7 @@ Pipfile .DS_Store .vs/ -/target/ +**/target/ Cargo.lock **/*.rs.bk /target diff --git a/01_Acey_Ducey/rust/Cargo.toml b/01_Acey_Ducey/rust/Cargo.toml new file mode 100644 index 00000000..3b1d02f5 --- /dev/null +++ b/01_Acey_Ducey/rust/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.5" diff --git a/01_Acey_Ducey/rust/src/main.rs b/01_Acey_Ducey/rust/src/main.rs new file mode 100644 index 00000000..b9057180 --- /dev/null +++ b/01_Acey_Ducey/rust/src/main.rs @@ -0,0 +1,28 @@ +use std::io; + + +fn main() { + let mut user_bank: u16 = 100; + +} + +fn hello() { + println!(" 🂡 ACEY DUCEY CARD GAME 🂱"); + println!("CREATIVE COMPUTING - MORRISTOWN, NEW JERSEY"); + println!(" ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER"); + println!("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP"); + println!("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING"); + println!("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE"); + println!("A VALUE BETWEEN THE FIRST TWO."); + println!("IF YOU DO NOT WANT TO BET IN A ROUND, ENTER 0"); +} + +fn card_name(card: u8) -> String { + match card { + 11 => String::from("JACK"), + 12 => String::from("QUEEN"), + 13 => String::from("KING"), + 14 => String::from("ACE"), + _ => card.to_string() + } +} From 28afbb35aa68ac2dac1d741ab8bba02ce94a71c7 Mon Sep 17 00:00:00 2001 From: mur4ik18 Date: Wed, 16 Feb 2022 00:52:33 +0200 Subject: [PATCH 315/337] :rocket: half of game complete --- 01_Acey_Ducey/rust/src/main.rs | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/01_Acey_Ducey/rust/src/main.rs b/01_Acey_Ducey/rust/src/main.rs index b9057180..aece3f53 100644 --- a/01_Acey_Ducey/rust/src/main.rs +++ b/01_Acey_Ducey/rust/src/main.rs @@ -1,9 +1,43 @@ use std::io; +use std::process; +use rand::{Rng, prelude::ThreadRng}; + +struct CardsPool { + first: u8, + second: u8, + third: u8 +} +impl CardsPool { + fn new(rng: &mut ThreadRng)-> CardsPool{ + CardsPool{ + first: rng.gen_range(2..15), + second: rng.gen_range(2..15), + third: rng.gen_range(2..15) + } + } +} fn main() { + // user start bank let mut user_bank: u16 = 100; + let mut rng = rand::thread_rng(); + loop { + println!("YOU NOW HAVE {} DOLLARS.", &mut user_bank); + println!("HERE ARE YOUR NEXT TWO CARDS:"); + // get new random cards + let cards = CardsPool::new(&mut rng); + println!("{}", card_name(cards.first)); + println!("{}", card_name(cards.second)); + let mut user_bet: u16; + user_bet = get_bet(user_bank); + if user_bet == 0 { + println!("CHICKEN!!!"); + continue; + } + println!("{}", card_name(cards.third)); + } } fn hello() { @@ -26,3 +60,26 @@ fn card_name(card: u8) -> String { _ => card.to_string() } } + + +fn get_bet(user_bank: u16) -> u16 { + println!("WHAT IS YOUR BET? ENTER 0 IF YOU DON'T WANT TO BET (CTRL+C TO EXIT)"); + let mut bet: u16; + let mut input = String::new(); + + io::stdin() + .read_line(&mut input) + .expect("Sorry your input incorrect"); + + bet = input.trim().parse::().unwrap(); + match bet { + 0 => bet, + bet if bet < user_bank => bet, + _ => { + println!("SORRY, MY FRIEND, BUT YOU BET TOO MUCH."); + println!("YOU HAVE ONLY {} DOLLARS TO BET.", user_bank); + get_bet(user_bank) + } + } +} + From 281bcbf2a2a32ff9903e31ad7191d09194300cbb Mon Sep 17 00:00:00 2001 From: mur4ik18 Date: Wed, 16 Feb 2022 05:19:38 +0200 Subject: [PATCH 316/337] :rocket: 01 in rust complete --- 01_Acey_Ducey/rust/src/main.rs | 51 ++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/01_Acey_Ducey/rust/src/main.rs b/01_Acey_Ducey/rust/src/main.rs index aece3f53..3aeca5c5 100644 --- a/01_Acey_Ducey/rust/src/main.rs +++ b/01_Acey_Ducey/rust/src/main.rs @@ -1,5 +1,4 @@ use std::io; -use std::process; use rand::{Rng, prelude::ThreadRng}; struct CardsPool { @@ -9,9 +8,18 @@ struct CardsPool { } impl CardsPool { fn new(rng: &mut ThreadRng)-> CardsPool{ + let mut f = rng.gen_range(2..15); + let mut s = rng.gen_range(2..15); + + if f > s { + let x = f; + f = s; + s = x; + } + CardsPool{ - first: rng.gen_range(2..15), - second: rng.gen_range(2..15), + first: f, + second: s, third: rng.gen_range(2..15) } } @@ -19,6 +27,7 @@ impl CardsPool { fn main() { + hello(); // user start bank let mut user_bank: u16 = 100; let mut rng = rand::thread_rng(); @@ -27,16 +36,47 @@ fn main() { println!("HERE ARE YOUR NEXT TWO CARDS:"); // get new random cards let cards = CardsPool::new(&mut rng); + println!("{}", card_name(cards.first)); println!("{}", card_name(cards.second)); + let mut user_bet: u16; user_bet = get_bet(user_bank); + if user_bet == 0 { - println!("CHICKEN!!!"); + println!("CHICKEN!!!\n"); continue; } + else { + println!("THANK YOU! YOUR BET IS {} DOLLARS.", &mut user_bet); + } + + println!("\nTHE THIRD CARD IS:"); println!("{}", card_name(cards.third)); + if cards.first <= cards.third && cards.third <= cards.second { + println!("YOU WIN!!!\n"); + user_bank += user_bet; + } else { + println!("SORRY, YOU LOSE\n"); + user_bank -= user_bet; + } + + + if user_bank == 0 { + println!("\nSORRY, FRIEND, BUT YOU BLEW YOUR WAD.\n"); + println!("TRY AGAIN? (yes OR no)"); + let mut input = String::new(); + io::stdin() + .read_line(&mut input) + .expect("Incorrect input"); + + if String::from("yes") == input { + user_bank = 100; + } else { + println!("O.K., HOPE YOU HAD FUN!"); + } + } } } @@ -49,6 +89,7 @@ fn hello() { println!("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE"); println!("A VALUE BETWEEN THE FIRST TWO."); println!("IF YOU DO NOT WANT TO BET IN A ROUND, ENTER 0"); + println!("\n\n\n"); } fn card_name(card: u8) -> String { @@ -64,7 +105,7 @@ fn card_name(card: u8) -> String { fn get_bet(user_bank: u16) -> u16 { println!("WHAT IS YOUR BET? ENTER 0 IF YOU DON'T WANT TO BET (CTRL+C TO EXIT)"); - let mut bet: u16; + let bet: u16; let mut input = String::new(); io::stdin() From d520f15f141f7bd26459ed1372eca82e5a8e8ea9 Mon Sep 17 00:00:00 2001 From: Alex Kotov <79057640+mur4ik18@users.noreply.github.com> Date: Wed, 16 Feb 2022 05:23:37 +0200 Subject: [PATCH 317/337] Create README.md --- 01_Acey_Ducey/rust/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 01_Acey_Ducey/rust/README.md diff --git a/01_Acey_Ducey/rust/README.md b/01_Acey_Ducey/rust/README.md new file mode 100644 index 00000000..9df86bc0 --- /dev/null +++ b/01_Acey_Ducey/rust/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Rust](https://www.rust-lang.org/) by Alex Kotov [mur4ik18@github](https://github.com/mur4ik18). From e12ade3656ae565de02dc456b6603b2641fd1ab1 Mon Sep 17 00:00:00 2001 From: remimimimi Date: Wed, 16 Feb 2022 17:10:21 +0300 Subject: [PATCH 318/337] Refactor code --- 01_Acey_Ducey/rust/src/main.rs | 107 +++++++++++++++++---------------- 1 file changed, 56 insertions(+), 51 deletions(-) diff --git a/01_Acey_Ducey/rust/src/main.rs b/01_Acey_Ducey/rust/src/main.rs index 3aeca5c5..d8eed2ba 100644 --- a/01_Acey_Ducey/rust/src/main.rs +++ b/01_Acey_Ducey/rust/src/main.rs @@ -1,60 +1,79 @@ -use std::io; -use rand::{Rng, prelude::ThreadRng}; +use rand::{prelude::ThreadRng, Rng}; +use std::{fmt, io, mem}; -struct CardsPool { - first: u8, - second: u8, - third: u8 -} -impl CardsPool { - fn new(rng: &mut ThreadRng)-> CardsPool{ - let mut f = rng.gen_range(2..15); - let mut s = rng.gen_range(2..15); +#[derive(PartialEq, Eq, PartialOrd, Ord)] +struct Card(u8); - if f > s { - let x = f; - f = s; - s = x; - } - - CardsPool{ - first: f, - second: s, - third: rng.gen_range(2..15) - } +impl Card { + fn new_random(rng: &mut ThreadRng) -> Card { + Card(rng.gen_range(2..15)) } } +impl fmt::Display for Card { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match self.0 { + 11 => String::from("JACK"), + 12 => String::from("QUEEN"), + 13 => String::from("KING"), + 14 => String::from("ACE"), + otherwise => otherwise.to_string(), + } + ) + } +} + +struct CardsPool(Card, Card, Card); + +impl CardsPool { + fn new() -> CardsPool { + let mut rng = rand::thread_rng(); + let mut first = Card::new_random(&mut rng); + let mut second = Card::new_random(&mut rng); + let third = Card::new_random(&mut rng); + + if first > second { + mem::swap(&mut first, &mut second); + } + + CardsPool(first, second, third) + } + + fn is_in_win_range(&self) -> bool { + self.0 <= self.2 && self.2 <= self.1 + } +} fn main() { hello(); // user start bank let mut user_bank: u16 = 100; - let mut rng = rand::thread_rng(); + loop { println!("YOU NOW HAVE {} DOLLARS.", &mut user_bank); println!("HERE ARE YOUR NEXT TWO CARDS:"); - // get new random cards - let cards = CardsPool::new(&mut rng); + // get new random cards + let cards = CardsPool::new(); - println!("{}", card_name(cards.first)); - println!("{}", card_name(cards.second)); + println!("{}", cards.0); + println!("{}", cards.1); - let mut user_bet: u16; - user_bet = get_bet(user_bank); + let user_bet: u16 = get_bet(user_bank); if user_bet == 0 { println!("CHICKEN!!!\n"); continue; - } - else { - println!("THANK YOU! YOUR BET IS {} DOLLARS.", &mut user_bet); + } else { + println!("THANK YOU! YOUR BET IS {} DOLLARS.", user_bet); } println!("\nTHE THIRD CARD IS:"); - println!("{}", card_name(cards.third)); + println!("{}", cards.2); - if cards.first <= cards.third && cards.third <= cards.second { + if cards.is_in_win_range() { println!("YOU WIN!!!\n"); user_bank += user_bet; } else { @@ -62,16 +81,13 @@ fn main() { user_bank -= user_bet; } - if user_bank == 0 { println!("\nSORRY, FRIEND, BUT YOU BLEW YOUR WAD.\n"); println!("TRY AGAIN? (yes OR no)"); let mut input = String::new(); - io::stdin() - .read_line(&mut input) - .expect("Incorrect input"); + io::stdin().read_line(&mut input).expect("Incorrect input"); - if String::from("yes") == input { + if "yes" == input { user_bank = 100; } else { println!("O.K., HOPE YOU HAD FUN!"); @@ -92,17 +108,6 @@ fn hello() { println!("\n\n\n"); } -fn card_name(card: u8) -> String { - match card { - 11 => String::from("JACK"), - 12 => String::from("QUEEN"), - 13 => String::from("KING"), - 14 => String::from("ACE"), - _ => card.to_string() - } -} - - fn get_bet(user_bank: u16) -> u16 { println!("WHAT IS YOUR BET? ENTER 0 IF YOU DON'T WANT TO BET (CTRL+C TO EXIT)"); let bet: u16; @@ -112,6 +117,7 @@ fn get_bet(user_bank: u16) -> u16 { .read_line(&mut input) .expect("Sorry your input incorrect"); + // XXX: Unhandled input bet = input.trim().parse::().unwrap(); match bet { 0 => bet, @@ -123,4 +129,3 @@ fn get_bet(user_bank: u16) -> u16 { } } } - From 925f5263fe602fe138a1911d0a2c1ea3037f6755 Mon Sep 17 00:00:00 2001 From: roygilliam <58305899+roygilliam@users.noreply.github.com> Date: Fri, 18 Feb 2022 22:10:49 -0500 Subject: [PATCH 319/337] Initial C# conversion --- 66_Number/csharp/program.cs | 126 ++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 66_Number/csharp/program.cs diff --git a/66_Number/csharp/program.cs b/66_Number/csharp/program.cs new file mode 100644 index 00000000..a94fc7b2 --- /dev/null +++ b/66_Number/csharp/program.cs @@ -0,0 +1,126 @@ +using System.Text; + +namespace Number +{ + class Number + { + private void DisplayIntro() + { + Console.WriteLine(); + Console.WriteLine("NUMBER".PadLeft(23)); + Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("You have 100 points. By guessing numbers from 1 to 5, you"); + Console.WriteLine("can gain or lose points depending upon how close you get to"); + Console.WriteLine("a random number selected by the computer."); + Console.WriteLine(); + Console.WriteLine("You occaisionally will get a jackpot which will double(!)"); + Console.WriteLine("your point count. You win when you get 500 points."); + Console.WriteLine(); + + } + private int PromptForGuess() + { + bool Success = false; + int Guess = 0; + + while (!Success) + { + Console.Write("Guess a number from 1 to 5? "); + string LineInput = Console.ReadLine().Trim().ToLower(); + + if (int.TryParse(LineInput, out Guess)) + { + if (Guess >= 0 && Guess <= 5) + Success = true; + } + else + Console.WriteLine("Please enter a number between 1 and 5."); + } + + return Guess; + } + + private void GetRandomNumbers(out int Random1, out int Random2, out int Random3, out int Random4, out int Random5) + { + Random rand = new Random(); + + // Get a unique set of random numbers between 1 and 5 + // I assume this is what the original BASIC FNR(X)=INT(5*RND(1)+1) is doing + Random1 = (int)(5 * rand.NextDouble() + 1); + do + { + Random2 = (int)(5 * rand.NextDouble() + 1); + } while (Random2 == Random1); + do + { + Random3 = (int)(5 * rand.NextDouble() + 1); + } while (Random3 == Random1 || Random3 == Random2); + do + { + Random4 = (int)(5 * rand.NextDouble() + 1); + } while (Random4 == Random1 || Random4 == Random2 || Random4 == Random3); + do + { + Random5 = (int)(5 * rand.NextDouble() + 1); + } while (Random5 == Random1 || Random5 == Random2 || Random5 == Random3 || Random5 == Random4); + + } + private void Play() + { + + int Points = 100; + bool Win = false; + int Random1, Random2, Random3, Random4, Random5; + int Guess = 0; + + GetRandomNumbers(out Random1, out Random2, out Random3, out Random4, out Random5); + + while (!Win) + { + + Guess = PromptForGuess(); + + if (Guess == Random1) + Points -= 5; + else if (Guess == Random2) + Points += 5; + else if (Guess == Random3) + { + Points += Points; + Console.WriteLine("You hit the jackpot!!!"); + } + else if (Guess == Random4) + Points += 1; + else if (Guess == Random5) + Points -= (int)(Points * 0.5); + + if (Points > 500) + { + Console.WriteLine("!!!!You Win!!!! with {0} points.", Points); + Win = true; + } + else + Console.WriteLine("You have {0} points.", Points); + } + } + + public void PlayTheGame() + { + DisplayIntro(); + + Play(); + } + } + class Program + { + static void Main(string[] args) + { + + new Number().PlayTheGame(); + + } + } +} \ No newline at end of file From 12f902bdbd2a10a7c1cb09e238fc0f43e8cb09ed Mon Sep 17 00:00:00 2001 From: uMetalooper Date: Sat, 19 Feb 2022 12:39:43 +0000 Subject: [PATCH 320/337] Gomoko python --- 40_Gomoko/python/Gomoko.py | 126 +++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 40_Gomoko/python/Gomoko.py diff --git a/40_Gomoko/python/Gomoko.py b/40_Gomoko/python/Gomoko.py new file mode 100644 index 00000000..3ab1ca13 --- /dev/null +++ b/40_Gomoko/python/Gomoko.py @@ -0,0 +1,126 @@ +import random + + +def print_n_whitespaces(n: int): + print(" "*n, end="") + + +def print_board(): + """PRINT THE BOARD""" + for I in range(N): + print(" ", end="") + for J in range(N): + print(A[I][J], end="") + print(" ", end="") + print() + + +def check_move(_I, _J, _N) -> bool: # 910 + if _I < 1 or _I > _N or _J < 1 or _J > _N: + return False + return True + + +print_n_whitespaces(33) +print("GOMOKU") +print_n_whitespaces(15) +print("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") +print() +print() +print() +print("WELCOME TO THE ORIENTAL GAME OF GOMOKO.") +print() +print("THE GAME IS PLAYED ON AN N BY N GRID OF A SIZE") +print("THAT YOU SPECIFY. DURING YOUR PLAY, YOU MAY COVER ONE GRID") +print("INTERSECTION WITH A MARKER. THE OBJECT OF THE GAME IS TO GET") +print("5 ADJACENT MARKERS IN A ROW -- HORIZONTALLY, VERTICALLY, OR") +print("DIAGONALLY. ON THE BOARD DIAGRAM, YOUR MOVES ARE MARKED") +print("WITH A '1' AND THE COMPUTER MOVES WITH A '2'.") +print() +print("THE COMPUTER DOES NOT KEEP TRACK OF WHO HAS WON.") +print("TO END THE GAME, TYPE -1,-1 FOR YOUR MOVE.") +print() + +while True: + N = 0 + while True: + N = input("WHAT IS YOUR BOARD SIZE (MIN 7/ MAX 19)? ") + N = int(N) + if N < 7 or N > 19: + print("I SAID, THE MINIMUM IS 7, THE MAXIMUM IS 19.") + print() + else: + break + + # Initialize the board + A = [] + for I in range(N): + subA = [] + for J in range(N): + subA.append(0) + A.append(subA) + print() + print() + print("WE ALTERNATE MOVES. YOU GO FIRST...") + print() + + while True: + IJ = input("YOUR PLAY (I,J)? ") + print() + I, J = IJ.split(",") + try: + I = int(I) + J = int(J) + except: + print("ILLEGAL MOVE. TRY AGAIN...") + continue + if I == -1: + break + elif check_move(I, J, N) == False: + print("ILLEGAL MOVE. TRY AGAIN...") + else: + if A[I-1][J-1] != 0: + print("SQUARE OCCUPIED. TRY AGAIN...") + else: + A[I-1][J-1] = 1 + # COMPUTER TRIES AN INTELLIGENT MOVE + SkipEFLoop = False + for E in range(-1, 2): + for F in range(-1, 2): + if E+F-E*F == 0 or SkipEFLoop: + continue + X = I + F + Y = J + F + if check_move(X, Y, N) == False: + continue + if A[X-1][Y-1] == 1: + SkipEFLoop = True + X = I - E + Y = J - F + if check_move(X, Y, N) == False: # 750 + while True: # 610 + X = random.randint(1, N) + Y = random.randint(1, N) + if check_move(X, Y, N) and A[X-1][Y-1] == 0: + A[X-1][Y-1] = 2 + print_board() + break + else: + if A[X-1][Y-1] != 0: + while True: + X = random.randint(1, N) + Y = random.randint(1, N) + if check_move(X, Y, N) and A[X-1][Y-1] == 0: + A[X-1][Y-1] = 2 + print_board() + break + else: + A[X-1][Y-1] = 2 + print_board() + print() + print("THANKS FOR THE GAME!!") + Repeat = input("PLAY AGAIN (1 FOR YES, 0 FOR NO)? ") + Repeat = int(Repeat) + if Repeat == 0: + break +# print_board() From f305b8cb30bbbeb7ee01b23928c011d87119feec Mon Sep 17 00:00:00 2001 From: uMetalooper Date: Sun, 20 Feb 2022 12:39:03 +0000 Subject: [PATCH 321/337] Minor update on Python utility on Windows --- 00_Utilities/markdown_todo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/00_Utilities/markdown_todo.py b/00_Utilities/markdown_todo.py index 74e358c0..4f1ebf03 100644 --- a/00_Utilities/markdown_todo.py +++ b/00_Utilities/markdown_todo.py @@ -18,7 +18,7 @@ checklist = ["game", "csharp", "java", "javascript", prev_game = "" for dirName, subdirList, fileList in os.walk(rootDir): - split_dir = dirName.split("/") + split_dir = dirName.split(os.path.sep) if len(split_dir) == 2 and not split_dir[1] in ['.git', '00_Utilities']: if prev_game == "": @@ -46,5 +46,5 @@ sorted_strings = list(map(lambda l: " | ".join(l) + "\n", write_string += ''.join(sorted_strings) -with open("README.md", "w") as f: +with open("README.md", "w", encoding='utf-8') as f: f.write(write_string) From 294353d793939bf17e0851536ce8448b33fccf65 Mon Sep 17 00:00:00 2001 From: berkersal Date: Sun, 20 Feb 2022 16:14:15 +0300 Subject: [PATCH 322/337] Format prints to be in groups when printed, fix endgame, handle panics caused by user inputs and print self-explanatory error messages --- 01_Acey_Ducey/rust/README.md | 4 +++ 01_Acey_Ducey/rust/src/main.rs | 60 +++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/01_Acey_Ducey/rust/README.md b/01_Acey_Ducey/rust/README.md index 9df86bc0..916a737b 100644 --- a/01_Acey_Ducey/rust/README.md +++ b/01_Acey_Ducey/rust/README.md @@ -1,3 +1,7 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Rust](https://www.rust-lang.org/) by Alex Kotov [mur4ik18@github](https://github.com/mur4ik18). + +Further edits by + +- Berker Şal [berkersal@github](https://github.com/berkersal) diff --git a/01_Acey_Ducey/rust/src/main.rs b/01_Acey_Ducey/rust/src/main.rs index d8eed2ba..8df9f327 100644 --- a/01_Acey_Ducey/rust/src/main.rs +++ b/01_Acey_Ducey/rust/src/main.rs @@ -54,7 +54,7 @@ fn main() { loop { println!("YOU NOW HAVE {} DOLLARS.", &mut user_bank); - println!("HERE ARE YOUR NEXT TWO CARDS:"); + println!("\nHERE ARE YOUR NEXT TWO CARDS:"); // get new random cards let cards = CardsPool::new(); @@ -74,58 +74,66 @@ fn main() { println!("{}", cards.2); if cards.is_in_win_range() { - println!("YOU WIN!!!\n"); + println!("\nYOU WIN!!!"); user_bank += user_bet; } else { - println!("SORRY, YOU LOSE\n"); + println!("\nSORRY, YOU LOSE"); user_bank -= user_bet; } if user_bank == 0 { - println!("\nSORRY, FRIEND, BUT YOU BLEW YOUR WAD.\n"); - println!("TRY AGAIN? (yes OR no)"); + println!("\nSORRY, FRIEND, BUT YOU BLEW YOUR WAD."); + println!("\nTRY AGAIN? (YES OR NO)"); let mut input = String::new(); io::stdin().read_line(&mut input).expect("Incorrect input"); - if "yes" == input { + if input.trim().to_lowercase() == "yes" { user_bank = 100; + println!(); } else { - println!("O.K., HOPE YOU HAD FUN!"); + println!("\nO.K., HOPE YOU HAD FUN!"); + break; } } } } fn hello() { - println!(" 🂡 ACEY DUCEY CARD GAME 🂱"); + println!(" 🂡 ACEY DUCEY CARD GAME 🂱"); println!("CREATIVE COMPUTING - MORRISTOWN, NEW JERSEY"); - println!(" ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER"); + println!("ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER"); println!("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP"); println!("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING"); println!("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE"); println!("A VALUE BETWEEN THE FIRST TWO."); println!("IF YOU DO NOT WANT TO BET IN A ROUND, ENTER 0"); - println!("\n\n\n"); + println!("\n\n"); } fn get_bet(user_bank: u16) -> u16 { - println!("WHAT IS YOUR BET? ENTER 0 IF YOU DON'T WANT TO BET (CTRL+C TO EXIT)"); - let bet: u16; - let mut input = String::new(); + loop { + println!("\nWHAT IS YOUR BET? ENTER 0 IF YOU DON'T WANT TO BET (CTRL+C TO EXIT)"); + let bet: u16; + let mut input = String::new(); - io::stdin() - .read_line(&mut input) - .expect("Sorry your input incorrect"); + io::stdin() + .read_line(&mut input) + .expect("CANNOT READ INPUT!"); - // XXX: Unhandled input - bet = input.trim().parse::().unwrap(); - match bet { - 0 => bet, - bet if bet < user_bank => bet, - _ => { - println!("SORRY, MY FRIEND, BUT YOU BET TOO MUCH."); - println!("YOU HAVE ONLY {} DOLLARS TO BET.", user_bank); - get_bet(user_bank) - } + match input.trim().parse::() { + Ok(i) => bet = i, + Err(e) => { + println!("CHECK YOUR INPUT! {}!", e.to_string().to_uppercase()); + continue; + } + }; + + match bet { + bet if bet <= user_bank => return bet, + _ => { + println!("\nSORRY, MY FRIEND, BUT YOU BET TOO MUCH."); + println!("YOU HAVE ONLY {} DOLLARS TO BET.", user_bank); + } + }; } } From e77ca9b983f064a190b3d6c7d5d0e6a073cab87c Mon Sep 17 00:00:00 2001 From: uMetalooper Date: Sun, 20 Feb 2022 21:42:51 +0000 Subject: [PATCH 323/337] Bug game added --- 16_Bug/python/Bug.py | 302 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 16_Bug/python/Bug.py diff --git a/16_Bug/python/Bug.py b/16_Bug/python/Bug.py new file mode 100644 index 00000000..ba5f4de4 --- /dev/null +++ b/16_Bug/python/Bug.py @@ -0,0 +1,302 @@ +import random + + +def print_n_whitespaces(n: int): + print(" "*n, end="") + + +def print_n_newlines(n: int): + for _ in range(n): + print() + + +def print_feelers(n_feelers, is_player=True): + for _ in range(4): + print_n_whitespaces(10) + for _ in range(n_feelers): + print("A " if is_player else "F ", end="") + print() + + +def print_head(): + print(" HHHHHHH") + print(" H H") + print(" H O O H") + print(" H H") + print(" H V H") + print(" HHHHHHH") + + +def print_neck(): + print(" N N") + print(" N N") + + +def print_body(has_tail=False): + print(" BBBBBBBBBBBB") + print(" B B") + print(" B B") + print("TTTTTB B") if has_tail else "" + print(" BBBBBBBBBBBB") + + +def print_legs(n_legs): + for _ in range(2): + print_n_whitespaces(5) + for _ in range(n_legs): + print(" L", end="") + print() + + +print_n_whitespaces(34) +print("BUG") +print_n_whitespaces(15) +print("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") +print_n_newlines(3) + +print("THE GAME BUG") +print("I HOPE YOU ENJOY THIS GAME.") +print() +Z = input("DO YOU WANT INSTRUCTIONS? ") +if Z != "NO": + print("THE OBJECT OF BUG IS TO FINISH YOUR BUG BEFORE I FINISH") + print("MINE. EACH NUMBER STANDS FOR A PART OF THE BUG BODY.") + print("I WILL ROLL THE DIE FOR YOU, TELL YOU WHAT I ROLLED FOR YOU") + print("WHAT THE NUMBER STANDS FOR, AND IF YOU CAN GET THE PART.") + print("IF YOU CAN GET THE PART I WILL GIVE IT TO YOU.") + print("THE SAME WILL HAPPEN ON MY TURN.") + print("IF THERE IS A CHANGE IN EITHER BUG I WILL GIVE YOU THE") + print("OPTION OF SEEING THE PICTURES OF THE BUGS.") + print("THE NUMBERS STAND FOR PARTS AS FOLLOWS:") + table = [ + ["NUMBER", "PART", "NUMBER OF PART NEEDED"], + ["1", "BODY", "1"], + ["2", "NECK", "1"], + ["3", "HEAD", "1"], + ["4", "FEELERS", "2"], + ["5", "TAIL", "1"], + ["6", "LEGS", "6"] + ] + for row in table: + print("{:<16}{:<16}{:<20}".format(row[0], row[1], row[2])) + print_n_newlines(2) + +A = 0 +B = 0 +H = 0 +L = 0 +N = 0 +P = 0 +Q = 0 +R = 0 # NECK +S = 0 # FEELERS +T = 0 +U = 0 +V = 0 +Y = 0 + +while not (Y > 0): + Z = random.randint(1, 6) + print() + C = 1 + print("YOU ROLLED A", Z) + if Z == 1: + print("1=BODY") + if B == 1: + print("YOU DO NOT NEED A BODY.") + # goto 970 + else: + print("YOU NOW HAVE A BODY.") + B = 1 + C = 0 + # goto 970 + elif Z == 2: + print("2=NECK") + if N == 1: + print("YOU DO NOT NEED A NECK.") + # goto 970 + elif B == 0: + print("YOU DO NOT HAVE A BODY.") + # goto 970 + else: + print("YOU NOW HAVE A NECK.") + N = 1 + C = 0 + # goto 970 + elif Z == 3: + print("3=HEAD") + if N == 0: + print("YOU DO NOT HAVE A NECK.") + # goto 970 + elif H == 1: + print("YOU HAVE A HEAD.") + # goto 970 + else: + print("YOU NEEDED A HEAD.") + H = 1 + C = 0 + # goto 970 + elif Z == 4: + print("4=FEELERS") + if H == 0: + print("YOU DO NOT HAVE A HEAD.") + # goto 970 + elif A == 2: + print("YOU HAVE TWO FEELERS ALREADY.") + # goto 970 + else: + print("I NOW GIVE YOU A FEELER.") + A = A + 1 + C = 0 + # goto 970 + elif Z == 5: + print("5=TAIL") + if B == 0: + print("YOU DO NOT HAVE A BODY.") + # goto 970 + elif T == 1: + print("YOU ALREADY HAVE A TAIL.") + # goto 970 + else: + print("I NOW GIVE YOU A TAIL.") + T = T + 1 + C = 0 + # goto 970 + elif Z == 6: + print("6=LEG") + if L == 6: + print("YOU HAVE 6 FEET ALREADY.") + # goto 970 + elif B == 0: + print("YOU DO NOT HAVE A BODY.") + # goto 970 + else: + L = L + 1 + C = 0 + print(f"YOU NOW HAVE {L} LEGS") + # goto 970 + + # 970 + X = random.randint(1, 6) + print() + for delay in range(2000): + pass + + print("I ROLLED A", X) + if X == 1: + print("1=BODY") + if P == 1: + print("I DO NOT NEED A BODY.") + # goto 1630 + else: + print("I NOW HAVE A BODY.") + C = 0 + P = 1 + # goto 1630 + elif X == 2: + print("2=NECK") + if Q == 1: + print("I DO NOT NEED A NECK.") + # goto 1630 + elif P == 0: + print("I DO NOT HAVE A BODY.") + # goto 1630 + else: + print("I NOW HAVE A NECK.") + Q = 1 + C = 0 + # goto 1630 + elif X == 3: + print("3=HEAD") + if Q == 0: + print("I DO NOT HAVE A NECK.") + # goto 1630 + elif R == 1: + print("I HAVE A HEAD.") + # goto 1630 + else: + print("I NEEDED A HEAD.") + R = 1 + C = 0 + # goto 1630 + elif X == 4: + print("4=FEELERS") + if R == 0: + print("I DO NOT HAVE A HEAD.") + # goto 1630 + elif S == 2: + print("I HAVE TWO FEELERS ALREADY.") + # goto 1630 + else: + print("I GET A FEELER.") + S = S + 1 + C = 0 + # goto 1630 + elif X == 5: + print("5=TAIL") + if P == 0: + print("I DO NOT HAVE A BODY.") + # goto 1630 + elif U == 1: + print("I ALREADY HAVE A TAIL.") + # goto 1630 + else: + print("I NOW HAVE A TAIL.") + U = 1 + C = 0 + # goto 1630 + elif X == 6: + print("6=LEG") + if V == 6: + print("I HAVE 6 FEET.") + # goto 1630 + elif P == 0: + print("I DO NOT HAVE A BODY.") + # goto 1630 + else: + V = V + 1 + C = 0 + print(f"I NOW HAVE {V} LEGS") + # goto 1630 + + # 1630 + if (A == 2) and (T == 1) and (L == 6): + print("YOUR BUG IS FINISHED.") + Y = Y + 1 + if (S == 2) and (P == 1) and (V == 6): + print("MY BUG IS FINISHED.") + Y = Y + 2 + if C == 1: + continue + Z = input("DO YOU WANT THE PICTURES? ") + if Z != "NO": + print("*****YOUR BUG*****") + print_n_newlines(2) + if A != 0: + print_feelers(A, is_player=True) + if H != 0: + print_head() + if N != 0: + print_neck() + if B != 0: + print_body(True) if T == 1 else print_body(False) + if L != 0: + print_legs(L) + print_n_newlines(4) + print("*****MY BUG*****") + print_n_newlines(3) + if S != 0: + print_feelers(S, is_player=False) + if R == 1: + print_head() + if Q != 0: + print_neck() + if P != 0: + print_body(True) if U == 1 else print_body(False) + if V != 0: + print_legs(V) + + if Y != 0: + break + +print("I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!") \ No newline at end of file From 4e85aa83cd96b1a39854074146213d98d8a0e73f Mon Sep 17 00:00:00 2001 From: cowboy8625 Date: Mon, 21 Feb 2022 07:35:21 -0600 Subject: [PATCH 324/337] A rust verstion of the Tic Tac Toe Game --- 89_Tic-Tac-Toe/rust/Cargo.toml | 4 ++ 89_Tic-Tac-Toe/rust/README.md | 6 ++ 89_Tic-Tac-Toe/rust/src/main.rs | 110 ++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 89_Tic-Tac-Toe/rust/Cargo.toml create mode 100644 89_Tic-Tac-Toe/rust/README.md create mode 100644 89_Tic-Tac-Toe/rust/src/main.rs diff --git a/89_Tic-Tac-Toe/rust/Cargo.toml b/89_Tic-Tac-Toe/rust/Cargo.toml new file mode 100644 index 00000000..39d7d04b --- /dev/null +++ b/89_Tic-Tac-Toe/rust/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "rust" +version = "0.1.0" +[dependencies] diff --git a/89_Tic-Tac-Toe/rust/README.md b/89_Tic-Tac-Toe/rust/README.md new file mode 100644 index 00000000..d05c9af4 --- /dev/null +++ b/89_Tic-Tac-Toe/rust/README.md @@ -0,0 +1,6 @@ +README.md + +Original source downloaded from Vintage Basic + +Conversion to Rust + diff --git a/89_Tic-Tac-Toe/rust/src/main.rs b/89_Tic-Tac-Toe/rust/src/main.rs new file mode 100644 index 00000000..5aab976b --- /dev/null +++ b/89_Tic-Tac-Toe/rust/src/main.rs @@ -0,0 +1,110 @@ +use std::fmt::{self, Display}; +use std::io::{stdin, stdout, Write}; + +const WIN: [(usize, usize, usize); 8] = [ + (0, 1, 2), + (3, 4, 5), + (6, 7, 8), + (0, 4, 8), + (2, 4, 6), + (0, 3, 6), + (1, 4, 7), + (2, 5, 8), +]; + +type Board = [Sign; 9]; + +fn main() { + let mut board: Board = [Sign::E; 9]; + let mut sign = Sign::X; + loop { + clear(); + render(&board, &sign); + let (win, winner) = check_board(board); + if win { + match winner { + Sign::X => break println!("Looks like X own this one!"), + Sign::O => break println!("O is the winner!!"), + Sign::C => break println!("Cat got this one!"), + Sign::E => {} + } + } + let num = input("Pick a number 1 - 9:> "); + if let Some(Sign::E) = board.get(num) { + board.get_mut(num).map(|s| *s = sign); + sign = if sign == Sign::X { Sign::O } else { Sign::X }; + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq)] +enum Sign { + X, + O, + C, + E, +} + +impl Display for Sign { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let sign = match self { + Self::X => 'X', + Self::O => 'O', + Self::C => 'C', + Self::E => ' ', + }; + write!(f, "{}", sign) + } +} + +fn check_board(board: Board) -> (bool, Sign) { + for &(a, b, c) in WIN.iter() { + if board[a] == board[b] && board[a] == board[c] { + return (true, board[a]); + } + } + if !board.contains(&Sign::E) { + return (true, Sign::C); + } + (false, Sign::E) +} + +fn clear() { + println!("\x1b[2J\x1b[0;0H"); +} + +fn input(message: &str) -> usize { + let mut out = String::new(); + loop { + print!("{}", message); + stdout().flush().expect("Failed to flush to stdout."); + stdin().read_line(&mut out).expect("Failed to read line"); + let num = out.trim().parse::(); + match num { + Ok(n) => match n { + 1..=9 => return n - 1, + _ => println!("The number needs to be between 1 - 9."), + }, + Err(_) => println!("'{}' is not a number.", out.trim()), + } + out.clear(); + } +} + +fn render(spots: &Board, sign: &Sign) { + println!(" The board is numbered"); + println!( + " {} │ {} │ {} [{}: Turn] 1 │ 2 │ 3", + spots[0], spots[1], spots[2], sign + ); + println!("⎼⎼⎼╄⎼⎼⎼╄⎼⎼⎼ ⎼⎼⎼╄⎼⎼⎼╄⎼⎼⎼"); + println!( + " {} │ {} │ {} 4 │ 5 │ 6 ", + spots[3], spots[4], spots[5] + ); + println!("⎼⎼⎼╄⎼⎼⎼╄⎼⎼⎼ ⎼⎼⎼╄⎼⎼⎼╄⎼⎼⎼"); + println!( + " {} │ {} │ {} 7 │ 8 │ 9 ", + spots[6], spots[7], spots[8] + ); +} From abe199102c1f00c74c6d5b1c4f157dc754b04498 Mon Sep 17 00:00:00 2001 From: uMetalooper Date: Mon, 21 Feb 2022 18:39:20 +0000 Subject: [PATCH 325/337] Bullfight added --- 17_Bullfight/python/Bullfight.py | 242 +++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 17_Bullfight/python/Bullfight.py diff --git a/17_Bullfight/python/Bullfight.py b/17_Bullfight/python/Bullfight.py new file mode 100644 index 00000000..4b77c2de --- /dev/null +++ b/17_Bullfight/python/Bullfight.py @@ -0,0 +1,242 @@ +import math +import random + + +def print_n_whitespaces(n: int): + print(" "*n, end="") + + +def print_n_newlines(n: int): + for _ in range(n): + print() + + +def subroutine_1610(): + B = 3/A*random.random() + if (B < 0.37): + C = 0.5 + elif (B < 0.5): + C = 0.4 + elif (B < 0.63): + C = 0.3 + elif (B < 0.87): + C = 0.2 + else: + C = 0.1 + T = math.floor(10*C+0.2) + print(f"THE {AS}{BS} DID A {LS[T]} JOB.") + if T >= 4: + if T == 5: + # 1800 & 1810 are unreachable, so it's not presented here + K = random.randint(1, 2) + if K == 1: + print(f"ONE OF THE {AS}{BS} WAS KILLED.") + elif K == 2: + print(f"NO {AS}{BS} WERE KILLED.") + else: + if AS != "TOREAD": + K = random.randint(1, 2) + print(f"{K} OF THE HORSES OF THE {AS}{BS} KILLED.") + K = random.randint(1, 2) + print(f"{K} OF THE {AS}{BS} KILLED.") + print() + return C + + +def FNC(): + Q = (4.5+L/6-(D[1]+D[2])*2.5+4*D[4]+2 * + D[5]-(D[3] ** 2)/120-A)*random.random() + return Q + + +print_n_whitespaces(34) +print("BULL") +print_n_whitespaces(15) +print("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + +print_n_newlines(2) +L = 1 + +Z = input("DO YOU WANT INSTRUCTIONS? ") +if Z != "NO": + print("HELLO, ALL YOU BLOODLOVERS AND AFICIONADOS.") + print("HERE IS YOUR BIG CHANCE TO KILL A BULL.") + print() + print("ON EACH PASS OF THE BULL, YOU MAY TRY") + print("0 - VERONICA (DANGEROUS INSIDE MOVE OF THE CAPE)") + print("1 - LESS DANGEROUS OUTSIDE MOVE OF THE CAPE") + print("2 - ORDINARY SWIRL OF THE CAPE.") + print() + print("INSTEAD OF THE ABOVE, YOU MAY TRY TO KILL THE BULL") + print("ON ANY TURN: 4 (OVER THE HORNS), 5 (IN THE CHEST).") + print("BUT IF I WERE YOU,") + print("I WOULDN'T TRY IT BEFORE THE SEVENTH PASS.") + print() + print("THE CROWD WILL DETERMINE WHAT AWARD YOU DESERVE") + print("(POSTHUMOUSLY IF NECESSARY).") + print("THE BRAVER YOU ARE, THE BETTER THE AWARD YOU RECEIVE.") + print() + print("THE BETTER THE JOB THE PICADORES AND TOREADORES DO,") + print("THE BETTER YOUR CHANCES ARE.") +print_n_newlines(2) + +D = {} +D[5] = 1 +D[4] = 1 +LS = ["", "SUPERB", "GOOD", "FAIR", "POOR", "AWFUL"] +A = random.randint(1, 5) +print(f"YOU HAVE DRAWN A {LS[A]} BULL.") +if A > 4: + print("YOU'RE LUCKY.") +elif A < 2: + print("GOOD LUCK. YOU'LL NEED IT.") + print() +print() +AS = "PICADO" +BS = "RES" +C = subroutine_1610() +D[1] = C +AS = "TOREAD" +BS = "ORES" +subroutine_1610() +D[2] = C +print_n_newlines(2) +D[3] = 0 +while True: + D[3] = D[3] + 1 # 660 + print(f"PASS NUMBER {D[3]}") + if D[3] >= 3: + while True: # 1930 + AS = input("HERE COMES THE BULL. TRY FOR A KILL? ") + if AS not in ["YES", "NO"]: + print("INCORRECT ANSWER - - PLEASE TYPE 'YES' OR 'NO'.") + else: + break + Z1 = 1 if AS == "YES" else 2 + if Z1 != 1: + print("CAPE MOVE? ", end="") + else: + pass + # goto 1130 + else: + print("THE BULL IS CHARGING AT YOU! YOU ARE THE MATADOR--") + while True: # 1930 + AS = input("DO YOU WANT TO KILL THE BULL? ") + if AS not in ["YES", "NO"]: + print("INCORRECT ANSWER - - PLEASE TYPE 'YES' OR 'NO'.") + else: + break + Z1 = 1 if AS == "YES" else 2 + if Z1 != 1: + print("WHAT MOVE DO YOU MAKE WITH THE CAPE? ", end="") + else: + # goto 1130 + pass + gore = 0 + if Z1 != 1: # NO + while True: + E = float(input()) + if E != float(int(abs(E))): + print("DON'T PANIC, YOU IDIOT! PUT DOWN A CORRECT NUMBER") + elif E < 3: + break + if E == 0: + M = 3 + elif E == 1: + M = 2 + else: + M = 0.5 + L = L + M + F = (6-A+M/10)*random.random()/((D[1]+D[2]+D[3]/10)*5) + if F < 0.51: + continue + gore = 1 + else: # YES + print() + print("IT IS THE MOMENT OF TRUTH.") + print() + H = int(input("HOW DO YOU TRY TO KILL THE BULL? ")) + if H not in [4, 5]: + print("YOU PANICKED. THE BULL GORED YOU.") + gore = 2 + # goto 970 + else: + K=(6-A)*10*random.random()/((D[1]+D[2])*5*D[3]) + if H == 4: + if K > 0.8: + gore = 1 + else: + if K > 0.2: + gore = 1 + if gore == 0: + print("YOU KILLED THE BULL!") + D[5] = 2 + break + if gore > 0: + if gore == 1: + print("THE BULL HAS GORED YOU!") + death = False + while True: + _ = random.randint(1, 2) # 970 + if _ == 1: + print("YOU ARE DEAD.") + D[4] = 1.5 + # goto 1320 + death = True + break + else: + print("YOU ARE STILL ALIVE.") + print() + print("DO YOU RUN FROM THE RING? ", end="") + while True: # 1930 + AS = input() + if AS not in ["YES", "NO"]: + print("INCORRECT ANSWER - - PLEASE TYPE 'YES' OR 'NO'.") + else: + break + Z1 = 1 if AS == "YES" else 2 + if Z1 == 2: + print("YOU ARE BRAVE. STUPID, BUT BRAVE.") + _ = random.randint(1, 2) + if _ == 1: + D[4] = 2 + # goto 660, outter while loop + death = True + break + else: + print("YOU ARE GORED AGAIN!") + # goto 970 + else: + print("COWARD") + D[4] = 0 + # goto 1310, break outter while loop + death = True + break + + if death==True: + break +# 1310 +print_n_newlines(3) +if D[4] == 0: + print("THE CROWD BOOS FOR TEN MINUTES. IF YOU EVER DARE TO SHOW") + print("YOUR FACE IN A RING AGAIN, THEY SWEAR THEY WILL KILL YOU--") + print("UNLESS THE BULL DOES FIRST.") +else: + if D[4] == 2: + print("THE CROWD CHEERS WILDLY!") + elif D[5] == 2: + print("THE CROWD CHEERS!") + print() + print("THE CROWD AWARDS YOU") + if FNC() < 2.4: + print("NOTHING AT ALL.") + elif FNC() < 4.9: + print("ONE EAR OF THE BULL.") + elif FNC() < 7.4: + print("BOTH EARS OF THE BULL!") + print("OLE!") + else: + print("OLE! YOU ARE 'MUY HOMBRE'!! OLE! OLE!") + print() + print("ADIOS") + print_n_newlines(3) From 06c8d2be697f2908dbf2e43ea8e80c1c23deac99 Mon Sep 17 00:00:00 2001 From: Taciano Dreckmann Perez Date: Mon, 21 Feb 2022 21:42:22 +0100 Subject: [PATCH 326/337] added 84_Super_Star_Trek Java port --- .../java/SuperStarTrekGame.java | 1239 +++++++++++++++++ .../java/SuperStarTrekInstructions.java | 162 +++ 2 files changed, 1401 insertions(+) create mode 100644 84_Super_Star_Trek/java/SuperStarTrekGame.java create mode 100644 84_Super_Star_Trek/java/SuperStarTrekInstructions.java diff --git a/84_Super_Star_Trek/java/SuperStarTrekGame.java b/84_Super_Star_Trek/java/SuperStarTrekGame.java new file mode 100644 index 00000000..213b2a0b --- /dev/null +++ b/84_Super_Star_Trek/java/SuperStarTrekGame.java @@ -0,0 +1,1239 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * SUPER STARTREK - MAY 16,1978 + * **** **** STAR TREK **** **** + * **** SIMULATION OF A MISSION OF THE STARSHIP ENTERPRISE, + * **** AS SEEN ON THE STAR TREK TV SHOW. + * **** ORIGINAL PROGRAM BY MIKE MAYFIELD, MODIFIED VERSION + * **** PUBLISHED IN DEC'S "101 BASIC GAMES", BY DAVE AHL. + * **** MODIFICATIONS TO THE LATTER (PLUS DEBUGGING) BY BOB + * *** LEEDOM - APRIL & DECEMBER 1974, + * *** WITH A LITTLE HELP FROM HIS FRIENDS . . . + * + * Ported to Java in Jan-Feb 2022 by + * Taciano Dreckmann Perez (taciano.perez@gmail.com) + */ +public class SuperStarTrekGame { + + // markers + static final String MARKER_EMPTY = " "; + static final String MARKER_ENTERPRISE = "<*>"; + static final String MARKER_KLINGON = "+K+"; + static final String MARKER_STARBASE = ">!<"; + static final String MARKER_STAR = " * "; + + // commands + static final int COMMAND_NAV = 1; + static final int COMMAND_SRS = 2; + static final int COMMAND_LRS = 3; + static final int COMMAND_PHA = 4; + static final int COMMAND_TOR = 5; + static final int COMMAND_SHE = 6; + static final int COMMAND_DAM = 7; + static final int COMMAND_COM = 8; + static final int COMMAND_XXX = 9; + + // computer commands + static final int COMPUTER_COMMAND_CUMULATIVE_GALACTIC_RECORD = 1; + static final int COMPUTER_COMMAND_STATUS_REPORT = 2; + static final int COMPUTER_COMMAND_PHOTON_TORPEDO_DATA = 3; + static final int COMPUTER_COMMAND_STARBASE_NAV_DATA = 4; + static final int COMPUTER_COMMAND_DIR_DIST_CALC = 5; + static final int COMPUTER_COMMAND_GALAXY_MAP = 6; + + // devices + static final int DEVICE_WARP_ENGINES = 1; + static final int DEVICE_SHORT_RANGE_SENSORS = 2; + static final int DEVICE_LONG_RANGE_SENSORS = 3; + static final int DEVICE_PHASER_CONTROL = 4; + static final int DEVICE_PHOTON_TUBES = 5; + static final int DEVICE_DAMAGE_CONTROL = 6; + static final int DEVICE_SHIELD_CONTROL = 7; + static final int DEVICE_LIBRARY_COMPUTER = 8; + + // other constants + static final String QUADRANT_ROW = " "; + static final String COMMANDS = "NAVSRSLRSPHATORSHEDAMCOMXXX"; + static final Random random = new Random(); + + // game state + final int galaxy[][] = new int[9][9]; // 8x8 galaxy map G + final int cardinalDirections[][] = new int[10][3]; // 9x2 vectors in cardinal directions C + final int klingonQuadrants[][] = new int[4][4]; // 3x3 position of klingons K + final int chartedGalaxy[][] = new int[9][9]; // 8x8 charted galaxy map Z + final double deviceStatus[] = new double[9]; // 8 device damage stats D + String quadrantMap = QUADRANT_ROW + QUADRANT_ROW + QUADRANT_ROW + QUADRANT_ROW + QUADRANT_ROW + QUADRANT_ROW + QUADRANT_ROW + leftStr(QUADRANT_ROW, 17); // current quadrant map + double stardate = toInt(random() * 20 + 20); // T + int energy = 3000; // E + boolean shipDocked = false; // D0 + int torpedoes = 10; // P + int shields = 0; // S + int missionDuration = 25 + toInt(random() * 10); // T9 (mission duration in stardates) + int basesInGalaxy = 0; // B9 + int remainingKlingons; // K7 + int klingonsInGalaxy = 0; // K9 + int quadrantX; // Q1 + int quadrantY; // Q2 + int sectorX; // S1 + int sectorY; // S2 + int klingons = 0; //K3 + int starbases = 0; // B3 + int stars = 0; // S3 + int starbaseX = 0; // X coordinate of starbase + int starbaseY = 0; // Y coord of starbase + double repairCost; // damage repair cost D4 + boolean restart = false; + + // initial values + final double initialStardate = stardate; // T0 + final int initialEnergy = energy; // E0 + final int initialTorpedoes = torpedoes; // P0 + final int avgKlingonShieldEnergy = 200; // S9 + + public static void main(String[] args) { + final SuperStarTrekGame game = new SuperStarTrekGame(); + printBanner(); + while (true) { + game.setup(); + game.enterNewQuadrant(); + game.restart = false; + game.commandLoop(); + } + } + + static void printBanner() { // 220 + IntStream.range(1, 10).forEach(i -> { + println(""); + }); + println( + """ + ,------*------, + ,------------- '--- ------' + '-------- --' / / + ,---' '-------/ /--, + '----------------' + + THE USS ENTERPRISE --- NCC-1701" + + """ + ); + } + + double fnd(int i) { // 470 + return Math.sqrt((klingonQuadrants[i][1] - sectorX) ^ 2 + (klingonQuadrants[i][2] - sectorY) ^ 2); + } + + static int fnr() { // 475 + // Generate a random integer from 1 to 8 inclusive. + return toInt(random() * 7 + 1); + } + + void setup() { + this.initEnterprisePosition(); + this.setupWhatExistsInTheGalaxy(); + } + + void initEnterprisePosition() { // 480 + quadrantX = fnr(); + quadrantY = fnr(); + sectorX = fnr(); + sectorY = fnr(); + IntStream.range(1, 9).forEach(i -> { + cardinalDirections[i][1] = 0; + cardinalDirections[i][2] = 0; + }); + cardinalDirections[3][1] = -1; + cardinalDirections[2][1] = -1; + cardinalDirections[4][1] = -1; + cardinalDirections[4][2] = -1; + cardinalDirections[5][2] = -1; + cardinalDirections[6][2] = -1; + cardinalDirections[1][2] = 1; + cardinalDirections[2][2] = 1; + cardinalDirections[6][1] = 1; + cardinalDirections[7][1] = 1; + cardinalDirections[8][1] = 1; + cardinalDirections[8][2] = 1; + cardinalDirections[9][2] = 1; + IntStream.range(1, 8).forEach(i -> deviceStatus[i] = 0); + } + + void setupWhatExistsInTheGalaxy() { // 810 + // KLINGONS, STARBASES, STARS + IntStream.range(1, 8).forEach(x -> { + IntStream.range(1, 8).forEach(y -> { + klingons = 0; + chartedGalaxy[x][y] = 0; + float random = random(); + if (random > .98) { + klingons = 3; + klingonsInGalaxy = +3; + } else if (random > .95) { + klingons = 2; + klingonsInGalaxy = +2; + } else if (random > .80) { + klingons = 1; + klingonsInGalaxy = +1; + } + starbases = 0; + if (random() > .96) { + starbases = 1; + basesInGalaxy = +1; + } + galaxy[x][y] = klingons * 100 + starbases * 10 + fnr(); + }); + }); + if (klingonsInGalaxy > missionDuration) missionDuration = klingonsInGalaxy + 1; + if (basesInGalaxy == 0) { + if (galaxy[quadrantX][quadrantY] < 200) { + galaxy[quadrantX][quadrantY] = galaxy[quadrantX][quadrantY] + 120; + klingonsInGalaxy = +1; + } + basesInGalaxy = 1; + galaxy[quadrantX][quadrantY] = +10; + quadrantX = fnr(); + quadrantY = fnr(); + } + remainingKlingons = klingonsInGalaxy; + println("YOUR ORDERS ARE AS FOLLOWS:\n" + + " DESTROY THE " + klingonsInGalaxy + " KLINGON WARSHIP" + ((klingonsInGalaxy == 1) ? "" : "S") + " WHICH HAVE INVADED\n" + + " THE GALAXY BEFORE THEY CAN ATTACK FEDERATION HEADQUARTERS\n" + + " ON STARDATE " + initialStardate + missionDuration + " THIS GIVES YOU " + missionDuration + " DAYS. THERE " + ((basesInGalaxy == 1) ? "IS" : "ARE") + "\n" + + " " + basesInGalaxy + " STARBASE" + ((basesInGalaxy == 1) ? "" : "S") + " IN THE GALAXY FOR RESUPPLYING YOUR SHIP"); + } + + void enterNewQuadrant() { // 1320 + // ANY TIME NEW QUADRANT ENTERED + klingons = 0; + starbases = 0; + stars = 0; + repairCost = .5 * random(); + chartedGalaxy[quadrantX][quadrantY] = galaxy[quadrantX][quadrantY]; + if (!(quadrantX < 1 || quadrantX > 8 || quadrantY < 1 || quadrantY > 8)) { + final String quadrantName = getQuadrantName(false, quadrantX, quadrantY); + if (initialStardate == stardate) { + println("YOUR MISSION BEGINS WITH YOUR STARSHIP LOCATED\n" + + "IN THE GALACTIC QUADRANT, '" + quadrantName + "'."); + } else { + println("NOW ENTERING " + quadrantName + " QUADRANT . . ."); + } + println(""); + klingons = (int) Math.round(galaxy[quadrantX][quadrantY] * .01); + starbases = (int) Math.round(galaxy[quadrantX][quadrantY] * .1) - 10 * klingons; + stars = galaxy[quadrantX][quadrantY] - 100 * klingons - 10 * starbases; + if (klingons != 0) { + println("COMBAT AREA CONDITION RED"); + if (shields <= 200) { + println(" SHIELDS DANGEROUSLY LOW"); + } + } + IntStream.range(1, 3).forEach(i -> { + klingonQuadrants[i][1] = 0; + klingonQuadrants[i][2] = 0; + }); + } + IntStream.range(1, 3).forEach(i -> { + klingonQuadrants[i][3] = 0; + }); + // POSITION ENTERPRISE IN QUADRANT + insertMarker(MARKER_ENTERPRISE, sectorX, sectorY); + // position Klingons + if (klingons >= 1) { + for (int i = 1; i <= klingons; i++) { + final int[] emptyCoordinate = findEmptyPlaceInQuadrant(quadrantMap); + insertMarker(MARKER_KLINGON, emptyCoordinate[0], emptyCoordinate[1]); + klingonQuadrants[i][1] = emptyCoordinate[0]; + klingonQuadrants[i][2] = emptyCoordinate[1]; + klingonQuadrants[i][3] = (int) Math.round(avgKlingonShieldEnergy * (0.5 + random())); + } + } + // position Bases + if (starbases >= 1) { + final int[] emptyCoordinate = findEmptyPlaceInQuadrant(quadrantMap); + starbaseX = emptyCoordinate[0]; + starbaseY = emptyCoordinate[1]; + insertMarker(MARKER_STARBASE, emptyCoordinate[0], emptyCoordinate[1]); + } + // position stars + for (int i = 1; i <= stars; i++) { + final int[] emptyCoordinate = findEmptyPlaceInQuadrant(quadrantMap); + insertMarker(MARKER_STAR, emptyCoordinate[0], emptyCoordinate[1]); + } + shortRangeSensorScan(); // 1980 + } + + void commandLoop() { + while (!this.restart) { + checkShipEnergy(); // 1990 + String cmdStr = ""; + while ("".equals(cmdStr)) cmdStr = inputStr("COMMAND"); + boolean foundCommand = false; + for (int i = 1; i <= 9; i++) { + if (leftStr(cmdStr, 3).equals(midStr(COMMANDS, 3 * i - 2, 3))) { + switch (i) { + case COMMAND_NAV: + navigation(); + foundCommand = true; + break; + case COMMAND_SRS: + shortRangeSensorScan(); + foundCommand = true; + break; + case COMMAND_LRS: + longRangeSensorScan(); + foundCommand = true; + break; + case COMMAND_PHA: + firePhasers(); + foundCommand = true; + break; + case COMMAND_TOR: + firePhotonTorpedo(); + foundCommand = true; + break; + case COMMAND_SHE: + shieldControl(); + foundCommand = true; + break; + case COMMAND_DAM: + damageControl(); + foundCommand = true; + break; + case COMMAND_COM: + libraryComputer(); + foundCommand = true; + break; + case COMMAND_XXX: + endGameFail(false); + foundCommand = true; + break; + default: + printCommandOptions(); + foundCommand = true; + } + } + } + if (!foundCommand) printCommandOptions(); + } + } + + void checkShipEnergy() { + int totalEnergy = (shields + energy); + if (totalEnergy < 10 && (energy <= 10 || deviceStatus[DEVICE_SHIELD_CONTROL] != 0)) { + println("\n** FATAL ERROR ** YOU'VE JUST STRANDED YOUR SHIP IN "); + println("SPACE"); + println("YOU HAVE INSUFFICIENT MANEUVERING ENERGY,"); + println(" AND SHIELD CONTROL"); + println("IS PRESENTLY INCAPABLE OF CROSS"); + println("-CIRCUITING TO ENGINE ROOM!!"); + endGameFail(false); + } + } + + void printCommandOptions() { + println("ENTER ONE OF THE FOLLOWING:"); + println(" NAV (TO SET COURSE)"); + println(" SRS (FOR SHORT RANGE SENSOR SCAN)"); + println(" LRS (FOR LONG RANGE SENSOR SCAN)"); + println(" PHA (TO FIRE PHASERS)"); + println(" TOR (TO FIRE PHOTON TORPEDOES)"); + println(" SHE (TO RAISE OR LOWER SHIELDS)"); + println(" DAM (FOR DAMAGE CONTROL REPORTS)"); + println(" COM (TO CALL ON LIBRARY-COMPUTER)"); + println(" XXX (TO RESIGN YOUR COMMAND)\n"); + } + + void navigation() { // 2290 + float course = toInt(inputFloat("COURSE (0-9)")); + if (course == 9) course = 1; + if (course < 1 || course >= 9) { + println(" LT. SULU REPORTS, 'INCORRECT COURSE DATA, SIR!'"); + return; + } + println("WARP FACTOR (0-" + ((deviceStatus[DEVICE_WARP_ENGINES] < 0) ? "0.2" : "8") + ")"); + float warp = inputFloat(""); + if (deviceStatus[DEVICE_WARP_ENGINES] < 0 && warp > .2) { + // 2470 + println("WARP ENGINES ARE DAMAGED. MAXIMUM SPEED = WARP 0.2"); + return; + } + if (warp == 0) return; + if (warp > 0 && warp <= 8) { + // 2490 + int n = toInt(warp * 8); + if (energy - n >= 0) { + klingonsMoveAndFire(); + repairDamagedDevices(course, warp, n); + moveStarship(course, warp, n); + } else { + println("ENGINEERING REPORTS 'INSUFFICIENT ENERGY AVAILABLE"); + println(" FOR MANEUVERING AT WARP" + warp + "!'"); + if (shields < n - energy || deviceStatus[DEVICE_SHIELD_CONTROL] < 0) return; + println("DEFLECTOR CONTROL ROOM ACKNOWLEDGES" + shields + "UNITS OF ENERGY"); + println(" PRESENTLY DEPLOYED TO SHIELDS."); + return; + } + } else { + println(" CHIEF ENGINEER SCOTT REPORTS 'THE ENGINES WON'T TAKE"); + println(" WARP " + warp + "!'"); + return; + } + } + + void klingonsMoveAndFire() { // 2590 + // KLINGONS MOVE/FIRE ON MOVING STARSHIP . . . + for (int i = 1; i <= klingons; i++) { + if (klingonQuadrants[i][3] == 0) continue; + insertMarker(MARKER_EMPTY, klingonQuadrants[i][1], klingonQuadrants[i][2]); + final int[] newCoords = findEmptyPlaceInQuadrant(quadrantMap); + klingonQuadrants[i][1] = newCoords[0]; + klingonQuadrants[i][2] = newCoords[1]; + insertMarker(MARKER_KLINGON, klingonQuadrants[i][1], klingonQuadrants[i][2]); + } + klingonsShoot(); + } + + void repairDamagedDevices(final float course, final float warp, final int N) { + // repair damaged devices and print damage report + for (int i = 1; i <= 8; i++) { + if (deviceStatus[i] < 0) { + deviceStatus[i] += Math.min(warp, 1); + if ((deviceStatus[i] > -.1) && (deviceStatus[i] < 0)) { + deviceStatus[i] = -.1; + break; + } else if (deviceStatus[i] >= 0) { + println("DAMAGE CONTROL REPORT: "); + println(tab(8) + printDeviceName(i) + " REPAIR COMPLETED."); + } + } + } + if (random() > .2) moveStarship(course, warp, N); // 80% chance no damage nor repair + int randomDevice = fnr(); // random device + if (random() >= .6) { // 40% chance of repair of random device + deviceStatus[randomDevice] = deviceStatus[randomDevice] + random() * 3 + 1; + println("DAMAGE CONTROL REPORT: " + printDeviceName(randomDevice) + " STATE OF REPAIR IMPROVED\n"); + } else { // 60% chance of damage of random device + deviceStatus[randomDevice] = deviceStatus[randomDevice] - (random() * 5 + 1); // + println("DAMAGE CONTROL REPORT: " + printDeviceName(randomDevice) + " DAMAGED"); + } + } + + void moveStarship(final float course, final float warp, final int n) { // 3070 + insertMarker(MARKER_EMPTY, toInt(sectorX), toInt(sectorY)); + int ic1 = toInt(course); + float x1 = cardinalDirections[ic1][1] + (cardinalDirections[ic1 + 1][1] - cardinalDirections[ic1][1]) * (course - ic1); + float x = sectorX; + float y = sectorY; + float x2 = cardinalDirections[ic1][2] + (cardinalDirections[ic1 + 1][2] - cardinalDirections[ic1][2]) * (course - ic1); + final int initialQuadrantX = quadrantX; + final int initialQuadrantY = quadrantY; + for (int i = 1; i <= n; i++) { + sectorX += x1; + sectorY += x2; + if (sectorX < 1 || sectorX >= 9 || sectorY < 1 || sectorY >= 9) { + // exceeded quadrant limits + x = 8 * quadrantX + x + n * x1; + y = 8 * quadrantY + y + n * x2; + quadrantX = toInt(x / 8); + quadrantY = toInt(y / 8); + sectorX = toInt(x - quadrantX * 8); + sectorY = toInt(y - quadrantY * 8); + if (sectorX == 0) { + quadrantX = quadrantX - 1; + sectorX = 8; + } + if (sectorY == 0) { + quadrantY = quadrantY - 1; + sectorY = 8; + } + boolean hitEdge = false; + if (quadrantX < 1) { + hitEdge = true; + quadrantX = 1; + sectorX = 1; + } + if (quadrantX > 8) { + hitEdge = true; + quadrantX = 8; + sectorX = 8; + } + if (quadrantY < 1) { + hitEdge = true; + quadrantY = 8; + sectorY = 8; + } + if (quadrantY > 8) { + hitEdge = true; + quadrantY = 8; + sectorY = 8; + } + if (hitEdge) { + println("LT. UHURA REPORTS MESSAGE FROM STARFLEET COMMAND:"); + println(" 'PERMISSION TO ATTEMPT CROSSING OF GALACTIC PERIMETER"); + println(" IS HEREBY *DENIED*. SHUT DOWN YOUR ENGINES.'"); + println("CHIEF ENGINEER SCOTT REPORTS 'WARP ENGINES SHUT DOWN"); + println(" AT SECTOR " + sectorX + "," + sectorY + " OF QUADRANT " + quadrantX + "," + quadrantY + ".'"); + if (stardate > initialStardate + missionDuration) endGameFail(false); + } + if (8 * quadrantX + quadrantY == 8 * initialQuadrantX + initialQuadrantY) { + break; + } + stardate += 1; + maneuverEnergySR(n); + enterNewQuadrant(); + return; + } else { + int S8 = toInt(sectorX) * 24 + toInt(sectorY) * 3 - 26; // S8 = pos + if (!(" ".equals(midStr(quadrantMap, S8, 2)))) { + sectorX = toInt(sectorX - x1); + sectorY = toInt(sectorY - x2); + println("WARP ENGINES SHUT DOWN AT "); + println("SECTOR " + sectorX + "," + sectorY + " DUE TO BAD NAVIGATION"); + break; + } + } + } + sectorX = toInt(sectorX); + sectorY = toInt(sectorY); + insertMarker(MARKER_ENTERPRISE, toInt(sectorX), toInt(sectorY)); + maneuverEnergySR(n); + double stardateDelta = 1; + if (warp < 1) stardateDelta = .1 * toInt(10 * warp); + stardate = stardate + stardateDelta; + if (stardate > initialStardate + missionDuration) endGameFail(false); + shortRangeSensorScan(); + } + + void maneuverEnergySR(final int N) { // 3910 + energy = energy - N - 10; + if (energy >= 0) return; + println("SHIELD CONTROL SUPPLIES ENERGY TO COMPLETE THE MANEUVER."); + shields = shields + energy; + energy = 0; + if (shields <= 0) shields = 0; + } + + void longRangeSensorScan() { // 3390 + // LONG RANGE SENSOR SCAN CODE + if (deviceStatus[DEVICE_LONG_RANGE_SENSORS] < 0) { + println("LONG RANGE SENSORS ARE INOPERABLE"); + return; + } + println("LONG RANGE SCAN FOR QUADRANT " + quadrantX + "," + quadrantY); + final String rowStr = "-------------------"; + println(rowStr); + final int n[] = new int[4]; + for (int i = quadrantX - 1; i <= quadrantX + 1; i++) { + n[1] = -1; + n[2] = -2; + n[3] = -3; + for (int j = quadrantY - 1; j <= quadrantY + 1; j++) { + if (i > 0 && i < 9 && j > 0 && j < 9) { + n[j - quadrantY + 2] = galaxy[i][j]; + chartedGalaxy[i][j] = galaxy[i][j]; + } + } + for (int l = 1; l <= 3; l++) { + print(": "); + if (n[l] < 0) { + print("*** "); + continue; + } + print(": " + rightStr(Integer.toString(n[l] + 1000), 3) + " "); + } + println(": \n" + rowStr); + } + } + + void firePhasers() { // 4260 + if (deviceStatus[DEVICE_PHASER_CONTROL] < 0) { + println("PHASERS INOPERATIVE"); + return; + } + if (klingons <= 0) { + printNoEnemyShipsMessage(); + return; + } + if (deviceStatus[DEVICE_LIBRARY_COMPUTER] < 0) println("COMPUTER FAILURE HAMPERS ACCURACY"); + println("PHASERS LOCKED ON TARGET; "); + int nrUnitsToFire; + while (true) { + println("ENERGY AVAILABLE = " + energy + " UNITS"); + nrUnitsToFire = toInt(inputFloat("NUMBER OF UNITS TO FIRE")); + if (nrUnitsToFire <= 0) return; + if (energy - nrUnitsToFire >= 0) break; + } + energy = energy - nrUnitsToFire; + if (deviceStatus[DEVICE_SHIELD_CONTROL] < 0) nrUnitsToFire = toInt(nrUnitsToFire * random()); + int h1 = toInt(nrUnitsToFire / klingons); + for (int i = 1; i <= 3; i++) { + if (klingonQuadrants[i][3] <= 0) break; + int hitPoints = toInt((h1 / fnd(0)) * (random() + 2)); + if (hitPoints <= .15 * klingonQuadrants[i][3]) { + println("SENSORS SHOW NO DAMAGE TO ENEMY AT " + klingonQuadrants[i][1] + "," + klingonQuadrants[i][2]); + continue; + } + klingonQuadrants[i][3] = klingonQuadrants[i][3] - hitPoints; + println(hitPoints + " UNIT HIT ON KLINGON AT SECTOR " + klingonQuadrants[i][1] + "," + klingonQuadrants[i][2]); + if (klingonQuadrants[i][3] <= 0) { + println("*** KLINGON DESTROYED ***"); + klingons -= 1; + klingonsInGalaxy -= 1; + insertMarker(MARKER_EMPTY, klingonQuadrants[i][1], klingonQuadrants[i][2]); + klingonQuadrants[i][3] = 0; + galaxy[quadrantX][quadrantY] -= 100; + chartedGalaxy[quadrantX][quadrantY] = galaxy[quadrantX][quadrantY]; + if (klingonsInGalaxy <= 0) endGameSuccess(); + } else { + println(" (SENSORS SHOW" + klingonQuadrants[i][3] + "UNITS REMAINING)"); + } + } + klingonsShoot(); + } + + void printNoEnemyShipsMessage() { // 4270 + println("SCIENCE OFFICER SPOCK REPORTS 'SENSORS SHOW NO ENEMY SHIPS"); + println(" IN THIS QUADRANT'"); + } + + void firePhotonTorpedo() { // 4700 + // PHOTON TORPEDO CODE BEGINS HERE + if (torpedoes <= 0) { + println("ALL PHOTON TORPEDOES EXPENDED"); + return; + } + if (deviceStatus[DEVICE_PHOTON_TUBES] < 0) { + println("PHOTON TUBES ARE NOT OPERATIONAL"); + } + float c1 = inputFloat("PHOTON TORPEDO COURSE (1-9)"); + if (c1 == 9) c1 = 1; + if (c1 < 1 && c1 >= 9) { + println("ENSIGN CHEKOV REPORTS, 'INCORRECT COURSE DATA, SIR!'"); + return; + } + int ic1 = toInt(c1); + float x1 = cardinalDirections[ic1][1] + (cardinalDirections[ic1 + 1][1] - cardinalDirections[ic1][1]) * (c1 - ic1); + energy = energy - 2; + torpedoes = torpedoes - 1; + float x2 = cardinalDirections[ic1][2] + (cardinalDirections[ic1 + 1][2] - cardinalDirections[ic1][2]) * (c1 - ic1); + float x = sectorX; + float y = sectorY; + println("TORPEDO TRACK:"); + while (true) { + x = x + x1; + y = y + x2; + int x3 = Math.round(x); + int y3 = Math.round(y); + if (x3 < 1 || x3 > 8 || y3 < 1 || y3 > 8) { + println("TORPEDO MISSED"); // 5490 + klingonsShoot(); + return; + } + println(" " + x3 + "," + y3); + if (compareMarker(quadrantMap, MARKER_EMPTY, toInt(x), toInt(y))) { + continue; + } else if (compareMarker(quadrantMap, MARKER_KLINGON, toInt(x), toInt(y))) { + println("*** KLINGON DESTROYED ***"); + klingons = klingons - 1; + klingonsInGalaxy = klingonsInGalaxy - 1; + if (klingonsInGalaxy <= 0) endGameSuccess(); + for (int i = 1; i <= 3; i++) { + if (x3 == klingonQuadrants[i][1] && y3 == klingonQuadrants[i][2]) break; + } + int i = 3; + klingonQuadrants[i][3] = 0; + } else if (compareMarker(quadrantMap, MARKER_STAR, toInt(x), toInt(y))) { + println("STAR AT " + x3 + "," + y3 + " ABSORBED TORPEDO ENERGY."); + klingonsShoot(); + return; + } else if (compareMarker(quadrantMap, MARKER_STARBASE, toInt(x), toInt(y))) { + println("*** STARBASE DESTROYED ***"); + starbases = starbases - 1; + basesInGalaxy = basesInGalaxy - 1; + if (basesInGalaxy == 0 && klingonsInGalaxy <= stardate - initialStardate - missionDuration) { + println("THAT DOES IT, CAPTAIN!! YOU ARE HEREBY RELIEVED OF COMMAND"); + println("AND SENTENCED TO 99 STARDATES AT HARD LABOR ON CYGNUS 12!!"); + endGameFail(false); + } else { + println("STARFLEET COMMAND REVIEWING YOUR RECORD TO CONSIDER"); + println("COURT MARTIAL!"); + shipDocked = false; + } + } + insertMarker(MARKER_EMPTY, toInt(x), toInt(y)); + galaxy[quadrantX][quadrantY] = klingons * 100 + starbases * 10 + stars; + chartedGalaxy[quadrantX][quadrantY] = galaxy[quadrantX][quadrantY]; + klingonsShoot(); + } + } + + void shieldControl() { + if (deviceStatus[DEVICE_SHIELD_CONTROL] < 0) { + println("SHIELD CONTROL INOPERABLE"); + return; + } + println("ENERGY AVAILABLE = " + (energy + shields)); + int energyToShields = toInt(inputFloat("NUMBER OF UNITS TO SHIELDS")); + if (energyToShields < 0 || shields == energyToShields) { + println(""); + return; + } + if (energyToShields > energy + energyToShields) { + println("SHIELD CONTROL REPORTS 'THIS IS NOT THE FEDERATION TREASURY.'"); + println(""); + return; + } + energy = energy + shields - energyToShields; + shields = energyToShields; + println("DEFLECTOR CONTROL ROOM REPORT:"); + println(" 'SHIELDS NOW AT " + toInt(shields) + " UNITS PER YOUR COMMAND.'"); + } + + void shortRangeSensorScan() { // 6430 + // SHORT RANGE SENSOR SCAN & STARTUP SUBROUTINE + boolean docked = false; + String shipCondition; // ship condition (docked, red, yellow, green) + for (int i = sectorX - 1; i <= sectorX + 1; i++) { + for (int j = sectorY - 1; j <= sectorY + 1; j++) { + if ((toInt(i) >= 1) && (toInt(i) <= 8) && (toInt(j) >= 1) && (toInt(j) <= 8)) { + if (compareMarker(quadrantMap, MARKER_STARBASE, i, j)) { + docked = true; + } + } + } + } + if (!docked) { + shipDocked = false; + if (klingons > 0) { + shipCondition = "*RED*"; + } else { + shipCondition = "GREEN"; + if (energy < initialEnergy * .1) { + shipCondition = "YELLOW"; + } + } + } else { + shipDocked = true; + shipCondition = "DOCKED"; + energy = initialEnergy; + torpedoes = initialTorpedoes; + println("SHIELDS DROPPED FOR DOCKING PURPOSES"); + shields = 0; + } + if (deviceStatus[DEVICE_SHORT_RANGE_SENSORS] < 0) { // are short range sensors out? + println("\n*** SHORT RANGE SENSORS ARE OUT ***\n"); + return; + } + final String row = "---------------------------------"; + println(row); + for (int i = 1; i <= 8; i++) { + String sectorMapRow = ""; + for (int j = (i - 1) * 24 + 1; j <= (i - 1) * 24 + 22; j += 3) { + sectorMapRow += " " + midStr(quadrantMap, j, 3); + } + switch (i) { + case 1: + println(sectorMapRow + " STARDATE " + toInt(stardate * 10) * .1); + break; + case 2: + println(sectorMapRow + " CONDITION " + shipCondition); + break; + case 3: + println(sectorMapRow + " QUADRANT " + quadrantX + "," + quadrantY); + break; + case 4: + println(sectorMapRow + " SECTOR " + sectorX + "," + sectorY); + break; + case 5: + println(sectorMapRow + " PHOTON TORPEDOES " + toInt(torpedoes)); + break; + case 6: + println(sectorMapRow + " TOTAL ENERGY " + toInt((energy + shields))); + break; + case 7: + println(sectorMapRow + " SHIELDS " + toInt(shields)); + break; + case 8: + println(sectorMapRow + " KLINGONS REMAINING " + toInt(klingonsInGalaxy)); + } + ; + } + println(row); // 7260 + } + + void libraryComputer() { // 7290 + // REM LIBRARY COMPUTER CODE + if (deviceStatus[DEVICE_LIBRARY_COMPUTER] < 0) { + println("COMPUTER DISABLED"); + return; + } + while (true) { + final float commandInput = inputFloat("COMPUTER ACTIVE AND AWAITING COMMAND"); + if (commandInput < 0) return; + println(""); + int command = toInt(commandInput) + 1; + if (command >= COMPUTER_COMMAND_CUMULATIVE_GALACTIC_RECORD && command <= COMPUTER_COMMAND_GALAXY_MAP) { + switch (command) { + case COMPUTER_COMMAND_CUMULATIVE_GALACTIC_RECORD: + //GOTO 7540 + cumulativeGalacticRecord(true); + return; + case COMPUTER_COMMAND_STATUS_REPORT: + //GOTO 7900 + statusReport(); + return; + case COMPUTER_COMMAND_PHOTON_TORPEDO_DATA: + //GOTO 8070 + photonTorpedoData(); + return; + case COMPUTER_COMMAND_STARBASE_NAV_DATA: + //GOTO 8500 + starbaseNavData(); + return; + case COMPUTER_COMMAND_DIR_DIST_CALC: + //GOTO 8150 + directionDistanceCalculator(); + return; + case COMPUTER_COMMAND_GALAXY_MAP: + //GOTO 7400 + cumulativeGalacticRecord(false); + return; + } + } else { + // invalid command + println("FUNCTIONS AVAILABLE FROM LIBRARY-COMPUTER:"); + println(" 0 = CUMULATIVE GALACTIC RECORD"); + println(" 1 = STATUS REPORT"); + println(" 2 = PHOTON TORPEDO DATA"); + println(" 3 = STARBASE NAV DATA"); + println(" 4 = DIRECTION/DISTANCE CALCULATOR"); + println(" 5 = GALAXY 'REGION NAME' MAP"); + println(""); + } + } + } + + void cumulativeGalacticRecord(final boolean cumulativeReport) { // 7540 + if (cumulativeReport) { + println(""); + println(" "); + println("COMPUTER RECORD OF GALAXY FOR QUADRANT " + quadrantX + "," + quadrantY); + println(""); + } else { + println(" THE GALAXY"); + } + println(" 1 2 3 4 5 6 7 8"); + final String rowDivider = " ----- ----- ----- ----- ----- ----- ----- -----"; + println(rowDivider); + for (int i = 1; i <= 8; i++) { + print(i + " "); + if (cumulativeReport) { + int y = 1; + String quadrantName = getQuadrantName(false, i, y); + int tabLen = toInt(15 - .5 * strlen(quadrantName)); + println(tab(tabLen) + quadrantName); + y = 5; + quadrantName = getQuadrantName(false, i, y); + tabLen = toInt(39 - .5 * strlen(quadrantName)); + println(tab(tabLen) + quadrantName); + } else { + for (int j = 1; j <= 8; j++) { + print(" "); + if (chartedGalaxy[i][j] == 0) { + print("***"); + } else { + print(rightStr(Integer.toString(chartedGalaxy[i][j] + 1000), 3)); + } + } + } + println(""); + println(rowDivider); + } + println(""); + } + + void statusReport() { // 7900 + println(" STATUS REPORT:"); + println("KLINGON" + ((klingonsInGalaxy > 1)? "S" : "") + " LEFT: " + klingonsInGalaxy); + println("MISSION MUST BE COMPLETED IN " + .1 * toInt((initialStardate + missionDuration - stardate) * 10) + "STARDATES"); + if (basesInGalaxy >= 1) { + println("THE FEDERATION IS MAINTAINING " + basesInGalaxy + " STARBASE" + ((basesInGalaxy > 1)? "S" : "") + " IN THE GALAXY"); + } else { + println("YOUR STUPIDITY HAS LEFT YOU ON YOUR OWN IN"); + println(" THE GALAXY -- YOU HAVE NO STARBASES LEFT!"); + } + damageControl(); + } + + void photonTorpedoData() { // 8070 + // TORPEDO, BASE NAV, D/D CALCULATOR + if (klingons <= 0) { + printNoEnemyShipsMessage(); + return; + } + println("FROM ENTERPRISE TO KLINGON BATTLE CRUISER" + ((klingons > 1)? "S" : "")); + for (int i = 1; i <= 3; i++) { + if (klingonQuadrants[i][3] > 0) { + printDirection(sectorX, sectorY, klingonQuadrants[i][1], klingonQuadrants[i][2]); + } + } + } + + void directionDistanceCalculator() { // 8150 + println("DIRECTION/DISTANCE CALCULATOR:"); + println("YOU ARE AT QUADRANT " + quadrantX + "," + quadrantY + " SECTOR " + sectorX + "," + sectorY); + print("PLEASE ENTER "); + int[] initialCoords = inputCoords(" INITIAL COORDINATES (X,Y)"); + int[] finalCoords = inputCoords(" FINAL COORDINATES (X,Y)"); + printDirection(initialCoords[0], initialCoords[1], finalCoords[0], finalCoords[1]); + } + + void printDirection(int from_x, int from_y, int to_x, int to_y) { // 8220 + to_y = to_y - from_y; // delta 2 + from_y = from_x - to_x; // delta 1 + if (to_y > 0) { + if (from_y < 0) { + from_x = 7; + } else { + from_x = 1; + int tempA = from_y; + from_y = to_y; + to_y = tempA; + } + } else { + if (from_y > 0) { + from_x = 3; + } else { + from_x = 5; + int tempA = from_y; + from_y = to_y; + to_y = tempA; + } + } + + from_y = Math.abs(from_y); + to_y = Math.abs(to_y); + + if (from_y > 0 || to_y > 0) { + if (from_y >= to_y) { + println("DIRECTION = " + (from_x + to_y / from_y)); + } else { + println("DIRECTION = " + (from_x + 2 - to_y / from_y)); + } + } + println("DISTANCE = " + round(Math.sqrt(to_y ^ 2 + from_y ^ 2), 6)); + } + + void starbaseNavData() { // 8500 + if (starbases != 0) { + println("FROM ENTERPRISE TO STARBASE:"); + printDirection(sectorX, sectorY, starbaseX, starbaseY); + } else { + println("MR. SPOCK REPORTS, 'SENSORS SHOW NO STARBASES IN THIS"); + println(" QUADRANT.'"); + } + } + + /** + * Finds random empty coordinates in a quadrant. + * + * @param quadrantString + * @return an array with a pair of coordinates x, y + */ + int[] findEmptyPlaceInQuadrant(String quadrantString) { // 8590 + final int x = fnr(); + final int y = fnr(); + if (!compareMarker(quadrantString, MARKER_EMPTY, x, y)) { + return findEmptyPlaceInQuadrant(quadrantString); + } + return new int[]{x, y}; + } + + + void insertMarker(final String marker, final int x, final int y) { // 8670 + final int pos = toInt(y) * 3 + toInt(x) * 24 + 1; + if (marker.length() != 3) { + System.err.println("ERROR"); + System.exit(-1); + } + if (pos == 1) { + quadrantMap = marker + rightStr(quadrantMap, 189); + } + if (pos == 190) { + quadrantMap = leftStr(quadrantMap, 189) + marker; + } + quadrantMap = leftStr(quadrantMap, (pos - 1)) + marker + rightStr(quadrantMap, (190 - pos)); + } + + String printDeviceName(final int deviceNumber) { // 8790 + // PRINTS DEVICE NAME + switch (deviceNumber) { + case DEVICE_WARP_ENGINES: + return "WARP ENGINES"; + case DEVICE_SHORT_RANGE_SENSORS: + return "SHORT RANGE SENSORS"; + case DEVICE_LONG_RANGE_SENSORS: + return "LONG RANGE SENSORS"; + case DEVICE_PHASER_CONTROL: + return "PHASER CONTROL"; + case DEVICE_PHOTON_TUBES: + return "PHOTON TUBES"; + case DEVICE_DAMAGE_CONTROL: + return "DAMAGE CONTROL"; + case DEVICE_SHIELD_CONTROL: + return "SHIELD CONTROL"; + case DEVICE_LIBRARY_COMPUTER: + return "LIBRARY-COMPUTER"; + } + return ""; + } + + boolean compareMarker(final String quadrantString, final String marker, int x, int y) { // 8830 + final int markerRegion = (y - 1) * 3 + (x - 1) * 24 + 1; + if (midStr(quadrantString, markerRegion, 3).equals(marker)) { + return true; + } + return false; + } + + String getRegionName(final boolean regionNameOnly, final int y) { + if (!regionNameOnly) { + switch (y % 4) { + case 1: + return " I"; + case 2: + return " II"; + case 3: + return " III"; + case 4: + return " IV"; + } + } + return ""; + } + + String getQuadrantName(final boolean regionNameOnly, final int x, final int y) { // 9030 + if (y <= 4) { + switch (x) { + case 1: + return "ANTARES" + getRegionName(regionNameOnly, y); + case 2: + return "RIGEL" + getRegionName(regionNameOnly, y); + case 3: + return "PROCYON" + getRegionName(regionNameOnly, y); + case 4: + return "VEGA" + getRegionName(regionNameOnly, y); + case 5: + return "CANOPUS" + getRegionName(regionNameOnly, y); + case 6: + return "ALTAIR" + getRegionName(regionNameOnly, y); + case 7: + return "SAGITTARIUS" + getRegionName(regionNameOnly, y); + case 8: + return "POLLUX" + getRegionName(regionNameOnly, y); + } + } else { + switch (x) { + case 1: + return "SIRIUS" + getRegionName(regionNameOnly, y); + case 2: + return "DENEB" + getRegionName(regionNameOnly, y); + case 3: + return "CAPELLA" + getRegionName(regionNameOnly, y); + case 4: + return "BETELGEUSE" + getRegionName(regionNameOnly, y); + case 5: + return "ALDEBARAN" + getRegionName(regionNameOnly, y); + case 6: + return "REGULUS" + getRegionName(regionNameOnly, y); + case 7: + return "ARCTURUS" + getRegionName(regionNameOnly, y); + case 8: + return "SPICA" + getRegionName(regionNameOnly, y); + } + } + return "UNKNOWN - ERROR"; + } + + void damageControl() { // 5690 + if (deviceStatus[DEVICE_DAMAGE_CONTROL] < 0) { + println("DAMAGE CONTROL REPORT NOT AVAILABLE"); + } else { + println("\nDEVICE STATE OF REPAIR"); + for (int deviceNr = 1; deviceNr <= 8; deviceNr++) { + print(printDeviceName(deviceNr) + leftStr(QUADRANT_ROW, 25 - strlen(printDeviceName(deviceNr))) + " " + toInt(deviceStatus[deviceNr] * 100) * .01 + "\n"); + } + } + if (!shipDocked) return; + + double deltaToRepair = 0; + for (int i = 1; i <= 8; i++) { + if (deviceStatus[i] < 0) deltaToRepair += .1; + } + if (deltaToRepair > 0) { + deltaToRepair += repairCost; + if (deltaToRepair >= 1) deltaToRepair = .9; + println("TECHNICIANS STANDING BY TO EFFECT REPAIRS TO YOUR SHIP;"); + println("ESTIMATED TIME TO REPAIR:'" + .01 * toInt(100 * deltaToRepair) + " STARDATES"); + final String reply = inputStr("WILL YOU AUTHORIZE THE REPAIR ORDER (Y/N)"); + if ("Y".equals(reply)) { + for (int deviceNr = 1; deviceNr <= 8; deviceNr++) { + if (deviceStatus[deviceNr] < 0) deviceStatus[deviceNr] = 0; + } + stardate = stardate + deltaToRepair + .1; + } + } + } + + void klingonsShoot() { // 6000 + if (klingons <= 0) return; // no klingons + if (shipDocked) { // enterprise is docked + println("STARBASE SHIELDS PROTECT THE ENTERPRISE"); + return; + } + for (int i = 1; i <= 3; i++) { + if (klingonQuadrants[i][3] <= 0) continue; + int hits = toInt((klingonQuadrants[i][3] / fnd(1)) * (2 + random())); // hit points + shields = shields - hits; + klingonQuadrants[i][3] = toInt(klingonQuadrants[i][3] / (3 + random())); // FIXME: RND(0) + println(hits + " UNIT HIT ON ENTERPRISE FROM SECTOR " + klingonQuadrants[i][1] + "," + klingonQuadrants[i][2]); + if (shields <= 0) endGameFail(true); + println(" "); + if (hits < 20) continue; + if ((random() > .6) || (hits / shields <= .02)) continue; + int randomDevice = fnr(); + deviceStatus[randomDevice] = deviceStatus[randomDevice] - hits / shields - .5 * random(); + println("DAMAGE CONTROL REPORTS " + printDeviceName(randomDevice) + " DAMAGED BY THE HIT'"); + } + } + + void endGameFail(final boolean enterpriseDestroyed) { // 6220 + if (enterpriseDestroyed) { + println("\nTHE ENTERPRISE HAS BEEN DESTROYED. THEN FEDERATION "); + println("WILL BE CONQUERED"); + } + println("\nIT IS STARDATE " + stardate); + println("THERE WERE " + klingonsInGalaxy + " KLINGON BATTLE CRUISERS LEFT AT"); + println("THE END OF YOUR MISSION."); + repeatGame(); + } + + void endGameSuccess() { // 6370 + println("CONGRATULATION, CAPTAIN! THE LAST KLINGON BATTLE CRUISER"); + println("MENACING THE FEDERATION HAS BEEN DESTROYED.\n"); + println("YOUR EFFICIENCY RATING IS " + (Math.sqrt(1000 * (remainingKlingons / (stardate - initialStardate))))); + repeatGame(); + } + + void repeatGame() {// 6290 + println("\n"); + if (basesInGalaxy != 0) { + println("THE FEDERATION IS IN NEED OF A NEW STARSHIP COMMANDER"); + println("FOR A SIMILAR MISSION -- IF THERE IS A VOLUNTEER,"); + final String reply = inputStr("LET HIM STEP FORWARD AND ENTER 'AYE'"); + if ("AYE".equals(reply)) { + this.restart = true; + } else { + System.exit(0); + } + } + } + + static int toInt(final double num) { + int x = (int) Math.floor(num); + if (x < 0) x *= -1; + return x; + } + + static void println(final String s) { + System.out.println(s); + } + + static void print(final String s) { + System.out.print(s); + } + + static String tab(final int n) { + return IntStream.range(1, n).mapToObj(num -> " ").collect(Collectors.joining()); + } + + static int strlen(final String s) { + return s.length(); + } + + static String inputStr(final String message) { + System.out.print(message + "? "); + final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + try { + return reader.readLine(); + } catch (IOException ioe) { + ioe.printStackTrace(); + return ""; + } + } + + static int[] inputCoords(final String message) { + while (true) { + final String input = inputStr(message); + try { + final String[] splitInput = input.split(","); + if (splitInput.length == 2) { + int x = Integer.parseInt(splitInput[0]); + int y = Integer.parseInt(splitInput[0]); + return new int[]{x, y}; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + static float inputFloat(final String message) { + while (true) { + System.out.print(message + "? "); + final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + try { + final String input = reader.readLine(); + if (input.length() > 0) { + return Float.parseFloat(input); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + static String leftStr(final String input, final int len) { + if (input == null || input.length() < len) return input; + return input.substring(0, len); + } + + static String midStr(final String input, final int start, final int len) { + if (input == null || input.length() < ((start - 1) + len)) return input; + return input.substring(start - 1, (start - 1) + len); + } + + static String rightStr(final String input, final int len) { + if (input == null || input.length() < len) return ""; + return input.substring(input.length() - len); + } + + static float random() { + return random.nextFloat(); + } + + private static double round(double value, int places) { + if (places < 0) throw new IllegalArgumentException(); + BigDecimal bd = new BigDecimal(Double.toString(value)); + bd = bd.setScale(places, RoundingMode.HALF_UP); + return bd.doubleValue(); + } +} diff --git a/84_Super_Star_Trek/java/SuperStarTrekInstructions.java b/84_Super_Star_Trek/java/SuperStarTrekInstructions.java new file mode 100644 index 00000000..16f730da --- /dev/null +++ b/84_Super_Star_Trek/java/SuperStarTrekInstructions.java @@ -0,0 +1,162 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * SUPER STARTREK INSTRUCTIONS + * MAR 5, 1978 + * Just the instructions for SUPERSTARTREK + * + * Ported to Java in Jan-Feb 2022 by + * Taciano Dreckmann Perez (taciano.perez@gmail.com) + */ +public class SuperStarTrekInstructions { + + public static void main(String[] args) { + printBanner(); + final String reply = inputStr("DO YOU NEED INSTRUCTIONS (Y/N)? "); + if ("Y".equals(reply)) { + printInstructions(); + } + } + + static void printBanner() { + print(tab(10)+"*************************************"); + print(tab(10)+"* *"); + print(tab(10)+"* *"); + print(tab(10)+"* * * SUPER STAR TREK * * *"); + print(tab(10)+"* *"); + print(tab(10)+"* *"); + print(tab(10)+"*************************************"); + } + + static void printInstructions() { + print(" INSTRUCTIONS FOR 'SUPER STAR TREK'"); + print(""); + print("1. WHEN YOU SEE \\COMMAND ?\\ PRINTED, ENTER ONE OF THE LEGAL"); + print(" COMMANDS (NAV,SRS,LRS,PHA,TOR,SHE,DAM,COM, OR XXX)."); + print("2. IF YOU SHOULD TYPE IN AN ILLEGAL COMMAND, YOU'LL GET A SHORT"); + print(" LIST OF THE LEGAL COMMANDS PRINTED OUT."); + print("3. SOME COMMANDS REQUIRE YOU TO ENTER DATA (FOR EXAMPLE, THE"); + print(" 'NAV' COMMAND COMES BACK WITH 'COURSE (1-9) ?'.) IF YOU"); + print(" TYPE IN ILLEGAL DATA (LIKE NEGATIVE NUMBERS), THAN COMMAND"); + print(" WILL BE ABORTED"); + print(""); + print(" THE GALAXY IS DIVIDED INTO AN 8 X 8 QUADRANT GRID,"); + print("AND EACH QUADRANT IS FURTHER DIVIDED INTO AN 8 X 8 SECTOR GRID."); + print(""); + print(" YOU WILL BE ASSIGNED A STARTING POINT SOMEWHERE IN THE"); + print("GALAXY TO BEGIN A TOUR OF DUTY AS COMANDER OF THE STARSHIP"); + print("\\ENTERPRISE\\; YOUR MISSION: TO SEEK AND DESTROY THE FLEET OF"); + print("KLINGON WARWHIPS WHICH ARE MENACING THE UNITED FEDERATION OF"); + print("PLANETS."); + print(""); + print(" YOU HAVE THE FOLLOWING COMMANDS AVAILABLE TO YOU AS CAPTAIN"); + print("OF THE STARSHIP ENTERPRISE:"); + print(""); + print("\\NAV\\ COMMAND = WARP ENGINE CONTROL --"); + print(" COURSE IS IN A CIRCULAR NUMERICAL 4 3 2"); + print(" VECTOR ARRANGEMENT AS SHOWN . . ."); + print(" INTEGER AND REAL VALUES MAY BE ..."); + print(" USED. (THUS COURSE 1.5 IS HALF- 5 ---*--- 1"); + print(" WAY BETWEEN 1 AND 2 ..."); + print(" . . ."); + print(" VALUES MAY APPROACH 9.0, WHICH 6 7 8"); + print(" ITSELF IS EQUIVALENT TO 1.0"); + print(" COURSE"); + print(" ONE WARP FACTOR IS THE SIZE OF "); + print(" ONE QUADTANT. THEREFORE, TO GET"); + print(" FROM QUADRANT 6,5 TO 5,5, YOU WOULD"); + print(" USE COURSE 3, WARP FACTOR 1."); + print(""); + print("\\SRS\\ COMMAND = SHORT RANGE SENSOR SCAN"); + print(" SHOWS YOU A SCAN OF YOUR PRESENT QUADRANT."); + print(""); + print(" SYMBOLOGY ON YOUR SENSOR SCREEN IS AS FOLLOWS:"); + print(" <*> = YOUR STARSHIP'S POSITION"); + print(" +K+ = KLINGON BATTLE CRUISER"); + print(" >!< = FEDERATION STARBASE (REFUEL/REPAIR/RE-ARM HERE!)"); + print(" * = STAR"); + print(""); + print(" A CONDENSED 'STATUS REPORT' WILL ALSO BE PRESENTED."); + print(""); + print("\\LRS\\ COMMAND = LONG RANGE SENSOR SCAN"); + print(" SHOWS CONDITIONS IN SPACE FOR ONE QUADRANT ON EACH SIDE"); + print(" OF THE ENTERPRISE (WHICH IS IN THE MIDDLE OF THE SCAN)"); + print(" THE SCAN IS CODED IN THE FORM \\###\\, WHERE TH UNITS DIGIT"); + print(" IS THE NUMBER OF STARS, THE TENS DIGIT IS THE NUMBER OF"); + print(" STARBASES, AND THE HUNDRESDS DIGIT IS THE NUMBER OF"); + print(" KLINGONS."); + print(""); + print(" EXAMPLE - 207 = 2 KLINGONS, NO STARBASES, & 7 STARS."); + print(""); + print("\\PHA\\ COMMAND = PHASER CONTROL."); + print(" ALLOWS YOU TO DESTROY THE KLINGON BATTLE CRUISERS BY "); + print(" ZAPPING THEM WITH SUITABLY LARGE UNITS OF ENERGY TO"); + print(" DEPLETE THEIR SHIELD POWER. (REMEMBER, KLINGONS HAVE"); + print(" PHASERS TOO!)"); + print(""); + print("\\TOR\\ COMMAND = PHOTON TORPEDO CONTROL"); + print(" TORPEDO COURSE IS THE SAME AS USED IN WARP ENGINE CONTROL"); + print(" IF YOU HIT THE KLINGON VESSEL, HE IS DESTROYED AND"); + print(" CANNOT FIRE BACK AT YOU. IF YOU MISS, YOU ARE SUBJECT TO"); + print(" HIS PHASER FIRE. IN EITHER CASE, YOU ARE ALSO SUBJECT TO "); + print(" THE PHASER FIRE OF ALL OTHER KLINGONS IN THE QUADRANT."); + print(""); + print(" THE LIBRARY-COMPUTER (\\COM\\ COMMAND) HAS AN OPTION TO "); + print(" COMPUTE TORPEDO TRAJECTORY FOR YOU (OPTION 2)"); + print(""); + print("\\SHE\\ COMMAND = SHIELD CONTROL"); + print(" DEFINES THE NUMBER OF ENERGY UNITS TO BE ASSIGNED TO THE"); + print(" SHIELDS. ENERGY IS TAKEN FROM TOTAL SHIP'S ENERGY. NOTE"); + print(" THAN THE STATUS DISPLAY TOTAL ENERGY INCLUDES SHIELD ENERGY"); + print(""); + print("\\DAM\\ COMMAND = DAMMAGE CONTROL REPORT"); + print(" GIVES THE STATE OF REPAIR OF ALL DEVICES. WHERE A NEGATIVE"); + print(" 'STATE OF REPAIR' SHOWS THAT THE DEVICE IS TEMPORARILY"); + print(" DAMAGED."); + print(""); + print("\\COM\\ COMMAND = LIBRARY-COMPUTER"); + print(" THE LIBRARY-COMPUTER CONTAINS SIX OPTIONS:"); + print(" OPTION 0 = CUMULATIVE GALACTIC RECORD"); + print(" THIS OPTION SHOWES COMPUTER MEMORY OF THE RESULTS OF ALL"); + print(" PREVIOUS SHORT AND LONG RANGE SENSOR SCANS"); + print(" OPTION 1 = STATUS REPORT"); + print(" THIS OPTION SHOWS THE NUMBER OF KLINGONS, STARDATES,"); + print(" AND STARBASES REMAINING IN THE GAME."); + print(" OPTION 2 = PHOTON TORPEDO DATA"); + print(" WHICH GIVES DIRECTIONS AND DISTANCE FROM THE ENTERPRISE"); + print(" TO ALL KLINGONS IN YOUR QUADRANT"); + print(" OPTION 3 = STARBASE NAV DATA"); + print(" THIS OPTION GIVES DIRECTION AND DISTANCE TO ANY "); + print(" STARBASE WITHIN YOUR QUADRANT"); + print(" OPTION 4 = DIRECTION/DISTANCE CALCULATOR"); + print(" THIS OPTION ALLOWS YOU TO ENTER COORDINATES FOR"); + print(" DIRECTION/DISTANCE CALCULATIONS"); + print(" OPTION 5 = GALACTIC /REGION NAME/ MAP"); + print(" THIS OPTION PRINTS THE NAMES OF THE SIXTEEN MAJOR "); + print(" GALACTIC REGIONS REFERRED TO IN THE GAME."); + } + + static void print(final String s) { + System.out.println(s); + } + + static String tab(final int n) { + return IntStream.range(1, n).mapToObj(num -> " ").collect(Collectors.joining()); + } + + static String inputStr(final String message) { + System.out.print(message + "? "); + final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + try { + return reader.readLine(); + } catch (IOException ioe) { + ioe.printStackTrace(); + return ""; + } + } + +} From 92cc8bebb83d8129146f68a1ec3735b410353796 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 21 Feb 2022 17:29:00 -0800 Subject: [PATCH 327/337] Added ignorecase and y / yes as acceptable answers to continue playing --- 44_Hangman/java/Hangman.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/44_Hangman/java/Hangman.java b/44_Hangman/java/Hangman.java index 56567bb2..f0acfa7c 100644 --- a/44_Hangman/java/Hangman.java +++ b/44_Hangman/java/Hangman.java @@ -5,11 +5,7 @@ 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 @@ -32,7 +28,7 @@ public class Hangman { int[] usedWords = new int[50]; int roundNumber = 1; int totalWords = words.size(); - boolean continueGame; + boolean continueGame = false; do { if (roundNumber > totalWords) { @@ -53,7 +49,10 @@ public class Hangman { System.out.print("\nWANT ANOTHER WORD? "); } final String anotherWordChoice = scan.next(); - continueGame = "YES".equals(anotherWordChoice); + + if (anotherWordChoice.toUpperCase().equals("YES") || anotherWordChoice.toUpperCase().equals("Y")) { + continueGame = true; + } roundNumber++; } while (continueGame); @@ -99,7 +98,7 @@ public class Hangman { System.out.print("WHAT IS YOUR GUESS? "); var tmpRead = scan.next(); - guessLetter = tmpRead.charAt(0); + guessLetter = Character.toUpperCase(tmpRead.charAt(0)); if (lettersUsed.contains(guessLetter)) { System.out.println("YOU GUESSED THAT LETTER BEFORE!"); } else { @@ -132,7 +131,7 @@ public class Hangman { printDiscoveredLetters(discoveredLetters); System.out.print("WHAT IS YOUR GUESS FOR THE WORD? "); final String wordGuess = scan.next(); - if (wordGuess.equals(word)) { + if (wordGuess.toUpperCase().equals(word)) { System.out.printf("RIGHT!! IT TOOK YOU %s GUESSES!", totalWordGuesses); return true; } else { @@ -241,5 +240,3 @@ public class Hangman { } } - - From 27809ca45597e2a76b13e1fe2c229809b2e30d12 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 21 Feb 2022 17:30:51 -0800 Subject: [PATCH 328/337] Added ignorecase and y / yes as acceptable answers to continue playing --- 44_Hangman/java/Hangman.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/44_Hangman/java/Hangman.java b/44_Hangman/java/Hangman.java index f0acfa7c..629ea52f 100644 --- a/44_Hangman/java/Hangman.java +++ b/44_Hangman/java/Hangman.java @@ -5,6 +5,11 @@ 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 { From 34f97d69b8932203f0e4fe53a8a8665575bcdf00 Mon Sep 17 00:00:00 2001 From: Aldrin Misquitta Date: Tue, 22 Feb 2022 14:02:22 +0000 Subject: [PATCH 329/337] Ported 79. Slalom to Java. Also, documented one possible bug in the orignal program. --- 79_Slalom/README.md | 8 + 79_Slalom/java/Slalom.java | 373 +++++++++++++++++++++++++++++++++++++ 2 files changed, 381 insertions(+) create mode 100644 79_Slalom/java/Slalom.java diff --git a/79_Slalom/README.md b/79_Slalom/README.md index 7e46e3a5..e76ead94 100644 --- a/79_Slalom/README.md +++ b/79_Slalom/README.md @@ -14,3 +14,11 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html + +### Bugs + +- In the original version, the data pointer doesn't reset after a race is completed. This causes subsequent races to +error at some future point at line 540, + + 540 READ Q + diff --git a/79_Slalom/java/Slalom.java b/79_Slalom/java/Slalom.java new file mode 100644 index 00000000..4b0c947d --- /dev/null +++ b/79_Slalom/java/Slalom.java @@ -0,0 +1,373 @@ +import java.util.Arrays; +import java.util.InputMismatchException; +import java.util.Random; +import java.util.Scanner; + +/** + * Slalom + *

+ * Converted from BASIC to Java by Aldrin Misquitta (@aldrinm) + * + * There is a bug in the original version where the data pointer doesn't reset after a race is completed. This causes subsequent races to error at + * some future point on line "540 READ Q" + */ +public class Slalom { + + private static final int MAX_NUM_GATES = 25; + private static final int[] MAX_SPEED = { + 14, 18, 26, 29, 18, + 25, 28, 32, 29, 20, + 29, 29, 25, 21, 26, + 29, 20, 21, 20, 18, + 26, 25, 33, 31, 22 + }; + + public static void main(String[] args) { + var random = new Random(); + + printIntro(); + Scanner scanner = new Scanner(System.in); + + int numGates = readNumberOfGatesChoice(scanner); + + printMenu(); + MenuChoice menuChoice; + do { + menuChoice = readMenuOption(scanner); + switch (menuChoice) { + case INS: + printInstructions(); + break; + case MAX: + printApproxMaxSpeeds(numGates); + break; + case RUN: + run(numGates, scanner, random); + break; + } + } while (menuChoice != MenuChoice.RUN); + } + + private static void run(int numGates, Scanner scan, Random random) { + int rating = readSkierRating(scan); + boolean gameInProgress = true; + var medals = new Medals(0, 0, 0); + + while (gameInProgress) { + System.out.println("THE STARTER COUNTS DOWN...5...4...3...2...1...GO!"); + System.out.println("YOU'RE OFF!"); + + int speed = random.nextInt(18 - 9) + 9; + + float totalTimeTaken = 0; + try { + totalTimeTaken = runThroughGates(numGates, scan, random, speed); + System.out.printf("%nYOU TOOK %.2f SECONDS.%n", totalTimeTaken + random.nextFloat()); + + medals = evaluateAndUpdateMedals(totalTimeTaken, numGates, rating, medals); + } catch (WipedOutOrSnaggedAFlag | DisqualifiedException e) { + //end of this race! Print time taken and stop + System.out.printf("%nYOU TOOK %.2f SECONDS.%n", totalTimeTaken + random.nextFloat()); + } + + gameInProgress = readRaceAgainChoice(scan); + } + + System.out.println("THANKS FOR THE RACE"); + if (medals.getGold() >= 1) System.out.printf("GOLD MEDALS: %d%n", medals.getGold()); + if (medals.getSilver() >= 1) System.out.printf("SILVER MEDALS: %d%n", medals.getSilver()); + if (medals.getBronze() >= 1) System.out.printf("BRONZE MEDALS: %d%n", medals.getBronze()); + } + + private static Medals evaluateAndUpdateMedals(float totalTimeTaken, int numGates, int rating, + Medals medals) { + var m = totalTimeTaken; + m = m / numGates; + int goldMedals = medals.getGold(); + int silverMedals = medals.getSilver(); + int bronzeMedals = medals.getBronze(); + if (m < 1.5 - (rating * 0.1)) { + System.out.println("YOU WON A GOLD MEDAL!"); + goldMedals++; + } else if (m < 2.9 - rating * 0.1) { + System.out.println("YOU WON A SILVER MEDAL"); + silverMedals++; + } else if (m < 4.4 - rating * 0.01) { + System.out.println("YOU WON A BRONZE MEDAL"); + bronzeMedals++; + } + return new Medals(goldMedals, silverMedals, bronzeMedals); + } + + /** + * @return the total time taken through all the gates. + */ + private static float runThroughGates(int numGates, Scanner scan, Random random, int speed) throws DisqualifiedException, WipedOutOrSnaggedAFlag { + float totalTimeTaken = 0.0f; + for (int i = 0; i < numGates; i++) { + var gateNum = i + 1; + boolean stillInRace = true; + boolean gateCompleted = false; + while (!gateCompleted) { + System.out.printf("%nHERE COMES GATE # %d:%n", gateNum); + printSpeed(speed); + + var tmpSpeed = speed; + + int chosenOption = readOption(scan); + switch (chosenOption) { + case 0: + //how long + printHowLong(totalTimeTaken, random); + break; + case 1: + //speed up a lot + speed = speed + random.nextInt(10 - 5) + 5; + break; + case 2: + //speed up a little + speed = speed + random.nextInt(5 - 3) + 3; + break; + case 3: + //speed up a teensy + speed = speed + random.nextInt(4 - 1) + 1; + break; + case 4: + //keep going at the same speed + break; + case 5: + //check a teensy + speed = speed - random.nextInt(4 - 1) + 1; + break; + case 6: + //check a little + speed = speed - random.nextInt(5 - 3) + 3; + break; + case 7: + //check a lot + speed = speed - random.nextInt(10 - 5) + 5; + break; + case 8: + //cheat + System.out.println("***CHEAT"); + if (random.nextFloat() < 0.7) { + System.out.println("AN OFFICIAL CAUGHT YOU!"); + stillInRace = false; + } else { + System.out.println("YOU MADE IT!"); + totalTimeTaken = totalTimeTaken + 1.5f; + } + break; + } + + if (stillInRace) { + printSpeed(speed); + stillInRace = checkAndProcessIfOverMaxSpeed(random, speed, MAX_SPEED[i]); + if (!stillInRace) throw new WipedOutOrSnaggedAFlag(); + } else { + throw new DisqualifiedException();//we've been dis-qualified + } + + if (speed < 7) { + System.out.println("LET'S BE REALISTIC, OK? LET'S GO BACK AND TRY AGAIN..."); + speed = tmpSpeed; + gateCompleted = false; + } else { + totalTimeTaken = totalTimeTaken + (MAX_SPEED[i] - speed + 1); + if (speed > MAX_SPEED[i]) { + totalTimeTaken = totalTimeTaken + 0.5f; + } + gateCompleted = true; + } + } + + } + return totalTimeTaken; + } + + private static boolean checkAndProcessIfOverMaxSpeed(Random random, int speed, int maxSpeed) { + boolean stillInRace = true; + if (speed > maxSpeed) { + if (random.nextFloat() >= (speed - maxSpeed) * 0.1 + 0.2) { + System.out.println("YOU WENT OVER THE MAXIMUM SPEED AND MADE IT!"); + } else { + System.out.print("YOU WENT OVER THE MAXIMUM SPEED AND "); + if (random.nextBoolean()) { + System.out.println("WIPED OUT!"); + } else { + System.out.println("SNAGGED A FLAG!"); + } + stillInRace = false; + } + } else if (speed > maxSpeed - 1) { + System.out.println("CLOSE ONE!"); + } + return stillInRace; + } + + private static boolean readRaceAgainChoice(Scanner scan) { + System.out.print("\nDO YOU WANT TO RACE AGAIN? "); + String raceAgain = ""; + final String YES = "YES"; + final String NO = "NO"; + while (!YES.equals(raceAgain) && !NO.equals(raceAgain)) { + raceAgain = scan.nextLine(); + if (!(YES.equals(raceAgain) || NO.equals(raceAgain))) { + System.out.println("PLEASE TYPE 'YES' OR 'NO'"); + } + } + return raceAgain.equals(YES); + } + + private static void printSpeed(int speed) { + System.out.printf("%3d M.P.H.%n", speed); + } + + private static void printHowLong(float t, Random random) { + System.out.printf("YOU'VE TAKEN %.2f SECONDS.%n", t + random.nextFloat()); + } + + private static int readOption(Scanner scan) { + Integer option = null; + + while (option == null) { + System.out.print("OPTION? "); + try { + option = scan.nextInt(); + } catch (InputMismatchException ex) { + System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE\n"); + } + scan.nextLine(); + if (option != null && (option > 8 || option < 0)) { + System.out.println("WHAT?"); + option = null; + } + } + return option; + } + + private static int readSkierRating(Scanner scan) { + int rating = 0; + + while (rating < 1 || rating > 3) { + System.out.print("RATE YOURSELF AS A SKIER, (1=WORST, 3=BEST)? "); + try { + rating = scan.nextInt(); + if (rating < 1 || rating > 3) { + System.out.println("THE BOUNDS ARE 1-3"); + } + } catch (InputMismatchException ex) { + System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE\n"); + } + scan.nextLine(); + } + return rating; + } + + private static void printApproxMaxSpeeds(int numGates) { + System.out.println("GATE MAX"); + System.out.println(" # M.P.H."); + System.out.println("---------"); + for (int i = 0; i < numGates; i++) { + System.out.println((i+1) + " " + MAX_SPEED[i]); + } + } + + private static void printInstructions() { + System.out.println("\n*** SLALOM: THIS IS THE 1976 WINTER OLYMPIC GIANT SLALOM. YOU ARE"); + System.out.println(" THE AMERICAN TEAM'S ONLY HOPE OF A GOLD MEDAL."); + System.out.println(); + System.out.println(" 0 -- TYPE THIS IS YOU WANT TO SEE HOW LONG YOU'VE TAKEN."); + System.out.println(" 1 -- TYPE THIS IF YOU WANT TO SPEED UP A LOT."); + System.out.println(" 2 -- TYPE THIS IF YOU WANT TO SPEED UP A LITTLE."); + System.out.println(" 3 -- TYPE THIS IF YOU WANT TO SPEED UP A TEENSY."); + System.out.println(" 4 -- TYPE THIS IF YOU WANT TO KEEP GOING THE SAME SPEED."); + System.out.println(" 5 -- TYPE THIS IF YOU WANT TO CHECK A TEENSY."); + System.out.println(" 6 -- TYPE THIS IF YOU WANT TO CHECK A LITTLE."); + System.out.println(" 7 -- TYPE THIS IF YOU WANT TO CHECK A LOT."); + System.out.println(" 8 -- TYPE THIS IF YOU WANT TO CHEAT AND TRY TO SKIP A GATE."); + System.out.println(); + System.out.println(" THE PLACE TO USE THESE OPTIONS IS WHEN THE COMPUTER ASKS:"); + System.out.println(); + System.out.println("OPTION?"); + System.out.println(); + System.out.println(" GOOD LUCK!"); + } + + private static MenuChoice readMenuOption(Scanner scan) { + System.out.print("COMMAND--? "); + MenuChoice menuChoice = null; + + while (menuChoice == null) { + String choice = scan.next(); + if (Arrays.stream(MenuChoice.values()).anyMatch(a -> a.name().equals(choice))) { + menuChoice = MenuChoice.valueOf(choice); + } else { + System.out.print("\""+ choice + "\" IS AN ILLEGAL COMMAND--RETRY? "); + } + scan.nextLine(); + } + return menuChoice; + } + + private static void printMenu() { + System.out.println("TYPE INS FOR INSTRUCTIONS"); + System.out.println("TYPE MAX FOR APPROXIMATE MAXIMUM SPEEDS"); + System.out.println("TYPE RUN FOR THE BEGINNING OF THE RACE"); + } + + private static int readNumberOfGatesChoice(Scanner scan) { + int numGates = 0; + while (numGates < 1) { + System.out.print("HOW MANY GATES DOES THIS COURSE HAVE (1 TO 25)? "); + numGates = scan.nextInt(); + if (numGates > MAX_NUM_GATES) { + System.out.println(MAX_NUM_GATES + " IS THE LIMIT."); + numGates = MAX_NUM_GATES; + } + } + return numGates; + } + + private static void printIntro() { + System.out.println(" SLALOM"); + System.out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println("\n\n"); + } + + private enum MenuChoice { + INS, MAX, RUN + } + + private static class DisqualifiedException extends Exception { + } + + private static class WipedOutOrSnaggedAFlag extends Exception { + } + + private static class Medals { + private int gold = 0; + private int silver = 0; + private int bronze = 0; + + public Medals(int gold, int silver, int bronze) { + this.gold = gold; + this.silver = silver; + this.bronze = bronze; + } + + public int getGold() { + return gold; + } + + public int getSilver() { + return silver; + } + + public int getBronze() { + return bronze; + } + } + + +} \ No newline at end of file From 4ebf3b74799f0df37c1ce469ca3952d9d12c9457 Mon Sep 17 00:00:00 2001 From: uMetalooper Date: Tue, 22 Feb 2022 17:13:43 +0000 Subject: [PATCH 330/337] Bullseye added --- 18_Bullseye/python/Bullseye.py | 100 +++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 18_Bullseye/python/Bullseye.py diff --git a/18_Bullseye/python/Bullseye.py b/18_Bullseye/python/Bullseye.py new file mode 100644 index 00000000..82c1d8cb --- /dev/null +++ b/18_Bullseye/python/Bullseye.py @@ -0,0 +1,100 @@ +import random + + +def print_n_whitespaces(n: int): + print(" "*n, end="") + + +def print_n_newlines(n: int): + for _ in range(n): + print() + +print_n_whitespaces(32) +print("BULLSEYE") +print_n_whitespaces(15) +print("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") +print_n_newlines(3) +print("IN THIS GAME, UP TO 20 PLAYERS THROW DARTS AT A TARGET") +print("WITH 10, 20, 30, AND 40 POINT ZONES. THE OBJECTIVE IS") +print("TO GET 200 POINTS.") +print() +print("THROW",end="");print_n_whitespaces(20);print("DESCRIPTION", end="");print_n_whitespaces(45);print("PROBABLE SCORE") +print(" 1",end="");print_n_whitespaces(20);print("FAST OVERARM",end="");print_n_whitespaces(45);print("BULLSEYE OR COMPLETE MISS") +print(" 2",end="");print_n_whitespaces(20);print("CONTROLLED OVERARM",end="");print_n_whitespaces(45);print("10, 20 OR 30 POINTS") +print(" 3",end="");print_n_whitespaces(20);print("UNDERARM",end="");print_n_whitespaces(45);print("ANYTHING") +print() + +M = 0 +R = 0 + +W = {} +for I in range(1, 11): + W[I] = 0 + +S = {} +for I in range(1, 21): + S[I] = 0 + +N = int(input("HOW MANY PLAYERS? ")) +A = {} +for I in range(1, N+1): + Name = input("NAME OF PLAYER #") + A[I] = Name + +while M == 0: + R = R + 1 + print() + print(f"ROUND {R}---------") + for I in range(1, N+1): + print() + while True: + T = int(input(f"{A[I]}'S THROW? ")) + if T < 1 or T > 3: + print("INPUT 1, 2, OR 3!") + else: + break + if T == 1: + P1=.65 + P2=.55 + P3=.5 + P4=.5 + elif T == 2: + P1=.99 + P2=.77 + P3=.43 + P4=.01 + elif T == 3: + P1=.95 + P2=.75 + P3=.45 + P4=.05 + U = random.random() + if U >= P1: + print("BULLSEYE!! 40 POINTS!") + B = 40 + elif U >= P2: + print("30-POINT ZONE!") + B = 30 + elif U >= P3: + print("20-POINT ZONE") + B = 20 + elif U >= P4: + print("WHEW! 10 POINTS.") + B = 10 + else: + print("MISSED THE TARGET! TOO BAD.") + B = 0 + S[I] = S[I] + B + print(f"TOTAL SCORE = {S[I]}") + for I in range(1, N+1): + if S[I] > 200: + M = M+1 + W[M] = I + +print() +print("WE HAVE A WINNER!!") +print() +for I in range(1, M+1): + print(f"{A[W[I]]} SCORED {S[W[I]]} POINTS.") +print() +print("THANKS FOR THE GAME.") \ No newline at end of file From 67e6481f0c3dc959d0e41864f9a1bb6f44114cce Mon Sep 17 00:00:00 2001 From: Peter Sharp Date: Tue, 8 Feb 2022 17:15:43 -0700 Subject: [PATCH 331/337] Adds bug python game --- 16_Bug/python/bug.py | 231 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 16_Bug/python/bug.py diff --git a/16_Bug/python/bug.py b/16_Bug/python/bug.py new file mode 100644 index 00000000..6c27b35a --- /dev/null +++ b/16_Bug/python/bug.py @@ -0,0 +1,231 @@ +from random import randint +from collections import namedtuple + +PAGE_WIDTH = 64 + +def main(): + states = { + 'start': (print_start, control_start, update_state), + 'instructions': (print_instructions, goto_game, update_state), + 'game': (print_game, control_game, update_game), + 'pictures': (print_pictures, goto_game, update_state), + 'won': (print_winner, exit_game, update_state) + } + + partTypes = ( + Bodypart(name="BODY", count=1 , depends=None), + Bodypart(name="NECK", count=1 , depends=0), + Bodypart(name="HEAD", count=1 , depends=1), + Bodypart(name="FEELERS", count=2 , depends=2), + Bodypart(name="TAIL", count=1 , depends=0), + Bodypart(name="LEGS", count=6 , depends=0) + ) + + data = { + 'state': 'start', + 'partNo': None, + 'players': { + 'YOU': [0] * len(partTypes), + 'I': [0] * len(partTypes) + }, + 'partTypes': partTypes, + 'finished': [], + 'logs': [] + } + + while True: + if 'exit' == data['state']: break + view, control, model = states[data['state']] + cmd = view(data) + action = control(cmd) + data = model(data, action) + +Bodypart = namedtuple('Bodypart', ['name', 'count', 'depends']) + +def print_start(_): + print_centered("BUG") + print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + print() + print() + print() + print("THE GAME BUG") + print("I HOPE YOU ENJOY THIS GAME.") + print() + return input("DO YOU WANT INSTRUCTIONS? ") + +def control_start(cmd): + if cmd.lower() in ('y', 'yes'): + action = 'instructions' + else: + action = 'game' + return action + +def print_instructions(data): + print("THE OBJECT OF BUG IS TO FINISH YOUR BUG BEFORE I FINISH") + print("MINE. EACH NUMBER STANDS FOR A PART OF THE BUG BODY.") + print("I WILL ROLL THE DIE FOR YOU, TELL YOU WHAT I ROLLED FOR YOU") + print("WHAT THE NUMBER STANDS FOR, AND IF YOU CAN GET THE PART.") + print("IF YOU CAN GET THE PART I WILL GIVE IT TO YOU.") + print("THE SAME WILL HAPPEN ON MY TURN.") + print("IF THERE IS A CHANGE IN EITHER BUG I WILL GIVE YOU THE") + print("OPTION OF SEEING THE PICTURES OF THE BUGS.") + print("THE NUMBERS STAND FOR PARTS AS FOLLOWS:") + + print_table([ + ("NUMBER","PART","NUMBER OF PART NEEDED"), + *[(i + 1, part.name, part.count) for i, part in enumerate(data['partTypes'])] + ]) + print() + print() + return '' + +def goto_game(_): + return 'game' + +def update_state(data, action): + return {**data, 'state': action} + +def update_game(data, action): + logs = [] + + if 'pictures' == action: + data['state'] = 'pictures' + else: + partAdded = False + while partAdded == False: + for player, parts in data['players'].items(): + newPartIdx = randint(1,6) - 1 + partType = data['partTypes'][newPartIdx] + partCount = parts[newPartIdx] + + logs.append(('rolled', newPartIdx, player)) + + overMaxParts = partType.count < partCount + 1 + missingPartDep = partType.depends != None and parts[partType.depends] == 0 + + if not overMaxParts and not missingPartDep: + partCount += 1 + logs.append(('added', newPartIdx, player)) + partAdded = True + elif missingPartDep: + logs.append(('missingDep', newPartIdx, player, partType.depends)) + if overMaxParts: + logs.append(('overMax', newPartIdx, player, partCount)) + + data['players'][player][newPartIdx] = partCount + data['logs'] = logs + + finished = get_finished(data) + if len(finished) > 0: + data['finished'] = finished + data['state'] = 'won' + return data + +def get_finished(data): + totalParts = sum([partType.count for partType in data['partTypes']]) + finished = [] + for player, parts in data['players'].items(): + if(sum(parts) == totalParts): finished.append(player) + return finished + +def print_game(data): + for log in data['logs']: + code, partIdx, player, *logdata = log + partType = data['partTypes'][partIdx] + + if('rolled' == code): + print() + print(f"{player} ROLLED A {partIdx + 1}") + print(f"{partIdx + 1}={partType.name}") + + elif('added' == code): + if 'YOU' == player: + if partType.name in ['FEELERS', 'LEGS', 'TAIL']: + print(f"I NOW GIVE YOU A {partType.name.replace('s', '')}.") + else: + print(f"YOU NOW HAVE A {partType.name}.") + elif 'I' == player: + if partType.name in ['BODY', 'NECK', 'TAIL']: + print(f"I NOW HAVE A {partType.name}.") + elif partType.name == 'FEELERS': + print("I GET A FEELER.") + + if partType.count > 2: + print(f"{player} NOW HAVE {data['players'][player][partIdx]} {partType.name}") + + elif 'missingDep' == code: + depIdx, = logdata + dep = data['partTypes'][depIdx] + print(f"YOU DO NOT HAVE A {dep.name}" if 'YOU' == player else f"I NEEDED A {dep.name}") + + elif 'overMax' == code: + partCount, = logdata + if(partCount > 1): + num = 'TWO' if 2 == partCount else partCount + maxMsg = f"HAVE {num} {partType.name}S ALREADY" + else: + maxMsg = f"ALREADY HAVE A {partType.name}" + print(f"{player} {maxMsg}") + + return input("DO YOU WANT THE PICTURES? ") if len(data['logs']) else 'n' + +def print_pictures(data): + typeIxs = { partType.name: idx for idx, partType in enumerate(data['partTypes']) } + PIC_WIDTH = 22 + for player, parts in data['players'].items(): + print(f"*****{'YOUR' if 'YOU' == player else 'MY'} BUG*****") + print() + print() + if(parts[typeIxs['BODY']] > 0): + if(parts[typeIxs['FEELERS']] > 0): + F = ' '.join(['F'] * parts[typeIxs['FEELERS']]) + for _ in range(4): + print(' ' * 9 + F) + if(parts[typeIxs['HEAD']] > 0): + print_centered("HHHHHHH", PIC_WIDTH) + print_centered("H H", PIC_WIDTH) + print_centered("H O O H", PIC_WIDTH) + print_centered("H H", PIC_WIDTH) + print_centered("H V H", PIC_WIDTH) + print_centered("HHHHHHH", PIC_WIDTH) + if(parts[typeIxs['NECK']] > 0): + for _ in range(2): + print_centered("N N", PIC_WIDTH) + print_centered("BBBBBBBBBBBB", PIC_WIDTH) + for _ in range(2): + print_centered("B B", PIC_WIDTH) + + if(parts[typeIxs['TAIL']] > 0): + print("TTTTTB B") + print_centered("BBBBBBBBBBBB", PIC_WIDTH) + if(parts[typeIxs['LEGS']] > 0): + L = 'L' * parts[typeIxs['LEGS']] + for _ in range(2): + print(' '*5+L) + print() + +def control_game(cmd): + if cmd.lower() in ('y', 'yes'): + action = 'pictures' + else: + action = 'game' + return action + +def print_winner(data): + for player in data['finished']: + print(f"{'YOUR' if 'YOU' == player else 'MY'} BUG IS FINISHED.") + print("I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!") + +def exit_game(_): + return 'exit' + +def print_centered(msg, width=PAGE_WIDTH): + spaces = " " * ((width - len(msg)) // 2) + print(spaces + msg) + +def print_table(rows): + for row in rows: + print(*row, sep="\t") + +if __name__ == '__main__': + main() \ No newline at end of file From c7386b795ad91af3403e79b62e702f52d9a0eecc Mon Sep 17 00:00:00 2001 From: Peter Sharp Date: Tue, 22 Feb 2022 07:08:26 -0700 Subject: [PATCH 332/337] Adds comments --- 16_Bug/python/bug.py | 139 +++++++++++++++++++++++++++++++++---------- 1 file changed, 109 insertions(+), 30 deletions(-) diff --git a/16_Bug/python/bug.py b/16_Bug/python/bug.py index 6c27b35a..d87c53c7 100644 --- a/16_Bug/python/bug.py +++ b/16_Bug/python/bug.py @@ -1,37 +1,25 @@ +""" +BUG + +Ported by Peter Sharp +""" + from random import randint from collections import namedtuple PAGE_WIDTH = 64 -def main(): - states = { - 'start': (print_start, control_start, update_state), - 'instructions': (print_instructions, goto_game, update_state), - 'game': (print_game, control_game, update_game), - 'pictures': (print_pictures, goto_game, update_state), - 'won': (print_winner, exit_game, update_state) - } - - partTypes = ( - Bodypart(name="BODY", count=1 , depends=None), - Bodypart(name="NECK", count=1 , depends=0), - Bodypart(name="HEAD", count=1 , depends=1), - Bodypart(name="FEELERS", count=2 , depends=2), - Bodypart(name="TAIL", count=1 , depends=0), - Bodypart(name="LEGS", count=6 , depends=0) - ) - - data = { - 'state': 'start', - 'partNo': None, - 'players': { - 'YOU': [0] * len(partTypes), - 'I': [0] * len(partTypes) - }, - 'partTypes': partTypes, - 'finished': [], - 'logs': [] - } +def main(states, data): + """ + Starts the game loop using given states and data + + Uses a modified version of the MVC (Model View Controller) pattern that uses functions instead of objects + + each state in the game has one of each of the following: + View, displays data + Control, converts raw command from user into something the model understands + Model, updates game data based on action received from controller + """ while True: if 'exit' == data['state']: break @@ -43,6 +31,9 @@ def main(): Bodypart = namedtuple('Bodypart', ['name', 'count', 'depends']) def print_start(_): + """ + Prints start message + """ print_centered("BUG") print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") print() @@ -54,6 +45,9 @@ def print_start(_): return input("DO YOU WANT INSTRUCTIONS? ") def control_start(cmd): + """ + Controls the start state + """ if cmd.lower() in ('y', 'yes'): action = 'instructions' else: @@ -61,6 +55,9 @@ def control_start(cmd): return action def print_instructions(data): + """ + Prints game instructions + """ print("THE OBJECT OF BUG IS TO FINISH YOUR BUG BEFORE I FINISH") print("MINE. EACH NUMBER STANDS FOR A PART OF THE BUG BODY.") print("I WILL ROLL THE DIE FOR YOU, TELL YOU WHAT I ROLLED FOR YOU") @@ -80,12 +77,22 @@ def print_instructions(data): return '' def goto_game(_): + """ + Returns game + """ return 'game' def update_state(data, action): + """ + sets game state to given player value + """ return {**data, 'state': action} def update_game(data, action): + """ + Updates game data for player turns until one player successfully gets a body part + """ + # stores logs of what happened during a particular round logs = [] if 'pictures' == action: @@ -94,16 +101,24 @@ def update_game(data, action): partAdded = False while partAdded == False: for player, parts in data['players'].items(): + # rolls the dice for a part newPartIdx = randint(1,6) - 1 + + # gets information about the picked part partType = data['partTypes'][newPartIdx] + + # gets the number of existing parts of that type the player has partCount = parts[newPartIdx] logs.append(('rolled', newPartIdx, player)) + # a new part can only be added if the player has the parts + # the new part depends on and doesn't have enough of the part already overMaxParts = partType.count < partCount + 1 missingPartDep = partType.depends != None and parts[partType.depends] == 0 if not overMaxParts and not missingPartDep: + # adds a new part partCount += 1 logs.append(('added', newPartIdx, player)) partAdded = True @@ -115,13 +130,18 @@ def update_game(data, action): data['players'][player][newPartIdx] = partCount data['logs'] = logs + # checks if any players have finished their bug finished = get_finished(data) if len(finished) > 0: + # and sets the state to 'won' if that's the case data['finished'] = finished data['state'] = 'won' return data def get_finished(data): + """ + Gets players who have finished their bugs + """ totalParts = sum([partType.count for partType in data['partTypes']]) finished = [] for player, parts in data['players'].items(): @@ -129,6 +149,9 @@ def get_finished(data): return finished def print_game(data): + """ + Displays the results of the game turn + """ for log in data['logs']: code, partIdx, player, *logdata = log partType = data['partTypes'][partIdx] @@ -170,6 +193,9 @@ def print_game(data): return input("DO YOU WANT THE PICTURES? ") if len(data['logs']) else 'n' def print_pictures(data): + """ + Displays what the bugs look like for each player + """ typeIxs = { partType.name: idx for idx, partType in enumerate(data['partTypes']) } PIC_WIDTH = 22 for player, parts in data['players'].items(): @@ -205,6 +231,9 @@ def print_pictures(data): print() def control_game(cmd): + """ + returns state based on command + """ if cmd.lower() in ('y', 'yes'): action = 'pictures' else: @@ -212,14 +241,23 @@ def control_game(cmd): return action def print_winner(data): + """ + Displays the winning message + """ for player in data['finished']: print(f"{'YOUR' if 'YOU' == player else 'MY'} BUG IS FINISHED.") print("I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!") def exit_game(_): + """ + Exists the game regardless of input + """ return 'exit' def print_centered(msg, width=PAGE_WIDTH): + """ + Prints given message centered to given width + """ spaces = " " * ((width - len(msg)) // 2) print(spaces + msg) @@ -228,4 +266,45 @@ def print_table(rows): print(*row, sep="\t") if __name__ == '__main__': - main() \ No newline at end of file + + # The main states in the game + states = { + # Initial state of the game + 'start': (print_start, control_start, update_state), + + # displays game instructions + 'instructions': (print_instructions, goto_game, update_state), + + # the main game state + 'game': (print_game, control_game, update_game), + + # displays pictures before returning to game + 'pictures': (print_pictures, goto_game, update_state), + + # Displays the winning players and message + 'won': (print_winner, exit_game, update_state) + } + + # body part types used by the game to work out whether a player's body part can be added + partTypes = ( + Bodypart(name="BODY", count=1 , depends=None), + Bodypart(name="NECK", count=1 , depends=0), + Bodypart(name="HEAD", count=1 , depends=1), + Bodypart(name="FEELERS", count=2 , depends=2), + Bodypart(name="TAIL", count=1 , depends=0), + Bodypart(name="LEGS", count=6 , depends=0) + ) + + # all the data used by the game + data = { + 'state': 'start', + 'partNo': None, + 'players': { + 'YOU': [0] * len(partTypes), + 'I': [0] * len(partTypes) + }, + 'partTypes': partTypes, + 'finished': [], + 'logs': [] + } + main(states, data) \ No newline at end of file From f256da75cf3bac224384225a09e548f85716eca7 Mon Sep 17 00:00:00 2001 From: Peter Sharp Date: Tue, 22 Feb 2022 11:40:24 -0700 Subject: [PATCH 333/337] Renames bug to bug-overengineereed Updates description to match --- 16_Bug/python/{bug.py => bug-overengineered.py} | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) rename 16_Bug/python/{bug.py => bug-overengineered.py} (98%) diff --git a/16_Bug/python/bug.py b/16_Bug/python/bug-overengineered.py similarity index 98% rename from 16_Bug/python/bug.py rename to 16_Bug/python/bug-overengineered.py index d87c53c7..adb9a31e 100644 --- a/16_Bug/python/bug.py +++ b/16_Bug/python/bug-overengineered.py @@ -1,5 +1,8 @@ """ -BUG +BUG (overengineered) + +Overengineered version of bug game +Demonstrates function-based Model View Controller pattern Ported by Peter Sharp """ From 929ff4618ac56c4db601c53558bc91c864ede163 Mon Sep 17 00:00:00 2001 From: "R.T. Lechow" Date: Thu, 24 Feb 2022 01:30:04 -0500 Subject: [PATCH 334/337] 47_Hi-Lo Ruby --- 47_Hi-Lo/ruby/README.md | 2 +- 47_Hi-Lo/ruby/hi_lo.rb | 59 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 47_Hi-Lo/ruby/hi_lo.rb diff --git a/47_Hi-Lo/ruby/README.md b/47_Hi-Lo/ruby/README.md index fb32811e..241656ad 100644 --- a/47_Hi-Lo/ruby/README.md +++ b/47_Hi-Lo/ruby/README.md @@ -1,3 +1,3 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) -Conversion to [Ruby](https://www.ruby-lang.org/en/) +Conversion to [Ruby](https://www.ruby-lang.org/en/) by [R.T. Lechow](https://github.com/rtlechow) diff --git a/47_Hi-Lo/ruby/hi_lo.rb b/47_Hi-Lo/ruby/hi_lo.rb new file mode 100644 index 00000000..02989a91 --- /dev/null +++ b/47_Hi-Lo/ruby/hi_lo.rb @@ -0,0 +1,59 @@ +#!/usr/bin/env ruby +MAX_TRIES = 6 +RANGE = (1..100) + +def intro + puts <<~END_OF_INTRO + #{'HI LO'.center(74)} + #{"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n".center(76)} + THIS IS THE GAME OF HI LO.\n + YOU WILL HAVE #{MAX_TRIES} TRIES TO GUESS THE AMOUNT OF MONEY IN THE + HI LO JACKPOT, WHICH IS BETWEEN #{RANGE.min} AND #{RANGE.max} DOLLARS. IF YOU + GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT! + THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY. HOWEVER, + IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.\n\n + END_OF_INTRO +end + +def make_guess + puts 'YOUR GUESS?' + @guess = gets.to_i +end + +def check_guess + if @guess == @number + @guessed_correctly = true + @total_winnings += @number + puts <<~END_OF_WIN_TEXT + GOT IT!!!!!!!!!! YOU WIN #{@number} DOLLARS. + YOUR TOTAL WINNINGS ARE NOW #{@total_winnings} DOLLARS. + END_OF_WIN_TEXT + else + puts "YOUR GUESS IS TOO #{@guess > @number ? 'HIGH' : 'LOW'}.\n\n" + end +end + +def blew_it + @total_winnings = 0 + puts "YOU BLEW IT...TOO BAD...THE NUMBER WAS #{@number}" +end + +def outro + puts "\nSO LONG. HOPE YOU ENJOYED YOURSELF!!!" +end + +intro +@total_winnings = 0 +loop do + @guessed_correctly = false + @number = rand(RANGE) + MAX_TRIES.times do + make_guess + check_guess + break if @guessed_correctly + end + blew_it unless @guessed_correctly + puts "\nPLAY AGAIN (YES OR NO)?" + break if gets.start_with?(/n/i) +end +outro From 69944fecc1ea083f90bf656e81c15319d823a477 Mon Sep 17 00:00:00 2001 From: Gabry Date: Thu, 24 Feb 2022 19:20:23 +0100 Subject: [PATCH 335/337] Ported [79 - Slalom] to python --- 79_Slalom/python/slalom.py | 165 +++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 79_Slalom/python/slalom.py diff --git a/79_Slalom/python/slalom.py b/79_Slalom/python/slalom.py new file mode 100644 index 00000000..aab08e68 --- /dev/null +++ b/79_Slalom/python/slalom.py @@ -0,0 +1,165 @@ +from random import random + +print("SLALOM".rjust(39)) +print("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n".rjust(57)) + +medals = { + "gold": 0, + "silver": 0, + "bronze": 0, +} +max_speeds = [14,18,26,29,18,25,28,32,29,20,29,29,25,21,26,29,20,21,20,18,26,25,33,31,22] + +def ask(question): + print(question, end="? ") + return input().upper() + +def ask_int(question): + reply = ask(question) + return int(reply) if reply.isnumeric() else -1 + +def pre_run(): + print("\nTYPE \"INS\" FOR INSTRUCTIONS") + print("TYPE \"MAX\" FOR APPROXIMATE MAXIMUM SPEEDS") + print("TYPE \"RUN\" FOR THE BEGINNING OF THE RACE") + cmd = ask("COMMAND--") + while cmd != "RUN": + if cmd == "INS": + print("\n*** SLALOM: THIS IS THE 1976 WINTER OLYMPIC GIANT SLALOM. YOU ARE") + print(" THE AMERICAN TEAM'S ONLY HOPE OF A GOLD MEDAL.\n") + print(" 0 -- TYPE THIS IS YOU WANT TO SEE HOW LONG YOU'VE TAKEN.") + print(" 1 -- TYPE THIS IF YOU WANT TO SPEED UP A LOT.") + print(" 2 -- TYPE THIS IF YOU WANT TO SPEED UP A LITTLE.") + print(" 3 -- TYPE THIS IF YOU WANT TO SPEED UP A TEENSY.") + print(" 4 -- TYPE THIS IF YOU WANT TO KEEP GOING THE SAME SPEED.") + print(" 5 -- TYPE THIS IF YOU WANT TO CHECK A TEENSY.") + print(" 6 -- TYPE THIS IF YOU WANT TO CHECK A LITTLE.") + print(" 7 -- TYPE THIS IF YOU WANT TO CHECK A LOT.") + print(" 8 -- TYPE THIS IF YOU WANT TO CHEAT AND TRY TO SKIP A GATE.\n") + print(" THE PLACE TO USE THESE OPTIONS IS WHEN THE COMPUTER ASKS:\n") + print("OPTION?\n") + print(" GOOD LUCK!\n") + cmd = ask("COMMAND--") + elif cmd == "MAX": + print("GATE MAX") + print(" # M.P.H.") + print("----------") + for i in range(0, gates): + print(f" {i + 1} {max_speeds[i]}") + cmd = ask("COMMAND--") + else: + cmd = ask(f"\"{cmd}\" IS AN ILLEGAL COMMAND--RETRY") + +def run(): + global medals + print("THE STARTER COUNTS DOWN...5...4...3...2...1...GO!") + time = 0 + speed = int(random() * (18 - 9) + 9) + print("YOU'RE OFF") + for i in range(0, gates): + while True: + print(f"\nHERE COMES GATE #{i + 1}:") + print(f" {int(speed)}M.P.H.") + old_speed = speed + opt = ask_int("OPTION") + while opt < 1 or opt > 8: + if(opt == 0): + print(f"YOU'VE TAKEN {int(time)}SECONDS.") + else: + print("WHAT?") + opt = ask_int("OPTION") + + if opt == 8: + print("***CHEAT") + if random() < .7: + print("AN OFFICIAL CAUGHT YOU!") + print(f"YOU TOOK {int(time + random())}SECONDS.") + return + else: + print("YOU MADE IT!") + time += 1.5 + else: + match opt: + case 1: + speed += int(random() * (10 - 5) + 5) + + case 2: + speed += int(random() * (5 - 3) + 3) + + case 3: + speed += int(random() * (4 - 1) + 1) + + case 5: + speed -= int(random() * (4 - 1) + 1) + + case 6: + speed -= int(random() * (5 - 3) + 3) + + case 7: + speed -= int(random() * (10 - 5) + 5) + print(f" {int(speed)}M.P.H.") + if speed > max_speeds[i]: + if random() < ((speed - max_speeds[i]) * .1) + .2: + print(f"YOU WENT OVER THE MAXIMUM SPEED AND {'SNAGGED A FLAG' if random() < .5 else 'WIPED OUT'}!") + print(f"YOU TOOK {int(time + random())}SECONDS") + return + else: + print("YOU WENT OVER THE NAXIMUM SPEED AND MADE IT!") + if speed > max_speeds[i] - 1: + print("CLOSE ONE!") + if speed < 7: + print("LET'S BE REALISTIC, OK? LET'S GO BACK AND TRY AGAIN...") + speed = old_speed + else: + time += max_speeds[i] - speed + 1 + if speed > max_speeds[i]: + time += .5 + break + print(f"\nYOU TOOK {int(time + random())}SECONDS.") + avg = time / gates + if avg < 1.5 - (lvl * .1): + print("YOU WON A GOLD MEDAL!") + medals["gold"] += 1 + elif avg < 2.9 - (lvl * .1): + print("YOU WON A SILVER MEDAL!") + medals["silver"] += 1 + elif avg < 4.4 - (lvl * .01): + print("YOU WON A BRONZE MEDAL!") + medals["bronze"] += 1 + +while True: + gates = ask_int("HOW MANY GATES DOES THIS COURSE HAVE (1 TO 25)") + if gates < 1: + print("TRY AGAIN,") + else: + if(gates > 25): + print("25 IS THE LIMIT.") + break + +pre_run() + +while True: + lvl = ask_int("RATE YOURSELF AS A SKIER, (1=WORST, 3=BEST)") + if lvl < 1 or lvl > 3: + print("THE BOUNDS ARE 1-3.") + else: + break + +while True: + run() + while True: + answer = ask("DO YOU WANT TO PLAY AGAIN?") + if answer == "YES" or answer == "NO": + break + else: + print("PLEASE TYPE 'YES' OR 'NO'") + if answer == "NO": + break + +print("THANKS FOR THE RACE") +if medals["gold"] > 0: + print(f"GOLD MEDALS: {medals['gold']}") +if medals["silver"] > 0: + print(f"SILVER MEDALS: {medals['silver']}") +if medals["bronze"] > 0: + print(f"BRONZE MEDALS: {medals['bronze']}") From 74ad6e9ea7c5263b8fc739430113c6a8920370ba Mon Sep 17 00:00:00 2001 From: Gabry Date: Thu, 24 Feb 2022 19:34:26 +0100 Subject: [PATCH 336/337] Formatted the output texts to follow a more modern style --- 79_Slalom/python/slalom.py | 114 ++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/79_Slalom/python/slalom.py b/79_Slalom/python/slalom.py index aab08e68..44ce0fde 100644 --- a/79_Slalom/python/slalom.py +++ b/79_Slalom/python/slalom.py @@ -1,7 +1,7 @@ from random import random -print("SLALOM".rjust(39)) -print("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n".rjust(57)) +print("Slalom".rjust(39)) +print("Creative Computing Morristown, New Jersey\n\n\n".rjust(57)) medals = { "gold": 0, @@ -19,64 +19,64 @@ def ask_int(question): return int(reply) if reply.isnumeric() else -1 def pre_run(): - print("\nTYPE \"INS\" FOR INSTRUCTIONS") - print("TYPE \"MAX\" FOR APPROXIMATE MAXIMUM SPEEDS") - print("TYPE \"RUN\" FOR THE BEGINNING OF THE RACE") - cmd = ask("COMMAND--") + print("\nType \"INS\" for instructions") + print("Type \"MAX\" for approximate maximum speeds") + print("Type \"RUN\" for the beginning of the race") + cmd = ask("Command--") while cmd != "RUN": if cmd == "INS": - print("\n*** SLALOM: THIS IS THE 1976 WINTER OLYMPIC GIANT SLALOM. YOU ARE") - print(" THE AMERICAN TEAM'S ONLY HOPE OF A GOLD MEDAL.\n") - print(" 0 -- TYPE THIS IS YOU WANT TO SEE HOW LONG YOU'VE TAKEN.") - print(" 1 -- TYPE THIS IF YOU WANT TO SPEED UP A LOT.") - print(" 2 -- TYPE THIS IF YOU WANT TO SPEED UP A LITTLE.") - print(" 3 -- TYPE THIS IF YOU WANT TO SPEED UP A TEENSY.") - print(" 4 -- TYPE THIS IF YOU WANT TO KEEP GOING THE SAME SPEED.") - print(" 5 -- TYPE THIS IF YOU WANT TO CHECK A TEENSY.") - print(" 6 -- TYPE THIS IF YOU WANT TO CHECK A LITTLE.") - print(" 7 -- TYPE THIS IF YOU WANT TO CHECK A LOT.") - print(" 8 -- TYPE THIS IF YOU WANT TO CHEAT AND TRY TO SKIP A GATE.\n") - print(" THE PLACE TO USE THESE OPTIONS IS WHEN THE COMPUTER ASKS:\n") - print("OPTION?\n") - print(" GOOD LUCK!\n") - cmd = ask("COMMAND--") + print("\n*** Slalom: This is the 1976 Winter Olypic Giant Slalom. You are") + print(" the American team's only hope for a gold medal.\n") + print(" 0 -- Type this if you want to see how long you've taken.") + print(" 1 -- Type this if you want to speed up a lot.") + print(" 2 -- Type this if you want to speed up a little.") + print(" 3 -- Type this if you want to speed up a teensy.") + print(" 4 -- Type this if you want to keep going the same speed.") + print(" 5 -- Type this if you want to check a teensy.") + print(" 6 -- Type this if you want to check a little.") + print(" 7 -- Type this if you want to check a lot.") + print(" 8 -- Type this if you want to cheat and try to skip a gate.\n") + print(" The place to use these options is when the Computer asks:\n") + print("Option?\n") + print(" Good Luck!\n") + cmd = ask("Command--") elif cmd == "MAX": - print("GATE MAX") + print("Gate Max") print(" # M.P.H.") print("----------") for i in range(0, gates): print(f" {i + 1} {max_speeds[i]}") - cmd = ask("COMMAND--") + cmd = ask("Command--") else: - cmd = ask(f"\"{cmd}\" IS AN ILLEGAL COMMAND--RETRY") + cmd = ask(f"\"{cmd}\" is an illegal command--Retry") def run(): global medals - print("THE STARTER COUNTS DOWN...5...4...3...2...1...GO!") + print("The starter counts down...5...4...3...2...1...Go!") time = 0 speed = int(random() * (18 - 9) + 9) - print("YOU'RE OFF") + print("You're off") for i in range(0, gates): while True: - print(f"\nHERE COMES GATE #{i + 1}:") - print(f" {int(speed)}M.P.H.") + print(f"\nHere comes gate #{i + 1}:") + print(f" {int(speed)} M.P.H.") old_speed = speed - opt = ask_int("OPTION") + opt = ask_int("Option") while opt < 1 or opt > 8: if(opt == 0): - print(f"YOU'VE TAKEN {int(time)}SECONDS.") + print(f"You've taken {int(time)} seconds.") else: - print("WHAT?") - opt = ask_int("OPTION") + print("What?") + opt = ask_int("Option") if opt == 8: - print("***CHEAT") + print("***Cheat") if random() < .7: - print("AN OFFICIAL CAUGHT YOU!") - print(f"YOU TOOK {int(time + random())}SECONDS.") + print("An official caught you!") + print(f"You took {int(time + random())} seconds.") return else: - print("YOU MADE IT!") + print("You made it!") time += 1.5 else: match opt: @@ -97,69 +97,69 @@ def run(): case 7: speed -= int(random() * (10 - 5) + 5) - print(f" {int(speed)}M.P.H.") + print(f" {int(speed)} M.P.H.") if speed > max_speeds[i]: if random() < ((speed - max_speeds[i]) * .1) + .2: - print(f"YOU WENT OVER THE MAXIMUM SPEED AND {'SNAGGED A FLAG' if random() < .5 else 'WIPED OUT'}!") - print(f"YOU TOOK {int(time + random())}SECONDS") + print(f"You went over the maximum speed and {'snagged a flag' if random() < .5 else 'wiped out'}!") + print(f"You took {int(time + random())} seconds") return else: - print("YOU WENT OVER THE NAXIMUM SPEED AND MADE IT!") + print("You went over the maximum speed and made it!") if speed > max_speeds[i] - 1: - print("CLOSE ONE!") + print("Close one!") if speed < 7: - print("LET'S BE REALISTIC, OK? LET'S GO BACK AND TRY AGAIN...") + print("Let's be realistic, ok? Let's go back and try again...") speed = old_speed else: time += max_speeds[i] - speed + 1 if speed > max_speeds[i]: time += .5 break - print(f"\nYOU TOOK {int(time + random())}SECONDS.") + print(f"\nYou took {int(time + random())} seconds.") avg = time / gates if avg < 1.5 - (lvl * .1): - print("YOU WON A GOLD MEDAL!") + print("Yout won a gold medal!") medals["gold"] += 1 elif avg < 2.9 - (lvl * .1): - print("YOU WON A SILVER MEDAL!") + print("You won a silver medal!") medals["silver"] += 1 elif avg < 4.4 - (lvl * .01): - print("YOU WON A BRONZE MEDAL!") + print("You won a bronze medal!") medals["bronze"] += 1 while True: - gates = ask_int("HOW MANY GATES DOES THIS COURSE HAVE (1 TO 25)") + gates = ask_int("How many gates does this course have (1 to 25)") if gates < 1: - print("TRY AGAIN,") + print("Try again,") else: if(gates > 25): - print("25 IS THE LIMIT.") + print("25 is the limit.") break pre_run() while True: - lvl = ask_int("RATE YOURSELF AS A SKIER, (1=WORST, 3=BEST)") + lvl = ask_int("Rate yourself as a skier, (1=Worst, 3=Best)") if lvl < 1 or lvl > 3: - print("THE BOUNDS ARE 1-3.") + print("The bounds are 1-3.") else: break while True: run() while True: - answer = ask("DO YOU WANT TO PLAY AGAIN?") + answer = ask("Do you want to play again?") if answer == "YES" or answer == "NO": break else: - print("PLEASE TYPE 'YES' OR 'NO'") + print("Please type \"YES\" or \"NO\"") if answer == "NO": break -print("THANKS FOR THE RACE") +print("Thanks for the race") if medals["gold"] > 0: - print(f"GOLD MEDALS: {medals['gold']}") + print(f"Gold medals: {medals['gold']}") if medals["silver"] > 0: - print(f"SILVER MEDALS: {medals['silver']}") + print(f"Silver medals: {medals['silver']}") if medals["bronze"] > 0: - print(f"BRONZE MEDALS: {medals['bronze']}") + print(f"Bronze medals: {medals['bronze']}") From 10af3318d66d7314c0b49023447f0970b716a140 Mon Sep 17 00:00:00 2001 From: Gabry Date: Thu, 24 Feb 2022 19:35:40 +0100 Subject: [PATCH 337/337] Formatted the output texts to follow a more modern style --- 79_Slalom/python/slalom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/79_Slalom/python/slalom.py b/79_Slalom/python/slalom.py index 44ce0fde..a764e84a 100644 --- a/79_Slalom/python/slalom.py +++ b/79_Slalom/python/slalom.py @@ -76,7 +76,7 @@ def run(): print(f"You took {int(time + random())} seconds.") return else: - print("You made it!") + print("You made it!") time += 1.5 else: match opt: